Skip to content
Open
Show file tree
Hide file tree
Changes from 9 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 {
}

}
}
}

38 changes: 38 additions & 0 deletions ignis/services/hyprland/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ def __init__(self):
self._windows: dict[str, HyprlandWindow] = {}
self._active_window: HyprlandWindow = HyprlandWindow()
self._monitors: dict[str, HyprlandMonitor] = {}
self._urgent_windows = set()

self._OBJ_TYPES: dict[str, _HyprlandObjDesc] = {
"workspace": _HyprlandObjDesc(
Expand Down Expand Up @@ -143,6 +144,29 @@ def workspaces(self) -> list[HyprlandWorkspace]:
"""
return list(self._workspaces.values())

@IgnisProperty
def urgent_windows(self) -> list[str]:
"""
- read-only

A list of urgent windows.
"""
return list(self._urgent_windows)

@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.

They should return a list of HyprlandWindow and HyprlandWorkspace accordingly

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.

This should be done in my latest commits.

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?

"""
- read-only

A list of urgent workspaces.
"""
clients = json.loads(self.send_command("j/clients"))
urgent_workspaces = []
for i in clients:
if i["address"][len("0x") :] in self._urgent_windows:
urgent_workspaces.append(i["workspace"]["id"])
return urgent_workspaces

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

match event_type:
case "urgent":
self.__sync_urgent(value_list[0])
case "destroyworkspacev2":
self.__destroy_workspace(int(value_list[0]))
case "createworkspacev2":
Expand Down Expand Up @@ -357,12 +383,24 @@ 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:
self._urgent_windows.add(urgent_window)
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"][len("0x") :]
if active_window_id in self._urgent_windows:
self._urgent_windows.remove(active_window_id)
self.notify("urgent_windows")
self.notify("urgent_workspaces")

self.notify("active-window")

def __open_window(self, address: str) -> None:
Expand Down