aboutsummaryrefslogtreecommitdiffstats
path: root/window-switcher
diff options
context:
space:
mode:
Diffstat (limited to 'window-switcher')
-rw-r--r--window-switcher/Switcher.qml29
1 files changed, 25 insertions, 4 deletions
diff --git a/window-switcher/Switcher.qml b/window-switcher/Switcher.qml
index 2e911b7..960cb58 100644
--- a/window-switcher/Switcher.qml
+++ b/window-switcher/Switcher.qml
@@ -29,6 +29,29 @@ Scope {
// since the last showing would otherwise be missing from the grid.
onOpenChanged: if (open) Windows.refresh();
+ // A focus dispatched while the overlay is up is accepted and then ignored:
+ // the layer surface holds keyboard focus exclusively, and the compositor
+ // will not move window focus out from under that grab. Closing in the same
+ // turn does not help either, because close() only clears a property and the
+ // surface survives until the frame after. So the target is remembered and
+ // focused once the grab is really gone.
+ property var pendingFocus: null
+
+ function focusAfterClose(toplevel) {
+ root.pendingFocus = toplevel;
+ root.close();
+ focusTimer.restart();
+ }
+
+ Timer {
+ id: focusTimer
+ interval: 60
+ onTriggered: {
+ if (root.pendingFocus) Windows.focus(root.pendingFocus);
+ root.pendingFocus = null;
+ }
+ }
+
// A config with no visible window exits, reporting nothing. This 1x1
// click-through window is what holds the shell open while the overlay
// is hidden, which is almost always.
@@ -71,10 +94,8 @@ Scope {
function commit() {
const list = Windows.windows;
- if (selectedIndex >= 0 && selectedIndex < list.length) {
- Windows.focus(list[selectedIndex]);
- root.close();
- }
+ if (selectedIndex >= 0 && selectedIndex < list.length)
+ root.focusAfterClose(list[selectedIndex]);
}
function move(delta) {