mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 09:16:11 +03:00
Merge pull request #1955 from ghostty-org/ibsr
terminal: implement in-band size reports (Mode 2048)
This commit is contained in:
@ -216,6 +216,7 @@ const entries: []const ModeEntry = &.{
|
||||
.{ .name = "synchronized_output", .value = 2026 },
|
||||
.{ .name = "grapheme_cluster", .value = 2027 },
|
||||
.{ .name = "report_color_scheme", .value = 2031 },
|
||||
.{ .name = "in_band_size_reports", .value = 2048 },
|
||||
};
|
||||
|
||||
test {
|
||||
|
@ -344,6 +344,7 @@ pub fn changeConfig(self: *Termio, td: *ThreadData, config: *DerivedConfig) !voi
|
||||
/// Resize the terminal.
|
||||
pub fn resize(
|
||||
self: *Termio,
|
||||
td: *ThreadData,
|
||||
grid_size: renderer.GridSize,
|
||||
screen_size: renderer.ScreenSize,
|
||||
padding: renderer.Padding,
|
||||
@ -377,7 +378,37 @@ pub fn resize(
|
||||
|
||||
// Wake up our renderer so any changes will be shown asap
|
||||
self.renderer_wakeup.notify() catch {};
|
||||
|
||||
// If we have size reporting enabled we need to send a report.
|
||||
if (self.terminal.modes.get(.in_band_size_reports)) {
|
||||
try self.sizeReportLocked(td);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Make a mode 2048 in-band size report.
|
||||
pub fn sizeReport(self: *Termio, td: *ThreadData) !void {
|
||||
self.renderer_state.mutex.lock();
|
||||
defer self.renderer_state.mutex.unlock();
|
||||
try self.sizeReportLocked(td);
|
||||
}
|
||||
|
||||
fn sizeReportLocked(self: *Termio, td: *ThreadData) !void {
|
||||
// 1024 bytes should be enough for size report since report
|
||||
// in columns and pixels.
|
||||
var buf: [1024]u8 = undefined;
|
||||
const message = try std.fmt.bufPrint(
|
||||
&buf,
|
||||
"\x1B[48;{};{};{};{}t",
|
||||
.{
|
||||
self.grid_size.rows,
|
||||
self.grid_size.columns,
|
||||
self.terminal.height_px,
|
||||
self.terminal.width_px,
|
||||
},
|
||||
);
|
||||
|
||||
try self.queueWrite(td, message, false);
|
||||
}
|
||||
|
||||
/// Reset the synchronized output mode. This is usually called by timer
|
||||
|
@ -267,6 +267,7 @@ fn drainMailbox(
|
||||
},
|
||||
.inspector => |v| self.flags.has_inspector = v,
|
||||
.resize => |v| self.handleResize(cb, v),
|
||||
.size_report => try io.sizeReport(data),
|
||||
.clear_screen => |v| try io.clearScreen(data, v.history),
|
||||
.scroll_viewport => |v| try io.scrollViewport(v),
|
||||
.jump_to_prompt => |v| try io.jumpToPrompt(v),
|
||||
@ -369,7 +370,12 @@ fn coalesceCallback(
|
||||
|
||||
if (cb.self.coalesce_data.resize) |v| {
|
||||
cb.self.coalesce_data.resize = null;
|
||||
cb.io.resize(v.grid_size, v.screen_size, v.padding) catch |err| {
|
||||
cb.io.resize(
|
||||
&cb.data,
|
||||
v.grid_size,
|
||||
v.screen_size,
|
||||
v.padding,
|
||||
) catch |err| {
|
||||
log.warn("error during resize err={}", .{err});
|
||||
};
|
||||
}
|
||||
|
@ -42,6 +42,10 @@ pub const Message = union(enum) {
|
||||
/// Resize the window.
|
||||
resize: Resize,
|
||||
|
||||
/// Request a size report is sent to the pty (in-band size report,
|
||||
/// mode 2048: https://gist.github.com/rockorager/e695fb2924d36b2bcf1fff4a3704bd83)
|
||||
size_report: void,
|
||||
|
||||
/// Clear the screen.
|
||||
clear_screen: struct {
|
||||
/// Include clearing the history
|
||||
|
@ -597,6 +597,10 @@ pub const StreamHandler = struct {
|
||||
self.messageWriter(.{ .linefeed_mode = enabled });
|
||||
},
|
||||
|
||||
.in_band_size_reports => if (enabled) self.messageWriter(.{
|
||||
.size_report = {},
|
||||
}),
|
||||
|
||||
.mouse_event_x10 => {
|
||||
if (enabled) {
|
||||
self.terminal.flags.mouse_event = .x10;
|
||||
|
Reference in New Issue
Block a user