From 7a244092e506f8a310aac936100c46ce5341787f Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Fri, 31 Jul 2020 12:16:11 +0200 Subject: [PATCH] view: sidestep transaction for float/fullscreen Transactions are only useful when multiple views need to atomically change size together. Float/fullscreen views are independant of the layout and should bypass the transaction system. --- river/Output.zig | 9 ++------- river/View.zig | 7 ++----- river/XdgToplevel.zig | 12 ++++++------ river/command/toggle_float.zig | 8 +++++++- river/command/toggle_fullscreen.zig | 22 ++++++++++++++++++++-- 5 files changed, 37 insertions(+), 21 deletions(-) diff --git a/river/Output.zig b/river/Output.zig index a77efe2..ef6d443 100644 --- a/river/Output.zig +++ b/river/Output.zig @@ -296,17 +296,12 @@ fn layoutExternal(self: *Self, visible_count: u32, output_tags: u32) !void { pub fn arrangeViews(self: *Self) void { const full_area = Box.fromWlrBox(c.wlr_output_layout_get_box(self.root.wlr_output_layout, self.wlr_output).*); - // Make fullscreen views take the full area, count up views that will be - // arranged by the layout. + // Count up views that will be arranged by the layout var layout_count: u32 = 0; var it = ViewStack(View).pendingIterator(self.views.first, self.pending.tags); while (it.next()) |node| { const view = &node.view; - if (view.pending.fullscreen) { - view.pending.box = full_area; - } else if (!view.pending.float) { - layout_count += 1; - } + if (!view.pending.float) layout_count += 1; } // If the usable area has a zero dimension, trying to arrange the layout diff --git a/river/View.zig b/river/View.zig index 2b0dea1..ab90976 100644 --- a/river/View.zig +++ b/river/View.zig @@ -218,9 +218,6 @@ pub fn setFocused(self: *Self, focused: bool) void { /// Set the pending state to fullscren and inform the client. Should be /// followed by starting a transaction to apply the pending state. pub fn setFullscreen(self: *Self, fullscreen: bool) void { - // If transitionng from fullscreen -> float, return to the saved - // floating dimensions. - if (self.pending.fullscreen and self.pending.float) self.pending.box = self.float_box; self.pending.fullscreen = fullscreen; switch (self.impl) { .xdg_toplevel => |xdg_toplevel| xdg_toplevel.setFullscreen(fullscreen), @@ -315,7 +312,7 @@ pub fn map(self: *Self) void { self.output.sendViewTags(); - root.arrange(); + if (self.pending.float) self.configure() else root.arrange(); } /// Called by the impl when the surface will no longer be displayed @@ -339,7 +336,7 @@ pub fn unmap(self: *Self) void { self.output.sendViewTags(); - root.arrange(); + if (!self.current.float and !self.current.fullscreen) root.arrange(); } /// Destory the view and free the ViewStack node holding it. diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig index 8636fcb..bf01edc 100644 --- a/river/XdgToplevel.zig +++ b/river/XdgToplevel.zig @@ -245,14 +245,14 @@ fn handleCommit(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { view.surface_box = new_box; if (s == self.wlr_xdg_surface.configure_serial) { - // If this commit is in response to our configure, either notify - // the transaction code or apply the pending state immediately, - // depending on whether or not the view is floating. + // If this commit is in response to our configure and the view is + // part of the layout, notify the transaction code. If floating or + // fullscreen apply the pending state immediately. view.pending_serial = null; - if (view.current.float and view.pending.float) - view.current = view.pending + if (!view.pending.float and !view.pending.fullscreen) + view.output.root.notifyConfigured() else - view.output.root.notifyConfigured(); + view.current = view.pending; } else { // If the client has not yet acked our configure, we need to send a // frame done event so that it commits another buffer. These diff --git a/river/command/toggle_float.zig b/river/command/toggle_float.zig index b392081..8f57454 100644 --- a/river/command/toggle_float.zig +++ b/river/command/toggle_float.zig @@ -39,8 +39,14 @@ pub fn toggleFloat( // Don't modify views which are the target of a cursor action if (seat.input_manager.isCursorActionTarget(view)) return; - if (!view.pending.float) view.pending.box = view.float_box; view.pending.float = !view.pending.float; + + // If switching from layout to float, restore the previous floating dimensions + if (view.pending.float) { + view.pending.box = view.float_box; + view.configure(); + } + view.output.root.arrange(); } } diff --git a/river/command/toggle_fullscreen.zig b/river/command/toggle_fullscreen.zig index c5ffb12..6e2ac2d 100644 --- a/river/command/toggle_fullscreen.zig +++ b/river/command/toggle_fullscreen.zig @@ -17,6 +17,9 @@ const std = @import("std"); +const c = @import("../c.zig"); + +const Box = @import("../Box.zig"); const Error = @import("../command.zig").Error; const Seat = @import("../Seat.zig"); @@ -35,7 +38,22 @@ pub fn toggleFullscreen( // Don't modify views which are the target of a cursor action if (seat.input_manager.isCursorActionTarget(view)) return; - view.setFullscreen(!seat.focused.view.pending.fullscreen); - view.output.root.arrange(); + view.setFullscreen(!view.pending.fullscreen); + + if (view.pending.fullscreen) { + const output = view.output; + view.pending.box = Box.fromWlrBox( + c.wlr_output_layout_get_box(output.root.wlr_output_layout, output.wlr_output).*, + ); + view.configure(); + } else if (view.pending.float) { + // If transitioning from fullscreen -> float, return to the saved + // floating dimensions. + view.pending.box = view.float_box; + view.configure(); + } else { + // Transitioning to layout, arrange and start a transaction + view.output.root.arrange(); + } } }