1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-08-01 19:18:28 -04:00

hyprland: workaround for focus re-grabbing a closing surface

related #2577
This commit is contained in:
bbedward
2026-07-06 11:45:38 -04:00
parent 35613ebba8
commit c175f4823a
4 changed files with 49 additions and 23 deletions
+2 -6
View File
@@ -1,5 +1,4 @@
import QtQuick
import Quickshell.Hyprland
import qs.Common
import qs.Services
import qs.Widgets
@@ -61,12 +60,9 @@ Item {
}
// Hyprland OnDemand grab delivers keyboard focus to the modal content surface.
HyprlandFocusGrab {
DankFocusGrab {
windows: (root.contentWindow ? [root.contentWindow] : []).concat(root.transientSurfaceTracker?.focusWindows ?? [])
active: KeyboardFocus.wantsGrab(root.shouldHaveFocus, root.customKeyboardFocus)
property var restoreToplevel: null
onActiveChanged: restoreToplevel = active ? KeyboardFocus.captureActiveToplevel() : KeyboardFocus.restoreToplevel(restoreToplevel)
wanted: KeyboardFocus.wantsGrab(root.shouldHaveFocus, root.customKeyboardFocus)
}
readonly property var contentWindow: impl.item ? impl.item.contentWindow : null
readonly property var effectiveScreen: impl.item ? impl.item.effectiveScreen : null
@@ -1,7 +1,6 @@
import QtQuick
import QtQuick.Effects
import Quickshell
import Quickshell.Hyprland
import Quickshell.Services.SystemTray
import Quickshell.Wayland
import Quickshell.Widgets
@@ -1048,12 +1047,9 @@ BasePill {
WlrLayershell.namespace: "dms:tray-overflow-menu"
color: "transparent"
HyprlandFocusGrab {
DankFocusGrab {
windows: [overflowMenu].concat(KeyboardFocus.barWindows)
active: root.useOverflowPopup && KeyboardFocus.wantsGrab(root.menuOpen, null)
property var restoreToplevel: null
onActiveChanged: restoreToplevel = active ? KeyboardFocus.captureActiveToplevel() : KeyboardFocus.restoreToplevel(restoreToplevel)
wanted: root.useOverflowPopup && KeyboardFocus.wantsGrab(root.menuOpen, null)
}
Connections {
@@ -1601,12 +1597,9 @@ BasePill {
WlrLayershell.keyboardFocus: KeyboardFocus.keyboardFocus(menuRoot.showMenu, null)
color: "transparent"
HyprlandFocusGrab {
DankFocusGrab {
windows: [menuWindow].concat(KeyboardFocus.barWindows)
active: KeyboardFocus.wantsGrab(menuRoot.showMenu, null)
property var restoreToplevel: null
onActiveChanged: restoreToplevel = active ? KeyboardFocus.captureActiveToplevel() : KeyboardFocus.restoreToplevel(restoreToplevel)
wanted: KeyboardFocus.wantsGrab(menuRoot.showMenu, null)
}
anchors {
+41
View File
@@ -0,0 +1,41 @@
import QtQuick
import Quickshell.Hyprland
import qs.Common
// Delays grab release so keyboardFocus=None commits before the grab dies,
// keeping Hyprland from handing focus back to the closing surface (#2577)
HyprlandFocusGrab {
id: root
property bool wanted: false
property bool _held: false
property bool _compositorCleared: false
property var _restoreToplevel: null
property Timer _releaseTimer: Timer {
interval: 50
onTriggered: {
root._held = false;
root.active = false;
root._restoreToplevel = root._compositorCleared ? null : KeyboardFocus.restoreToplevel(root._restoreToplevel);
}
}
onWantedChanged: _sync()
Component.onCompleted: _sync()
function _sync() {
if (!wanted) {
if (_held)
_releaseTimer.restart();
return;
}
_releaseTimer.stop();
_held = true;
_compositorCleared = false;
_restoreToplevel = KeyboardFocus.captureActiveToplevel();
active = true;
}
onCleared: _compositorCleared = true
}
+2 -6
View File
@@ -1,5 +1,4 @@
import QtQuick
import Quickshell.Hyprland
import qs.Common
import qs.Services
@@ -62,7 +61,7 @@ Item {
}
// Hyprland OnDemand grab: whitelist popout surfaces and bars so dismiss clicks still land.
HyprlandFocusGrab {
DankFocusGrab {
windows: {
const list = [];
if (root.contentWindow)
@@ -72,10 +71,7 @@ Item {
const transientWindows = root.transientSurfaceTracker?.focusWindows ?? [];
return list.concat(transientWindows).concat(KeyboardFocus.barWindows);
}
active: KeyboardFocus.wantsGrab(root.shouldBeVisible, root.customKeyboardFocus)
property var restoreToplevel: null
onActiveChanged: restoreToplevel = active ? KeyboardFocus.captureActiveToplevel() : KeyboardFocus.restoreToplevel(restoreToplevel)
wanted: KeyboardFocus.wantsGrab(root.shouldBeVisible, root.customKeyboardFocus)
}
Loader {