From 550bd493cdb4696069f23b00616b86daa348a89a Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Sun, 26 Apr 2020 16:49:50 +0200 Subject: [PATCH] Greatly simplify view offset handling Fixes https://github.com/ifreund/river/issues/9 --- src/box.zig | 23 ++++++++--- src/layer_surface.zig | 2 +- src/output.zig | 34 +++++++++++----- src/render.zig | 93 ++++++++++++++++--------------------------- src/view.zig | 2 +- src/xdg_toplevel.zig | 8 ++-- 6 files changed, 82 insertions(+), 80 deletions(-) diff --git a/src/box.zig b/src/box.zig index 5d33f98..2d28a1c 100644 --- a/src/box.zig +++ b/src/box.zig @@ -1,6 +1,17 @@ -pub const Box = struct { - x: i32, - y: i32, - width: u32, - height: u32, -}; +const Self = @This(); + +const c = @import("c.zig"); + +x: i32, +y: i32, +width: u32, +height: u32, + +pub fn toWlrBox(self: Self) c.wlr_box { + return c.wlr_box{ + .x = @intCast(c_int, self.x), + .y = @intCast(c_int, self.y), + .width = @intCast(c_int, self.width), + .height = @intCast(c_int, self.height), + }; +} diff --git a/src/layer_surface.zig b/src/layer_surface.zig index 38af53a..105eaad 100644 --- a/src/layer_surface.zig +++ b/src/layer_surface.zig @@ -1,7 +1,7 @@ const std = @import("std"); const c = @import("c.zig"); -const Box = @import("box.zig").Box; +const Box = @import("box.zig"); const Log = @import("log.zig").Log; const Output = @import("output.zig").Output; diff --git a/src/output.zig b/src/output.zig index 59b43dd..be762c6 100644 --- a/src/output.zig +++ b/src/output.zig @@ -2,7 +2,7 @@ const std = @import("std"); const c = @import("c.zig"); const render = @import("render.zig"); -const Box = @import("box.zig").Box; +const Box = @import("box.zig"); const LayerSurface = @import("layer_surface.zig").LayerSurface; const Log = @import("log.zig").Log; const Root = @import("root.zig").Root; @@ -160,6 +160,8 @@ pub const Output = struct { const master_count = std.math.min(self.master_count, visible_count); const slave_count = if (master_count >= visible_count) 0 else visible_count - master_count; + const border_width = self.root.server.config.border_width; + const view_padding = self.root.server.config.view_padding; const outer_padding = self.root.server.config.outer_padding; const layout_width = @intCast(u32, self.usable_box.width) - outer_padding * 2; @@ -183,30 +185,34 @@ pub const Output = struct { var it = ViewStack(View).pendingIterator(self.views.first, output_tags); while (it.next()) |node| { const view = &node.view; + if (view.floating) { continue; } + + var new_box: Box = undefined; + + // Add the remainder to the first master/slave to ensure every + // pixel of height is used if (i < master_count) { - // Add the remainder to the first master to ensure every pixel of height is used const master_height = @divTrunc(layout_height, master_count); const master_height_rem = layout_height % master_count; - view.pending_box = Box{ - .x = @intCast(i32, outer_padding), - .y = @intCast(i32, outer_padding + i * master_height + + new_box = .{ + .x = 0, + .y = @intCast(i32, i * master_height + if (i > 0) master_height_rem else 0), .width = master_column_width, .height = master_height + if (i == 0) master_height_rem else 0, }; } else { - // Add the remainder to the first slave to ensure every pixel of height is used const slave_height = @divTrunc(layout_height, slave_count); const slave_height_rem = layout_height % slave_count; - view.pending_box = Box{ - .x = @intCast(i32, outer_padding + master_column_width), - .y = @intCast(i32, outer_padding + (i - master_count) * slave_height + + new_box = .{ + .x = @intCast(i32, master_column_width), + .y = @intCast(i32, (i - master_count) * slave_height + if (i > master_count) slave_height_rem else 0), .width = slave_column_width, @@ -215,6 +221,16 @@ pub const Output = struct { }; } + // Apply offsets from borders and padding + new_box.x += @intCast(i32, border_width + outer_padding + view_padding); + new_box.y += @intCast(i32, border_width + outer_padding + view_padding); + + new_box.width -= (border_width + view_padding) * 2; + new_box.height -= (border_width + view_padding) * 2; + + // Set the view's pending box to the new dimensions + view.pending_box = new_box; + i += 1; } } diff --git a/src/render.zig b/src/render.zig index 9c4ab43..2e4dba6 100644 --- a/src/render.zig +++ b/src/render.zig @@ -1,6 +1,7 @@ const std = @import("std"); const c = @import("c.zig"); +const Box = @import("box.zig"); const LayerSurface = @import("layer_surface.zig").LayerSurface; const Output = @import("output.zig").Output; const Server = @import("server.zig").Server; @@ -168,13 +169,11 @@ fn renderView(output: Output, view: *View, now: *c.timespec) void { // If we have a stashed buffer, we are in the middle of a transaction // and need to render that buffer until the transaction is complete. if (view.stashed_buffer) |buffer| { - const border_width = view.output.root.server.config.border_width; - const view_padding = view.output.root.server.config.view_padding; var box = c.wlr_box{ - .x = view.current_box.x + @intCast(i32, border_width + view_padding), - .y = view.current_box.y + @intCast(i32, border_width + view_padding), - .width = @intCast(c_int, view.current_box.width - border_width * 2 - view_padding * 2), - .height = @intCast(c_int, view.current_box.height - border_width * 2 - view_padding * 2), + .x = view.current_box.x, + .y = view.current_box.y, + .width = @intCast(c_int, view.current_box.width), + .height = @intCast(c_int, view.current_box.height), }; // Scale the box to the output's current scaling factor @@ -229,11 +228,9 @@ fn renderSurface(_surface: ?*c.wlr_surface, sx: c_int, sy: c_int, data: ?*c_void return; } - const border_width = view.output.root.server.config.border_width; - const view_padding = view.output.root.server.config.view_padding; var box = c.wlr_box{ - .x = view.current_box.x + sx + @intCast(c_int, border_width + view_padding), - .y = view.current_box.y + sy + @intCast(c_int, border_width + view_padding), + .x = view.current_box.x + sx, + .y = view.current_box.y + sy, .width = surface.current.width, .height = surface.current.height, }; @@ -259,66 +256,46 @@ fn renderSurface(_surface: ?*c.wlr_surface, sx: c_int, sy: c_int, data: ?*c_void } fn renderBorders(output: Output, view: *View, now: *c.timespec) void { - var border: c.wlr_box = undefined; + var border: Box = undefined; const color = if (view.focused) [_]f32{ 0.57647059, 0.63137255, 0.63137255, 1.0 } // Solarized base1 else [_]f32{ 0.34509804, 0.43137255, 0.45882353, 1.0 }; // Solarized base01 const border_width = output.root.server.config.border_width; - const view_padding = output.root.server.config.view_padding; - // left border - border.x = view.current_box.x + @intCast(c_int, view_padding); - border.y = view.current_box.y + @intCast(c_int, view_padding); - border.width = @intCast(c_int, border_width); - border.height = @intCast(c_int, view.current_box.height - view_padding * 2); - scaleBox(&border, output.wlr_output.scale); - c.wlr_render_rect( - output.root.server.wlr_renderer, - &border, - &color, - &output.wlr_output.transform_matrix, - ); + // left and right, covering the corners as well + border.y = view.current_box.y - @intCast(i32, border_width); + border.width = border_width; + border.height = view.current_box.height + border_width * 2; - // right border - border.x = view.current_box.x + - @intCast(c_int, view.current_box.width - border_width - view_padding); - border.y = view.current_box.y + @intCast(c_int, view_padding); - border.width = @intCast(c_int, border_width); - border.height = @intCast(c_int, view.current_box.height - view_padding * 2); - scaleBox(&border, output.wlr_output.scale); - c.wlr_render_rect( - output.root.server.wlr_renderer, - &border, - &color, - &output.wlr_output.transform_matrix, - ); + // left + border.x = view.current_box.x - @intCast(i32, border_width); + renderRect(output, border, color); - // top border - border.x = view.current_box.x + @intCast(c_int, border_width + view_padding); - border.y = view.current_box.y + @intCast(c_int, view_padding); - border.width = @intCast(c_int, view.current_box.width - - border_width * 2 - view_padding * 2); - border.height = @intCast(c_int, border_width); - scaleBox(&border, output.wlr_output.scale); - c.wlr_render_rect( - output.root.server.wlr_renderer, - &border, - &color, - &output.wlr_output.transform_matrix, - ); + // right + border.x = view.current_box.x + @intCast(i32, view.current_box.width); + renderRect(output, border, color); + + // top and bottom + border.x = view.current_box.x; + border.width = view.current_box.width; + border.height = border_width; + + // top + border.y = view.current_box.y - @intCast(i32, border_width); + renderRect(output, border, color); // bottom border - border.x = view.current_box.x + @intCast(c_int, border_width + view_padding); - border.y = view.current_box.y + - @intCast(c_int, view.current_box.height - border_width - view_padding); - border.width = @intCast(c_int, view.current_box.width - - border_width * 2 - view_padding * 2); - border.height = @intCast(c_int, border_width); - scaleBox(&border, output.wlr_output.scale); + border.y = view.current_box.y + @intCast(i32, view.current_box.height); + renderRect(output, border, color); +} + +fn renderRect(output: Output, box: Box, color: [4]f32) void { + var wlr_box = box.toWlrBox(); + scaleBox(&wlr_box, output.wlr_output.scale); c.wlr_render_rect( output.root.server.wlr_renderer, - &border, + &wlr_box, &color, &output.wlr_output.transform_matrix, ); diff --git a/src/view.zig b/src/view.zig index 19614d0..a4ede46 100644 --- a/src/view.zig +++ b/src/view.zig @@ -1,7 +1,7 @@ const std = @import("std"); const c = @import("c.zig"); -const Box = @import("box.zig").Box; +const Box = @import("box.zig"); const Log = @import("log.zig").Log; const Output = @import("output.zig").Output; const Root = @import("root.zig").Root; diff --git a/src/xdg_toplevel.zig b/src/xdg_toplevel.zig index 4e7115a..0e64396 100644 --- a/src/xdg_toplevel.zig +++ b/src/xdg_toplevel.zig @@ -3,7 +3,7 @@ const Self = @This(); const c = @import("c.zig"); const std = @import("std"); -const Box = @import("box.zig").Box; +const Box = @import("box.zig"); const Log = @import("log.zig").Log; const View = @import("view.zig").View; const ViewStack = @import("view_stack.zig").ViewStack; @@ -44,12 +44,10 @@ pub fn init(self: *Self, view: *View, wlr_xdg_surface: *c.wlr_xdg_surface) void } pub fn configure(self: Self, pending_box: Box) void { - const border_width = self.view.output.root.server.config.border_width; - const view_padding = self.view.output.root.server.config.view_padding; self.view.pending_serial = c.wlr_xdg_toplevel_set_size( self.wlr_xdg_surface, - pending_box.width - border_width * 2 - view_padding * 2, - pending_box.height - border_width * 2 - view_padding * 2, + pending_box.width, + pending_box.height, ); }