diff --git a/src/Surface.zig b/src/Surface.zig index df2612a55..199ba1e52 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -444,8 +444,8 @@ pub fn init( .io = io, .io_thread = io_thread, .io_thr = undefined, - .screen_size = screen_size, - .grid_size = grid_size, + .screen_size = .{ .width = 0, .height = 0 }, + .grid_size = .{}, .cell_size = cell_size, .padding = padding, .config = try DerivedConfig.init(alloc, config), @@ -827,20 +827,35 @@ pub fn sizeCallback(self: *Surface, size: apprt.SurfaceSize) !void { const tracy = trace(@src()); defer tracy.end(); - // TODO: if our screen size didn't change, then we should avoid the - // overhead of inter-thread communication - - // Save our screen size - self.screen_size = .{ + const new_screen_size: renderer.ScreenSize = .{ .width = size.width, .height = size.height, }; - // Recalculate our grid size - self.grid_size = renderer.GridSize.init( + // Update our screen size, but only if it actually changed. And if + // the screen size didn't change, then our grid size could not have + // changed, so we just return. + if (self.screen_size.equals(new_screen_size)) return; + + // Save our screen size + self.screen_size = new_screen_size; + + // Mail the renderer so that it can update the GPU and re-render + _ = self.renderer_thread.mailbox.push(.{ + .screen_size = self.screen_size, + }, .{ .forever = {} }); + try self.queueRender(); + + // Recalculate our grid size. Because Ghostty supports fluid resizing, + // its possible the grid doesn't change at all even if the screen size changes. + const new_grid_size = renderer.GridSize.init( self.screen_size.subPadding(self.padding), self.cell_size, ); + if (self.grid_size.equals(new_grid_size)) return; + + // Grid size changed, update our grid size and notify the terminal + self.grid_size = new_grid_size; if (self.grid_size.columns < 5 and (self.padding.left > 0 or self.padding.right > 0)) { log.warn("WARNING: very small terminal grid detected with padding " ++ "set. Is your padding reasonable?", .{}); @@ -850,12 +865,6 @@ pub fn sizeCallback(self: *Surface, size: apprt.SurfaceSize) !void { "set. Is your padding reasonable?", .{}); } - // Mail the renderer - _ = self.renderer_thread.mailbox.push(.{ - .screen_size = self.screen_size, - }, .{ .forever = {} }); - try self.queueRender(); - // Mail the IO thread _ = self.io_thread.mailbox.push(.{ .resize = .{ diff --git a/src/renderer/size.zig b/src/renderer/size.zig index 5398a7def..6d456b100 100644 --- a/src/renderer/size.zig +++ b/src/renderer/size.zig @@ -52,6 +52,11 @@ pub const ScreenSize = struct { .height = self.height -| (padding.top + padding.bottom), }; } + + /// Returns true if two sizes are equal. + pub fn equals(self: ScreenSize, other: ScreenSize) bool { + return self.width == other.width and self.height == other.height; + } }; /// The dimensions of the grid itself, in rows/columns units. @@ -80,6 +85,11 @@ pub const GridSize = struct { self.columns = @max(1, calc_cols); self.rows = @max(1, calc_rows); } + + /// Returns true if two sizes are equal. + pub fn equals(self: GridSize, other: GridSize) bool { + return self.columns == other.columns and self.rows == other.rows; + } }; /// The padding to add to a screen.