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

commit9ca05feef4e32f7072e159ae998f9cd3f935a96f
parentce0fcefde6
authorIsaac Freund <[email protected]>
date2024-01-13 12:27
attach-mode: code/documentation style tweaks

 doc/riverctl.1.scd            |  6 +++---
 river/Config.zig              |  6 +++---
 river/Output.zig              |  6 +++---
 river/View.zig                | 20 ++++++++++----------
 river/command/attach_mode.zig | 27 ++++++++++++++++-----------
 5 files changed, 35 insertions(+), 30 deletions(-)

diff --git a/doc/riverctl.1.scd b/doc/riverctl.1.scd
index b3c95b2..1f0c4a2 100644
--- a/doc/riverctl.1.scd
+++ b/doc/riverctl.1.scd
@@ -347,7 +347,7 @@ matches everything while _\*\*_ and the empty string are invalid.
 
 ## CONFIGURATION
 
-*attach-mode* *top*|*bottom*|*after <N>*
+*default-attach-mode* *top*|*bottom*|*after <N>*
 	Set the attach mode to be used by all outputs by default.
 
 	Possible values:
@@ -355,8 +355,8 @@ matches everything while _\*\*_ and the empty string are invalid.
 	- bottom: Appends the newly spawned view at the bottom of the stack.
 	- after <N>: Inserts the newly spawned view after N views in the stack.
 
-*default-attach-mode* *top*|*bottom*|*after <N>*
-	Alias to attach-mode.
+	Note that the deprecated *attach-mode* command is aliased to
+	*default-attach-mode* for backwards compatibility.
 
 *output-attach-mode* *top*|*bottom*|*after <N>*
 	Set the attach mode of the currently focused output, overriding the value of
