From c78d31acf4c2f06eb7a2a9a4d4be2a444e9ca1e0 Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Mon, 29 Jun 2020 11:15:55 +0200 Subject: [PATCH] view: save and restore floating dimensions When a floating view is fullscreened and returned to floating, it should remember its previous floating size/position. --- river/View.zig | 19 +++---------------- river/XdgToplevel.zig | 14 ++++++++++---- river/XwaylandView.zig | 10 ++++++++-- river/command/toggle_float.zig | 2 +- river/command/toggle_fullscreen.zig | 3 +++ 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/river/View.zig b/river/View.zig index 160f22e..06baf04 100644 --- a/river/View.zig +++ b/river/View.zig @@ -85,9 +85,9 @@ saved_surface_box: Box, /// These are what we render while a transaction is in progress saved_buffers: std.ArrayList(SavedBuffer), -/// The dimensions the view would have taken if we didn't force it to tile -natural_width: u32, -natural_height: u32, +/// The floating dimensions the view, saved so that they can be restored if the +/// view returns to floating mode. +float_box: Box, pub fn init(self: *Self, output: *Output, tags: u32, surface: var) void { self.output = output; @@ -259,19 +259,6 @@ pub fn getTitle(self: Self) [*:0]const u8 { }; } -/// Return a box centered on the usable area of the current output and with -/// the natural width/height of the view. -pub fn getDefaultFloatBox(self: Self) Box { - return .{ - .x = std.math.max(0, @divTrunc(@intCast(i32, self.output.usable_box.width) - - @intCast(i32, self.natural_width), 2)), - .y = std.math.max(0, @divTrunc(@intCast(i32, self.output.usable_box.height) - - @intCast(i32, self.natural_height), 2)), - .width = self.natural_width, - .height = self.natural_height, - }; -} - /// Called by the impl when the surface is ready to be displayed pub fn map(self: *Self) void { const root = self.output.root; diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig index 647c85e..02ab1b6 100644 --- a/river/XdgToplevel.zig +++ b/river/XdgToplevel.zig @@ -155,8 +155,14 @@ fn handleMap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { view.wlr_surface = self.wlr_xdg_surface.surface; - view.natural_width = @intCast(u32, self.wlr_xdg_surface.geometry.width); - view.natural_height = @intCast(u32, self.wlr_xdg_surface.geometry.height); + // Use the view's "natural" size centered on the output as the default + // floating dimensions + view.float_box.width = @intCast(u32, self.wlr_xdg_surface.geometry.width); + view.float_box.height = @intCast(u32, self.wlr_xdg_surface.geometry.height); + view.float_box.x = std.math.max(0, @divTrunc(@intCast(i32, view.output.usable_box.width) - + @intCast(i32, view.float_box.width), 2)); + view.float_box.y = std.math.max(0, @divTrunc(@intCast(i32, view.output.usable_box.height) - + @intCast(i32, view.float_box.height), 2)); const wlr_xdg_toplevel: *c.wlr_xdg_toplevel = @field( self.wlr_xdg_surface, @@ -170,13 +176,13 @@ fn handleMap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { if (wlr_xdg_toplevel.parent != null or has_fixed_size) { // If the toplevel has a parent or has a fixed size make it float view.pending.float = true; - view.pending.box = view.getDefaultFloatBox(); + view.pending.box = view.float_box; } else { // Make views with app_ids listed in the float filter float for (root.server.config.float_filter.items) |filter_app_id| { if (std.mem.eql(u8, std.mem.span(app_id), std.mem.span(filter_app_id))) { view.pending.float = true; - view.pending.box = view.getDefaultFloatBox(); + view.pending.box = view.float_box; break; } } diff --git a/river/XwaylandView.zig b/river/XwaylandView.zig index 0f6cc82..a18a105 100644 --- a/river/XwaylandView.zig +++ b/river/XwaylandView.zig @@ -142,8 +142,14 @@ fn handleMap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { view.wlr_surface = self.wlr_xwayland_surface.surface; - view.natural_width = self.wlr_xwayland_surface.width; - view.natural_height = self.wlr_xwayland_surface.height; + // Use the view's "natural" size centered on the output as the default + // floating dimensions + view.float_box.width = self.wlr_xwayland_surface.width; + view.float_box.height = self.wlr_xwayland_surface.height; + view.float_box.x = std.math.max(0, @divTrunc(@intCast(i32, view.output.usable_box.width) - + @intCast(i32, view.float_box.width), 2)); + view.float_box.y = std.math.max(0, @divTrunc(@intCast(i32, view.output.usable_box.height) - + @intCast(i32, view.float_box.height), 2)); view.map(); } diff --git a/river/command/toggle_float.zig b/river/command/toggle_float.zig index 29f433d..38ff74f 100644 --- a/river/command/toggle_float.zig +++ b/river/command/toggle_float.zig @@ -34,7 +34,7 @@ pub fn toggleFloat( // Don't float fullscreen views if (view.pending.fullscreen) return; - if (!view.pending.float) view.pending.box = view.getDefaultFloatBox(); + if (!view.pending.float) view.pending.box = view.float_box; view.pending.float = !view.pending.float; view.output.root.arrange(); } diff --git a/river/command/toggle_fullscreen.zig b/river/command/toggle_fullscreen.zig index 0b3acc7..13e4296 100644 --- a/river/command/toggle_fullscreen.zig +++ b/river/command/toggle_fullscreen.zig @@ -30,6 +30,9 @@ pub fn toggleFullscreen( if (args.len > 1) return Error.TooManyArguments; if (seat.focused_view) |view| { + // If transitionng from fullscreen -> float, return to the saved + // floating dimensions. + if (view.pending.fullscreen and view.pending.float) view.pending.box = view.float_box; view.setFullscreen(!view.pending.fullscreen); view.output.root.arrange(); }