Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
View: Add attachRelative function
This is used for the above/below attach-modes introduced in d71bebc.
Also remove redundant focusedIndex function in Output.PendingState.
river/Output.zig | 14 --------------
river/View.zig | 47 +++++++++++++++++++++++++++++++----------------
2 files changed, 31 insertions(+), 30 deletions(-)
diff --git a/river/Output.zig b/river/Output.zig
index 32f221a..d208cb6 100644
--- a/river/Output.zig
+++ b/river/Output.zig
@@ -60,20 +60,6 @@ pub const PendingState = struct {
///
/// This includes both floating/fullscreen views and those arranged in the layout.
wm_stack: wl.list.Head(View, .pending_wm_stack_link),
- ///
- /// Index of the first view in focus_stack in the wm_stack list.
- pub fn focusedIndex(self: *PendingState) ?u32 {
- var focus_stack_it = self.focus_stack.iterator(.forward);
- const focused_view = focus_stack_it.next() orelse return null;
-
- var it = self.wm_stack.iterator(.forward);
- var count: u32 = 0;
- while (it.next()) |other| {
- if (other == focused_view) break;
- count += 1;
- }
- return count;
- }
};
wlr_output: *wlr.Output,
diff --git a/river/View.zig b/river/View.zig
index 592f2d9..9d00f48 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -54,6 +54,11 @@ const Impl = union(enum) {
none,
};
+const AttachRelativeMode = enum {
+ above,
+ below,
+};
+
pub const State = struct {
/// The output the view is currently assigned to.
/// May be null if there are no outputs or for newly created views.
@@ -479,14 +484,8 @@ pub fn setPendingOutput(view: *Self, output: *Output) void {
.top => output.pending.wm_stack.prepend(view),
.bottom => output.pending.wm_stack.append(view),
.after => |n| view.attachAfter(&output.pending, n),
- .above => view.attachAfter(
- &output.pending,
- output.pending.focusedIndex() orelse 0,
- ),
- .below => view.attachAfter(
- &output.pending,
- (output.pending.focusedIndex() orelse 0) + 1,
- ),
+ .above => view.attachRelative(&output.pending, .above),
+ .below => view.attachRelative(&output.pending, .below),
}
output.pending.focus_stack.prepend(view);
@@ -557,6 +556,28 @@ pub fn attachAfter(view: *Self, pending_state: *Output.PendingState, n: usize) v
it.current.prev.?.insert(&view.pending_wm_stack_link);
}
+/// Attach above or below the currently focused view
+pub fn attachRelative(view: *Self, pending_state: *Output.PendingState, mode: AttachRelativeMode) void {
+ var focus_stack_it = pending_state.focus_stack.iterator(.forward);
+ const focused_view = focus_stack_it.next();
+
+ if (focused_view == null) {
+ pending_state.wm_stack.append(view);
+ return;
+ }
+
+ var it = pending_state.wm_stack.iterator(.forward);
+ while (it.next()) |other| {
+ if (other == focused_view) {
+ switch (mode) {
+ .above => it.current.prev.?.insert(&view.pending_wm_stack_link),
+ .below => it.current.insert(&view.pending_wm_stack_link),
+ }
+ return;
+ }
+ }
+}
+
/// Called by the impl when the surface is ready to be displayed
pub fn map(view: *Self) !void {
log.debug("view '{?s}' mapped", .{view.getTitle()});
@@ -615,14 +636,8 @@ pub fn map(view: *Self) !void {
.top => server.root.fallback_pending.wm_stack.prepend(view),
.bottom => server.root.fallback_pending.wm_stack.append(view),
.after => |n| view.attachAfter(&server.root.fallback_pending, n),
- .above => view.attachAfter(
- &server.root.fallback_pending,
- server.root.fallback_pending.focusedIndex() orelse 0,
- ),
- .below => view.attachAfter(
- &server.root.fallback_pending,
- (server.root.fallback_pending.focusedIndex() orelse 0) + 1,
- ),
+ .above => view.attachRelative(&server.root.fallback_pending, .above),
+ .below => view.attachRelative(&server.root.fallback_pending, .below),
}
server.root.fallback_pending.focus_stack.prepend(view);