aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsaac Freund <mail@isaacfreund.com>2023-11-09 16:36:39 +0100
committerIsaac Freund <mail@isaacfreund.com>2023-11-09 16:36:39 +0100
commit69b61602cfa8ee5afd2a03748005e17eebeb6919 (patch)
tree649cc24cf8c7d3b8e8b8baafc83a4f9809a1885f
parent927dceb071f4d068ea271a3d97c3ece9db0da3b4 (diff)
downloadriver-69b61602cfa8ee5afd2a03748005e17eebeb6919.tar.gz
river-69b61602cfa8ee5afd2a03748005e17eebeb6919.tar.xz
View: handle map while no outputs are available
Currently views which are mapped while no outputs are available can never actually get rendered because they have 0 tags and are stuck in the hidden stack. This commit fixes this and they should now be restored when a new output becomes available.
-rw-r--r--river/Root.zig3
-rw-r--r--river/View.zig63
2 files changed, 46 insertions, 20 deletions
diff --git a/river/Root.zig b/river/Root.zig
index bb6f7ee..cc3a630 100644
--- a/river/Root.zig
+++ b/river/Root.zig
@@ -362,6 +362,9 @@ pub fn activateOutput(root: *Self, output: *Output) void {
// If we previously had no outputs, move all views to the new output and focus it.
if (first) {
+ const log = std.log.scoped(.output_manager);
+ log.debug("moving views from fallback stacks to new output", .{});
+
output.pending.tags = root.fallback.tags;
{
var it = root.fallback.pending.focus_stack.safeIterator(.reverse);
diff --git a/river/View.zig b/river/View.zig
index e4ea30d..f22cc43 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -495,32 +495,55 @@ pub fn map(view: *Self) !void {
view.pending.ssd = ssd;
}
- const focused_output = server.input_manager.defaultSeat().focused_output;
- if (try server.config.outputRuleMatch(view) orelse focused_output) |output| {
- if (server.config.rules.position.match(view)) |position| {
- view.pending.box.x = position.x;
- view.pending.box.y = position.y;
- } else {
- // Center the initial pending box on the output
- view.pending.box.x = @divTrunc(@max(0, output.usable_box.width - view.pending.box.width), 2);
- view.pending.box.y = @divTrunc(@max(0, output.usable_box.height - view.pending.box.height), 2);
- }
+ if (server.config.rules.dimensions.match(view)) |dimensions| {
+ view.pending.box.width = dimensions.width;
+ view.pending.box.height = dimensions.height;
+ }
- if (server.config.rules.dimensions.match(view)) |dimensions| {
- view.pending.box.width = dimensions.width;
- view.pending.box.height = dimensions.height;
- }
+ const output = try server.config.outputRuleMatch(view) orelse
+ server.input_manager.defaultSeat().focused_output;
- view.pending.tags = blk: {
- if (server.config.rules.tags.match(view)) |tags| break :blk tags;
- const tags = output.pending.tags & server.config.spawn_tagmask;
- break :blk if (tags != 0) tags else output.pending.tags;
- };
+ if (server.config.rules.position.match(view)) |position| {
+ view.pending.box.x = position.x;
+ view.pending.box.y = position.y;
+ } else if (output) |o| {
+ // Center the initial pending box on the output
+ view.pending.box.x = @divTrunc(@max(0, o.usable_box.width - view.pending.box.width), 2);
+ view.pending.box.y = @divTrunc(@max(0, o.usable_box.height - view.pending.box.height), 2);
+ }
+
+ view.pending.tags = blk: {
+ const default = if (output) |o| o.pending.tags else server.root.fallback.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;
+ };
- view.setPendingOutput(output);
+ if (output) |o| {
+ view.setPendingOutput(o);
var it = server.input_manager.seats.first;
while (it) |seat_node| : (it = seat_node.next) seat_node.data.focus(view);
+ } else {
+ log.debug("no output available for newly mapped view, adding to fallback stacks", .{});
+
+ view.pending_wm_stack_link.remove();
+ view.pending_focus_stack_link.remove();
+ view.inflight_wm_stack_link.remove();
+ view.inflight_focus_stack_link.remove();
+
+ switch (server.config.attach_mode) {
+ .top => {
+ server.root.fallback.pending.wm_stack.prepend(view);
+ server.root.fallback.inflight.wm_stack.prepend(view);
+ },
+ .bottom => {
+ server.root.fallback.pending.wm_stack.append(view);
+ server.root.fallback.inflight.wm_stack.append(view);
+ },
+ }
+ server.root.fallback.pending.focus_stack.prepend(view);
+ server.root.fallback.inflight.focus_stack.prepend(view);
}
view.float_box = view.pending.box;