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

commitd7952cc5c1a8d61c61f99d690118c5455e108eeb
parentb2b172a95a
authorIsaac Freund <[email protected]>
date2024-01-12 16:49
Root: use Output.PendingState for fallback

Using the same type for these has the potential to simplify some future
code.

 river/Output.zig | 44 +++++++++++++++++++++++---------------------
 river/Root.zig   | 37 ++++++++++++++-----------------------
 river/View.zig   |  8 ++++----
 3 files changed, 41 insertions(+), 48 deletions(-)

diff --git a/river/Output.zig b/river/Output.zig
index 1c092ee..f9c3b0e 100644
--- a/river/Output.zig
+++ b/river/Output.zig
@@ -39,6 +39,28 @@ const View = @import("View.zig");
 
 const log = std.log.scoped(.output);
 
+pub const PendingState = struct {
+    /// A bit field of focused tags
+    tags: u32 = 1 << 0,
+    /// The stack of views in focus/rendering order.
+    ///
+    /// This contains views that aren't currently visible because they do not
+    /// match the tags of the output.
+    ///
+    /// This list is used to update the rendering order of nodes in the scene
+    /// graph when the pending state is committed.
+    focus_stack: wl.list.Head(View, .pending_focus_stack_link),
+    /// The stack of views acted upon by window management commands such
+    /// as focus-view, zoom, etc.
+    ///
+    /// This contains views that aren't currently visible because they do not
+    /// match the tags of the output. This means that a filtered version of the
+    /// list must be used for window management commands.
+    ///
+    /// This includes both floating/fullscreen views and those arranged in the layout.
+    wm_stack: wl.list.Head(View, .pending_wm_stack_link),
+};
+
 wlr_output: *wlr.Output,
 scene_output: *wlr.SceneOutput,
 
@@ -113,27 +135,7 @@ gamma_dirty: bool = false,
 ///
 /// Any time pending state is modified Root.applyPending() must be called
 /// before yielding back to the event loop.
-pending: struct {
-    /// A bit field of focused tags
-    tags: u32 = 1 << 0,
-    /// The stack of views in focus/rendering order.
-    ///
-    /// This contains views that aren't currently visible because they do not
-    /// match the tags of the output.
-    ///
-    /// This list is used to update the rendering order of nodes in the scene
-    /// graph when the pending state is committed.
-    focus_stack: wl.list.Head(View, .pending_focus_stack_link),
-    /// The stack of views acted upon by window management commands such
-    /// as focus-view, zoom, etc.
-    ///
-    /// This contains views that aren't currently visible because they do not
-    /// match the tags of the output. This means that a filtered version of the
-    /// list must be used for window management commands.
-    ///
-    /// This includes both floating/fullscreen views and those arranged in the layout.
-    wm_stack: wl.list.Head(View, .pending_wm_stack_link),
-},
+pending: PendingState,
 
 /// The state most recently sent to the layout generator and clients.
 /// This state is immutable until all clients have replied and the transaction
diff --git a/river/Root.zig b/river/Root.zig
index 5c3238d..58b4ddf 100644
--- a/river/Root.zig
+++ b/river/Root.zig
@@ -74,14 +74,7 @@ hidden: struct {
 /// There is no need for inflight lists, instead the inflight links of views are
 /// remove()'d from their current list and init()'d so they may be remove()'d again
 /// when an output becomes available and they are moved to the output's inflight lists.
-fallback: struct {
-    tags: u32 = 1 << 0,
-
-    pending: struct {
-        focus_stack: wl.list.Head(View, .pending_focus_stack_link),
-        wm_stack: wl.list.Head(View, .pending_wm_stack_link),
-    },
-},
+fallback_pending: Output.PendingState,
 
 views: wl.list.Head(View, .link),
 
@@ -165,11 +158,9 @@ pub fn init(self: *Self) !void {
                 .wm_stack = undefined,
             },
         },
