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 = "synchronized_output", .value = 2026 },
|
||||||
.{ .name = "grapheme_cluster", .value = 2027 },
|
.{ .name = "grapheme_cluster", .value = 2027 },
|
||||||
.{ .name = "report_color_scheme", .value = 2031 },
|
.{ .name = "report_color_scheme", .value = 2031 },
|
||||||
|
.{ .name = "in_band_size_reports", .value = 2048 },
|
||||||
};
|
};
|
||||||
|
|
||||||
test {
|
test {
|
||||||
|
@ -344,6 +344,7 @@ pub fn changeConfig(self: *Termio, td: *ThreadData, config: *DerivedConfig) !voi
|
|||||||
/// Resize the terminal.
|
/// Resize the terminal.
|
||||||
pub fn resize(
|
pub fn resize(
|
||||||
self: *Termio,
|
self: *Termio,
|
||||||
|
td: *ThreadData,
|
||||||
grid_size: renderer.GridSize,
|
grid_size: renderer.GridSize,
|
||||||
screen_size: renderer.ScreenSize,
|
screen_size: renderer.ScreenSize,
|
||||||
padding: renderer.Padding,
|
padding: renderer.Padding,
|
||||||
@ -377,9 +378,39 @@ pub fn resize(
|
|||||||
|
|
||||||
// Wake up our renderer so any changes will be shown asap
|
// Wake up our renderer so any changes will be shown asap
|
||||||
self.renderer_wakeup.notify() catch {};
|
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
|
/// Reset the synchronized output mode. This is usually called by timer
|
||||||
/// expiration from the termio thread.
|
/// expiration from the termio thread.
|
||||||
pub fn resetSynchronizedOutput(self: *Termio) void {
|
pub fn resetSynchronizedOutput(self: *Termio) void {
|
||||||
|
@ -267,6 +267,7 @@ fn drainMailbox(
|
|||||||
},
|
},
|
||||||
.inspector => |v| self.flags.has_inspector = v,
|
.inspector => |v| self.flags.has_inspector = v,
|
||||||
.resize => |v| self.handleResize(cb, v),
|
.resize => |v| self.handleResize(cb, v),
|
||||||
|
.size_report => try io.sizeReport(data),
|
||||||
.clear_screen => |v| try io.clearScreen(data, v.history),
|
.clear_screen => |v| try io.clearScreen(data, v.history),
|
||||||
.scroll_viewport => |v| try io.scrollViewport(v),
|
.scroll_viewport => |v| try io.scrollViewport(v),
|
||||||
.jump_to_prompt => |v| try io.jumpToPrompt(v),
|
.jump_to_prompt => |v| try io.jumpToPrompt(v),
|
||||||
@ -369,7 +370,12 @@ fn coalesceCallback(
|
|||||||
|
|
||||||
if (cb.self.coalesce_data.resize) |v| {
|
if (cb.self.coalesce_data.resize) |v| {
|
||||||
cb.self.coalesce_data.resize = null;
|
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});
|
log.warn("error during resize err={}", .{err});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,10 @@ pub const Message = union(enum) {
|
|||||||
/// Resize the window.
|
/// Resize the window.
|
||||||
resize: Resize,
|
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 the screen.
|
||||||
clear_screen: struct {
|
clear_screen: struct {
|
||||||
/// Include clearing the history
|
/// Include clearing the history
|
||||||
|
@ -597,6 +597,10 @@ pub const StreamHandler = struct {
|
|||||||
self.messageWriter(.{ .linefeed_mode = enabled });
|
self.messageWriter(.{ .linefeed_mode = enabled });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
.in_band_size_reports => if (enabled) self.messageWriter(.{
|
||||||
|
.size_report = {},
|
||||||
|
}),
|
||||||
|
|
||||||
.mouse_event_x10 => {
|
.mouse_event_x10 => {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
self.terminal.flags.mouse_event = .x10;
|
self.terminal.flags.mouse_event = .x10;
|
||||||
|
Reference in New Issue
Block a user