Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions examples/bar/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ def hyprland_workspace_button(workspace: HyprlandWorkspace) -> widgets.Button:
)
if workspace.id == hyprland.active_workspace.id:
widget.add_css_class("active")
if workspace.id in hyprland.urgent_workspaces:
widget.add_css_class("urgent")

return widget

Expand Down Expand Up @@ -104,8 +106,8 @@ def hyprland_workspaces() -> widgets.EventBox:
css_classes=["workspaces"],
spacing=5,
child=hyprland.bind_many( # bind also to active_workspace to regenerate workspaces list when active workspace changes
["workspaces", "active_workspace"],
transform=lambda workspaces, active_workspace: [
["workspaces", "active_workspace", "urgent_workspaces"],
transform=lambda workspaces, active_workspace, urgent_workspaces: [
workspace_button(i) for i in workspaces
],
),
Expand Down
9 changes: 8 additions & 1 deletion examples/bar/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ $bg-light: #261d1e;
$fg: #f0dedf;
$active: #ffb2bc;
$unactive: #d7c1c3;
$urgent: #eb6f92;

.bar {
padding: 0.4rem 1rem;
Expand Down Expand Up @@ -54,6 +55,11 @@ $unactive: #d7c1c3;
color: $bg;
}

.workspace.urgent {
background-color: $urgent;
color: $bg;
}

.tray-item {
all: unset;
}
Expand Down Expand Up @@ -97,4 +103,5 @@ popover.menu {
}

}
}
}

37 changes: 37 additions & 0 deletions ignis/services/hyprland/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,28 @@ def workspaces(self) -> list[HyprlandWorkspace]:
"""
return list(self._workspaces.values())

@IgnisProperty
def urgent_windows(self) -> list[str]:
"""
A list of urgent windows.
"""
return [i for i in self._windows.values() if i.is_urgent]

@IgnisProperty
def urgent_workspaces(self) -> list[str]:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, maybe HyprlandWindow and HyprlandWorkspace should simply have is_urgent property? Instead of making separate lists

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that, how would you bind to urgent though? Do you just bind to the windows property at that point?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HyprlandWindow (and HyprlandWorkspace) are GObjects too, so you can bind to them

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wouldn't support binding to both properties under HyprlandWindow and the hyprland service though. I might be over-complicating it but how would I do what I'm doing in hyprland_workspaces() in the example bar?

"""
A list of urgent workspaces.
"""
clients = json.loads(self.send_command("j/clients"))
urgent_workspaces = []
for i in clients:
address = i["address"]
if address not in self._windows:
continue
if self._windows[address].is_urgent:
urgent_workspaces.append(i["workspace"]["id"])
return urgent_workspaces

@IgnisProperty
def active_workspace(self) -> HyprlandWorkspace:
"""
Expand Down Expand Up @@ -194,6 +216,8 @@ def get_full_w_addr(addr: str) -> str:
value_list = event_value.split(",")

match event_type:
case "urgent":
self.__sync_urgent(get_full_w_addr(value_list[0]))
case "destroyworkspacev2":
self.__destroy_workspace(int(value_list[0]))
case "createworkspacev2":
Expand Down Expand Up @@ -357,12 +381,25 @@ def __sync_main_keyboard(self) -> None:
def __sync_active_layout(self, layout: str) -> None:
self._main_keyboard.sync({"active_keymap": layout})

def __sync_urgent(self, urgent_window) -> None:
if urgent_window in self._windows:
self._windows[urgent_window]._urgent = True
self.notify("urgent_windows")
self.notify("urgent_workspaces")

def __sync_active_window(self) -> None:
active_window_data = json.loads(self.send_command("j/activewindow"))
if active_window_data == {}:
active_window_data = HyprlandWindow().data

self.active_window.sync(active_window_data)

active_window_id = active_window_data["address"]
if active_window_id in self._windows and self._windows[active_window_id]._urgent:
self._windows[active_window_id]._urgent = False
self.notify("urgent_windows")
self.notify("urgent_workspaces")

self.notify("active-window")

def __open_window(self, address: str) -> None:
Expand Down
8 changes: 8 additions & 0 deletions ignis/services/hyprland/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def __init__(self):
self._swallowing: str = ""
self._focus_history_id: int = -1
self._inhibiting_idle: bool = False
self._urgent: bool = False

def sync(self, data: dict[str, Any]) -> None:
"""
Expand Down Expand Up @@ -227,3 +228,10 @@ def inhibiting_idle(self) -> bool:
The inhibiting idle status.
"""
return self._inhibiting_idle

@IgnisProperty
def is_urgent(self) -> bool:
"""
Whether this window is urgent or not
"""
return self._urgent
Loading