From ad368a76d60fdec54dc75347245d858657ef9491 Mon Sep 17 00:00:00 2001 From: Zacharias-Brohn Date: Fri, 24 Oct 2025 02:15:37 +0200 Subject: [PATCH] second try at custom tray menu --- Modules/TrayWidget.qml | 1 - popout-test/modules/GetIcons.qml | 16 ++++++ popout-test/modules/Popout.qml | 50 +++++++++++++++++ popout-test/shell.qml | 94 ++++++++++++++++++++++++++++++++ 4 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 popout-test/modules/GetIcons.qml create mode 100644 popout-test/modules/Popout.qml create mode 100644 popout-test/shell.qml diff --git a/Modules/TrayWidget.qml b/Modules/TrayWidget.qml index e271c67..23122aa 100644 --- a/Modules/TrayWidget.qml +++ b/Modules/TrayWidget.qml @@ -9,7 +9,6 @@ Rectangle { implicitWidth: rowL.implicitWidth + 20 color: "transparent" - RowLayout { spacing: 10 id: rowL diff --git a/popout-test/modules/GetIcons.qml b/popout-test/modules/GetIcons.qml new file mode 100644 index 0000000..293adc9 --- /dev/null +++ b/popout-test/modules/GetIcons.qml @@ -0,0 +1,16 @@ +pragma Singleton + +import Quickshell +import Quickshell.Services.Notifications + +Singleton { + id: root + + function getTrayIcon(id: string, icon: string): string { + if (icon.includes("?path=")) { + const [name, path] = icon.split("?path="); + icon = Qt.resolvedUrl(`${path}/${name.slice(name.lastIndexOf("/") + 1)}`); + } + return icon; + } +} diff --git a/popout-test/modules/Popout.qml b/popout-test/modules/Popout.qml new file mode 100644 index 0000000..8484282 --- /dev/null +++ b/popout-test/modules/Popout.qml @@ -0,0 +1,50 @@ +pragma ComponentBehavior: Bound + +import Quickshell +import QtQuick +import QtQuick.Layouts + +PopupWindow { + id: root + required property QsMenuHandle menu + property int height: menuOpener.children.values.length * entryHeight + property int entryHeight: 25 + implicitWidth: 300 + implicitHeight: height + + QsMenuOpener { + id: menuOpener + menu: root.menu + } + + ColumnLayout { + anchors.fill: parent + spacing: 0 + Repeater { + model: menuOpener.children + Rectangle { + id: menuItem + width: root.implicitWidth + height: modelData.isSeparator ? 5 : root.entryHeight + color: mouseArea.containsMouse ? "#22000000" : "transparent" + required property QsMenuEntry modelData + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + acceptedButtons: Qt.LeftButton + onClicked: { + menuItem.modelData.triggered(); + root.visible = false; + } + Text { + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: 10 + text: menuItem.modelData.text + } + } + } + } + } +} diff --git a/popout-test/shell.qml b/popout-test/shell.qml new file mode 100644 index 0000000..3235e61 --- /dev/null +++ b/popout-test/shell.qml @@ -0,0 +1,94 @@ +import Quickshell +import Quickshell.Wayland +import Quickshell.Hyprland +import Quickshell.Services.SystemTray +import Quickshell.Widgets +import Caelestia +import QtQuick +import QtQuick.Layouts +import qs.modules + +Variants { + model: Quickshell.screens + + Scope { + id: scope + required property ShellScreen modelData + + PanelWindow { + screen: scope.modelData + color: "#99000000" + anchors { + top: true + left: true + right: true + } + + implicitHeight: 34 + + Rectangle { + anchors.centerIn: parent + implicitHeight: parent.height + implicitWidth: rowL.implicitWidth + 10 + color: "transparent" + RowLayout { + spacing: 8 + id: rowL + anchors.centerIn: parent + Repeater { + model: SystemTray.items + MouseArea { + id: trayItem + required property SystemTrayItem modelData + property SystemTrayItem item: modelData + implicitWidth: 20 + implicitHeight: 20 + + hoverEnabled: true + acceptedButtons: Qt.RightButton | Qt.LeftButton + + IconImage { + id: icon + + anchors.fill: parent + layer.enabled: true + + layer.onEnabledChanged: { + if (layer.enabled && status === Image.Ready) + analyser.requestUpdate(); + } + + onStatusChanged: { + if (layer.enabled && status === Image.Ready) + analyser.requestUpdate(); + } + + source: GetIcons.getTrayIcon(trayItem.item.id, trayItem.item.icon) + + mipmap: false + asynchronous: true + ImageAnalyser { + id: analyser + sourceItem: icon + } + } + Popout { + id: popout + menu: trayItem.item.menu + anchor.item: trayItem + anchor.edges: Edges.Bottom | Edges.Left + } + onClicked: { + if ( mouse.button === Qt.LeftButton ) { + trayItem.item.activate(); + } else if ( mouse.button === Qt.RightButton ) { + popout.visible = !popout.visible; + } + } + } + } + } + } + } + } +}