quickshell: custom QML tray context menus
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
63bd64ec56
commit
e02e1f41c1
1 changed files with 116 additions and 3 deletions
|
|
@ -566,6 +566,7 @@ in
|
|||
import Quickshell
|
||||
import Quickshell.Hyprland
|
||||
import Quickshell.Services.SystemTray
|
||||
import Quickshell.Widgets
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
|
|
@ -655,6 +656,7 @@ in
|
|||
}
|
||||
}
|
||||
|
||||
// Tray icon popup
|
||||
PopupWindow {
|
||||
id: trayPopup
|
||||
anchor.item: trayToggle
|
||||
|
|
@ -696,13 +698,13 @@ in
|
|||
}
|
||||
|
||||
MouseArea {
|
||||
id: trayMouse
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: (event) => {
|
||||
if (event.button === Qt.RightButton && modelData.hasMenu) {
|
||||
let mapped = trayMouse.mapToItem(null, event.x, event.y);
|
||||
modelData.display(trayPopup, mapped.x, mapped.y);
|
||||
contextMenu.trayItem = modelData;
|
||||
menuOpener.menu = modelData.menu;
|
||||
contextMenu.visible = true;
|
||||
} else {
|
||||
modelData.activate();
|
||||
}
|
||||
|
|
@ -713,6 +715,117 @@ in
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Custom-rendered context menu
|
||||
PopupWindow {
|
||||
id: contextMenu
|
||||
property var trayItem: null
|
||||
anchor.item: trayToggle
|
||||
anchor.edges: Edges.Bottom | Edges.Right
|
||||
anchor.gravity: Edges.Bottom | Edges.Left
|
||||
anchor.adjustment: PopupAdjustment.Slide
|
||||
visible: false
|
||||
color: "transparent"
|
||||
implicitWidth: menuColumn.width + 2
|
||||
implicitHeight: menuColumn.height + 2
|
||||
|
||||
QsMenuOpener {
|
||||
id: menuOpener
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: menuColumn
|
||||
width: menuItems.width + 16
|
||||
height: menuItems.height + 12
|
||||
color: "#${c.base00}"
|
||||
border.color: "#${c.base03}"
|
||||
border.width: 1
|
||||
radius: 8
|
||||
|
||||
Column {
|
||||
id: menuItems
|
||||
anchors.centerIn: parent
|
||||
width: 200
|
||||
|
||||
Repeater {
|
||||
model: menuOpener.children
|
||||
|
||||
Loader {
|
||||
required property var modelData
|
||||
width: 200
|
||||
sourceComponent: modelData.isSeparator ? separatorComp : menuItemComp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close when clicking outside
|
||||
onVisibleChanged: {
|
||||
if (!visible) {
|
||||
menuOpener.menu = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Menu item delegate
|
||||
component MenuItemDelegate: Rectangle {
|
||||
required property var modelData
|
||||
width: 200
|
||||
height: modelData.isSeparator ? 1 : 28
|
||||
color: itemMouse.containsMouse && modelData.enabled ? "#${c.base02}" : "transparent"
|
||||
radius: 4
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 10
|
||||
anchors.rightMargin: 10
|
||||
spacing: 8
|
||||
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
text: modelData.text ?? ""
|
||||
color: modelData.enabled ? "#${c.base05}" : "#${c.base03}"
|
||||
font.family: "FiraMono Nerd Font"
|
||||
font.pixelSize: 12
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
Text {
|
||||
visible: modelData.buttonType !== QsMenuButtonType.None
|
||||
text: modelData.checkState === Qt.Checked ? "\u2713" : ""
|
||||
color: "#${c.base0D}"
|
||||
font.family: "FiraMono Nerd Font"
|
||||
font.pixelSize: 12
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: itemMouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
enabled: modelData.enabled
|
||||
onClicked: {
|
||||
modelData.triggered();
|
||||
contextMenu.visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Separator delegate
|
||||
component SeparatorDelegate: Rectangle {
|
||||
width: 200
|
||||
height: 9
|
||||
color: "transparent"
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - 20
|
||||
height: 1
|
||||
color: "#${c.base03}"
|
||||
}
|
||||
}
|
||||
|
||||
Component { id: menuItemComp; MenuItemDelegate {} }
|
||||
Component { id: separatorComp; SeparatorDelegate {} }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue