diff options
| author | Isaac Freund <mail@isaacfreund.com> | 2023-02-28 22:56:12 +0100 |
|---|---|---|
| committer | Isaac Freund <mail@isaacfreund.com> | 2023-02-28 22:56:12 +0100 |
| commit | 8cb5ca904195260e17ac0a64972a93f8205d9743 (patch) | |
| tree | 53c0bd4de227a14a79d7a76a7733c1e980c1532a | |
| parent | e11d4dc0de2d6688bf55fb44ca8b1b5d6f80ddac (diff) | |
| download | river-8cb5ca904195260e17ac0a64972a93f8205d9743.tar.gz river-8cb5ca904195260e17ac0a64972a93f8205d9743.tar.xz | |
river: fix various fullscreen related bugs
| m--------- | deps/zig-wayland | 0 | ||||
| -rw-r--r-- | river/Output.zig | 2 | ||||
| -rw-r--r-- | river/Root.zig | 187 | ||||
| -rw-r--r-- | river/View.zig | 6 | ||||
| -rw-r--r-- | river/command/toggle_fullscreen.zig | 3 |
5 files changed, 111 insertions, 87 deletions
diff --git a/deps/zig-wayland b/deps/zig-wayland -Subproject dd9ffa05cca1b5001523a309c646738c65e86ae +Subproject e9484c814801b520cbe4ed719cceb4d0a59f134 diff --git a/river/Output.zig b/river/Output.zig index 0a921cf..adbded4 100644 --- a/river/Output.zig +++ b/river/Output.zig @@ -406,6 +406,8 @@ fn handleMode(listener: *wl.Listener(*wlr.Output), _: *wlr.Output) void { var it = self.layers.fullscreen.children.iterator(.forward); const background_color_rect = @fieldParentPtr(wlr.SceneRect, "node", it.next().?); background_color_rect.setSize(width, height); + + std.log.info("new output mode, width: {}, height: {}", .{ width, height }); } server.root.applyPending(); diff --git a/river/Root.zig b/river/Root.zig index 3a892bd..4f08d38 100644 --- a/river/Root.zig +++ b/river/Root.zig @@ -377,87 +377,102 @@ pub fn applyPending(root: *Self) void { } } - var output_it = root.outputs.first; - while (output_it) |node| : (output_it = node.next) { - const output = &node.data; - - if (output.inflight.fullscreen) |view| { - if (!view.pending.fullscreen or view.pending.tags & output.pending.tags == 0) { - output.inflight.fullscreen = null; - - view.setFullscreen(false); - view.pending.box = view.post_fullscreen_box; - } - } + { + var output_it = root.outputs.first; + while (output_it) |node| : (output_it = node.next) { + const output = &node.data; - // Iterate the focus stack in order to ensure the currently focused/most - // recently focused view that requests fullscreen is given fullscreen. - { - var it = output.pending.focus_stack.iterator(.forward); - while (it.next()) |view| { - assert(view.pending.output == output); - - if (view.current.float and !view.pending.float) { - // If switching from float to non-float, save the dimensions. - view.float_box = view.current.box; - } else if (!view.current.float and view.pending.float) { - // If switching from non-float to float, apply the saved float dimensions. - view.pending.box = view.float_box; - } + // Iterate the focus stack in order to ensure the currently focused/most + // recently focused view that requests fullscreen is given fullscreen. + var fullscreen_found = false; + { + var it = output.pending.focus_stack.iterator(.forward); + while (it.next()) |view| { + assert(view.pending.output == output); + + if (view.current.float and !view.pending.float) { + // If switching from float to non-float, save the dimensions. + view.float_box = view.current.box; + } else if (!view.current.float and view.pending.float) { + // If switching from non-float to float, apply the saved float dimensions. + view.pending.box = view.float_box; + } - if (output.inflight.fullscreen == null) { - if (view.pending.fullscreen and view.pending.tags & output.pending.tags != 0) { - output.inflight.fullscreen = view; - - view.setFullscreen(true); - 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, - ); + if (!fullscreen_found and view.pending.fullscreen and + view.pending.tags & output.pending.tags != 0) + { + fullscreen_found = true; + if (output.inflight.fullscreen != view) { + if (output.inflight.fullscreen) |old| { + old.setFullscreen(false); + old.pending.box = old.post_fullscreen_box; + old.inflight.box = old.pending.box; + } + + output.inflight.fullscreen = view; + + view.setFullscreen(true); + 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; + } } - } - view.inflight_focus_stack_link.remove(); - output.inflight.focus_stack.append(view); + view.inflight_focus_stack_link.remove(); + output.inflight.focus_stack.append(view); - view.inflight = view.pending; + view.inflight = view.pending; + } } - } - - { - var it = output.pending.wm_stack.iterator(.forward); - while (it.next()) |view| { - view.inflight_wm_stack_link.remove(); - output.inflight.wm_stack.append(view); + if (!fullscreen_found) { + output.inflight.fullscreen = null; } - } - output.inflight.tags = output.pending.tags; - - assert(output.inflight.layout_demand == null); - if (output.layout) |layout| { - var layout_count: u32 = 0; { - var it = output.inflight.wm_stack.iterator(.forward); + var it = output.pending.wm_stack.iterator(.forward); while (it.next()) |view| { - if (!view.inflight.float and !view.inflight.fullscreen and - view.inflight.tags & output.inflight.tags != 0) - { - layout_count += 1; - } + view.inflight_wm_stack_link.remove(); + output.inflight.wm_stack.append(view); } } - if (layout_count > 0) { - // TODO don't do this if the count has not changed - layout.startLayoutDemand(layout_count); + output.inflight.tags = output.pending.tags; + } + } + + { + // Layout demands can't be sent until after the inflight stacks of + // all outputs have been updated. + var output_it = root.outputs.first; + while (output_it) |node| : (output_it = node.next) { + const output = &node.data; + assert(output.inflight.layout_demand == null); + if (output.layout) |layout| { + var layout_count: u32 = 0; + { + var it = output.inflight.wm_stack.iterator(.forward); + while (it.next()) |view| { + if (!view.inflight.float and !view.inflight.fullscreen and + view.inflight.tags & output.inflight.tags != 0) + { + layout_count += 1; + } + } + } + + if (layout_count > 0) { + // TODO don't do this if the count has not changed + layout.startLayoutDemand(layout_count); + } } } } @@ -570,29 +585,15 @@ fn commitTransaction(root: *Self) void { } output.current.tags = output.inflight.tags; - if (output.inflight.fullscreen != output.current.fullscreen) { - if (output.current.fullscreen) |view| { - if (view.inflight.output) |new_output| { - view.tree.node.reparent(new_output.layers.views); - } else { - view.tree.node.reparent(root.hidden.tree); - } - } - if (output.inflight.fullscreen) |view| { - assert(view.inflight.output == output); - view.tree.node.reparent(output.layers.fullscreen); - } - output.current.fullscreen = output.inflight.fullscreen; - output.layers.fullscreen.node.setEnabled(output.current.fullscreen != null); - } - var focus_stack_it = output.inflight.focus_stack.iterator(.forward); while (focus_stack_it.next()) |view| { assert(view.inflight.output == output); view.inflight_serial = null; - if (view.current.output != output) { + if (view.current.output != output or + (output.current.fullscreen == view and output.inflight.fullscreen != view)) + { view.tree.node.reparent(output.layers.views); view.popup_tree.node.reparent(output.layers.popups); } @@ -600,12 +601,24 @@ fn commitTransaction(root: *Self) void { const enabled = view.current.tags & output.current.tags != 0; view.tree.node.setEnabled(enabled); view.popup_tree.node.setEnabled(enabled); - // TODO this approach for syncing the order will likely cause over-damaging. - view.tree.node.lowerToBottom(); + if (output.inflight.fullscreen != view) { + // TODO this approach for syncing the order will likely cause over-damaging. + view.tree.node.lowerToBottom(); + } view.updateCurrent(); } + if (output.inflight.fullscreen != output.current.fullscreen) { + if (output.inflight.fullscreen) |view| { + assert(view.inflight.output == output); + assert(view.current.output == output); + view.tree.node.reparent(output.layers.fullscreen); + } + output.current.fullscreen = output.inflight.fullscreen; + output.layers.fullscreen.node.setEnabled(output.current.fullscreen != null); + } + output.status.handleTransactionCommit(output); } diff --git a/river/View.zig b/river/View.zig index 4182a04..399dcdd 100644 --- a/river/View.zig +++ b/river/View.zig @@ -193,19 +193,25 @@ pub fn updateCurrent(view: *Self) void { view.tree.node.setPosition(box.x, box.y); view.popup_tree.node.setPosition(box.x, box.y); + const enable_borders = view.draw_borders and !view.current.fullscreen; + const border_width: c_int = config.border_width; + view.borders.left.node.setEnabled(enable_borders); view.borders.left.node.setPosition(-border_width, -border_width); view.borders.left.setSize(border_width, box.height + 2 * border_width); view.borders.left.setColor(color); + view.borders.right.node.setEnabled(enable_borders); view.borders.right.node.setPosition(box.width, -border_width); view.borders.right.setSize(border_width, box.height + 2 * border_width); view.borders.right.setColor(color); + view.borders.top.node.setEnabled(enable_borders); view.borders.top.node.setPosition(0, -border_width); view.borders.top.setSize(box.width, border_width); view.borders.top.setColor(color); + view.borders.bottom.node.setEnabled(enable_borders); view.borders.bottom.node.setPosition(0, box.height); view.borders.bottom.setSize(box.width, border_width); view.borders.bottom.setColor(color); diff --git a/river/command/toggle_fullscreen.zig b/river/command/toggle_fullscreen.zig index 5dfef41..402cce3 100644 --- a/river/command/toggle_fullscreen.zig +++ b/river/command/toggle_fullscreen.zig @@ -33,6 +33,9 @@ pub fn toggleFullscreen( const view = seat.focused.view; view.pending.fullscreen = !view.pending.fullscreen; + // It is possible to end up with multiple fullscreen views in which + // case making one non-fullscreen should switch focus to the next. + seat.focus(null); server.root.applyPending(); } } |
