From 4f1cee8eb904a7100ee0718b22b0ecb82b7e5c76 Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Fri, 18 Oct 2024 22:29:52 -0500 Subject: [PATCH] fix: report correct screen pixel size Mode 2048 and CSI 14 t are size report control sequences which contain the text area size in pixels. The text area is defined to be the extents of the grid (rows and columns). Ghostty calculates the available size for the text area by setting the available padding, and then filling as much of the remaining space as possible. However, if there are remainder pixels these are still reported as part of the text area size. Pass the cell_size geometry through so that we can always report the correct value: columns * cell width and rows * cell height. --- src/Surface.zig | 3 +++ src/termio/Options.zig | 3 +++ src/termio/Termio.zig | 27 ++++++++++++++++----------- src/termio/Thread.zig | 1 + src/termio/message.zig | 3 +++ 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/Surface.zig b/src/Surface.zig index c1b7afd7b..bd5073e3a 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -500,6 +500,7 @@ pub fn init( try termio.Termio.init(&self.io, alloc, .{ .grid_size = grid_size, + .cell_size = cell_size, .screen_size = screen_size, .padding = padding, .full_config = config, @@ -1331,6 +1332,7 @@ fn setCellSize(self: *Surface, size: renderer.CellSize) !void { self.io.queueMessage(.{ .resize = .{ .grid_size = self.grid_size, + .cell_size = self.cell_size, .screen_size = self.screen_size, .padding = self.padding, }, @@ -1435,6 +1437,7 @@ fn resize(self: *Surface, size: renderer.ScreenSize) !void { self.io.queueMessage(.{ .resize = .{ .grid_size = self.grid_size, + .cell_size = self.cell_size, .screen_size = self.screen_size, .padding = self.padding, }, diff --git a/src/termio/Options.zig b/src/termio/Options.zig index fe862a503..8014ed403 100644 --- a/src/termio/Options.zig +++ b/src/termio/Options.zig @@ -11,6 +11,9 @@ const termio = @import("../termio.zig"); /// The size of the terminal grid. grid_size: renderer.GridSize, +/// The size of a single cell, in pixels. +cell_size: renderer.CellSize, + /// The size of the viewport in pixels. screen_size: renderer.ScreenSize, diff --git a/src/termio/Termio.zig b/src/termio/Termio.zig index 865ca8d90..f28eb118e 100644 --- a/src/termio/Termio.zig +++ b/src/termio/Termio.zig @@ -60,6 +60,9 @@ surface_mailbox: apprt.surface.Mailbox, /// The cached grid size whenever a resize is called. grid_size: renderer.GridSize, +/// The size of a single cell. Used for size reports. +cell_size: renderer.CellSize, + /// The mailbox implementation to use. mailbox: termio.Mailbox, @@ -171,9 +174,8 @@ pub fn init(self: *Termio, alloc: Allocator, opts: termio.Options) !void { backend.initTerminal(&term); // Setup our terminal size in pixels for certain requests. - const screen_size = opts.screen_size.subPadding(opts.padding); - term.width_px = screen_size.width; - term.height_px = screen_size.height; + term.width_px = opts.grid_size.columns * opts.cell_size.width; + term.height_px = opts.grid_size.rows * opts.cell_size.height; // Create our stream handler. This points to memory in self so it // isn't safe to use until self.* is set. @@ -214,6 +216,7 @@ pub fn init(self: *Termio, alloc: Allocator, opts: termio.Options) !void { .renderer_mailbox = opts.renderer_mailbox, .surface_mailbox = opts.surface_mailbox, .grid_size = opts.grid_size, + .cell_size = opts.cell_size, .backend = opts.backend, .mailbox = opts.mailbox, .terminal_stream = .{ @@ -348,6 +351,7 @@ pub fn resize( self: *Termio, td: *ThreadData, grid_size: renderer.GridSize, + cell_size: renderer.CellSize, screen_size: renderer.ScreenSize, padding: renderer.Padding, ) !void { @@ -357,6 +361,7 @@ pub fn resize( // Update our cached grid size self.grid_size = grid_size; + self.cell_size = cell_size; // Enter the critical area that we want to keep small { @@ -371,8 +376,8 @@ pub fn resize( ); // Update our pixel sizes - self.terminal.width_px = padded_size.width; - self.terminal.height_px = padded_size.height; + self.terminal.width_px = self.grid_size.columns * self.cell_size.width; + self.terminal.height_px = self.grid_size.rows * self.cell_size.height; // Disable synchronized output mode so that we show changes // immediately for a resize. This is allowed by the spec. @@ -412,24 +417,24 @@ fn sizeReportLocked(self: *Termio, td: *ThreadData, style: termio.Message.SizeRe .{ self.grid_size.rows, self.grid_size.columns, - self.terminal.height_px, - self.terminal.width_px, + self.grid_size.rows * self.cell_size.height, + self.grid_size.columns * self.cell_size.width, }, ), .csi_14_t => try std.fmt.bufPrint( &buf, "\x1b[4;{};{}t", .{ - self.terminal.height_px, - self.terminal.width_px, + self.grid_size.rows * self.cell_size.height, + self.grid_size.columns * self.cell_size.width, }, ), .csi_16_t => try std.fmt.bufPrint( &buf, "\x1b[6;{};{}t", .{ - self.terminal.height_px / self.grid_size.rows, - self.terminal.width_px / self.grid_size.columns, + self.cell_size.height, + self.cell_size.width, }, ), .csi_18_t => try std.fmt.bufPrint( diff --git a/src/termio/Thread.zig b/src/termio/Thread.zig index 4c75b3b9e..0f9cd782e 100644 --- a/src/termio/Thread.zig +++ b/src/termio/Thread.zig @@ -383,6 +383,7 @@ fn coalesceCallback( cb.io.resize( &cb.data, v.grid_size, + v.cell_size, v.screen_size, v.padding, ) catch |err| { diff --git a/src/termio/message.zig b/src/termio/message.zig index 79b920ad7..22b72235b 100644 --- a/src/termio/message.zig +++ b/src/termio/message.zig @@ -20,6 +20,9 @@ pub const Message = union(enum) { /// The grid size for the given screen size with padding applied. grid_size: renderer.GridSize, + /// The updated cell size. + cell_size: renderer.CellSize, + /// The full screen (drawable) size. This does NOT include padding. /// This should be sent on to the renderer. screen_size: renderer.ScreenSize,