This brings the behavior of mode 47, 1047, and 1049 much closer to
xterm's behavior. I found that our prior implementation had many
deficiencies.
For example, we weren't properly copying the cursor state back to the
primary screen from the alternate screen for modes 47 and 1047. And we
weren't saving/restoring cursor state unconditionally for mode 1049 even
if we were already in the alternate screen.
I also found that we were dangling hyperlink state on the primary screen
when we switched to alternate. xterm doesn't support hyperlinks but we
did the opposite behavior for going from alternate to primary. So one
way or the other its a bug. I'm worried this one could've maybe led to
memory corruption under the right circumstances but I wasn't able to
prove it.
These are weird, edgy behaviors that I don't think anyone expected
(evidence by there being no bug reports about them), but they are bugs
nontheless.
Many tests added.
(Btw: this flew under the radar of our "xterm audit" because that only
included sequences and not modes. I noted this in the audit issue itself
but just an FYI.)
Related to #7468
This changes the behavior of "ignore". Previously, Ghostty would
consider "ignore" actions consumed but do nothing. They were like a
black hole. Now, Ghostty returns `ignored` which lets the apprt forward
the event to the OS/GUI.
This enables keys that would otherwise be pty-encoded to be processed
later, such as for GTK to show the GTK inspector.
Related to #7468
This changes the behavior of "ignore". Previously, Ghostty would
consider "ignore" actions consumed but do nothing. They were like a
black hole. Now, Ghostty returns `ignored` which lets the apprt forward
the event to the OS/GUI.
This enables keys that would otherwise be pty-encoded to be processed
later, such as for GTK to show the GTK inspector.
This brings the behavior of mode 47, 1047, and 1049 much closer to
xterm's behavior. I found that our prior implementation had many
deficiencies.
For example, we weren't properly copying the cursor state back to the
primary screen from the alternate screen for modes 47 and 1047. And we
weren't saving/restoring cursor state unconditionally for mode 1049 even
if we were already in the alternate screen.
These are weird, edgy behaviors that I don't think anyone expected
(evidence by there being no bug reports about them), but they are bugs
nontheless.
Many tests added.
This fixes an issue where Ghostty would not build against the macOS 15.5
SDK.
What was happening was that Zig was adding its embedded libc paths to
the clang command line, which included old headers that were
incompatible with the latest (macOS 15.5) SDK. Ghostty was adding the
newer paths but they were being overridden by the embedded libc paths.
The reason this was happening is because Zig was using its own logic to
find the libc paths and this was colliding with the paths we were
setting manually. To fix this, we now use a `libc.txt` file that
explicitly tells Zig where to find libc, and we base this on our own SDK
search logic.
This fixes an issue where Ghostty would not build against the macOS 15.5 SDK.
What was happening was that Zig was adding its embedded libc paths to
the clang command line, which included old headers that were
incompatible with the latest (macOS 15.5) SDK. Ghostty was adding the
newer paths but they were being overridden by the embedded libc paths.
The reason this was happening is because Zig was using its own logic to
find the libc paths and this was colliding with the paths we were
setting manually. To fix this, we now use a `libc.txt` file that
explicitly tells Zig where to find libc, and we base this on our own SDK
search logic.
The default keybinds for showing the GTK inspector (`ctrl+shift+i` and
`ctrl+shift+d`) don't work reliably in Ghostty due to the way Ghostty
handles input. You can show the GTK inspector by setting the environment
variable `GTK_DEBUG` to `interactive` before starting Ghostty but that's
not always convenient.
This adds a keybind action that will show the GTK inspector. Due to
API limitations toggling the GTK inspector using the keybind action is
impractical because GTK does not provide a convenient API to determine
if the GTK inspector is already showing. Thus we limit ourselves to
strictly showing the GTK inspector. To close the GTK inspector the user
must click the close button on the GTK inspector window. If the GTK
inspector window is already visible but is hidden, calling the keybind
action will not bring the GTK inspector window to the front.
Fixes#7215. The issue was that `GlobalEventTap` didn't fully initialize
the key event before passing it to `ghostty_app_key`. In particular, it
didn't set the `unshifted_codepoint` field, which is needed to find a
match when calling `keybind.set.getEvent`, because `keybind.set` stores
bindings by codepoint, not physical key (i.e., the trigger to match is
`ctrl+p`, not `ctrl+key_p`, et cetera).
The fix was to make `GlobalEventTap` initialize the key event using
`event.ghosttyKeyEvent`, like it's done in `SurfaceView.keyAction` and
`AppDelegate.localEventKeyDown`.
This is my first time touching either Zig or Swift, so I'm a bit green.
In particular, I don't know if it's possible to write a test covering
this, and if so, how and where to put it. Please edit or request changes
as you see fit.
As of Zig 0.14.0, `@splat` can be used for array types, which eliminates
a lot of redundant syntax and makes things generally cleaner.
I've explicitly avoided applying this change in the renderer files for
now since it would just create rebasing conflicts in my renderer rework
branch which I'll be PR-ing pretty soon.
As of Zig 0.14.0, `@splat` can be used for array types, which eliminates
a lot of redundant syntax and makes things generally cleaner.
I've explicitly avoided applying this change in the renderer files for
now since it would just create rebasing conflicts in my renderer rework
branch which I'll be PR-ing pretty soon.
This PR adds support for handling the escape sequences CSI ? 47 h/l,
which are related to alternate screen buffer switching. This is in
response to the issue reported in
[ghostty-org/ghostty#7386](https://github.com/ghostty-org/ghostty/issues/7386).
I'm unsure where to add tests for this change. Would it make sense to
add visual tests for this behavior, or is there a preferred approach or
location for testing such functionality? I tested it locally using the
following commands:
```bash
echo -e "\e[?47h"
echo "Printed on the alt screen"
echo -e "\e[?47l"
```
This PR fixes the problem discussed in #5058 and #7434 by reworking the
selection logic in a way that better handles edge cases as well as being
generally cleaner.
This rework does change how selection behaves slightly, especially
rectangular selection, but the new behavior of rectangular selection is
more in line with other terminals I tested (Terminal.app, Kitty).
There are some TODO comments for adding unit tests- I ran out of steam
tonight, but if this PR is still open tomorrow I'll go ahead and add
them.
Adds many test cases for expected behavior of the selection logic, this
will allow changes to be made more confidently in the future without
fear of regressions.
This logic is cleaner and produces better behavior when selecting by
dragging the mouse outside the bounds of the surface, previously when
doing this on the left side of the surface selections would include the
first cell of the next row, this is no longer the case.
This introduces methods on PageList.Pin which move a pin left or right
while wrapping to the prev/next row, or clamping to the ends of the row.
These need unit tests.
See commit messages for details.
If some of the commits in this PR have problems with them I'm perfectly
fine with the others being cherry-picked out while the problems are
addressed.
The biggest/broadest reaching changes in this PR come from converting a
lot of code to use decl literals where possible, so there are a lot of
files where only a handful of lines are modified very slightly.
Update to Nix 25.05 which gets us GTK 4.18, libadwaita 1.7, and Zig
0.14.1.
Since Nix updated to Zig 0.14.1, the devshell has been switched to Zig
0.14.1 from zig-overlay as well.
Fixes#7305
Ghostty doesn't support `$XDG_CONFIG_DIR`, it only supports
`$XDG_CONFIG_HOME`, so the documentation was incorrect. Not to be
confused with `$XDG_CONFIG_DIRS` nor `$XDG_RUNTIME_DIR` (very
consistent…).
Furthermore, `$XDG_CONFIG_HOME` is the correct XDG path:
> <ins>$XDG_CONFIG_HOME</ins> defines the base directory relative to
which user-specific configuration files should be stored. If
<ins>$XDG_CONFIG_HOME</ins> is either not set or empty, a default equal
to <ins>$HOME</ins>/.config should be used.
> […]
> <ins>$XDG_CONFIG_DIRS</ins> defines the preference-ordered set of base
directories to search for configuration files in addition to the
<ins>$XDG_CONFIG_HOME</ins> base directory. The directories in
<ins>$XDG_CONFIG_DIRS</ins> should be separated with a colon ':'.
— [XDG Base Directory Specification § Environment variables][xdgvars]
Cross-reference:
https://github.com/ghostty-org/ghostty/discussions/7431#discussioncomment-13283139.
[xdgvars]:
https://specifications.freedesktop.org/basedir-spec/latest#variables
This commit changes a LOT of areas of the code to use decl literals
instead of redundantly referring to the type.
These changes were mostly driven by some regex searches and then manual
adjustment on a case-by-case basis.
I almost certainly missed quite a few places where decl literals could
be used, but this is a good first step in converting things, and other
instances can be addressed when they're discovered.
I tested GLFW+Metal and building the framework on macOS and tested a GTK
build on Linux, so I'm 99% sure I didn't introduce any syntax errors or
other problems with this. (fingers crossed)
Cleaner and less visual noise, easy change to make, there are many other
areas in the code which would benefit from decl literals as well, but
this is an area that benefits a lot from them and is self-contained.
Update to Nix 25.05 which gets us GTK 4.18, libadwaita 1.7, and Zig 0.14.1.
Since Nix updated to Zig 0.14.1, the devshell has been switched to Zig 0.14.1
from zig-overlay as well.
Fixes#7305
'g_application_id_is_valid' doesn't allow empty elements or elements
that start with digits.
This commit updates 'isValidAppId' to be more consistant with
'g_application_id_is_valid' avoiding the app id defaulting to 'GTK
Application' for app ids like '0foo.bar' or 'foo..bar'.