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

commitebce3a035205b6301b0e79d8270bb2365f7a719f
parent6d3e02a0d4
authorIsaac Freund <[email protected]>
date2023-03-16 11:03
LayerSurface: handle focus when switching outputs

Currently if a layer surface is focused and the user focuses a different
output the layer surface remains focused. However, updating focus on
layer surface unmap only considers seats that have the layer surface's
output focused.

To fix this there are 3 approaches I see:

1. Unfocus all layer surfaces on the old output when switching output
focus, focus any layer surfaces on the new output.

2. Disallow switching output focus while a layer surface is focused.

3. Stop caring about output focus when determining which layer surface
should gain/lose focus.

I've taken the 3rd option here as it is significantly simpler to
implement and maintain but still feels reasonably intuitive.

 river/LayerSurface.zig | 3 ---
 river/Seat.zig         | 1 +
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/river/LayerSurface.zig b/river/LayerSurface.zig
index 265a4dc..690be64 100644
--- a/river/LayerSurface.zig
+++ b/river/LayerSurface.zig
@@ -166,9 +166,6 @@ fn handleKeyboardInteractiveExclusive(output: *Output) void {
     while (it) |node| : (it = node.next) {
         const seat = &node.data;
 
-        // Only grab focus of seats which have the output focused
-        if (seat.focused_output != output) continue;
-
         if (topmost_surface) |to_focus| {
             // If we found a surface that requires focus, grab the focus of all
             // seats.
diff --git a/river/Seat.zig b/river/Seat.zig
index ef561b1..2f78f83 100644
--- a/river/Seat.zig
+++ b/river/Seat.zig
@@ -152,6 +152,7 @@ pub fn focus(self: *Self, _target: ?*View) void {
     // While a layer surface is exclusively focused, views may not receive focus
     if (self.focused == .layer) {
         const wlr_layer_surface = self.focused.layer.wlr_layer_surface;
+        assert(wlr_layer_surface.mapped);
         if (wlr_layer_surface.current.keyboard_interactive == .exclusive and
             (wlr_layer_surface.current.layer == .top or wlr_layer_surface.current.layer == .overlay))
         {