Files
Modus/modules/dock/components/workspaces.py
T
2025-06-12 03:07:29 +05:45

149 lines
4.6 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 Workspaces, WorkspaceButton
from fabric.widgets.button import Button
import config.data as data
from fabric.widgets.box import Box
CHINESE_NUMERALS = ["一", "二", "三", "四", "五", "六", "七", "八", "九", "〇"]
class Workspace(Button):
def __init__(self):
# Determine if invert style should be applied
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):
"""Get list of workspaces that have windows"""
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):
"""Handle button click to cycle through workspaces"""
self._cycle_workspace()
def _cycle_workspace(self):
"""Core logic to cycle through workspaces"""
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))
# Create workspace components using Workspaces widget
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)
],
)
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)
],
)
# Create the workspace button instance
workspaceactive = Workspace()
# Export the workspace widget based on configuration
workspace = Box(
name="workspaces-container",
children=[
workspaces
if data.WORKSPACE_DOTS
else workspaces_num
if data.WORKSPACE_NUMS
else workspaceactive
],
)