-        .fallback = .{
-            .pending = .{
-                .focus_stack = undefined,
-                .wm_stack = undefined,
-            },
+        .fallback_pending = .{
+            .focus_stack = undefined,
+            .wm_stack = undefined,
         },
         .views = undefined,
         .output_layout = output_layout,
@@ -185,8 +176,8 @@ pub fn init(self: *Self) !void {
     self.hidden.inflight.focus_stack.init();
     self.hidden.inflight.wm_stack.init();
 
-    self.fallback.pending.focus_stack.init();
-    self.fallback.pending.wm_stack.init();
+    self.fallback_pending.focus_stack.init();
+    self.fallback_pending.wm_stack.init();
 
     self.views.init();
     self.all_outputs.init();
@@ -292,7 +283,7 @@ pub fn deactivateOutput(root: *Self, output: *Output) void {
         }
     }
     // Use the first output in the list as fallback. If the last real output
-    // is being removed, store the views in Root.fallback.
+    // is being removed, store the views in Root.fallback_pending.
     const fallback_output = blk: {
         var it = root.active_outputs.iterator(.forward);
         if (it.next()) |o| break :blk o;
@@ -305,11 +296,11 @@ pub fn deactivateOutput(root: *Self, output: *Output) void {
     } else {
         var it = output.pending.focus_stack.iterator(.forward);
         while (it.next()) |view| view.pending.output = null;
-        root.fallback.pending.focus_stack.prependList(&output.pending.focus_stack);
-        root.fallback.pending.wm_stack.prependList(&output.pending.wm_stack);
+        root.fallback_pending.focus_stack.prependList(&output.pending.focus_stack);
+        root.fallback_pending.wm_stack.prependList(&output.pending.wm_stack);
         // Store the focused output tags if we are hotplugged down to
         // 0 real outputs so they can be restored on gaining a new output.
-        root.fallback.tags = output.pending.tags;
+        root.fallback_pending.tags = output.pending.tags;
     }
 
     // Close all layer surfaces on the removed output
@@ -377,9 +368,9 @@ pub fn activateOutput(root: *Self, output: *Output) void {
         const log = std.log.scoped(.output_manager);
         log.debug("moving views from fallback stacks to new output", .{});
 
-        output.pending.tags = root.fallback.tags;
+        output.pending.tags = root.fallback_pending.tags;
         {
-            var it = root.fallback.pending.wm_stack.safeIterator(.reverse);
+            var it = root.fallback_pending.wm_stack.safeIterator(.reverse);
             while (it.next()) |view| view.setPendingOutput(output);
         }
         {
@@ -391,8 +382,8 @@ pub fn activateOutput(root: *Self, output: *Output) void {
             }
         }
     }
-    assert(root.fallback.pending.focus_stack.empty());
-    assert(root.fallback.pending.wm_stack.empty());
+    assert(root.fallback_pending.focus_stack.empty());
+    assert(root.fallback_pending.wm_stack.empty());
 }
 
 /// Trigger asynchronous application of pending state for all outputs and views.
diff --git a/river/View.zig b/river/View.zig
index 8ca0186..4deea21 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -513,7 +513,7 @@ pub fn map(view: *Self) !void {
     }
 
     view.pending.tags = blk: {
-        const default = if (output) |o| o.pending.tags else server.root.fallback.tags;
+        const default = if (output) |o| o.pending.tags else server.root.fallback_pending.tags;
         if (server.config.rules.tags.match(view)) |tags| break :blk tags;
         const tags = default & server.config.spawn_tagmask;
         break :blk if (tags != 0) tags else default;
@@ -531,10 +531,10 @@ pub fn map(view: *Self) !void {
         view.pending_focus_stack_link.remove();
 
         switch (server.config.attach_mode) {
-            .top => server.root.fallback.pending.wm_stack.prepend(view),
-            .bottom => server.root.fallback.pending.wm_stack.append(view),
+            .top => server.root.fallback_pending.wm_stack.prepend(view),
+            .bottom => server.root.fallback_pending.wm_stack.append(view),
         }
-        server.root.fallback.pending.focus_stack.prepend(view);
+        server.root.fallback_pending.focus_stack.prepend(view);
 
         view.inflight_wm_stack_link.remove();
         view.inflight_wm_stack_link.init();