fabric-makussu/bar/river/widgets.py
2025-05-01 14:09:14 +02:00

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()])