mirror of
https://github.com/zoriya/noctalia-shell.git
synced 2025-12-06 06:36:15 +00:00
102 lines
2.9 KiB
QML
102 lines
2.9 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Wayland
|
|
import qs.Commons
|
|
import qs.Services.UI
|
|
|
|
// Generic full-screen popup window for menus and context menus
|
|
// This is a top-level PanelWindow (sibling to MainScreen, not nested inside it)
|
|
// Provides click-outside-to-close functionality for any popup content
|
|
// Loads TrayMenu by default but can show context menus via showContextMenu()
|
|
PanelWindow {
|
|
id: root
|
|
|
|
required property ShellScreen screen
|
|
property string windowType: "popupmenu" // Used for namespace and registration
|
|
|
|
// Content item to display (set by the popup that uses this window)
|
|
property var contentItem: null
|
|
|
|
// Expose the trayMenu Loader directly (for backward compatibility)
|
|
readonly property alias trayMenuLoader: trayMenuLoader
|
|
|
|
anchors.top: true
|
|
anchors.left: true
|
|
anchors.right: true
|
|
anchors.bottom: true
|
|
visible: false
|
|
color: Color.transparent
|
|
|
|
// Use Top layer (same as MainScreen) for proper event handling
|
|
WlrLayershell.layer: WlrLayer.Top
|
|
WlrLayershell.keyboardFocus: hasDialog ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
|
WlrLayershell.namespace: "noctalia-" + windowType + "-" + (screen?.name || "unknown")
|
|
WlrLayershell.exclusionMode: ExclusionMode.Ignore
|
|
|
|
// Track if a dialog is currently open (needed for keyboard focus)
|
|
property bool hasDialog: false
|
|
|
|
// Register with PanelService so widgets can find this window
|
|
Component.onCompleted: {
|
|
objectName = "popupMenuWindow-" + (screen?.name || "unknown");
|
|
PanelService.registerPopupMenuWindow(screen, root);
|
|
}
|
|
|
|
// Load TrayMenu as the default content
|
|
Loader {
|
|
id: trayMenuLoader
|
|
source: Quickshell.shellDir + "/Modules/Bar/Extras/TrayMenu.qml"
|
|
onLoaded: {
|
|
if (item) {
|
|
item.screen = root.screen;
|
|
// Set the loaded item as default content
|
|
root.contentItem = item;
|
|
}
|
|
}
|
|
}
|
|
|
|
function open() {
|
|
visible = true;
|
|
}
|
|
|
|
// Show a context menu (temporarily replaces TrayMenu as content)
|
|
function showContextMenu(menu) {
|
|
if (menu) {
|
|
contentItem = menu;
|
|
open();
|
|
}
|
|
}
|
|
|
|
function close() {
|
|
visible = false;
|
|
// Call close/hide method on current content
|
|
if (contentItem) {
|
|
if (typeof contentItem.hideMenu === "function") {
|
|
contentItem.hideMenu();
|
|
} else if (typeof contentItem.close === "function") {
|
|
contentItem.close();
|
|
}
|
|
}
|
|
// Restore TrayMenu as default content
|
|
if (trayMenuLoader.item) {
|
|
contentItem = trayMenuLoader.item;
|
|
}
|
|
}
|
|
|
|
// Full-screen click catcher - click anywhere outside content closes the window
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
|
onClicked: root.close()
|
|
}
|
|
|
|
// Container for dialogs that need a full-screen Item parent (e.g., Qt Popup)
|
|
Item {
|
|
id: dialogContainer
|
|
anchors.fill: parent
|
|
}
|
|
|
|
// Expose the dialog container for external use
|
|
readonly property alias dialogParent: dialogContainer
|
|
}
|