This mode allows programs to modify the code that the `backspace`
key (backarrow key in DEC parlance) sends. If this mode is
`off`/`false`/`reset` (the default, the same as before this PR), we
send the byte `0x7f`. If this mode is `on`/`true`/`set` we send the
byte `0x08`.
When the kitty keyboard protocol "report all keys as escape codes" mode
was active, composed/IME text (e.g. from dead keys or compose sequences)
was silently dropped.
This happened because the composed text is sent within our GTK apprt
with key=unidentified and no unshifted_codepoint, so no kitty entry was
found and the encoder returned without producing any output. The
plain-text fallback was also skipped because report_all bypasses it.
Send composed text as raw UTF-8 when no kitty entry is found, matching
the behavior of Kitty on Linux for me.
Fixes#10049
There have been frequent reports of key encoding issues in vim and tmux
with version 1.2.3 on macOS: #9340, #9361, #9401,
https://discord.com/channels/1005603569187160125/1432413679806320772.
I think I found the culprit: the option modifier is always passed as alt
to the core, regardless of `macos-option-as-alt`. Since #9289, this
means that a key event where option was used (as option) for translation
is encoded as if it also has the alt modifier.
For example, consider the many European keyboard layouts where option+8
sends `[`. If `macos-option-as-alt = true`, Ghostty correctly intercepts
the option and encodes option+8 as alt+8 instead (that is,
`^[[27;3;56~`). But if `macos-option-as-alt = false`, Ghostty first
allows option to be used for translation, obtaining `[`, and then
encodes the key event as alt+[ (that is, `^[[27;3;91~`), rather than
just `[`.
Tweaking the test case from #9289, here's a quick way to see this: set
`macos-option-as-alt = left`, run
```
printf '\033[>4;2m'
cat
```
choose a European keyboard layout (e.g., Norwegian), and hit both
left-option+8 and right-option+8. The former inserts `^[[27;3;56~` in
all well-behaved terminals. The latter inserts `[` in other terminals,
but `^[[27;3;91~` in Ghostty.
Basically, while modify other keys 2 does require encoding consumed
modifiers, the option key is not one of the supported modifiers, and
should not be included (as alt or anything else) when
`macos-option-as-alt = false`.
This PR removes alts that were actually options when using modify other
keys 2.
This adds a set of Wasm convenience functions to ease memory management.
These are all prefixed with `ghostty_wasm` and are documented as part of
the standard Doxygen docs.
I also added a very simple single-page HTML example that demonstrates
how to use the Wasm module for key encoding.
This also adds a bunch of safety checks to the C API to verify that
valid values are actually passed to the function. This is an easy to hit
bug.
**AI disclosure:** The example is AI-written with Amp. I read through
all the code and understand it but I can't claim there isn't a better
way, I'm far from a JS expert. It is simple and works currently though.
Happy to see improvements if anyone wants to contribute.
Fixes#8900
Our xterm modify other keys state 2 encoding was stripped consumed mods
from the keyboard event. This doesn't match xterm or other popular
terminal emulators (but most importantly: xterm). Use the full set of
mods and add a test to verify this.
Reproduction:
```
printf '\033[>4;2m'
cat
```
Then press `ctrl+shift+h` and compare across terminals.
This modernizes `KeyEncoder` to a new `std.Io.Writer`-based API.
Additionally, instead of a single struct, it is now an `encode` function
that takes a series of more focused options. This is more idiomatic Zig
while also making it easier to expose via libghostty-vt.
libghostty-vt also gains access to key encoding APIs.