diff --git a/river/Config.zig b/river/Config.zig
index 75730f4..005cd48 100644
--- a/river/Config.zig
+++ b/river/Config.zig
@@ -32,9 +32,9 @@ const RuleList = @import("rule_list.zig").RuleList;
 const View = @import("View.zig");
 
 pub const AttachMode = union(enum) {
-    top: void,
-    bottom: void,
-    after: usize,
+    top,
+    bottom,
+    after: u32,
 };
 
 pub const FocusFollowsCursorMode = enum {
diff --git a/river/Output.zig b/river/Output.zig
index be370d9..f731c64 100644
--- a/river/Output.zig
+++ b/river/Output.zig
@@ -36,7 +36,7 @@ const LockSurface = @import("LockSurface.zig");
 const OutputStatus = @import("OutputStatus.zig");
 const SceneNodeData = @import("SceneNodeData.zig");
 const View = @import("View.zig");
-const AttachMode = @import("Config.zig").AttachMode;
+const Config = @import("Config.zig");
 
 const log = std.log.scoped(.output);
 
@@ -167,7 +167,7 @@ current: struct {
 /// Remembered version of tags (from last run)
 previous_tags: u32 = 1 << 0,
 
-attach_mode: ?AttachMode = null,
+attach_mode: ?Config.AttachMode = null,
 
 /// List of all layouts
 layouts: std.TailQueue(Layout) = .{},
@@ -612,6 +612,6 @@ pub fn layoutNamespace(self: Self) []const u8 {
     return self.layout_namespace orelse server.config.default_layout_namespace;
 }
 
-pub fn attachMode(self: Self) AttachMode {
+pub fn attachMode(self: Self) Config.AttachMode {
     return self.attach_mode orelse server.config.default_attach_mode;
 }
diff --git a/river/View.zig b/river/View.zig
index 7cdc82f..fdccecd 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -33,7 +33,6 @@ const SceneNodeData = @import("SceneNodeData.zig");
 const Seat = @import("Seat.zig");
 const XdgToplevel = @import("XdgToplevel.zig");
 const XwaylandView = @import("XwaylandView.zig");
-const PendingState = @import("Output.zig").PendingState;
 
 const log = std.log.scoped(.view);
 
@@ -422,7 +421,7 @@ pub fn setPendingOutput(view: *Self, output: *Output) void {
     switch (output.attachMode()) {
         .top => output.pending.wm_stack.prepend(view),
         .bottom => output.pending.wm_stack.append(view),
-        .after => |n| view.attach_after(&output.pending, n),
+        .after => |n| view.attachAfter(&output.pending, n),
     }
     output.pending.focus_stack.prepend(view);
 
@@ -478,15 +477,16 @@ pub fn applyConstraints(self: *Self, box: *wlr.Box) void {
     box.height = math.clamp(box.height, self.constraints.min_height, self.constraints.max_height);
 }
 
-/// Attach current view after n Views on the pending wm_stack
-pub fn attach_after(view: *Self, pending_state: *PendingState, n: usize) void {
-    var nvisible: u32 = 0;
+/// Attach after n visible, not-floating views in the pending wm_stack
+pub fn attachAfter(view: *Self, pending_state: *Output.PendingState, n: usize) void {
+    var visible: u32 = 0;
     var it = pending_state.wm_stack.iterator(.forward);
 
-    while (it.next()) |cur_view| {
-        if (nvisible >= n) break;
-        if (!cur_view.pending.float // ignore floating views
-        and cur_view.pending.tags & pending_state.tags != 0) nvisible += 1;
+    while (it.next()) |other| {
+        if (visible >= n) break;
+        if (!other.pending.float and other.pending.tags & pending_state.tags != 0) {
+            visible += 1;
+        }
     }
 
     it.current.prev.?.insert(&view.pending_wm_stack_link);
@@ -549,7 +549,7 @@ pub fn map(view: *Self) !void {
         switch (server.config.default_attach_mode) {
             .top => server.root.fallback_pending.wm_stack.prepend(view),
             .bottom => server.root.fallback_pending.wm_stack.append(view),
-            .after => |n| view.attach_after(&server.root.fallback_pending, n),
+            .after => |n| view.attachAfter(&server.root.fallback_pending, n),
         }
         server.root.fallback_pending.focus_stack.prepend(view);
 
diff --git a/river/command/attach_mode.zig b/river/command/attach_mode.zig
index bac7ad4..ef74edd 100644
--- a/river/command/attach_mode.zig
+++ b/river/command/attach_mode.zig
@@ -16,26 +16,31 @@
 
 const std = @import("std");
 const mem = std.mem;
+const meta = std.meta;
 
 const server = &@import("../main.zig").server;
 
 const Error = @import("../command.zig").Error;
 const Seat = @import("../Seat.zig");
-const AttachMode = @import("../Config.zig").AttachMode;
+const Config = @import("../Config.zig");
 
-fn parseAttachMode(args: []const [:0]const u8) Error!AttachMode {
+fn parseAttachMode(args: []const [:0]const u8) Error!Config.AttachMode {
     if (args.len < 2) return Error.NotEnoughArguments;
 
-    if (mem.eql(u8, "top", args[1])) {
-        return if (args.len > 2) Error.TooManyArguments else .top;
-    } else if (mem.eql(u8, "bottom", args[1])) {
-        return if (args.len > 2) Error.TooManyArguments else .bottom;
-    } else if (mem.eql(u8, "after", args[1])) {
-        if (args.len < 3) return Error.NotEnoughArguments;
-        if (args.len > 3) return Error.TooManyArguments;
-        return .{ .after = try std.fmt.parseInt(usize, args[2], 10) };
+    const tag = meta.stringToEnum(meta.Tag(Config.AttachMode), args[1]) orelse return Error.UnknownOption;
+    switch (tag) {
+        inline .top, .bottom => |mode| {
+            if (args.len > 2) return Error.TooManyArguments;
+
+            return mode;
+        },
+        .after => {
+            if (args.len < 3) return Error.NotEnoughArguments;
+            if (args.len > 3) return Error.TooManyArguments;
+
+            return .{ .after = try std.fmt.parseInt(u32, args[2], 10) };
+        },
     }
-    return Error.UnknownOption;
 }
 
 pub fn outputAttachMode(