git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commitb06fd0e3cdf090f25fa0979688061fd2ada1c194
parent3f4fe33a84
authorIsaac Freund <[email protected]>
date2024-07-02 15:03
layer-shell: fix on_demand keyboard focus

Currently keyboard focus is stolen from layer surfaces with
on_demand keyboard interactivity any time Root.applyPending() is called.

This commit fixes the behavior to only steal focus when explicitly
focusing a different window/layer surface.

 river/Seat.zig | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/river/Seat.zig b/river/Seat.zig
index ff77cce..4ac83f5 100644
--- a/river/Seat.zig
+++ b/river/Seat.zig
@@ -165,14 +165,21 @@ pub fn focus(seat: *Seat, _target: ?*View) void {
     // Views may not receive focus while locked.
     if (server.lock_manager.state != .unlocked) return;
 
-    // While a layer surface is exclusively focused, views may not receive focus
+    // A layer surface with exclusive focus will prevent any view from gaining
+    // focus if it is on the top or overlay layer. Otherwise, only steal focus
+    // from a focused layer surface if there is an explicit target view.
     if (seat.focused == .layer) {
         const wlr_layer_surface = seat.focused.layer.wlr_layer_surface;
         assert(wlr_layer_surface.surface.mapped);
-        if (wlr_layer_surface.current.keyboard_interactive == .exclusive and
-            (wlr_layer_surface.current.layer == .top or wlr_layer_surface.current.layer == .overlay))
-        {
-            return;
+        switch (wlr_layer_surface.current.keyboard_interactive) {
+            .none => {},
+            .exclusive => switch (wlr_layer_surface.current.layer) {
+                .top, .overlay => return,
+                .bottom, .background => if (target == null) return,
+                _ => {},
+            },
+            .on_demand => if (target == null) return,
+            _ => {},
         }
     }