mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 08:46:08 +03:00
modifyOtherKeys state 2 should send sequences for all chars
See: https://github.com/mitchellh/ghostty/issues/242#issuecomment-1678268533 Quoted: @hovsater OKAY! I've consulted _the source_, i.e. `xterm`. None of the other reference material was illuminating and there is so much conflicting implementation out there and so very few terminals actually support `modifyOtherKeys`. I believe I've figured it out. I believe that `C-S-h` is only supported via `modifyOtherKeys` state 2. iTerm emits it for state 1 but I think this is a mistake and I can't get any other terminal to do it, including `xterm`. Here is my test script on Linux: ``` printf "\x1b[>4;1m" # change to "2" for state 2 showkey -a ``` With state 1, I couldn't get any terminal to output anything for `C-S-h`. **But with state 2, xterm outputs: ** `CSI 27;6;72~`. One thing to note is 72 is `H` (uppercase), so in even this case, iTerm appears to be sending the wrong code or `dte -K` is outputting the wrong case (less likely I think). When I launch `dte` (the full editor), it only requests `modifyOtherKeys` state 1. So, with only `modifyOtherKeys` support, it shouldn't get access to `C-S-h`. Note that I couldn't get any terminal on macOS to show the same sequences as xterm under any circumstance. I also cracked open the `xterm` source and I only eyeballed it but I believe this is not sending the sequences under state 1: https://sourcegraph.com/github.com/ThomasDickey/xterm-snapshots@c2b36af8d216926b8931c6f9cebefd69228e437c/-/blob/input.c?L579 **I could be very wrong, I'm not confident.** Every implementation (and there are only few) seems different and the behaviors are not consistent at all. Hence, I'm falling back to `xterm`, but even then I could be reading the source wrong. But when I ran `xterm` manually I could only get `C-S-h` to show up in state 2.
This commit is contained in:
@ -1008,6 +1008,7 @@ pub fn charCallback(
|
|||||||
// Critical area
|
// Critical area
|
||||||
const critical: struct {
|
const critical: struct {
|
||||||
alt_esc_prefix: bool,
|
alt_esc_prefix: bool,
|
||||||
|
modify_other_keys: bool,
|
||||||
} = critical: {
|
} = critical: {
|
||||||
self.renderer_state.mutex.lock();
|
self.renderer_state.mutex.lock();
|
||||||
defer self.renderer_state.mutex.unlock();
|
defer self.renderer_state.mutex.unlock();
|
||||||
@ -1024,11 +1025,38 @@ pub fn charCallback(
|
|||||||
|
|
||||||
break :critical .{
|
break :critical .{
|
||||||
.alt_esc_prefix = self.io.terminal.modes.alt_esc_prefix,
|
.alt_esc_prefix = self.io.terminal.modes.alt_esc_prefix,
|
||||||
|
.modify_other_keys = self.io.terminal.modes.modify_other_keys,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Where we're going to write any data. Any data we write has to
|
||||||
|
// fit into the fixed size array so we just define it up front.
|
||||||
var data: termio.Message.WriteReq.Small.Array = undefined;
|
var data: termio.Message.WriteReq.Small.Array = undefined;
|
||||||
|
|
||||||
|
// In modify other keys state 2, we send the CSI 27 sequence
|
||||||
|
// for any char with a modifier. Ctrl sequences like Ctrl+A
|
||||||
|
// are handled in keyCallback and should never have reached this
|
||||||
|
// point.
|
||||||
|
if (critical.modify_other_keys and !mods.empty()) {
|
||||||
|
for (input.function_keys.modifiers, 2..) |modset, code| {
|
||||||
|
if (!mods.equal(modset)) continue;
|
||||||
|
|
||||||
|
const resp = try std.fmt.bufPrint(
|
||||||
|
&data,
|
||||||
|
"\x1B[27;{};{}~",
|
||||||
|
.{ code, codepoint },
|
||||||
|
);
|
||||||
|
_ = self.io_thread.mailbox.push(.{
|
||||||
|
.write_small = .{
|
||||||
|
.data = data,
|
||||||
|
.len = @intCast(resp.len),
|
||||||
|
},
|
||||||
|
}, .{ .forever = {} });
|
||||||
|
try self.io_thread.wakeup.notify();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Prefix our data with ESC if we have alt pressed.
|
// Prefix our data with ESC if we have alt pressed.
|
||||||
var i: u8 = 0;
|
var i: u8 = 0;
|
||||||
if (mods.alt) alt: {
|
if (mods.alt) alt: {
|
||||||
|
Reference in New Issue
Block a user