Files
dotfiles/noctalia/plugins/clipper/SelectionContextMenu.qml
T
Domipoke 955801c666 noctalia
2026-06-25 19:58:23 +02:00

121 lines
3.0 KiB
QML

import QtQuick
import Quickshell
import Quickshell.Hyprland
import Quickshell.Io
import Quickshell.Wayland
import qs.Commons
import qs.Services.UI
import qs.Widgets
// Universal selection context menu that appears at cursor position
PanelWindow {
id: root
required property ShellScreen screen
property var pluginApi: null
property var menuItems: []
signal itemSelected(string action)
signal cancelled
anchors.top: true
anchors.left: true
anchors.right: true
anchors.bottom: true
visible: false
color: "transparent"
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
WlrLayershell.namespace: "noctalia-selection-menu-" + (screen?.name || "unknown")
WlrLayershell.exclusionMode: ExclusionMode.Ignore
property int cursorX: 0
property int cursorY: 0
function show(items) {
menuItems = items || [];
visible = true;
getCursorPositionProcess.running = true;
}
function close() {
visible = false;
contextMenu.visible = false;
}
// Get cursor position from hyprctl
Process {
id: getCursorPositionProcess
command: ["hyprctl", "cursorpos", "-j"]
running: false
stdout: StdioCollector {
id: cursorStdout
}
onExited: (exitCode, exitStatus) => {
if (exitCode === 0) {
try {
const data = JSON.parse(cursorStdout.text);
root.cursorX = data.x || 0;
root.cursorY = data.y || 0;
// Position menu at cursor
anchorPoint.x = root.cursorX;
anchorPoint.y = root.cursorY;
contextMenu.model = root.menuItems;
contextMenu.anchorItem = anchorPoint;
contextMenu.visible = true;
} catch (e) {
ToastService.showError(pluginApi?.tr("toast.failed-to-get-cursor-position"));
root.close();
}
} else {
root.close();
}
}
}
// Context menu
NPopupContextMenu {
id: contextMenu
visible: false
screen: root.screen
minWidth: 200
onTriggered: (action, item) => {
root.itemSelected(action);
root.close();
}
}
// Anchor point for menu positioning
Item {
id: anchorPoint
width: 1
height: 1
x: 0
y: 0
}
// Fullscreen mouse area to capture outside clicks
MouseArea {
id: mouseCapture
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: mouse => {
root.cancelled();
root.close();
}
}
Component.onDestruction: {
if (getCursorPositionProcess.running) {
getCursorPositionProcess.terminate();
}
close();
}
}