Files
Modus/modules/dock/components/workspaces.py
T
2025-06-26 16:10:17 +05:45

148 lines
4.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import json
import subprocess
from fabric.hyprland.service import Hyprland
from fabric.hyprland.widgets import WorkspaceButton, Workspaces
from fabric.widgets.box import Box
from fabric.widgets.button import Button
import config.data as data
CHINESE_NUMERALS = ["一", "二", "三", "四", "五", "六", "七", "八", "九", "〇"]
class Workspace(Button):
def __init__(self):
should_invert = data.DOCK_THEME in ["Dense", "Edge"] or (
data.DOCK_THEME == "Pills" and data.DOCK_POSITION in ["Left", "Right"]
)
super().__init__(
name="workspace-single",
can_focus=True,
receives_default=True,
relief="none",
style_classes="invert" if should_invert else None,
)
self.connection = Hyprland()
self.activeWorkspace = str(self._get_active_workspace())
self.set_label(str(self.activeWorkspace))
self.connect("clicked", self._on_click)
self.connection.connect("event::workspace", self._on_workspace_changed)
self.set_sensitive(True)
self.show_all()
def _get_active_workspace(self):
active = self.connection.send_command("j/activeworkspace").reply
return json.loads(active.decode("utf-8"))["name"]
def _get_active_workspaces(self):
clients_data = self.connection.send_command("j/clients").reply
clients = json.loads(clients_data.decode("utf-8"))
active_workspaces = set()
for client in clients:
if "workspace" in client and "name" in client["workspace"]:
workspace_name = str(client["workspace"]["name"])
active_workspaces.add(workspace_name)
return sorted(
list(active_workspaces), key=lambda x: int(x) if x.isdigit() else x
)
def _on_click(self, _widget):
self._cycle_workspace()
def _cycle_workspace(self):
active_workspaces = self._get_active_workspaces()
if not active_workspaces:
return
if str(self.activeWorkspace) not in active_workspaces:
active_workspaces.append(str(self.activeWorkspace))
active_workspaces.sort(key=lambda x: int(x) if x.isdigit() else x)
current_index = active_workspaces.index(self.activeWorkspace)
next_index = (current_index + 1) % len(active_workspaces)
next_workspace = active_workspaces[next_index]
cmd = ["hyprctl", "dispatch", "workspace", str(next_workspace)]
subprocess.run(cmd, capture_output=True, text=True, timeout=2)
self.activeWorkspace = str(next_workspace)
self.set_label(str(self.activeWorkspace))
def _on_workspace_changed(self, _obj, signal):
"""Handle workspace change events from Hyprland"""
workspace_data = json.loads(signal.data[0])
self.activeWorkspace = str(workspace_data)
self.set_label(str(self.activeWorkspace))
workspaces = Workspaces(
name="workspaces",
invert_scroll=True,
empty_scroll=True,
v_align="fill",
orientation="h" if not data.VERTICAL else "v",
spacing=8,
buttons=[
WorkspaceButton(
h_expand=False,
v_expand=False,
h_align="center",
v_align="center",
id=i,
label=None,
style_classes=["vertical"] if data.VERTICAL else None,
)
for i in range(1, 11)
],
buttons_factory=None
if data.DOCK_HIDE_SPECIAL_WORKSPACE
else Workspaces.default_buttons_factory,
)
workspaces_num = Workspaces(
name="workspaces-num",
invert_scroll=True,
empty_scroll=True,
v_align="fill",
orientation="h" if not data.VERTICAL else "v",
spacing=0 if not data.WORKSPACE_USE_CHINESE_NUMERAL else 4,
buttons=[
WorkspaceButton(
h_expand=False,
v_expand=False,
h_align="center",
v_align="center",
id=i,
label=CHINESE_NUMERALS[i - 1]
if data.WORKSPACE_USE_CHINESE_NUMERAL and 1 <= i <= len(CHINESE_NUMERALS)
else str(i),
)
for i in range(1, 11)
],
buttons_factory=None
if data.DOCK_HIDE_SPECIAL_WORKSPACE
else Workspaces.default_buttons_factory,
)
workspaceactive = Workspace()
workspace = Box(
name="workspaces-container",
children=[
workspaces
if data.WORKSPACE_DOTS
else workspaces_num
if data.WORKSPACE_NUMS
else workspaceactive
],
)