urgent tags
This commit is contained in:
parent
0966c1ce70
commit
736e1a47c9
13
bar/bar.css
13
bar/bar.css
@ -73,12 +73,21 @@ button {
|
||||
font-size: 0px;
|
||||
}
|
||||
|
||||
#workspaces>button:hover {
|
||||
#workspaces button.hover {
|
||||
background-color: var(--ws-hover);
|
||||
}
|
||||
|
||||
#workspaces>button.urgent {
|
||||
#workspaces button.urgent {
|
||||
background-color: var(--ws-urgent);
|
||||
color: var(--foreground);
|
||||
font-weight: bold;
|
||||
animation: urgent-blink 1s infinite;
|
||||
}
|
||||
|
||||
@keyframes urgent-blink {
|
||||
0% { opacity: 1.0; }
|
||||
50% { opacity: 0.5; }
|
||||
100% { opacity: 1.0; }
|
||||
}
|
||||
|
||||
#workspaces>button.empty {
|
||||
|
||||
@ -10,7 +10,7 @@ from fabric.utils.helpers import idle_add
|
||||
|
||||
# Import pywayland components - ensure these imports are correct
|
||||
from pywayland.client import Display
|
||||
from pywayland.protocol.wayland import WlOutput, WlRegistry, WlSeat
|
||||
from pywayland.protocol.wayland import WlOutput, WlSeat
|
||||
from .generated.river_status_unstable_v1 import ZriverStatusManagerV1
|
||||
|
||||
|
||||
@ -23,6 +23,7 @@ class OutputInfo:
|
||||
status: Any = None # ZriverOutputStatusV1
|
||||
tags_view: List[int] = field(default_factory=list)
|
||||
tags_focused: List[int] = field(default_factory=list)
|
||||
tags_urgent: List[int] = field(default_factory=list)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@ -190,11 +191,23 @@ class River(Service):
|
||||
|
||||
return handler
|
||||
|
||||
def make_urgent_tags_handler(output_id):
|
||||
def handler(_, tags):
|
||||
decoded = self._decode_bitfields(tags)
|
||||
state["outputs"][output_id].tags_urgent = decoded
|
||||
logger.debug(
|
||||
f"[RiverService] Output {output_id} urgent tags: {decoded}"
|
||||
)
|
||||
idle_add(lambda: self._emit_urgent_tags(output_id, decoded))
|
||||
|
||||
return handler
|
||||
|
||||
# Bind output status listeners
|
||||
for name, info in list(state["outputs"].items()):
|
||||
status = state["river_status_mgr"].get_river_output_status(info.output)
|
||||
status.dispatcher["view_tags"] = make_view_tags_handler(name)
|
||||
status.dispatcher["focused_tags"] = make_focused_tags_handler(name)
|
||||
status.dispatcher["urgent_tags"] = make_urgent_tags_handler(name)
|
||||
info.status = status
|
||||
logger.info(f"[RiverService] Set up status for output {name}")
|
||||
|
||||
@ -251,6 +264,13 @@ class River(Service):
|
||||
self.notify("active-window")
|
||||
return False # Don't repeat
|
||||
|
||||
def _emit_urgent_tags(self, output_id, tags):
|
||||
"""Emit urgent_tags events (called on main thread)"""
|
||||
event = RiverEvent("urgent_tags", tags, output_id)
|
||||
self.emit("event::urgent_tags", event)
|
||||
self.emit(f"event::urgent_tags::{output_id}", tags)
|
||||
return False # Don't repeat
|
||||
|
||||
@staticmethod
|
||||
def _decode_bitfields(bitfields) -> List[int]:
|
||||
"""Decode River's tag bitfields into a list of tag indices"""
|
||||
|
||||
@ -43,11 +43,36 @@ class RiverWorkspaceButton(Button):
|
||||
self._empty = value
|
||||
(self.remove_style_class if not value else self.add_style_class)("empty")
|
||||
|
||||
@Property(bool, "read-write", default_value=False)
|
||||
def urgent(self) -> bool:
|
||||
return self._urgent
|
||||
|
||||
@urgent.setter
|
||||
def urgent(self, value: bool):
|
||||
self._urgent = value
|
||||
self._update_style()
|
||||
|
||||
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
|
||||
self._urgent = False
|
||||
|
||||
def _update_style(self):
|
||||
"""Update button styles based on states"""
|
||||
# Remove all state-related styles first
|
||||
self.remove_style_class("active")
|
||||
self.remove_style_class("empty")
|
||||
self.remove_style_class("urgent")
|
||||
|
||||
# Then apply current states
|
||||
if self._active:
|
||||
self.add_style_class("active")
|
||||
if self._empty:
|
||||
self.add_style_class("empty")
|
||||
if self._urgent:
|
||||
self.add_style_class("urgent")
|
||||
|
||||
|
||||
class RiverWorkspaces(EventBox):
|
||||
@ -71,6 +96,7 @@ class RiverWorkspaces(EventBox):
|
||||
# Connect to service events
|
||||
self.service.connect("event::focused_tags", self.on_focus_change_general)
|
||||
self.service.connect("event::view_tags", self.on_view_change_general)
|
||||
self.service.connect("event::urgent_tags", self.on_urgent_change_general)
|
||||
self.service.connect("event::output_removed", self.on_output_removed)
|
||||
|
||||
# Initial setup when service is ready
|
||||
@ -100,14 +126,16 @@ class RiverWorkspaces(EventBox):
|
||||
# Access fields directly on the OutputInfo dataclass
|
||||
focused_tags = output_info.tags_focused
|
||||
view_tags = output_info.tags_view
|
||||
urgent_tags = output_info.tags_urgent
|
||||
|
||||
logger.debug(
|
||||
f"[RiverWorkspaces] Initial state - focused: {focused_tags}, view: {view_tags}"
|
||||
f"[RiverWorkspaces] Initial state - focused: {focused_tags}, view: {view_tags}, urgent: {urgent_tags}"
|
||||
)
|
||||
|
||||
for i, btn in self._buttons.items():
|
||||
btn.active = i in focused_tags
|
||||
btn.empty = i not in view_tags
|
||||
btn.urgent = i in urgent_tags
|
||||
|
||||
def on_focus_change(self, _, tags):
|
||||
"""Handle focused tags change for our specific output"""
|
||||
@ -143,6 +171,23 @@ class RiverWorkspaces(EventBox):
|
||||
)
|
||||
self.on_view_change(_, event.data)
|
||||
|
||||
def on_urgent_change(self, _, tags):
|
||||
"""Handle urgent tags change for our specific output"""
|
||||
logger.debug(
|
||||
f"[RiverWorkspaces] Urgent change on output {self.output_id}: {tags}"
|
||||
)
|
||||
for i, btn in self._buttons.items():
|
||||
btn.urgent = i in tags
|
||||
|
||||
def on_urgent_change_general(self, _, event):
|
||||
"""Handle general urgent tags event"""
|
||||
# Only handle event if it's for our output
|
||||
if event.output_id == self.output_id:
|
||||
logger.debug(
|
||||
f"[RiverWorkspaces] General urgent change for output {self.output_id}"
|
||||
)
|
||||
self.on_urgent_change(_, event.data)
|
||||
|
||||
def on_output_removed(self, _, event):
|
||||
"""Handle output removal"""
|
||||
removed_id = event.data[0]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user