diff options
Diffstat (limited to 'desktop/island')
| -rw-r--r-- | desktop/island/Island.qml | 11 | ||||
| -rw-r--r-- | desktop/island/README.md | 4 | ||||
| -rw-r--r-- | desktop/island/StatusPill.qml | 17 |
3 files changed, 24 insertions, 8 deletions
diff --git a/desktop/island/Island.qml b/desktop/island/Island.qml index 12f49ea..ee03ca1 100644 --- a/desktop/island/Island.qml +++ b/desktop/island/Island.qml @@ -52,10 +52,9 @@ PanelWindow { // A tray menu is a separate popup: moving onto it un-hovers the pills, // and the hide timer would then hide the island under the open menu. The - // menu cannot report its own close through display(), so the hold ends - // the next time the pointer comes back to the island. - // ponytail: if the menu is dismissed elsewhere, the island may stay shown - // until the next hover. + // hold ends when the menu closes, or the next time the pointer comes back. + // It used to wait for the pointer alone, which left the island stuck open + // after a menu's Quit, since the pointer was on the menu, not the pills. property bool menuHeld: false onHoveredChanged: { @@ -319,6 +318,10 @@ PanelWindow { window: win panel: win.panel onMenuShown: win.menuHeld = true + onMenuClosed: { + win.menuHeld = false; + if (!win.hovered && win.panel === "") hideTimer.restart(); + } onOpenSound: win.panel = win.panel === "sound" ? "" : "sound" onOpenHeadphones: win.panel = win.panel === "headphones" ? "" : "headphones" onClosePanel: win.panel = "" diff --git a/desktop/island/README.md b/desktop/island/README.md index 9353f7e..01751c1 100644 --- a/desktop/island/README.md +++ b/desktop/island/README.md @@ -67,8 +67,8 @@ page now (`desktop/modules/perf/`). opens the sound panel. - **Tray** shows `SystemTray` items. Left click activates, right click opens the item's menu. The island is the session's StatusNotifier host. A tray - menu is a separate popup, so the island holds itself shown after `display()` - until the pointer returns. + menu is a separate popup, opened through a `QsMenuAnchor`, so the island + holds itself shown until the anchor reports the menu closed. - **Layout flag** shows the current keyboard layout, driven by Hyprland's `activelayout` event. Scroll switches layout with `hyprctl switchxkblayout current next|prev`. diff --git a/desktop/island/StatusPill.qml b/desktop/island/StatusPill.qml index 915807b..99f1512 100644 --- a/desktop/island/StatusPill.qml +++ b/desktop/island/StatusPill.qml @@ -38,8 +38,17 @@ Capsule { signal openHeadphones() signal closePanel() signal openDrawer() - // Emitted just before a tray menu opens; the menu cannot report its close. + // A tray menu opening and closing. display() reports no close, so menus + // open through a QsMenuAnchor, whose closed fires on any dismissal: an + // entry picked (Quit included), Escape or a click elsewhere. signal menuShown() + signal menuClosed() + + QsMenuAnchor { + id: menuAnchor + anchor.window: pill.window + onClosed: pill.menuClosed() + } expanded: panel === "sound" || panel === "headphones" restWidth: restRow.implicitWidth + 24 @@ -100,8 +109,12 @@ Capsule { if (!wantsMenu) { item.activate(); return; } if (!item.hasMenu) return; const p = trayIcon.mapToItem(null, 0, trayIcon.height + 6); + if (menuAnchor.visible) menuAnchor.close(); + menuAnchor.menu = item.menu; + menuAnchor.anchor.rect.x = p.x; + menuAnchor.anchor.rect.y = p.y; pill.menuShown(); - item.display(pill.window, p.x, p.y); + menuAnchor.open(); } } } |
