Sync upstream (2026-04-29)#8
Merged
saeedvaziry merged 92 commits intomainfrom Apr 29, 2026
Merged
Conversation
This makes sure that if Ghostty crashes, commands spawned are also terminated automatically by the Flatpak Session Helper.
Middle-click paste previously always read from the selection clipboard (falling back to the standard clipboard on platforms without one). Now the paste source follows copy-on-select: - copy-on-select = true: paste from selection clipboard (unchanged) - copy-on-select = clipboard: paste from system clipboard - copy-on-select = false: paste from selection clipboard (unchanged) Fixes ghostty-org#9788.
Previously `ghostty_app_key_is_binding` (unlike Surface) is just using `config.keybind` to check whether a KeyEvent is in the set or not. After this, I can add unit tests for keybinding more easily, with dummy configs.
Triggered by [comment](ghostty-org#11461 (comment)) from @jcollie. Vouch: @seyoungjeong Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This allows libghostty-vt to be cross-compiled for macOS from non-macOS platforms. I've updated pkg/apple-sdk to fallback to Zig's embedded macOS headers if the macOS SDK is not found. Additionally, CombineArchivesStep has been updated to use Linux tooling on Linux.
…org#12417) This allows libghostty-vt to be cross-compiled for macOS from non-macOS platforms. I've updated pkg/apple-sdk to fallback to Zig's embedded macOS headers if the macOS SDK is not found. Additionally, CombineArchivesStep has been updated to use Linux tooling on Linux. CI updated to test this.
…ramework on Darwin This fixes a hardcoded build issue on macOS where Zig unconditionally forces xcodebuild -create-xcframework to run during compilation, even when the caller explicitly specifies that they only want the raw standard C objects/headers (-Demit-lib-vt). The Bug: Around line 155 in build.zig, the libghostty-vt xcframework was being packaged unconditionally for Darwin builds. This caused developers (and wrappers like go-libghostty) attempting to natively build the vt library locally using only the minimal macOS Command Line Tools to experience an immediate crash, as xcodebuild -create-xcframework strictly demands a full Xcode application installation. The Fix: Guarded the GhosttyLibVt xcframework creation step with config.emit_xcframework. Because src/build/Config.zig intuitively forces emit_xcframework to default to false whenever emit_lib_vt is invoked, this structurally allows lightweight macOS builds to safely skip the xcodebuild invocation while still correctly compiling the standard .a object library files.
…ramework on Darwin (ghostty-org#12267) This fixes a hardcoded build issue on macOS where Zig unconditionally forces xcodebuild -create-xcframework to run during compilation, even when the caller explicitly specifies that they only want the raw standard C objects/headers (-Demit-lib-vt).
…2415) Previously `ghostty_app_key_is_binding` (unlike Surface) is just using `config.keybind` to check whether a KeyEvent is in the set or not. After this, I can add unit tests for keybinding more easily with dummy configs. I didn't find any usages of this in GTK, so it shouldn't affect anything. ci will see if this is the case:)
Triggered by [discussion comment](ghostty-org#12308 (comment)) from @jcollie. Vouch: @alaviss Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Link detection currently expands the clicked location to a full line before running the configured regexes. When semantic prompt markers are present, this can cause prompt text and neighboring content to be matched together even though they are distinct semantic regions. Use semantic prompt boundaries when selecting the text to inspect for link matching. This keeps prompt text separate from the content beside it and avoids folding prompt text into double-click link/path selection. Add a regression test that models a prompt and command on the same line and verifies the prompt region and input region remain separate.
Holding the renderer state mutex is a documented precondition of `processLinks`, but `mouseButtonCallback` previously called the function without the mutex. This creates a race with the I/O thread's `processOutput`, which can prune scrollback pages while `processLinks` is reading them, resulting in a use-after-free segfault. See ghostty-org#12409 (Linux: crash while selecting text). https://github.com/ghostty-org/ghostty/blob/57b5e1e2507cd65ab8197d39baa4ce2505185510/src/Surface.zig#L4354-L4355 https://github.com/ghostty-org/ghostty/blob/57b5e1e2507cd65ab8197d39baa4ce2505185510/src/Surface.zig#L3822-L3824 995e4e3 (os: open) changed the body of `processLinks` to be non-trivial and documented the precondition, but the lock was not held at the call site.
Triggered by [discussion comment](ghostty-org#12409 (reply in thread)) from @00-kat. Vouch: @jmr Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Notable dependency changes: - GTK: `4.20.4` -> `4.22.2` - libadwaita: `1.8.5` -> `1.9.0`
Due to a known Gtk issue, the scrolled_window at the root of the template is free-ed twice on dispose. This causes crashes when used with GNOME 49 platform (Gtk 4.20, libadwaita 1.8.5). Workaround this issue by wrapping the root child in another Adw.Bin, similar to widgets like ResizeOverlay. LLM was used to perform discovery against a manually recorded Valgrind trace, and helped tracking down known fixes for this problem. Fixes ghostty-org#12306 Assisted-by: OpenAI GPT-5.4
Triggered by [discussion comment](ghostty-org#12295 (comment)) from @mitchellh. Vouch: @dobbylee Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Triggered by [discussion comment](ghostty-org#12354 (comment)) from @mitchellh. Vouch: @007hacky007 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Triggered by [discussion comment](ghostty-org#12347 (comment)) from @mitchellh. Vouch: @rjwittams Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…tty-org#12426) Due to a known Gtk issue, the scrolled_window at the root of the template is free-ed twice on dispose. This causes crashes when used with GNOME 49 platform (Gtk 4.20, libadwaita 1.8.5). Workaround this issue by wrapping the root child in another Adw.Bin, similar to widgets like ResizeOverlay. LLM was used to perform discovery against a manually recorded Valgrind trace, and helped tracking down known fixes for this problem. The comment in code was taken from another instance in the repository. Fixes ghostty-org#12306 Assisted-by: OpenAI GPT-5.4
Triggered by [discussion comment](ghostty-org#11632 (comment)) from @mitchellh. Vouch: @ajiblock Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Triggered by [discussion comment](ghostty-org#11987 (comment)) from @mitchellh. Vouch: @nouritsu Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
`allocTmpDir` previously read `%TMP%` via `getenvW` and returned `null` if the variable wasn't set, requiring each caller to to deal with the nullable. Unfortunately, there isn't a platform-neutral default value that makes sense for those cases (i.e. `/tmp` is POSIX-y). We now use `GetTempPathW` on Windows, which is the official way to get this directory: `TMP` → `TEMP` → `USERPROFILE` → `GetWindowsDirectoryW`. With a real system call behind it, the function no longer needs to be nullable: the only remaining failure modes are OOM (propagated) and the syscall itself failing or returning data we can't decode. In those later cases, we use `C:\Windows\Temp` as a fallback, similar to how we use `/tmp` in the POSIX case. The Windows path always allocates so it still must be paired with `freeTmpDir`, which matches the existing contract.
…rg#12427) This makes sure that if Ghostty crashes, commands spawned are also terminated automatically by the Flatpak Session Helper. The few crashes I got left a lot of background processes, some of them pretty heavy and took awhile to be figured out.
`allocTmpDir` previously read `%TMP%` via `getenvW` and returned `null` if the variable wasn't set, requiring each caller to to deal with the nullable. Unfortunately, there isn't a platform-neutral default value that makes sense for those cases (i.e. `/tmp` is POSIX-y). We now use `GetTempPathW` on Windows, which is the official way to get this directory: `TMP` → `TEMP` → `USERPROFILE` → `GetWindowsDirectoryW`. With a real system call behind it, the function no longer needs to be nullable: the only remaining failure modes are OOM (propagated) and the syscall itself failing or returning data we can't decode. In those later cases, we use `C:\Windows\Temp` as a fallback, similar to how we use `/tmp` in the POSIX case. The Windows path always allocates so it still must be paired with `freeTmpDir`, which matches the existing contract. --- *AI Disclosure:* I verified the Windows path using Claude and Zig's cross-compilation capabilities because I don't have a Windows environment in which to test this. I do fully understand the code based on my prior life as a Windows game developer though.
Triggered by [discussion comment](ghostty-org#12484 (comment)) from @jcollie. Vouch: @kylesower Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Follow up for a3462dd
Follow up for a3462dd <img width="884" height="255" alt="image" src="https://github.com/user-attachments/assets/da4e4dd5-e645-40ed-8e9c-0ed8c9aee1c4" />
…hostty-org#12487) ## Problem Current `Se` sequence (reset cursor style) is `\E[2 q`, which always sets steady block, regardless of user config. ## Solution Update sequence to `\E[0 q`, which sets the cursor style to the user configured default cursor. fix ghostty-org#12482 Helps with neovim issue: neovim/neovim#38987 ## AI Disclosure I didn't use AI for this, haha. Unless you count random questions to learn about terminfo beforehand, but I relied on [legit resources](https://invisible-island.net/xterm/terminfo.html) for real info. It says: > Se resets the cursor style to the terminal power-on default. I think the useful interpretation is to set the user configured default.
Related to ghostty-org#12466 `Preedit.range()` returns an inclusive range, but the end position was calculated as `start + w`. For wide preedit text, this covers one extra cell. In Debug builds, Korean IME composition between existing Hangul characters can panic with: `index out of bounds: index 2, len 2` I reproduced this reliably when there are two Hangul characters to the right of the cursor. For example, type `가나다`, move the cursor between `가` and `나`, then start a new Korean IME composition. With the old range calculation, the renderer skips the first wide character plus the head cell of the next wide character, then resumes on that character's spacer tail. This changes the inclusive end to `start + (w - 1)` and adds focused tests for narrow, wide, and right-edge preedit ranges. This does not fully fix the visual behavior reported in ghostty-org#12466. The adjacent character can still disappear during composition, so this PR only fixes the crash side of the problem.
This updates UI tests and adds a test plan on disk, so we can change the configuration to different ones with the host app. If you changed the icon in regular ghostty config file, the tests can only be run once, since the signature is changed after changing the icon. Adding an on-disk test plan helps us to better control the environment for the tests.
…-hide is enabled (ghostty-org#12471) Fixes quick terminal breaking when auto-hide is enabled and quick terminal is manually toggled off (ghostty-org#11679). `quick-terminal-autohide` is implemented by the `Window.propIsActive` function in `apprt/gtk/class/window.zig` which calls `Window.toggleVisibility` when the quick terminal window becomes inactive (loses focus). However `Window.propIsActive` is also triggered when you manually hide the quick terminal because hiding it causes the window to become inactive. Normally that should just toggle the quick terminal off and immediately back on, but there is also a re-entrancy issue. Manually toggling off the terminal causes the `Application.toggleQuickTerminal` (in `apprt/gtk/class/application.zig`) to run which sets off the call chain `Window.toggleVisibility -> gtk_widget_set_visible -> ... GTK signal/event handling ... -> Window.propIsActive -> Window.toggleVisibility -> gtk_widget_set_visible`. The nested calls to `gtk_widget_set_visible` cause the GTK window state to become corrupted. The window is marked visible, but is not actually visible or just shows a placeholder. What exactly happens depends on the compositor and how it handles moving window focus. Reproduced the bug on KDE and hyprland and verified the fix on both. ### Changes `apprt/gtk/class/window.zig`: added check to `Window.propIsActive` to only toggle quick-terminal if it is inactive **and** visible. ### AI Disclosure Found the bug without AI using "printf debugging" then traced it through GTK with valgrind. Used GPT5.4 in setting up valgrind and researching how signals/events move through GTK internally.
This PR addresses ghostty-org#12108 implemented similarly to ghostty-org#8254 to allow middle click + TrackPoint scrolling on MacOS. `primary-paste` naming comes from `gtk_enable_primary_paste`. The following configuration values for `middle-click-action` are provided: - `primary-paste` - Paste from the selection (or system) clipboard per `copy-on-select`. - `ignore` - Do nothing, ignore the middle click. Tested locally on macOS with Zig 0.15.2 using `zig build -Doptimize=ReleaseFast`. Thank you!
fix hash outputs for flatpak build with Zig 0.16 from nixpkgs (which required fixing prettier reference in devShell.nix)
fix hash outputs for flatpak
…org#12492) This now fixes ghostty-org#11410 completely, `navigate_search:next` and `navigate_search:previous` are already fixed in 18f2702. Also fixes: surface is not focused after ending search via menu bar
Enforcing an absolute minimum of 1 for scroll events causes differing scroll speeds between high-resolution and standard scroll wheels on Linux. Since this was added to handle MacOS's precision scrolling emulation, this patch alters the behaviour so that the absolute minimum is only enforced on MacOS. Fixes ghostty-org#11648.
Enforcing an absolute minimum of 1 for scroll events causes differing scroll speeds between high-resolution and standard scroll wheels on Linux. Since this was added to handle MacOS's precision scrolling emulation, this patch alters the behaviour so that the absolute minimum is only enforced on MacOS. NB: This can't just be fixed by adjusting `mouse-scroll-multiplier` since that affects *all* scroll events whether they're high-resolution or not. Reducing `mouse-scroll-multiplier` to handle high-res scroll events better makes scrolling unusably slow for regular scroll wheels connected to the same machine. Fixes ghostty-org#11648.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Automated merge of
ghostty-org/ghostty@mainintomain. Review the diff and merge if our customizations still compile and behave correctly. Trigger the Build GhosttyKit workflow on main after merging to refresh the xcframework.