100 lines
3.0 KiB
Python
100 lines
3.0 KiB
Python
from fabric.core.service import Property
|
|
from fabric.widgets.button import Button
|
|
from fabric.widgets.box import Box
|
|
from fabric.widgets.eventbox import EventBox
|
|
from fabric.utils.helpers import bulk_connect
|
|
from .service import River
|
|
|
|
|
|
from gi.repository import Gdk
|
|
|
|
_connection: River | None = None
|
|
|
|
|
|
def get_river_connection() -> River:
|
|
global _connection
|
|
if not _connection:
|
|
_connection = River()
|
|
return _connection
|
|
|
|
|
|
class RiverWorkspaceButton(Button):
|
|
@Property(int, "readable")
|
|
def id(self) -> int:
|
|
return self._id
|
|
|
|
@Property(bool, "read-write", default_value=False)
|
|
def active(self) -> bool:
|
|
return self._active
|
|
|
|
@active.setter
|
|
def active(self, value: bool):
|
|
self._active = value
|
|
(self.remove_style_class if not value else self.add_style_class)("active")
|
|
|
|
@Property(bool, "read-write", default_value=False)
|
|
def empty(self) -> bool:
|
|
return self._empty
|
|
|
|
@empty.setter
|
|
def empty(self, value: bool):
|
|
self._empty = value
|
|
(self.remove_style_class if not value else self.add_style_class)("empty")
|
|
|
|
def __init__(self, id: int, label: str = None, **kwargs):
|
|
super().__init__(label or str(id), **kwargs)
|
|
self._id = id
|
|
self._active = False
|
|
self._empty = True
|
|
|
|
|
|
class RiverWorkspaces(EventBox):
|
|
def __init__(self, output_id: int, max_tags: int = 9, **kwargs):
|
|
super().__init__(events="scroll")
|
|
self.output_id = output_id
|
|
self.max_tags = max_tags
|
|
self.service = get_river_connection()
|
|
self._box = Box(**kwargs)
|
|
self.children = self._box
|
|
|
|
self._buttons = {i: RiverWorkspaceButton(i) for i in range(max_tags)}
|
|
for btn in self._buttons.values():
|
|
btn.connect("clicked", self.on_workspace_click)
|
|
self._box.add(btn)
|
|
|
|
# hook into River signals
|
|
self.service.connect(f"event::focused_tags::{output_id}", self.on_focus_change)
|
|
self.service.connect(f"event::view_tags::{output_id}", self.on_view_change)
|
|
if self.service.ready:
|
|
self.on_ready(None)
|
|
else:
|
|
self.service.connect("event::ready", self.on_ready)
|
|
|
|
self.connect("scroll-event", self.on_scroll)
|
|
|
|
def on_ready(self, _):
|
|
print(self.service.outputs)
|
|
|
|
def on_focus_change(self, _, tags: list[int]):
|
|
print(tags)
|
|
for i, btn in self._buttons.items():
|
|
btn.active = i in tags
|
|
|
|
def on_view_change(self, _, tags: list[int]):
|
|
print(tags)
|
|
for i, btn in self._buttons.items():
|
|
btn.empty = i not in tags
|
|
|
|
def on_workspace_click(self, btn: RiverWorkspaceButton):
|
|
import subprocess
|
|
|
|
subprocess.run(["riverctl", "tag", str(btn.id)])
|
|
return
|
|
|
|
def on_scroll(self, _, event: Gdk.EventScroll):
|
|
direction = event.direction # UP or DOWN
|
|
cmd = "tag +1" if direction == Gdk.ScrollDirection.DOWN else "tag -1"
|
|
import subprocess
|
|
|
|
subprocess.run(["riverctl", *cmd.split()])
|