From 6f14b522626f330f5644f38bcfae8145f423cb96 Mon Sep 17 00:00:00 2001 From: Rosty Hnatyshyn Date: Sun, 9 Aug 2026 15:28:16 -0700 Subject: [PATCH] add workspace window icons, right click menus on systrays --- quickshell/Bar.qml | 101 +++++++++++++++++++++++++++++++++++++++++-- quickshell/shell.qml | 1 + 2 files changed, 99 insertions(+), 3 deletions(-) diff --git a/quickshell/Bar.qml b/quickshell/Bar.qml index d405d7a..4be4d45 100644 --- a/quickshell/Bar.qml +++ b/quickshell/Bar.qml @@ -12,7 +12,6 @@ import Quickshell.Widgets Scope { id: root property string time - property int cpuUsage: 0 property string memUsage: "0" property var lastCpuIdle: 0 @@ -130,6 +129,51 @@ Scope { } } + Row { + spacing: 4 + + Repeater { + model: barRoot.monitor?.activeWorkspace?.toplevels ?? null + + delegate: Item { + id: appIconRoot + width: 18 + height: 18 + + property var desktopEntry: DesktopEntries.byId(modelData.wayland.appId) + + IconImage { + anchors.fill: parent + source: Quickshell.iconPath(desktopEntry.icon ?? modelData.appId, "image-missing") + opacity: modelData.activated ? 1.0 : 0.35 + } + + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton + + onClicked: mouse => { + if (mouse.button === Qt.LeftButton) { + modelData.wayland.activate(); + } else if (mouse.button === Qt.RightButton) { + modelData.wayland.close(); + } + } + } + } + } + + Connections { + target: barRoot.monitor?.activeWorkspace?.toplevels ?? null + function onObjectInsertedPost() { + Hyprland.refreshToplevels(); + } + function onObjectRemovedPost() { + Hyprland.refreshToplevels(); + } + } + } + Text { id: clock anchors.centerIn: parent @@ -175,7 +219,7 @@ Scope { Rectangle { width: 1 height: 16 - color: root.colMuted + color: barRoot.colMuted } IconImage { @@ -199,13 +243,64 @@ Scope { Repeater { model: SystemTray.items delegate: Image { + id: trayIcon source: modelData.icon + width: 16 height: 16 + QsMenuOpener { + id: menuOpener + menu: modelData.menu + } + + PopupWindow { + id: tooltip + visible: trayDelegate.containsMouse + color: "transparent" + implicitWidth: tooltipText.implicitWidth + 16 + implicitHeight: tooltipText.implicitHeight + 10 + + anchor.item: trayIcon + anchor.edges: Edges.Top | Edges.Left + anchor.gravity: Edges.Top | Edges.Right + anchor.adjustment: PopupAdjustment.SlideX | PopupAdjustment.FlipY + anchor.margins.bottom: 6 + + Rectangle { + anchors.fill: parent + color: barRoot.colBg + radius: 4 + border.color: barRoot.colMuted + border.width: 1 + + Text { + id: tooltipText + anchors.centerIn: parent + text: modelData.tooltipTitle || modelData.id + color: barRoot.colFg + font { + family: barRoot.fontFamily + pixelSize: barRoot.fontSize - 2 + } + } + } + } + MouseArea { + id: trayDelegate + hoverEnabled: true + anchors.fill: parent - onClicked: modelData.activate() + acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton + onClicked: mouse => { + if (mouse.button === Qt.LeftButton) { + modelData.activate(); + } else if (mouse.button === Qt.RightButton && modelData.hasMenu) { + let pos = trayIcon.mapToItem(null, 0, trayIcon.height); + modelData.display(barRoot, pos.x, pos.y); + } + } } } } diff --git a/quickshell/shell.qml b/quickshell/shell.qml index 9785164..0c8a02d 100644 --- a/quickshell/shell.qml +++ b/quickshell/shell.qml @@ -1,3 +1,4 @@ +//@ pragma UseQApplication import Quickshell Scope {