#!/bin/env python3 import os import sys import subprocess import json import socket from dataclasses import dataclass NAME = [ "?", "", "󰄛", "󰴈", "♪", "", "", "󰑴", "", ] @dataclass class State: wss: dict mname: str focused: bool prev_active: int def handle(state: State, event: str, data: str = None): wss = state.wss changed = True if event == "focusedmon": state.focused = data[:-2] == state.mname if not state.focused: return if event == "workspace": wid = int(data) if state.prev_active in wss.keys(): wss[state.prev_active]['focused'] = False if wid in wss.keys(): wss[wid]['focused'] = True state.prev_active = wid return output(state) if event == "createworkspace": wss[int(data)] = new_ws(int(data), True, False) state.wss = dict(sorted(wss.items())) return output(state) if event == "destroyworkspace": if int(data) in wss: del wss[int(data)] return output(state) def output(state: State): print(json.dumps(list(state.wss.values())), flush=True) def main(mid: str): state = get_state(mid) output(state) isig = os.getenv("HYPRLAND_INSTANCE_SIGNATURE") client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) client.connect(f"/tmp/hypr/{isig}/.socket2.sock") while True: r = client.recv(1024) if not r: break msgs = r.decode().strip().split("\n") for msg in msgs: parts = msg.split(">>") handle(state, *parts) def get_state(mid: str): mid = int(mid) res = subprocess.run( ["hyprctl", "monitors", "-j"], capture_output=True ) raw_mons = json.loads(res.stdout) res = subprocess.run( ["hyprctl", "workspaces", "-j"], capture_output=True ) raw_wss = json.loads(res.stdout) mname: str = None activews: int = None focused: bool = None for m in raw_mons: if m['id'] == mid: activews = int(m['activeWorkspace']['id']) mname = m['name'] focused = m['focused'] break if mname is None: print("Error: monitor not found", file=sys.stderr) sys.exit(1) wss = dict() for ws in raw_wss: if ws['monitor'] == mname: wid = int(ws['id']) wss[wid] = new_ws(wid, wid == activews, False) wss = dict(sorted(wss.items())) return State(wss, mname, focused, activews) def new_ws(wid, focused, urgent): return { 'id': wid, 'name': NAME[wid], 'focused': focused, 'urgent': urgent } if __name__ == '__main__': try: main(*sys.argv[1:]) except KeyboardInterrupt: pass