import QtQuick import Quickshell import "." as M M.PopupPanel { id: menuWindow required property var handle property var _currentHandle: handle property var _handleStack: [] property QsMenuOpener _opener: QsMenuOpener { menu: menuWindow._currentHandle } // Back button (submenus only) Item { visible: menuWindow._handleStack.length > 0 width: menuWindow.panelWidth height: visible ? 28 : 0 Rectangle { anchors.fill: parent anchors.leftMargin: 4 anchors.rightMargin: 4 color: backArea.containsMouse ? M.Theme.base02 : "transparent" radius: M.Theme.radius } Text { anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.leftMargin: 12 text: "\u2039 Back" color: M.Theme.base05 font.pixelSize: M.Theme.fontSize font.family: M.Theme.fontFamily } MouseArea { id: backArea anchors.fill: parent hoverEnabled: true onClicked: { const stack = menuWindow._handleStack.slice(); menuWindow._currentHandle = stack.pop(); menuWindow._handleStack = stack; } } } Repeater { model: menuWindow._opener.children delegate: Item { id: entryItem required property QsMenuEntry modelData width: menuWindow.panelWidth height: modelData.isSeparator ? 9 : 28 Rectangle { visible: entryItem.modelData.isSeparator anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: 8 anchors.rightMargin: 8 height: 1 color: M.Theme.base03 } Rectangle { visible: !entryItem.modelData.isSeparator anchors.fill: parent anchors.leftMargin: 4 anchors.rightMargin: 4 color: rowArea.containsMouse && entryItem.modelData.enabled ? M.Theme.base02 : "transparent" radius: M.Theme.radius } Image { id: entryIcon visible: !entryItem.modelData.isSeparator && entryItem.modelData.icon !== "" anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.leftMargin: 12 width: M.Theme.fontSize height: M.Theme.fontSize source: entryItem.modelData.icon fillMode: Image.PreserveAspectFit } Text { visible: !entryItem.modelData.isSeparator anchors.verticalCenter: parent.verticalCenter anchors.left: entryIcon.visible ? entryIcon.right : parent.left anchors.leftMargin: entryIcon.visible ? 6 : 12 anchors.right: entryChevron.visible ? entryChevron.left : parent.right anchors.rightMargin: entryChevron.visible ? 4 : 12 text: entryItem.modelData.text color: entryItem.modelData.enabled ? M.Theme.base05 : M.Theme.base03 font.pixelSize: M.Theme.fontSize font.family: M.Theme.fontFamily elide: Text.ElideRight } Text { id: entryChevron visible: !entryItem.modelData.isSeparator && entryItem.modelData.hasChildren anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right anchors.rightMargin: 12 text: "\u203A" color: entryItem.modelData.enabled ? M.Theme.base05 : M.Theme.base03 font.pixelSize: M.Theme.fontSize font.family: M.Theme.fontFamily } MouseArea { id: rowArea anchors.fill: parent hoverEnabled: true enabled: !entryItem.modelData.isSeparator && entryItem.modelData.enabled onClicked: { if (entryItem.modelData.hasChildren) { menuWindow._handleStack = menuWindow._handleStack.concat([menuWindow._currentHandle]); menuWindow._currentHandle = entryItem.modelData; } else { entryItem.modelData.triggered(); menuWindow.dismiss(); } } } } } }