From 98d1e6249c142b6efffab21396a13be7e3e61383 Mon Sep 17 00:00:00 2001 From: rope Date: Tue, 26 May 2026 17:13:58 +0100 Subject: [PATCH] quickshell: seamless switching between dropdowns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove grabFocus from BarDropdown. Centralized toggleDropdown() closes the active dropdown before opening a new one, so clicking between network/battery/calendar/tray is instant — no double-click. Co-Authored-By: Claude Opus 4.6 --- settings/hyprland.nix | 77 +++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 44 deletions(-) diff --git a/settings/hyprland.nix b/settings/hyprland.nix index 3edffd3..0a529ad 100644 --- a/settings/hyprland.nix +++ b/settings/hyprland.nix @@ -458,6 +458,25 @@ in implicitHeight: 30 color: "#D1${c.base00}" + property var activeDropdown: null + function closeAllDropdowns() { + if (activeDropdown && activeDropdown.visible) { + activeDropdown.visible = false; + } + activeDropdown = null; + } + function toggleDropdown(dd, setupFn) { + if (dd.visible) { + dd.visible = false; + activeDropdown = null; + } else { + closeAllDropdowns(); + if (setupFn) setupFn(); + dd.visible = true; + activeDropdown = dd; + } + } + // Left — workspaces Row { anchors.left: parent.left @@ -519,21 +538,9 @@ in MouseArea { anchors.fill: parent onClicked: { - if (calPopup.justDismissed) return; - if (calPopup.visible) { - calPopup.open = false; - calCloseTimer.start(); - } else { - calPopup.visible = true; - } + bar.toggleDropdown(calPopup); } } - - Timer { - id: calCloseTimer - interval: 230 - onTriggered: calPopup.visible = false - } } // Right — network, battery, tray @@ -653,16 +660,12 @@ in MouseArea { anchors.fill: parent onClicked: { - if (netDropdown.justDismissed) return; - if (netDropdown.visible) { - netDropdown.visible = false; - } else { + bar.toggleDropdown(netDropdown, function() { netWidget.wifiNetworks = []; wifiScanProc.running = true; let pos = netWidget.mapToItem(bar.contentItem, netWidget.width / 2, 0); netDropdown.dropdownX = pos.x; - netDropdown.visible = true; - } + }); } } } @@ -765,16 +768,12 @@ in MouseArea { anchors.fill: parent onClicked: { - if (batteryDropdown.justDismissed) return; - if (batteryDropdown.visible) { - batteryDropdown.visible = false; - } else { + bar.toggleDropdown(batteryDropdown, function() { batteryProc.running = true; profileProc.running = true; let pos = batteryWidget.mapToItem(bar.contentItem, batteryWidget.width / 2, 0); batteryDropdown.dropdownX = pos.x; - batteryDropdown.visible = true; - } + }); } } } @@ -815,13 +814,13 @@ in anchors.fill: parent acceptedButtons: Qt.LeftButton | Qt.RightButton onClicked: (event) => { - if (contextMenu.justDismissed) return; if (event.button === Qt.RightButton && modelData.hasMenu) { - let pos = parent.mapToItem(bar.contentItem, parent.width / 2, 0); - contextMenu.dropdownX = pos.x; - contextMenu.trayItem = modelData; - menuOpener.menu = modelData.menu; - contextMenu.visible = true; + bar.toggleDropdown(contextMenu, function() { + let pos = parent.mapToItem(bar.contentItem, parent.width / 2, 0); + contextMenu.dropdownX = pos.x; + contextMenu.trayItem = modelData; + menuOpener.menu = modelData.menu; + }); } else { modelData.activate(); } @@ -836,7 +835,6 @@ in component BarDropdown: PopupWindow { id: dropdown property bool open: false - property bool justDismissed: false property real dropdownX: 0 property real fullWidth: 200 property real fullHeight: 200 @@ -848,7 +846,6 @@ in anchor.edges: Edges.Top | Edges.Left anchor.gravity: Edges.Bottom | Edges.Right anchor.adjustment: PopupAdjustment.Slide - grabFocus: true visible: false color: "transparent" implicitWidth: fullWidth + 16 @@ -859,17 +856,9 @@ in open = true; } else { open = false; - justDismissed = true; - _dismissGuard.start(); } } - Timer { - id: _dismissGuard - interval: 100 - onTriggered: dropdown.justDismissed = false - } - Item { anchors.right: _dropdownRect.left anchors.top: parent.top @@ -1010,7 +999,7 @@ in enabled: !modelData.isSeparator && modelData.enabled onClicked: { modelData.triggered(); - contextMenu.visible = false; + bar.closeAllDropdowns(); } } } @@ -1071,7 +1060,7 @@ in netWidget.netState = "disconnected"; netWidget.netConn = ""; netWidget.netIcon = "\u{f05aa}"; - netDropdown.visible = false; + bar.closeAllDropdowns(); netRefreshDelay.start(); } } @@ -1160,7 +1149,7 @@ in wifiConnectProc.running = true; netRefreshDelay.start(); } - netDropdown.visible = false; + bar.closeAllDropdowns(); } } }