terminal: support click_events=2

This commit is contained in:
Alex Bennett
2026-06-07 23:01:53 +08:00
parent f146db5535
commit 3263ce5122
5 changed files with 29 additions and 12 deletions

View File

@@ -4218,20 +4218,24 @@ fn maybePromptClick(self: *Surface) !bool {
// Guarded at the start of this function
.none => unreachable,
.click_events => {
.click_events => |v| {
// For the event, we always send a left-click press event.
// This matches what Kitty sends.
const key: u8, const y: u32 = switch (v) {
.Absolute => .{ 1, pos_vp.y + 1 },
.Relative => .{ 2, pos_vp.y - prompt_pin.y + 1 },
};
var data: termio.Message.WriteReq.Small.Array = undefined;
const resp = try std.fmt.bufPrint(
&data,
"\x1B[<0;{d};{d}M",
.{ pos_vp.x + 1, pos_vp.y + 1 },
.{ pos_vp.x + 1, y },
);
// Not that noisy since this only happens on prompt clicks.
log.debug(
"sending click_events=1 event=ESC{s}",
.{resp[1..]},
"sending click_events={} event=ESC{s}",
.{ key, resp[1..] },
);
// Ask our IO thread to write the data

View File

@@ -393,7 +393,7 @@ pub fn semanticPromptTable(
_ = cimgui.c.ImGui_TableSetColumnIndex(1);
switch (semantic_prompt.click) {
.none => cimgui.c.ImGui_TextDisabled("(none)"),
.click_events => cimgui.c.ImGui_Text("click_events"),
.click_events => |click_events| cimgui.c.ImGui_Text("click_events=%s", @tagName(click_events).ptr),
.cl => |cl| cimgui.c.ImGui_Text("cl=%s", @tagName(cl).ptr),
}
}

View File

@@ -113,7 +113,7 @@ pub const SemanticPrompt = struct {
pub const SemanticClick = union(enum) {
none,
click_events,
click_events: osc.semantic_prompt.ClickEvents,
cl: osc.semantic_prompt.Click,
};
};

View File

@@ -1226,10 +1226,8 @@ pub fn semanticPrompt(
// within a prompt area to SGR mouse events and defers to the
// shell to handle them.
if (cmd.readOption(.click_events)) |v| {
if (v) {
screen.semantic_prompt.click = .click_events;
break :click;
}
screen.semantic_prompt.click = .{ .click_events = v } ;
break :click;
}
// If click_events was not set or disabled, fallback to `cl`.

View File

@@ -60,6 +60,16 @@ pub const Command = struct {
}
};
// ClickEvents can either be a click_events=1 or click_events=2.
// The click_events=1 sends a click event with the absolute coordinates
// of the click.
// The click_events=2 sends a click event with the coordinates of the click
// relative to the prompt area.
// See https://github.com/ghostty-org/ghostty/issues/10865 and
// https://github.com/kovidgoyal/kitty/issues/9500
// for further details.
pub const ClickEvents = enum { Absolute, Relative };
pub const Option = enum {
aid,
cl,
@@ -102,7 +112,7 @@ pub const Option = enum {
.err => []const u8,
.redraw => Redraw,
.special_key => bool,
.click_events => bool,
.click_events => ClickEvents,
.cmdline => []const u8,
.cmdline_url => []const u8,
.exit_code => i32,
@@ -200,7 +210,12 @@ pub const Option = enum {
.last
else
null,
.special_key, .click_events => if (value.len == 1) switch (value[0]) {
.click_events => if (value.len == 1) switch (value[0]) {
'1' => .Absolute,
'2' => .Relative,
else => null,
} else null,
.special_key => if (value.len == 1) switch (value[0]) {
'0' => false,
'1' => true,
else => null,