Fixes#1699
See #1699 for a lot more research. I haven't found a definitive source
of this behavior but this appears to match most of the mainstream
terminals and xterm for the realistic terminfo entries we have and
I'm going to consider that good enough.
For non-parameterized string values in a terminfo, the XTGETTCAP result
should be the tcap encoded form. This means replacing characters such as
`\E` with their byte form of 0x1B, and control characters such as `^H`
with their actual character 0x08, and so on.
"Non-parameterized" is a bit weird, the comment in this commit explains
my best guess (thanks to some community help) of why this may be.
This commit does NOT handle all encodings, but it handles the encodings
we use and the encodings I could cross-check with other terminals. The
actual tcap encoding is much more complicated and I'm sure for specific
types of terminfo values our encoding is not correct. If and when those
come up we should fix them.
When a shell is forced, we would supply its /-prefixed executable name
to mimic a path location. The rest of the integration detection logic
assumes just a base executable name. Fix the forced names accordingly.
Also add a unit test for this "force shell" behavior.
We don't actually use libc wcswidth to determine width and even if we
did some terminals use wcwidth (which behaves differently), some use
the Python wcswidth library (which behaves differently), etc. The
reality is there is no real consistency on "legacy" behavior so by
naming it "legacy" we show that we're doing our best but also gives us
wiggle room to change our behavior in the future.
Functionally nothing changes with this commit.
We were previously retaining Options on the Surface struct, but other
than userdata, we only use those values for initialization. Instead,
store just the opaque userdata value on the Surface and clarify that
Surface.Options are only used for initialization.
Fixes#1676
The comment in the diff explains. This is a regression that was not unit
tested properly in the old implementation prior to the paged-terminal
merge.
Fixes#1677
If eraseRowBounded is called at the top of a page AND there is a tracked
pin at the top of the page, then we'd have an integer overflow. The test
case covers this and this adds a fix.
We allow titlebarFont to be nil to differentiate between "system" (nil)
and "custom" (non-nil) behavior. For the "system" case, we need to use
the system _titlebar_ font (rather than just the default system font),
to match the system's conventions.
A minor addition, but saves future folks wondering if they need to
figure out different packages on Debian in order to get Ghostty to
compile (they don't).
Key contains pointers into DerivedConfig. Each surface has its own
DerivedConfig. This would cause memory corruption if the surface that
opened the initial font grid deallocates. Instead, let's make sure Key
owns its own DerivedConfig.