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

commitee3de32f0a360ab963656b8e655462e52de7d8e5
parentbca2fa4c4f
authorIsaac Freund <[email protected]>
date2020-06-29 01:00
seat: prioritize fullscreen views for focus

 river/Seat.zig | 33 +++++++++++++++++++--------------
 river/View.zig |  8 +++-----
 2 files changed, 22 insertions(+), 19 deletions(-)

diff --git a/river/Seat.zig b/river/Seat.zig
index f67fbae..c043b83 100644
--- a/river/Seat.zig
+++ b/river/Seat.zig
@@ -122,21 +122,26 @@ pub fn focus(self: *Self, _view: ?*View) void {
         return;
     }
 
-    // If view is null or not currently visible
-    if (if (view) |v|
-        v.output != self.focused_output or
-            v.current.tags & self.focused_output.current_focused_tags == 0
-    else
-        true) {
-        // Set view to the first currently visible view on in the focus stack if any
-        var it = ViewStack(*View).iterator(
-            self.focus_stack.first,
-            self.focused_output.current_focused_tags,
-        );
+    // If the view is not currently visible, behave as if null was passed
+    if (view) |v| {
+        if (v.output != self.focused_output or
+            v.current.tags & self.focused_output.current_focused_tags == 0) view = null;
+    }
+
+    // If the target view is not fullscreen or null, then a fullscreen view
+    // will grab focus if visible.
+    if (if (view) |v| !v.current.fullscreen else true) {
+        var it = ViewStack(*View).iterator(self.focus_stack.first, self.focused_output.current_focused_tags);
         view = while (it.next()) |node| {
-            if (node.view.output == self.focused_output) {
-                break node.view;
-            }
+            if (node.view.output == self.focused_output and node.view.current.fullscreen) break node.view;
+        } else view;
+    }
+
+    if (view == null) {
+        // Set view to the first currently visible view in the focus stack if any
+        var it = ViewStack(*View).iterator(self.focus_stack.first, self.focused_output.current_focused_tags);
+        view = while (it.next()) |node| {
+            if (node.view.output == self.focused_output) break node.view;
         } else null;
     }
 
diff --git a/river/View.zig b/river/View.zig
index e3995a8..160f22e 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -282,12 +282,10 @@ pub fn map(self: *Self) void {
     const node = @fieldParentPtr(ViewStack(Self).Node, "view", self);
     self.output.views.push(node);
 
-    // Focus the newly mapped view. Note: if a seat is focusing a different output
-    // it will continue to do so.
+    // Focus the new view, assuming the seat is focusing the proper output
+    // and there isn't something else like a fullscreen view grabbing focus.
     var it = root.server.input_manager.seats.first;
-    while (it) |seat_node| : (it = seat_node.next) {
-        seat_node.data.focus(self);
-    }
+    while (it) |seat_node| : (it = seat_node.next) seat_node.data.focus(self);
 
     c.wlr_surface_send_enter(self.wlr_surface.?, self.output.wlr_output);