diff --git a/src/Window.zig b/src/Window.zig index ad1b9b836..23f2a563c 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -79,8 +79,10 @@ io: termio.Impl, io_thread: termio.Thread, io_thr: std.Thread, -/// The dimensions of the grid in rows and columns. +/// All the cached sizes since we need them at various times. +screen_size: renderer.ScreenSize, grid_size: renderer.GridSize, +cell_size: renderer.CellSize, /// Explicit padding due to configuration padding: renderer.Padding, @@ -262,6 +264,9 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window { }); errdefer font_group.deinit(alloc); + // Pre-calculate our initial cell size ourselves. + const cell_size = try renderer.CellSize.init(alloc, font_group); + // Convert our padding from points to pixels const padding_x = (@intToFloat(f32, config.@"window-padding-x") * x_dpi) / 72; const padding_y = (@intToFloat(f32, config.@"window-padding-y") * y_dpi) / 72; @@ -279,6 +284,7 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window { .explicit = padding, .balance = config.@"window-padding-balance", }, + .window_mailbox = .{ .window = self, .app = app.mailbox }, }); errdefer renderer_impl.deinit(); renderer_impl.background = .{ @@ -298,13 +304,16 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window { .width = window_size.width, .height = window_size.height, }; - const grid_size = renderer_impl.gridSize(screen_size); + const grid_size = renderer.GridSize.init( + screen_size.subPadding(padding), + cell_size, + ); // Set a minimum size that is cols=10 h=4. This matches Mac's Terminal.app // but is otherwise somewhat arbitrary. try window.setSizeLimits(.{ - .width = @floatToInt(u32, renderer_impl.cell_size.width * 10), - .height = @floatToInt(u32, renderer_impl.cell_size.height * 4), + .width = @floatToInt(u32, cell_size.width * 10), + .height = @floatToInt(u32, cell_size.height * 4), }, .{ .width = null, .height = null }); // Create the cursor @@ -371,7 +380,9 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window { .io = io, .io_thread = io_thread, .io_thr = undefined, + .screen_size = screen_size, .grid_size = grid_size, + .cell_size = cell_size, .padding = padding, .config = config, @@ -569,18 +580,22 @@ fn sizeCallback(window: glfw.Window, width: i32, height: i32) void { }; }; - const screen_size: renderer.ScreenSize = .{ - .width = px_size.width, - .height = px_size.height, - }; - const win = window.getUserPointer(Window) orelse return; // TODO: if our screen size didn't change, then we should avoid the // overhead of inter-thread communication + // Save our screen size + win.screen_size = .{ + .width = px_size.width, + .height = px_size.height, + }; + // Recalculate our grid size - win.grid_size = win.renderer.gridSize(screen_size); + win.grid_size = renderer.GridSize.init( + win.screen_size.subPadding(win.padding), + win.cell_size, + ); if (win.grid_size.columns < 5 and (win.padding.left > 0 or win.padding.right > 0)) { log.warn("WARNING: very small terminal grid detected with padding " ++ "set. Is your padding reasonable?", .{}); @@ -594,7 +609,7 @@ fn sizeCallback(window: glfw.Window, width: i32, height: i32) void { _ = win.io_thread.mailbox.push(.{ .resize = .{ .grid_size = win.grid_size, - .screen_size = screen_size, + .screen_size = win.screen_size, .padding = win.padding, }, }, .{ .forever = {} }); @@ -1386,10 +1401,10 @@ fn cursorPosCallback( // // the boundary point at which we consider selection or non-selection - const cell_xboundary = win.renderer.cell_size.width * 0.6; + const cell_xboundary = win.cell_size.width * 0.6; // first xpos of the clicked cell - const cell_xstart = @intToFloat(f32, win.mouse.left_click_point.x) * win.renderer.cell_size.width; + const cell_xstart = @intToFloat(f32, win.mouse.left_click_point.x) * win.cell_size.width; const cell_start_xpos = win.mouse.left_click_xpos - cell_xstart; // If this is the same cell, then we only start the selection if weve @@ -1464,7 +1479,7 @@ fn posToViewport(self: Window, xpos: f64, ypos: f64) terminal.point.Viewport { return .{ .x = if (xpos < 0) 0 else x: { // Our cell is the mouse divided by cell width - const cell_width = @floatCast(f64, self.renderer.cell_size.width); + const cell_width = @floatCast(f64, self.cell_size.width); const x = @floatToInt(usize, xpos / cell_width); // Can be off the screen if the user drags it out, so max @@ -1473,7 +1488,7 @@ fn posToViewport(self: Window, xpos: f64, ypos: f64) terminal.point.Viewport { }, .y = if (ypos < 0) 0 else y: { - const cell_height = @floatCast(f64, self.renderer.cell_size.height); + const cell_height = @floatCast(f64, self.cell_size.height); const y = @floatToInt(usize, ypos / cell_height); break :y @min(y, self.io.terminal.rows - 1); }, diff --git a/src/renderer/Options.zig b/src/renderer/Options.zig index c313d91c6..38789f1c7 100644 --- a/src/renderer/Options.zig +++ b/src/renderer/Options.zig @@ -2,6 +2,7 @@ const font = @import("../font/main.zig"); const renderer = @import("../renderer.zig"); +const Window = @import("../Window.zig"); /// The font group that should be used. font_group: *font.GroupCache, @@ -9,6 +10,10 @@ font_group: *font.GroupCache, /// Padding options for the viewport. padding: Padding, +/// The mailbox for sending the window messages. This is only valid +/// once the thread has started and should not be used outside of the thread. +window_mailbox: Window.Mailbox, + pub const Padding = struct { // Explicit padding options, in pixels. The windowing thread is // expected to convert points to pixels for a given DPI.