From d9c9bf546bb767b079434d5fc8e199b2731f6375 Mon Sep 17 00:00:00 2001 From: pyrschtjag Date: Sat, 11 Jul 2026 16:41:17 +0400 Subject: [PATCH] test_version --- eww/scripts/workspaces.py | 232 ++++++++++++++++---------------- eww/scripts/workspaces_map.json | 2 +- hypr/config/exec.conf | 1 + hypr/config/programs.conf | 4 +- hypr/hyprland.conf | 4 +- 5 files changed, 120 insertions(+), 123 deletions(-) diff --git a/eww/scripts/workspaces.py b/eww/scripts/workspaces.py index 5919e45..1c52010 100755 --- a/eww/scripts/workspaces.py +++ b/eww/scripts/workspaces.py @@ -1,10 +1,9 @@ +#!/usr/bin/env python3 + +import asyncio import json -import subprocess import os import sys -import socket -import threading -import time class UnifiedWorkspaceManager: def __init__(self): @@ -16,11 +15,8 @@ class UnifiedWorkspaceManager: self.monitors_cache = {} self.load_icon_configuration() - self.clients_refresh() - self.monitors_refresh() def load_icon_configuration(self): - # тянем иконки из конфига config_path = os.path.join(self.script_directory, "workspaces_map.json") try: with open(config_path, 'r') as file: @@ -28,53 +24,59 @@ class UnifiedWorkspaceManager: except: self.icon_map = {"default": "", "no-icon": ""} - def monitors_refresh(self): - # обновляем инфу по мониторам + async def monitors_refresh(self): try: - raw = subprocess.check_output(["hyprctl", "-j", "monitors"], stderr=subprocess.DEVNULL) - monitors = json.loads(raw) - self.monitors_cache = { - m['name']: { - "id": m['id'], - "active_workspace_id": m['activeWorkspace']['id'], - "focused": m.get('focused', False) - } for m in monitors - } + proc = await asyncio.create_subprocess_exec( + "hyprctl", "-j", "monitors", + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.DEVNULL + ) + stdout, _ = await proc.communicate() + if proc.returncode == 0: + monitors = json.loads(stdout.decode()) + self.monitors_cache = { + m['name']: { + "id": m['id'], + "active_workspace_id": m['activeWorkspace']['id'], + "focused": m.get('focused', False) + } for m in monitors + } except: self.monitors_cache = {} - def clients_refresh(self): - # полный сброс и пересборка кэша окон + async def clients_refresh(self): try: - raw = subprocess.check_output(["hyprctl", "-j", "clients"], stderr=subprocess.DEVNULL) - clients = json.loads(raw) - self.clients_cache = { - c['address'].strip().replace('0x', ''): { - "class": c['class'], - "workspace_id": c['workspace']['id'], - "monitor_id": c['monitor'] - } for c in clients - } + proc = await asyncio.create_subprocess_exec( + "hyprctl", "-j", "clients", + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.DEVNULL + ) + stdout, _ = await proc.communicate() + if proc.returncode == 0: + clients = json.loads(stdout.decode()) + self.clients_cache = { + c['address'].strip().replace('0x', ''): { + "class": c['class'], + "workspace_id": c['workspace']['id'], + "monitor_id": c['monitor'] + } for c in clients + } except: self.clients_cache = {} def get_current_state_json(self): - # собираем финальный json try: output = {} - for mon_name, mon_data in self.monitors_cache.items(): m_id = mon_data["id"] active_id = mon_data["active_workspace_id"] focused = mon_data["focused"] - # готовим 10 слотов workspaces = { str(i): {"exists": False, "active": False, "focused": False, "urgent": False, "icons": []} for i in range(1, 11) } - # раскидываем окна по воркспейсам for addr, client in self.clients_cache.items(): if client['monitor_id'] == m_id: ws_id = str(client['workspace_id']) @@ -88,12 +90,10 @@ class UnifiedWorkspaceManager: if icon not in slot["icons"]: slot["icons"].append(icon) - # помечаем текущий активный воркспейс curr_ws = str(active_id) if curr_ws in workspaces: workspaces[curr_ws].update({"active": True, "focused": focused, "exists": True}) - # рисуем no-icon for ws in workspaces.values(): if ws["exists"] and not ws["icons"]: ws["icons"] = [self.icon_map.get("no-icon", "")] @@ -105,109 +105,105 @@ class UnifiedWorkspaceManager: return "{}" def push_update(self): - # отдаём json в stdout при изменении current = self.get_current_state_json() if current != self.last_sent_json: self.last_sent_json = current sys.stdout.write(current + '\n') sys.stdout.flush() - def update_client(self, window_address): - # обновляем окно + async def update_client(self, window_address): try: clean_addr = window_address.replace('0x', '') search_addr = f"0x{clean_addr}" - raw = subprocess.check_output(["hyprctl", "-j", "clients"], stderr=subprocess.DEVNULL) - clients = json.loads(raw) + proc = await asyncio.create_subprocess_exec( + "hyprctl", "-j", "clients", + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.DEVNULL + ) + stdout, _ = await proc.communicate() - target = next((c for c in clients if c['address'] == search_addr), None) - - if target: - self.clients_cache[clean_addr] = { - "class": target.get('class', 'unknown'), - "workspace_id": target['workspace']['id'], - "monitor_id": target['monitor'] - } - else: - self.clients_cache.pop(clean_addr, None) + if proc.returncode == 0: + clients = json.loads(stdout.decode()) + target = next((c for c in clients if c['address'] == search_addr), None) + if target: + self.clients_cache[clean_addr] = { + "class": target.get('class', 'unknown'), + "workspace_id": target['workspace']['id'], + "monitor_id": target['monitor'] + } + return + + self.clients_cache.pop(clean_addr, None) except: - # если что-то отвалилось, то просто пересобираем всё - self.clients_refresh() + await self.clients_refresh() - def run(self): + async def run(self): + await self.clients_refresh() + await self.monitors_refresh() self.push_update() - def event_socket_listener(): - # слушаем сокет хайпера - signature = os.environ.get('HYPRLAND_INSTANCE_SIGNATURE') - socket_path = f"/run/user/{os.getuid()}/hypr/{signature}/.socket2.sock" + signature = os.environ.get('HYPRLAND_INSTANCE_SIGNATURE') + socket_path = f"/run/user/{os.getuid()}/hypr/{signature}/.socket2.sock" - while True: - try: - with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as sock: - sock.connect(socket_path) - buf = "" - while True: - data = sock.recv(4096).decode('utf-8', errors='ignore') - if not data: break - buf += data - - if '\n' in buf: - lines = buf.split('\n') - buf = lines.pop() - - trigger = False - for line in lines: - if ">>" not in line: continue - event, args = line.split('>>') - - # ивенты с окнами - if event in ["openwindow", "movewindow"]: - addr = args.split(',')[0].replace('0x', '') - self.update_client(addr) - trigger = True - - elif event == "closewindow": - addr = args.replace('0x', '') - self.clients_cache.pop(addr, None) - self.urgent_window_addresses.discard(addr) - trigger = True + while True: + try: + reader, writer = await asyncio.open_unix_connection(socket_path) + + while True: + line_bytes = await reader.readline() + if not line_bytes: + break + + line = line_bytes.decode('utf-8', errors='ignore').strip() + if ">>" not in line: + continue + + event, args = line.split('>>') + trigger = False + + if event in ["openwindow", "movewindow"]: + addr = args.split(',')[0].replace('0x', '') + await self.update_client(addr) + trigger = True + + elif event == "closewindow": + addr = args.replace('0x', '') + self.clients_cache.pop(addr, None) + self.urgent_window_addresses.discard(addr) + trigger = True - # ивенты с мониторами - elif event in ["workspace", "workspacev2", "monitoradded", "monitorremoved"]: - self.monitors_refresh() - trigger = True + elif event in ["workspace", "workspacev2", "monitoradded", "monitorremoved"]: + await self.monitors_refresh() + trigger = True - elif event in ["focusedmon", "focusedmonv2"]: - mon_name = args.split(',')[0] - for name in self.monitors_cache: - self.monitors_cache[name]["focused"] = (name == mon_name) - trigger = True + elif event in ["focusedmon", "focusedmonv2"]: + mon_name = args.split(',')[0] + for name in self.monitors_cache: + self.monitors_cache[name]["focused"] = (name == mon_name) + trigger = True - # алерты - elif event == "urgent": - self.urgent_window_addresses.add(args.replace('0x', '')) - trigger = True - - elif event in ["activewindow", "activewindowv2"]: - addr = args.split(',')[0].replace('0x', '') - if addr in self.urgent_window_addresses: - self.urgent_window_addresses.remove(addr) - trigger = True + elif event == "urgent": + self.urgent_window_addresses.add(args.replace('0x', '')) + trigger = True + + elif event in ["activewindow", "activewindowv2"]: + addr = args.split(',')[0].replace('0x', '') + if addr in self.urgent_window_addresses: + self.urgent_window_addresses.remove(addr) + trigger = True - if trigger: - self.push_update() - except: - time.sleep(2) # реконнект, если хайпер отвалился - - # слушаем поток в фоне - threading.Thread(target=event_socket_listener, daemon=True).start() - - try: - while True: time.sleep(100) - except KeyboardInterrupt: sys.exit(0) + if trigger: + self.push_update() + + except (asyncio.CancelledError, KeyboardInterrupt): + break + except Exception as e: + await asyncio.sleep(2) if __name__ == "__main__": - UnifiedWorkspaceManager().run() \ No newline at end of file + try: + asyncio.run(UnifiedWorkspaceManager().run()) + except KeyboardInterrupt: + sys.exit(0) \ No newline at end of file diff --git a/eww/scripts/workspaces_map.json b/eww/scripts/workspaces_map.json index 8b39846..ac8f31d 100644 --- a/eww/scripts/workspaces_map.json +++ b/eww/scripts/workspaces_map.json @@ -4,7 +4,7 @@ "firefox": "", "code-oss": "󰨞", "org.telegram.desktop": "", - "kitty": "", + "foot": "", "steam": "", "Spotify": "", "discord": "󰙯", diff --git a/hypr/config/exec.conf b/hypr/config/exec.conf index cd713a9..2ad8464 100644 --- a/hypr/config/exec.conf +++ b/hypr/config/exec.conf @@ -6,3 +6,4 @@ exec-once = gsettings set org.gnome.desktop.interface gtk-theme "Adwaita-dark" exec-once = gsettings set org.gnome.desktop.interface color-scheme "prefer-dark" exec-once = eww daemon && sleep 1 && eww open-many bar_0 bar_1 wallpaper_0 wallpaper_1 exec-once = hypridle --grace 15 +exec-once = python3 /home/pyrschtjag/Documents/.ntfy-notify/ntfy-notify.py diff --git a/hypr/config/programs.conf b/hypr/config/programs.conf index d0ce321..8ca6d33 100644 --- a/hypr/config/programs.conf +++ b/hypr/config/programs.conf @@ -1,4 +1,4 @@ $mainMod = SUPER -$terminal = kitty -$fileManager = kitty mc +$terminal = foot +//$fileManager = kitty mc $menu = rofi -show drun diff --git a/hypr/hyprland.conf b/hypr/hyprland.conf index 34cffca..bd40daf 100644 --- a/hypr/hyprland.conf +++ b/hypr/hyprland.conf @@ -6,9 +6,9 @@ source = ~/.config/hypr/config/env.conf source = ~/.config/hypr/config/general.conf source = ~/.config/hypr/config/decoration.conf source = ~/.config/hypr/config/animations.conf -source = ~/.config/hypr/config/dwindle.conf +//source = ~/.config/hypr/config/dwindle.conf source = ~/.config/hypr/config/master.conf source = ~/.config/hypr/config/misc.conf source = ~/.config/hypr/config/input.conf source = ~/.config/hypr/config/bind.conf -source = ~/.config/hypr/config/windowrule.conf \ No newline at end of file +source = ~/.config/hypr/config/windowrule.conf