Conversation
… char (ghostty-org#11134) printCell, when overwriting a wide cell with a narrow cell at x<=1 and y>0, unconditionally sets the last cell of the previous row to .narrow. This is intended to clear a spacer_head left by a wrapped wide char, but the cell could be a spacer_tail if a wide char fit entirely on the previous row. Setting a spacer_tail to .narrow orphans the preceding .wide cell, which later causes an integrity violation in insertBlanks (assert that the cell after a .wide is .spacer_tail). Fix by guarding the assignment so it only fires when the previous row's last cell is actually a .spacer_head. The same fix is applied in both the .wide and .spacer_tail branches of printCell. Found by AFL++ stream fuzzer. ghostty-org#11109
resizeWithoutReflowGrowCols has a fast path that reuses existing page capacity when growing columns: it simply bumps page.size.cols without touching cell data. If any row has a spacer_head at the old last column (from a wide char that did not fit), that cell is no longer at the end of the now-wider row, causing a page integrity violation. Fix by checking for spacer_head cells at the old last column before taking the fast path. If any are found, fall through to the slow path which handles spacer heads correctly via cloneRowFrom. Found by AFL++ stream fuzzer. ghostty-org#11109
When deleteLines or insertLines count >= scroll region height, all rows go through the clear-only path (no shifting). This path did not call rowWillBeShifted, leaving orphaned spacer_tail cells when wide characters straddled the right margin boundary, causing a "spacer tail not following wide" page integrity violation. Add rowWillBeShifted before clearCells in the else branch of both functions. Found via AFL++ fuzzing. ghostty-org#11109
…g#11135) resizeWithoutReflowGrowCols has a fast path that reuses existing page capacity when growing columns: it simply bumps page.size.cols without touching cell data. If any row has a spacer_head at the old last column (from a wide char that did not fit), that cell is no longer at the end of the now-wider row, causing a page integrity violation. Fix by checking for spacer_head cells at the old last column before taking the fast path. If any are found, fall through to the slow path which handles spacer heads correctly via cloneRowFrom. Found by AFL++ stream fuzzer. ghostty-org#11109
…hostty-org#11136) When deleteLines or insertLines count >= scroll region height, all rows go through the clear-only path (no shifting). This path did not call rowWillBeShifted, leaving orphaned spacer_tail cells when wide characters straddled the right margin boundary, causing a "spacer tail not following wide" page integrity violation. Add rowWillBeShifted before clearCells in the else branch of both functions. Found via AFL++ fuzzing. ghostty-org#11109
When insertBlanks clears the entire region from cursor to the right margin (scroll_amount == 0), a wide character whose head is at the right margin gets cleared but its spacer_tail just beyond the margin is left behind, causing a "spacer tail not following wide" page integrity violation. Move the right-margin wide-char cleanup from inside the scroll_amount > 0 block to before it, so it runs unconditionally — matching the rowWillBeShifted pattern of cleaning up boundary-straddling wide chars up front. Found via AFL++ fuzzing. ghostty-org#11109
Triggered by [discussion comment](ghostty-org#11128 (comment)) from @mitchellh. Vouch: @noib3 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…hostty-org#11137) When insertBlanks clears the entire region from cursor to the right margin (scroll_amount == 0), a wide character whose head is at the right margin gets cleared but its spacer_tail just beyond the margin is left behind, causing a "spacer tail not following wide" page integrity violation. Move the right-margin wide-char cleanup from inside the scroll_amount > 0 block to before it, so it runs unconditionally — matching the rowWillBeShifted pattern of cleaning up boundary-straddling wide chars up front. Found via AFL++ fuzzing. ghostty-org#11109
When cursor-click-to-move is set to false, disable all prompt click-to-move mechanisms including shell-native methods such as OSC 133 cl= (arrow key synthesis) and click_events. I forgot to port this config over when we did the OSC133 stuff. Also update the config documentation to accurately describe the current behavior. Fixes ghostty-org#11138
…y-org#11141) When cursor-click-to-move is set to false, disable all prompt click-to-move mechanisms including shell-native methods such as OSC 133 cl= (arrow key synthesis) and click_events. I forgot to port this config over when we did the OSC133 stuff. Also update the config documentation to accurately describe the current behavior. Fixes ghostty-org#11138
This PR implements the fix discussed in ghostty-org#11128
This PR implements the fix discussed in ghostty-org#11128. Before: <img width="818" height="96" alt="before" src="https://github.com/user-attachments/assets/788f981f-3d1b-4c60-bf85-0c297641cae7" /> After: <img width="813" height="93" alt="after" src="https://github.com/user-attachments/assets/a530015a-053a-4680-9a85-812aa8df3d91" />
) Fixes ghostty-org#7937 Added `computeInitialSize` to GTK `Surface` and call it in GTK `Application` before the first `present()`, so the window manager centers the correct size on initial show. The issue occurs because the core `Surface.recomputeInitialSize()` runs only after the renderer is initialized. In GTK, the `GLArea` isn’t realized until after `present()`, so the initial size arrives too late for WM centering. **Limitations**: when we precompute size before `present()` we do not have access to padding, so the sizing will be very slightly off... but since it is only off a few pixels I was unable to tell visually that it wasn't perfectly centered. **Other thoughts**: I was hesitant to make changes to core `Surface` because the issue is Linux-specific, but it may make sense to extract a helper from `recomputeInitialSize` to avoid duplicating the sizing math. **AI Disclosure:** I used AI to explore the project, help with any language / API questions (I've never used zig before and rarely use gtk), and make implementation suggestions.
…ghostty-org#11147) This fixes ghostty-org#11146 and also ghostty-org#10993. Updated the comments added in ghostty-org#11052. > After finishing editing when the window resigns as the key window, using `labelFrame.minY` is fine with the same usage as ghostty-org#10993, but when double-clicking with text selected it will move up again 🤷🏻♂️. This makes focus state more accurate with cursor shape on the surface, when editing the title for a tab in another window group. [Incorrect example](https://github.com/user-attachments/assets/c3c4e774-a683-44e7-9bb6-3be79ac72ec2)
I'm running this now, 10 minutes with nothing but I figure this is a big enough target we should also add this.
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 ghostty-org#10049
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 ghostty-org#10049
Because of the global shared state that FontConfig maintains, FontConfig must be linked dynamically to the same system FontConfig shared library that GTK uses. Ghostty's default has been changed to always link to the system FontConfig library on non-macOS systems. If that is overridden (by specifying `-fno-sys=fontconfig` during the build) Ghostty may crash when trying to locate glyphs that are not available in the default font. Fixes ghostty-org#10432
…hostty-org#11152) Because of the global shared state that FontConfig maintains, FontConfig must be linked dynamically to the same system FontConfig shared library that GTK uses. Ghostty's default has been changed to always link to the system FontConfig library on non-macOS systems. If that is overridden (by specifying `-fno-sys=fontconfig` during the build) Ghostty may crash when trying to locate glyphs that are not available in the default font. Fixes ghostty-org#10432
Extends the macOS bell implementation to support the `audio` bell feature by playing a user-specified audio file via NSSound. Previously, macOS only supported the `system` feature (NSSound.beep()). This change adds support for: - `audio` bell feature: plays the file at `bell-audio-path` using NSSound, respecting the `bell-audio-volume` setting - Adds `cval()` to the `Path` type so it can be returned via the C API Also removes the "(GTK only)" restriction from `bell-audio-path` and `bell-audio-volume` documentation, as these options now work on macOS. Example config: bell-features = audio bell-audio-path = /System/Library/Sounds/Glass.aiff bell-audio-volume = 0.8
Triggered by [comment](ghostty-org#11154 (comment)) from @mitchellh. Vouch: @alaasdk Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Claude wrote the fail path in the UI tests, or you can easily reproduce this manually. This is kinda a regression after ghostty-org#11322, since we are not delaying the frame update anymore, which exposes some of the "flaws" of the previous implementation. The following three commits fix this step by step: - We shouldn't save intermediate frames when the window is loading, which is triggered by `windowDidResize` and `windowDidMove` during the process. - We should set the initial position (from the config) after the window is loaded. - A small refactor on `LastWindowPosition` to support restoring the window frame under certain conditions. https://github.com/user-attachments/assets/6f90f9a5-653d-4146-95c6-8e5c69bda656 ### AI Disclosure Claude helped me write the UI tests.
Bump of `zig-overlay`, allowing us to drop flake-utils from the flake inputs. :)
Fixes ghostty-org#11379 For this pass, I made it a very simple "within 20%" (height-wise) of the split handle. There is no horizontal component. I want to find the right balance between always visible (today mostly) to only visible on direct hover, because I think it'll be too hard to discover on that far right side.
…-org#11383) Fixes ghostty-org#11379 For this pass, I made it a very simple "within 20%" (height-wise) of the split handle down. There is no horizontal component. I want to find the right balance between always visible (today mostly) to only visible on direct hover, because I think it'll be too hard to discover on that far right side.
Triggered by [discussion comment](ghostty-org#11388 (comment)) from @jcollie. Vouch: @wyounas Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 8.0.0 to 8.0.1. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](actions/download-artifact@70fc10c...3e5f45b) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: 8.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
Add option to disable OSC 9;4 ConEmu progress bars via config. Fixes ghostty-org#11241
Fixes ghostty-org#11396 Track menu items populated from Ghostty keybind actions and only trigger those from SurfaceView performKeyEquivalent. This avoids app-default shortcuts such as Hide from pre-empting explicit keybinds.
…tty-org#11399) Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 8.0.0 to 8.0.1. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/actions/download-artifact/releases">actions/download-artifact's releases</a>.</em></p> <blockquote> <h2>v8.0.1</h2> <h2>What's Changed</h2> <ul> <li>Support for CJK characters in the artifact name by <a href="https://github.com/danwkennedy"><code>@danwkennedy</code></a> in <a href="https://redirect.github.com/actions/download-artifact/pull/471">actions/download-artifact#471</a></li> <li>Add a regression test for artifact name + content-type mismatches by <a href="https://github.com/danwkennedy"><code>@danwkennedy</code></a> in <a href="https://redirect.github.com/actions/download-artifact/pull/472">actions/download-artifact#472</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/download-artifact/compare/v8...v8.0.1">https://github.com/actions/download-artifact/compare/v8...v8.0.1</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/actions/download-artifact/commit/3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c"><code>3e5f45b</code></a> Add regression tests for CJK characters (<a href="https://redirect.github.com/actions/download-artifact/issues/471">#471</a>)</li> <li><a href="https://github.com/actions/download-artifact/commit/e6d03f67377d4412c7aa56a8e2e4988e6ec479dd"><code>e6d03f6</code></a> Add a regression test for artifact name + content-type mismatches (<a href="https://redirect.github.com/actions/download-artifact/issues/472">#472</a>)</li> <li>See full diff in <a href="https://github.com/actions/download-artifact/compare/70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3...3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details>
…-org#11403) Fixes ghostty-org#11396 Track menu items populated from Ghostty keybind actions and only trigger those from SurfaceView performKeyEquivalent. This avoids app-default shortcuts such as Hide from pre-empting explicit keybinds.
Adds progress-style config to control OSC 9;4 progress bar visibility. Defaults to true, set false to hide. Fixes ghostty-org#11241 AI Disclosure: Claude Code (Opus 4.6) used for codebase exploration, code review, and testing assistance. All code written and reviewed by hand.
Depends on ghostty-org#11417 Moved positioning part from `windowDidLoad` to `showWindow` to make new users happy. Also deleted `initialFrame`, since we don't need it anymore.
Added test case for cascading **without moving previous window**, ghostty-org#11161 will follow up for more accurate cascading after this. Fixed window cascading after last pr, now we should perform cascading **after** showing the window.
Make it smaller and add comparisons between y values
Syncs with ghostty-org/ghostty up to e11f350..597e8cf (88 commits). Upstream changes include: window positioning/cascading fixes, progress-style config option, key equivalent dispatch improvements, shell integration prompt handling rewrite, MacOSTitlebarStyle enum, ConfigTests, UserDefaults+Extension, harfbuzz shaper refactor, PageList improvements, and various bug fixes. All Ghostree customizations preserved: branding, bundle IDs, worktrunk sidebar, TerminalGlassContainer protocol, agent dock badges, CI workflows (GitHub-hosted runners), and AGENTS.md anti-squash rule.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 11eacca9b2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| .{ .copy_to_clipboard = .mixed }, | ||
| .{ .performable = true }, | ||
| ); |
There was a problem hiding this comment.
Keep default copy shortcut non-performable
Making the default copy binding performable changes behavior when nothing is selected: copy_to_clipboard returns false in that case, so this keypress is now unconsumed and falls through to terminal input. On Linux/Windows, pressing the default Ctrl+Shift+C with no selection can therefore propagate as Ctrl+C and interrupt the foreground process, which is a regression from the previous always-consumed copy shortcut.
Useful? React with 👍 / 👎.
Summary
Upstream highlights
progress-styleconfig optionMacOSTitlebarStyleenum (replaces raw strings)ConfigTests,UserDefaults+ExtensionGhostree customizations preserved
dev.sidequery.Ghostree)