Fixes#1514
We previously required all preedit inputs to fit into the small copied
message size. That's true for 99% of all inputs, but if a long pre-edit
input comes in, this may not be true. We should try the small array
fast-path but fall back to heap allocation if we must.
Fixes#1403
This changes the behavior of `grapheme-width-method = unicode` to change
the default state of mode 2027 to true. Prior to this, setting this
config would force grapheme clustering regardless of mode 2027. Now,
this only sets the default and running TUI programs can disable it if
they want.
Fixes#1401
SCOSC is ambiguous with regards to DECSLRM. This commit copies the logic
of xterm: if left/right mode is enabled, then CSI S is always DECSLRM.
But if left/right mode is disabled then CSI S empty always uses SCOSC.
SCORC always works.
A lot of the state that we put on Exec is just there to copy to
StreamHandler, but we already have it in DerivedConfig. I think this
whole copy copy copy is just legacy cruft since termio.Exec is one of
the older parts of the source code.
This rearchitects the Exec struct to act more like Surface and Renderer
where it stores its derived config. This lets us avoid a few extra
allocations and removes a LOT of struct member noise from termio.Exec.
For pointer lifetimes, the memory allocated is now owned by
DerivedConfig. When changeConfig is called, its the only time BOTH are
still alive, so we can safely swap pointers and deinit without having to
duplicate across threads. This is the same as renderer/surface.
Fixes#1198
This adds a fix similar to what we discovered with termio messages: we
attempt to send a surface message but if the queue is full we unlock the
terminal state and try again waiting forever.
In all cases, its safe to unlock the mutex while sending the message, no
scenario we send a surface message requires this lock to be held.
PR #1168 introduced a loop to kill all children. The `waitpid` call is
issued with the NOHANG flag, which means it returns immediately if no
child has exited. This has the effect that we can repeatedly run through
this loop making this syscall, flooding the system with calls and not
getting timely responses. On my system, this caused Ghostty to take ~30
seconds to close. In my attempts to debug, I added logging to the loop
which resolved the issue. To find out why, I added a loop counter and
found the loop would run > 70 million cycles while trying to close. By
adding logging, I introduced just enough delay in the loop cycle to
prevent whatever flooding of syscalls was happening. This reduced the
loop counter to ~2 cycles before closing.
Add a small delay to prevent syscall flooding.