mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-06-06 03:44:22 +00:00
Implement the XTWINOPS (CSI t) control sequences that "make sense".
These sequences were implemented: CSI 14 t - report the text area size in pixels CSI 16 t - report the cell size in pixels CSI 18 t - report the text area size in cells CSI 21 t - report the window title These sequences were not implemented because they manuipulate the window state in ways that we do not want. CSI 1 t CSI 2 t CSI 3 ; x ; y t CSI 4 ; height ; width ; t CSI 5 t CSI 6 t CSI 7 t CSI 8 ; height ; width ; t CSI 9 ; 0 t CSI 9 ; 1 t CSI 9 ; 2 t CSI 9 ; 3 t CSI 10 ; 0 t CSI 10 ; 1 t CSI 10 ; 2 t CSI 24 t These sequences were not implemented because they do not make sense in a Wayland context: CSI 11 t CSI 13 t CSI 14 ; 2 t These sequences were not implemented because they provide information about the screen that is unnecessary. CSI 15 t CSI 19 t These sequences were not implemeted because Ghostty does not maintain an icon title for windows. CSI 20 t CSI 22 ; 0 t CSI 22 ; 1 t CSI 23 ; 0 t CSI 23 ; 1 t These sequences were not implemented because of the additional complexity of maintaining a stack of window titles. CSI 22 ; 2 t CSI 23 ; 2 t
This commit is contained in:
@@ -383,32 +383,58 @@ pub fn resize(
|
||||
|
||||
// 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);
|
||||
try self.sizeReportLocked(td, .mode_2048);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Make a mode 2048 in-band size report.
|
||||
pub fn sizeReport(self: *Termio, td: *ThreadData) !void {
|
||||
/// Make a size report.
|
||||
pub fn sizeReport(self: *Termio, td: *ThreadData, style: termio.Message.SizeReport) !void {
|
||||
self.renderer_state.mutex.lock();
|
||||
defer self.renderer_state.mutex.unlock();
|
||||
try self.sizeReportLocked(td);
|
||||
try self.sizeReportLocked(td, style);
|
||||
}
|
||||
|
||||
fn sizeReportLocked(self: *Termio, td: *ThreadData) !void {
|
||||
fn sizeReportLocked(self: *Termio, td: *ThreadData, style: termio.Message.SizeReport) !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,
|
||||
},
|
||||
);
|
||||
const message = switch (style) {
|
||||
.mode_2048 => try std.fmt.bufPrint(
|
||||
&buf,
|
||||
"\x1B[48;{};{};{};{}t",
|
||||
.{
|
||||
self.grid_size.rows,
|
||||
self.grid_size.columns,
|
||||
self.terminal.height_px,
|
||||
self.terminal.width_px,
|
||||
},
|
||||
),
|
||||
.csi_14_t => try std.fmt.bufPrint(
|
||||
&buf,
|
||||
"\x1b[4;{};{}t",
|
||||
.{
|
||||
self.terminal.height_px,
|
||||
self.terminal.width_px,
|
||||
},
|
||||
),
|
||||
.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,
|
||||
},
|
||||
),
|
||||
.csi_18_t => try std.fmt.bufPrint(
|
||||
&buf,
|
||||
"\x1b[8;{};{}t",
|
||||
.{
|
||||
self.grid_size.rows,
|
||||
self.grid_size.columns,
|
||||
},
|
||||
),
|
||||
};
|
||||
|
||||
try self.queueWrite(td, message, false);
|
||||
}
|
||||
|
||||
@@ -267,7 +267,7 @@ fn drainMailbox(
|
||||
},
|
||||
.inspector => |v| self.flags.has_inspector = v,
|
||||
.resize => |v| self.handleResize(cb, v),
|
||||
.size_report => try io.sizeReport(data),
|
||||
.size_report => |v| try io.sizeReport(data, v),
|
||||
.clear_screen => |v| try io.clearScreen(data, v.history),
|
||||
.scroll_viewport => |v| try io.scrollViewport(v),
|
||||
.jump_to_prompt => |v| try io.jumpToPrompt(v),
|
||||
|
||||
@@ -42,9 +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,
|
||||
/// Request a size report is sent to the pty ([in-band
|
||||
/// size report, mode 2048](https://gist.github.com/rockorager/e695fb2924d36b2bcf1fff4a3704bd83) and
|
||||
/// [XTWINOPS](https://invisible-island.net/xterm/ctlseqs/ctlseqs.htmli#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-Ps;Ps;Ps-t.1EB0)).
|
||||
size_report: SizeReport,
|
||||
|
||||
/// Clear the screen.
|
||||
clear_screen: struct {
|
||||
@@ -94,6 +95,14 @@ pub const Message = union(enum) {
|
||||
.alloc => |v| Message{ .write_alloc = v },
|
||||
};
|
||||
}
|
||||
|
||||
/// The types of size reports that we support
|
||||
pub const SizeReport = enum {
|
||||
mode_2048,
|
||||
csi_14_t,
|
||||
csi_16_t,
|
||||
csi_18_t,
|
||||
};
|
||||
};
|
||||
|
||||
/// Creates a union that can be used to accommodate data that fit within an array,
|
||||
|
||||
@@ -598,7 +598,7 @@ pub const StreamHandler = struct {
|
||||
},
|
||||
|
||||
.in_band_size_reports => if (enabled) self.messageWriter(.{
|
||||
.size_report = {},
|
||||
.size_report = .mode_2048,
|
||||
}),
|
||||
|
||||
.mouse_event_x10 => {
|
||||
@@ -1259,4 +1259,14 @@ pub const StreamHandler = struct {
|
||||
|
||||
self.surfaceMessageWriter(message);
|
||||
}
|
||||
|
||||
/// Send a report to the pty.
|
||||
pub fn sendReport(self: *StreamHandler, style: terminal.stream.ReportStyle) void {
|
||||
switch (style) {
|
||||
.csi_14_t => self.messageWriter(.{ .size_report = .csi_14_t }),
|
||||
.csi_16_t => self.messageWriter(.{ .size_report = .csi_16_t }),
|
||||
.csi_18_t => self.messageWriter(.{ .size_report = .csi_18_t }),
|
||||
.csi_21_t => self.surfaceMessageWriter(.{ .report_title = .csi_21_t }),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user