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

commit573891f5b758cc79a997533c20882a2663989d17
parent9cf7aad7e1
authorIsaac Freund <[email protected]>
date2023-03-03 13:40
Root: keep all fullscreen views the correct size

Currently we may resize fullscreen views when they become visible/not
visible when switching tags even if their fullscreen state remains
constant. This is suboptimal, and as it turns out also much more complex
to implement.

 river/Output.zig |  3 ---
 river/Root.zig   | 49 ++++++++++++-------------------------------------
 river/View.zig   |  5 ++++-
 3 files changed, 16 insertions(+), 41 deletions(-)

diff --git a/river/Output.zig b/river/Output.zig
index 828b85d..65378f3 100644
--- a/river/Output.zig
+++ b/river/Output.zig
@@ -121,9 +121,6 @@ pending: struct {
     ///
     /// This includes both floating/fullscreen views and those arranged in the layout.
     wm_stack: wl.list.Head(View, .pending_wm_stack_link),
-    /// The view to be made fullscreen, if any.
-    /// This state should only be read/written inside Root.applyPending()
-    fullscreen: ?*View = null,
 },
 
 /// The state most recently sent to the layout generator and clients.
diff --git a/river/Root.zig b/river/Root.zig
index 4467fa5..7514217 100644
--- a/river/Root.zig
+++ b/river/Root.zig
@@ -391,7 +391,7 @@ pub fn applyPending(root: *Self) void {
 
             // Iterate the focus stack in order to ensure the currently focused/most
             // recently focused view that requests fullscreen is given fullscreen.
-            output.pending.fullscreen = null;
+            output.inflight.fullscreen = null;
             {
                 var it = output.pending.focus_stack.iterator(.forward);
                 while (it.next()) |view| {
@@ -406,10 +406,19 @@ pub fn applyPending(root: *Self) void {
                         view.pending.clampToOutput();
                     }
 
-                    if (output.pending.fullscreen == null and view.pending.fullscreen and
+                    if (!view.current.fullscreen and view.pending.fullscreen) {
+                        view.post_fullscreen_box = view.pending.box;
+                        view.pending.box = .{ .x = 0, .y = 0, .width = undefined, .height = undefined };
+                        output.wlr_output.effectiveResolution(&view.pending.box.width, &view.pending.box.height);
+                    } else if (view.current.fullscreen and !view.pending.fullscreen) {
+                        view.pending.box = view.post_fullscreen_box;
+                        view.pending.clampToOutput();
+                    }
+
+                    if (output.inflight.fullscreen == null and view.pending.fullscreen and
                         view.pending.tags & output.pending.tags != 0)
                     {
-                        output.pending.fullscreen = view;
+                        output.inflight.fullscreen = view;
                     }
 
                     view.inflight_focus_stack_link.remove();
@@ -418,14 +427,6 @@ pub fn applyPending(root: *Self) void {
                     view.inflight = view.pending;
                 }
             }
-            if (output.pending.fullscreen != output.inflight.fullscreen) {
-                if (output.inflight.fullscreen) |view| {
-                    view.pending.box = view.post_fullscreen_box;
-                    view.pending.clampToOutput();
-
-                    view.inflight.box = view.pending.box;
-                }
-            }
 
             {
                 var it = output.pending.wm_stack.iterator(.forward);
@@ -439,32 +440,6 @@ pub fn applyPending(root: *Self) void {
         }
     }
 
-    {
-        // This must be done after the original loop completes to handle the
-        // case where a fullscreen is moved between outputs.
-        var output_it = root.outputs.first;
-        while (output_it) |node| : (output_it = node.next) {
-            const output = &node.data;
-            if (output.pending.fullscreen != output.inflight.fullscreen) {
-                if (output.pending.fullscreen) |view| {
-                    view.post_fullscreen_box = view.pending.box;
-                    view.pending.box = .{
-                        .x = 0,
-                        .y = 0,
-                        .width = undefined,
-                        .height = undefined,
-                    };
-                    output.wlr_output.effectiveResolution(
-                        &view.pending.box.width,
-                        &view.pending.box.height,
-                    );
-                    view.inflight.box = view.pending.box;
-                }
-                output.inflight.fullscreen = output.pending.fullscreen;
-            }
-        }
-    }
-
     {
         // Layout demands can't be sent until after the inflight stacks of
         // all outputs have been updated.
diff --git a/river/View.zig b/river/View.zig
index 9a4fe5b..967fadb 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -341,7 +341,10 @@ pub fn setPendingOutput(view: *Self, output: *Output) void {
     }
     output.pending.focus_stack.prepend(view);
 
-    if (view.pending.float) {
+    if (view.pending.fullscreen) {
+        view.pending.box = .{ .x = 0, .y = 0, .width = undefined, .height = undefined };
+        output.wlr_output.effectiveResolution(&view.pending.box.width, &view.pending.box.height);
+    } else if (view.pending.float) {
         view.pending.clampToOutput();
     }
 }