Skip to content

Commit 4eae1a1

Browse files
committed
fix(core): wrap kitty graphics query in tmux DCS passthrough
Fixes #334 - Re-enable kitty graphics query (was disabled due to tmux pane title corruption) - Wrap query in tmux DCS passthrough when TMUX env var is present - Skip query for TERM=screen*/tmux* without TMUX (could be GNU Screen) - Add OPENTUI_NO_GRAPHICS env var to disable query manually
1 parent 4403a69 commit 4eae1a1

File tree

2 files changed

+25
-8
lines changed

2 files changed

+25
-8
lines changed

packages/core/src/zig/ansi.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ pub const ANSI = struct {
8989
pub const decrqmColorScheme = "\x1b[?2031$p";
9090
pub const csiUQuery = "\x1b[?u";
9191
pub const kittyGraphicsQuery = "\x1b_Gi=31337,s=1,v=1,a=q,t=d,f=24;AAAA\x1b\\\x1b[c";
92+
// tmux DCS passthrough variant (ESC chars doubled) to avoid pane title corruption (#334)
93+
pub const kittyGraphicsQueryTmux = "\x1bPtmux;\x1b\x1b_Gi=31337,s=1,v=1,a=q,t=d,f=24;AAAA\x1b\x1b\\\x1b\x1b[c\x1b\\";
9294
pub const sixelGeometryQuery = "\x1b[?2;1;0S";
9395
pub const cursorPositionRequest = "\x1b[6n";
9496
pub const explicitWidthQuery = "\x1b]66;w=1; \x1b\\";

packages/core/src/zig/terminal.zig

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ pub const TerminalInfo = struct {
6363
caps: Capabilities = .{},
6464
opts: Options = .{},
6565

66+
in_tmux: bool = false,
67+
skip_graphics_query: bool = false,
68+
6669
state: struct {
6770
alt_screen: bool = false,
6871
kitty_keyboard: bool = false,
@@ -177,14 +180,17 @@ pub fn queryTerminalSend(self: *Terminal, tty: anytype) !void {
177180

178181
// Version and capability queries
179182
ansi.ANSI.xtversion ++
180-
ansi.ANSI.csiUQuery ++
181-
// Kitty graphics detection: sends dummy query + DA1
182-
// Terminal will respond with ESC_Gi=31337;OK/ERROR ESC\ if supported, or just DA1 if not
183-
// NOTE: deactivated temporarily due to issues with tmux showing the query as pane title
184-
// ansi.ANSI.kittyGraphicsQuery ++
185-
ansi.ANSI.restoreCursorState
186-
// ++ ansi.ANSI.sixelGeometryQuery
187-
);
183+
ansi.ANSI.csiUQuery);
184+
185+
if (!self.skip_graphics_query) {
186+
if (self.in_tmux) {
187+
try tty.writeAll(ansi.ANSI.kittyGraphicsQueryTmux);
188+
} else {
189+
try tty.writeAll(ansi.ANSI.kittyGraphicsQuery);
190+
}
191+
}
192+
193+
try tty.writeAll(ansi.ANSI.restoreCursorState);
188194
}
189195

190196
pub fn enableDetectedFeatures(self: *Terminal, tty: anytype, use_kitty_keyboard: bool) !void {
@@ -221,20 +227,29 @@ pub fn enableDetectedFeatures(self: *Terminal, tty: anytype, use_kitty_keyboard:
221227
}
222228

223229
fn checkEnvironmentOverrides(self: *Terminal) void {
230+
self.in_tmux = false;
231+
self.skip_graphics_query = false;
232+
224233
var env_map = std.process.getEnvMap(std.heap.page_allocator) catch return;
225234
defer env_map.deinit();
226235

227236
// Always just try to enable bracketed paste, even if it was reported as not supported
228237
self.caps.bracketed_paste = true;
229238

230239
if (env_map.get("TMUX")) |_| {
240+
self.in_tmux = true;
231241
self.caps.unicode = .wcwidth;
232242
} else if (env_map.get("TERM")) |term| {
233243
if (std.mem.startsWith(u8, term, "tmux") or std.mem.startsWith(u8, term, "screen")) {
244+
self.skip_graphics_query = true; // could be GNU Screen, not safe to send kitty query
234245
self.caps.unicode = .wcwidth;
235246
}
236247
}
237248

249+
if (env_map.get("OPENTUI_NO_GRAPHICS")) |_| {
250+
self.skip_graphics_query = true;
251+
}
252+
238253
// Extract terminal name and version from environment variables
239254
// These will be overridden by xtversion responses if available
240255
if (!self.term_info.from_xtversion) {

0 commit comments

Comments
 (0)