aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-16 13:54:56 +0200
committerDanilo M. <danix@danix.xyz>2026-09-16 13:54:56 +0200
commit6d3747ec57db0bd23e6971dab2949381f3f195b5 (patch)
treea6bd484db9253d56bbdad2d1e4ca700e4deffa25
parent516e44c6c87825bfc985cbe6a1e73fce3fa7762a (diff)
downloadquickshell-6d3747ec57db0bd23e6971dab2949381f3f195b5.tar.gz
quickshell-6d3747ec57db0bd23e6971dab2949381f3f195b5.zip
feat(window-switcher): mark desktops with waybar's icons
The card's desktop line showed the workspace number. waybar draws the same eight desktops as CSS background images keyed by number, because its format-icons takes text rather than paths; those names now live in the Windows singleton and are resolved through the active icon theme, so a theme switch follows the drawer and the bar and the switcher agree. A named workspace, or one past eight, falls back to its number, and so does an icon the active theme cannot resolve.
-rw-r--r--window-switcher/README.md10
-rw-r--r--window-switcher/WindowCard.qml36
-rw-r--r--window-switcher/Windows.qml24
3 files changed, 62 insertions, 8 deletions
diff --git a/window-switcher/README.md b/window-switcher/README.md
index a9ddbd4..0f1cb90 100644
--- a/window-switcher/README.md
+++ b/window-switcher/README.md
@@ -15,7 +15,7 @@ a rofi list that showed the same windows as text.
│ └────────────────────┘ └────────────────────┘ │
│ firefox kitty │
│ a page title, elided... ~/Programming/GIT/... │
- │ [1] [4] │
+ │ [browser icon] [server icon] │
│ │
└──────────────────────────────────────────────────────────────┘
@@ -23,6 +23,14 @@ The cards are ordered most recently used first, so the window you just left is
the first one, the same order ALT+TAB implies. Windows on a `special:`
workspace are the scratchpad, which has its own bind, and are left out.
+Each card's desktop marker is the same icon waybar draws for that workspace, so
+the switcher and the bar agree rather than showing a bare number. waybar keeps
+the eight icons as CSS background images keyed by workspace number
+(`styles/modules.css` in `waybar-theme-udt`), because its `format-icons` takes
+text and not paths; here the same names are resolved through the active icon
+theme with `Quickshell.iconPath`. A named workspace, or one past eight, has no
+icon and falls back to `[name]`.
+
With nothing to switch to it says so, because a full-screen dim with nothing in
it reads as a hang.
diff --git a/window-switcher/WindowCard.qml b/window-switcher/WindowCard.qml
index de026e8..b86d69d 100644
--- a/window-switcher/WindowCard.qml
+++ b/window-switcher/WindowCard.qml
@@ -29,6 +29,14 @@ Column {
// that is appearing or going away. Everything below guards for it.
readonly property var wl: toplevel.wayland ?? null
+ // The bar's icon for this window's workspace, empty for a named workspace.
+ // Resolved to a path here so the card can fall back to the number when the
+ // active icon theme has no such icon, rather than showing a blank marker.
+ readonly property string workspaceIconPath: {
+ const name = Windows.workspaceIcon(toplevel.workspace);
+ return name !== "" ? Quickshell.iconPath(name, true) : "";
+ }
+
width: cardWidth
spacing: 8
@@ -125,12 +133,26 @@ Column {
font.pixelSize: 13
}
- Text {
- width: parent.width
- horizontalAlignment: Text.AlignHCenter
- text: "[" + (card.toplevel.workspace ? card.toplevel.workspace.name : "?") + "]"
- color: Theme.accent
- font.family: Theme.fontFamily
- font.pixelSize: 13
+ // The desktop marker, drawn with waybar's workspace icon rather than the
+ // number. A workspace with no icon keeps the number, so the line never
+ // goes blank.
+ Item {
+ width: card.width
+ height: 24
+
+ IconImage {
+ anchors.centerIn: parent
+ width: 22; height: 22
+ source: card.workspaceIconPath
+ }
+
+ Text {
+ anchors.centerIn: parent
+ visible: card.workspaceIconPath === ""
+ text: "[" + (card.toplevel.workspace ? card.toplevel.workspace.name : "?") + "]"
+ color: Theme.accent
+ font.family: Theme.fontFamily
+ font.pixelSize: 13
+ }
}
}
diff --git a/window-switcher/Windows.qml b/window-switcher/Windows.qml
index 040f4d4..fb582ad 100644
--- a/window-switcher/Windows.qml
+++ b/window-switcher/Windows.qml
@@ -64,4 +64,28 @@ Singleton {
function closeWindow(toplevel) {
Hyprland.dispatch(`hl.dsp.window.close({ window = "address:${addressOf(toplevel)}" })`);
}
+
+ // The desktop marker on a card is the same icon waybar's bar draws for that
+ // workspace, so the switcher and the bar agree. waybar keeps them as CSS
+ // background images by workspace number (styles/modules.css); the names are
+ // repeated here and resolved through the active icon theme, because a
+ // QML-side icon has to go by name. A named workspace, or one past eight,
+ // has no icon and the card falls back to its number.
+ readonly property var workspaceIcons: ({
+ 1: "web-browser",
+ 2: "utilities-terminal",
+ 3: "text-editor",
+ 4: "network-server",
+ 5: "document-edit",
+ 6: "applications-graphics",
+ 7: "internet-chat",
+ 8: "input-gaming",
+ })
+
+ function workspaceIcon(workspace) {
+ if (!workspace) return "";
+ const n = parseInt(String(workspace.name), 10);
+ if (isNaN(n)) return "";
+ return root.workspaceIcons[n] ?? "";
+ }
}