Skip to content

Latest commit

 

History

1,520 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

Tip

Subscribe to Releases: In GitHub, use Watch -> Custom -> Releases for this repository to get a daily notification with the previous day's Ghostty tip changes.

Note

This changelog summarizes Ghostty tip nightly builds. It is auto-updated every 3 hours by GitHub Actions and shows a rolling 7-day window by default.

Entries are grouped by UTC day and combine commits across all successful runs for each day.

Last updated: September 3, 2026 at 07:40 UTC.

September 3, 2026

Runs: 1, 2
Summary: 2 runs • 7 commits • 3 authors

Changes

  • e01e75b terminal: don't touch me! keep the page pool free list unobtrusive (@mitchellh)
    This replaces the `std.heap.MemoryPool` used for page buffers with
    a custom pool called `UntouchedPool`. This keeps its free list in a side
    array and never reads/writes items until `create()`. This means that
    demand-driven allocations (like mmaped pages) don't incur physical costs
    until they're actually used.
    
    The standard `std.heap.MemoryPool` uses an intrusive linked list for
    its items which causes every item to be touched, which forces a full
    page-in of memory.
    
    It turns out we also had a lot of assertions and logic to work around
    this in various ways (size of rows, asserting we overwrite the free
    list entry, etc.) that we can now remove because of this.
    
    For an 80x24 terminal on macOS (16 KB pages):
    
    | Per terminal                 | Before   | After    |
    |------------------------------|----------|----------|
    | Page-list memory dirty       | 128 KiB  | 48 KiB   |
    | Process phys_footprint delta | 143 KiB  | 62 KiB   |
    | Page-list virtual size       | 2208 KiB | 1600 KiB |
    
    The remaining 48 KB is the active page, because we sprinkle metadata
    around the page which forces every page to be paged in. I'm going to
    follow this up with some work trying to move all our metadata to the
    front of the page so we only page one in until the rest is needed,
    but not sure if its achievable.
    
    Micro-benchmarks on the pool show that its twice the speed (slower) to
    create/free due to the side list, but in an actual `+terminal-stream`
    benchmark churning through pages, there is no measurable difference. I
    think its a good trade.
    
  • 31bdcd5 terminal: don't touch me! keep the page pool free list unobtrusive (#14130) (@mitchellh)
    This replaces the `std.heap.MemoryPool` used for page buffers with a
    custom pool called `UntouchedPool`. This keeps its free list in a side
    array and never reads/writes items until `create()`. This means that
    demand-driven allocations (like mmaped pages) don't incur physical costs
    until they're actually used.
    
    The standard `std.heap.MemoryPool` uses an intrusive linked list for its
    items which causes every item to be touched, which forces a full page-in
    of memory.
    
    It turns out we also had a lot of assertions and logic to work around
    this in various ways (size of rows, asserting we overwrite the free list
    entry, etc.) that we can now remove because of this.
    
    For an 80x24 terminal on macOS (16 KB pages):
    
    | Per terminal                 | Before   | After    |
    |------------------------------|----------|----------|
    | Page-list memory dirty       | 128 KiB  | 48 KiB   |
    | Process phys_footprint delta | 143 KiB  | 62 KiB   |
    | Page-list virtual size       | 2208 KiB | 1600 KiB |
    
    The remaining 48 KB is the active page, because we sprinkle metadata
    around the page which forces every page to be paged in. I'm going to
    follow this up with some work trying to move all our metadata to the
    front of the page so we only page one in until the rest is needed, but
    not sure if its achievable.
    
    Micro-benchmarks on the pool show that its twice the speed (slower) to
    create/free due to the side list, but in an actual `+terminal-stream`
    benchmark churning through pages, there is no measurable difference. I
    think its a good trade.
    
  • 5dfb672 surface: restore mouse_shape when modifier overrides end (@j-c-m)
    hard-coded .default & .text overrode a previously set OSC22 pointer
    shape, this was a regression introduced in 6e8ed4e8b.
    
  • 6674aa3 surface: update keyToMouseShape tests to expect mouse_shape (@j-c-m)
    Update the tests to expect the mouse_shape back, not the hardcoded
    .default or .text
    
  • 3a766cc surface: show .text (i-beam) while shift is held without mouse tracking (@j-c-m)
    I think this is the expected behavoir when a custom OSC22 pointer is set. Once
    shift is released it will return to mouse_shape (whatever the pointer
    was before shit held).
    
  • 0fb6d29 SurfaceMouse: simplify keyToMouseShape (@vancluever)
    keyToMouseShape was initially designed with more of a transition table
    model in mind to handle key presses/overrides based on very specific
    cursor states. This never materialized, so I think it's safe to just
    simply the process of handling overrides and/or passing along the
    current cursor state from the terminal in the event of key presses.
    
    Also removed a test that is essentially a duplicate of one before it now
    (returning current surface shape in the event of no overrides).
    
  • 6000034 surface: restore application mouse shape after modifier overrides (#14128) (@mitchellh)
    This fixes a regression of 9a6469743 introduced in 6e8ed4e8b.
    
    With this fix the mouse pointer will be restored to the previous (which
    could have be set to something else via OSC22), not a hardcoded .text or
    .default.
    
    It also will change the cursor to a text selection if shift is held even
    without mouse tracking, I think this is the expected behavior when a
    cursor is set via OSC22. (Kitty additionaly, once you start selecting
    changes to text (I-beam), this would be a follow-up if we desire to
    behave like kitty with OSC22 pointers).
    

September 2, 2026

Runs: 1, 2
Summary: 2 runs • 31 commits • 8 authors

Changes

  • 807a51e updated localization file (andrejd-magix)
  • 36015c9 updated revision date (andrejd-magix)
  • ee10453 fix unclosed quote (andrejd-magix)
  • 59141ad add eu translation (@erral)
  • 58aa59d Update po/eu.po (@erral)
  • 6a51526 Update po/eu.po (@erral)
  • 4c731b5 Update po/eu.po (@erral)
  • 4ffec4b Update po/eu.po (@erral)
  • f407316 Update po/eu.po (@erral)
    applying but both eskuma and eskuina are OK.
    
  • 63039a6 update (@erral)
  • f184d3c update (@erral)
  • 4da902b update (@erral)
  • 9801423 update (@erral)
  • 7520175 more fixes (@erral)
  • 3b8141f os/open: consume the newline when draining opener stderr (@jzillmann)
    takeDelimiterExclusive never consumes the delimiter: it tosses only the
    exclusive length, so the '\n' stays buffered. Once the spawned opener
    writes a single line to stderr, every subsequent call returns an empty
    slice without advancing the stream, and openThread's loop spins forever
    - one pinned core per affected open(), logging empty
    "open stderr=" warnings at tens of thousands of messages per second for
    the lifetime of the process. The thread also never reaches exe.wait(),
    so the child is never reaped.
    
    Read inclusively instead (which does consume the delimiter) and trim
    the '\n' for logging.
    
    Repro: open a link whose handler writes to stderr, e.g. an OSC 8 link
    with an unknown scheme; watch a core disappear and the unified log
    flood with "os-open: open stderr=".
    
    See discussion #14100.
    
  • 372d691 i18n: complete eu translation (#14095) (@trag1c)
  • e212b73 Update mk localization for v1.4 (#14088) (@trag1c)
    Addressing #13766 for mk.
    
  • 349f026 os/open: consume the newline when draining opener stderr (#14125) (@mitchellh)
    Fixes the runaway-thread bug reported in #14100 (vouched there).
    
    `openThread` drains the spawned opener's stderr with
    `takeDelimiterExclusive('\n')`. That function tosses only the exclusive
    length, so the `'\n'` is never consumed. Once the child writes one line
    to stderr, every subsequent call returns an empty slice without
    advancing the stream: the `while (true)` loop spins forever — one pinned
    core per affected `open()`, logging empty `os-open: open stderr=`
    warnings at tens of thousands of messages per second for the lifetime of
    the process — and `exe.wait()` is never reached, so the child is never
    reaped.
    
    This change reads inclusively (`takeDelimiterInclusive`, which does
    consume the delimiter) and trims the `'\n'` for logging.
    
    Observed in the wild embedding libghostty on macOS: several days of
    uptime accumulated six leaked opener threads at ~70% of a core each
    (~4.4 cores), from six link clicks whose `/usr/bin/open` wrote to
    stderr. After the fix, the same workload shows zero `os-open` log
    traffic and no leaked threads.
    
    Repro without the fix: open a link whose handler writes to stderr (e.g.
    an OSC 8 link with an unknown scheme), then watch a core pin and `log
    stream --predicate 'subsystem == "com.mitchellh.ghostty"'` flood.
    
    **AI disclosure** (per `AI_POLICY.md`): the bug was diagnosed and this
    patch drafted with Claude Code (thread sampling, log analysis, and
    reading the Zig 0.16 `std.Io.Reader` source to confirm
    `takeDelimiterExclusive`/`takeDelimiterInclusive` toss semantics). I
    reviewed the analysis and the change, understand both, and verified the
    fix in a production build of the embedding app.
    
  • 2ba7576 build(deps): bump flatpak/flatpak-github-actions/flatpak-builder (@dependabot[bot])
    Bumps [flatpak/flatpak-github-actions/flatpak-builder](https://github.com/flatpak/flatpak-github-actions) from 6.7 to 6.8.
    - [Release notes](https://github.com/flatpak/flatpak-github-actions/releases)
    - [Commits](https://github.com/flatpak/flatpak-github-actions/compare/401fe28a8384095fc1531b9d320b292f0ee45adb...79327416609af08178ad73b352877e51450790b3)
    
    ---
    updated-dependencies:
    - dependency-name: flatpak/flatpak-github-actions/flatpak-builder
      dependency-version: '6.8'
      dependency-type: direct:production
      update-type: version-update:semver-minor
    ...
    
  • 7358067 build(deps): bump cachix/cachix-action (@dependabot[bot])
    Bumps [cachix/cachix-action](https://github.com/cachix/cachix-action) from 5f2d7c5294214f71b873db4b969586b980625e71 to 38b082610b782e7e93e209c35fd730d399dee866.
    - [Release notes](https://github.com/cachix/cachix-action/releases)
    - [Changelog](https://github.com/cachix/cachix-action/blob/master/RELEASE.md)
    - [Commits](https://github.com/cachix/cachix-action/compare/5f2d7c5294214f71b873db4b969586b980625e71...38b082610b782e7e93e209c35fd730d399dee866)
    
    ---
    updated-dependencies:
    - dependency-name: cachix/cachix-action
      dependency-version: 38b082610b782e7e93e209c35fd730d399dee866
      dependency-type: direct:production
    ...
    
  • 310797d macOS: fix cascading without affecting other new-window behaviours (@bo2themax)
  • a8b0855 macOS: fix cascading for HiddenTitlebarTerminalWindow (@bo2themax)
  • 5d6615f bash: upgrade to bash-preexec 0.7.0 (@jparise)
    https://github.com/rcaloras/bash-preexec/releases/tag/0.7.0
    
    We only source bash-preexec for bash < 4.4, so most of this release is
    inert for us: the PS0 function-substitution hook (bash >= 5.3) and the
    array PROMPT_COMMAND handling (bash >= 5.1) are never reached. What we
    do pick up is the simpler install string, per-prompt re-adjustment of
    PROMPT_COMMAND when something else modifies it, preservation of $? and
    $_ on early returns, and the first-command preexec fix.
    
    We continue to carry one local modification: __bp_adjust_histcontrol
    stays disabled in the DEBUG trap hook so the user's HISTCONTROL is
    respected (#2269). The original justification was that we didn't use
    the preexec command argument, which is no longer true because we use it
    for the window title. The comment now explains the current reasoning:
    our bash >= 4.4 integration also uses `history 1` without adjusting
    HISTCONTROL and accepts the same inaccuracy for space-prefixed commands,
    so the legacy path is kept consistent with it.
    
  • aafacb1 macOS: fix flickering when creating new tab with glass style (@bo2themax)
  • fec89f2 macOS: fix flickering when creating new tab with glass style (#14121) (@mitchellh)
    A regression from #13985.
    
    
    https://github.com/user-attachments/assets/cc7d76d7-7d86-4566-921c-a6531ce4087d
    
    
    
    
    ### AI Disclosure
    
    Used Claude to investigate, I reviewed and tested.
    
  • 0c1909d bash: upgrade to bash-preexec 0.7.0 (#14120) (@mitchellh)
    https://github.com/rcaloras/bash-preexec/releases/tag/0.7.0
    
    We only source bash-preexec for bash < 4.4, so most of this release is
    inert for us: the PS0 function-substitution hook (bash >= 5.3) and the
    array PROMPT_COMMAND handling (bash >= 5.1) are never reached. What we
    do pick up is the simpler install string, per-prompt re-adjustment of
    PROMPT_COMMAND when something else modifies it, preservation of $? and
    $_ on early returns, and the first-command preexec fix.
    
    We continue to carry one local modification: __bp_adjust_histcontrol
    stays disabled in the DEBUG trap hook so the user's HISTCONTROL is
    respected (#2269). The original justification was that we didn't use the
    preexec command argument, which is no longer true because we use it for
    the window title. The comment now explains the current reasoning: our
    bash >= 4.4 integration also uses `history 1` without adjusting
    HISTCONTROL and accepts the same inaccuracy for space-prefixed commands,
    so the legacy path is kept consistent with it.
    
    *AI Usage:* I asked Fable 5.1 to run a verification pass after my manual
    upgrade, and it confirmed the expected behavior.
    
  • 084316a macOS: fix cascading without affecting other new-window behaviours (#14118) (@mitchellh)
    Found another regression when investigating #14107 after the last fix.
    This regression appears on macOS 15 and 26 as well: **New window by
    Shortcuts.app or service menu while a window is visible would create a
    tab**.
    
    It appears that for `new-window` triggered by Shortcuts/Service, a small
    delay is needed to avoid automatic tabbing. It's either removing
    `NSWindow.userTabbingPreference == .always` completely or adding another
    "delay" for cascading. The latter should be better.
    
    Also fixes another cascading for `macos-titlebar-style = hidden`
    previously missed.
    
  • 41004c6 build(deps): bump cachix/cachix-action from 5f2d7c5294214f71b873db4b969586b980625e71 to 38b082610b782e7e93e209c35fd730d399dee866 (#14116) (@mitchellh)
    Bumps [cachix/cachix-action](https://github.com/cachix/cachix-action)
    from 5f2d7c5294214f71b873db4b969586b980625e71 to
    38b082610b782e7e93e209c35fd730d399dee866.
    <details>
    <summary>Changelog</summary>
    <p><em>Sourced from <a
    href="https://github.com/cachix/cachix-action/blob/master/RELEASE.md">cachix/cachix-action's
    changelog</a>.</em></p>
    <blockquote>
    <h1>Release</h1>
    <ol>
    <li>
    <p>Create and push a new tag:</p>
    <pre lang="console"><code>git tag v17
    git push origin v17
    </code></pre>
    </li>
    <li>
    <p>Wait for CI to pass.</p>
    </li>
    <li>
    <p><a href="https://github.com/cachix/cachix-action/releases/new">Create
    a release</a> for the new tag.</p>
    </li>
    <li>
    <p>Move the major version tag to the latest release:</p>
    <pre lang="console"><code>git tag -fa v17
    git push origin v17 --force
    </code></pre>
    </li>
    </ol>
    </blockquote>
    </details>
    <details>
    <summary>Commits</summary>
    <ul>
    <li><a
    href="https://github.com/cachix/cachix-action/commit/38b082610b782e7e93e209c35fd730d399dee866"><code>38b0826</code></a>
    dev: cleanup tests and dev files</li>
    <li><a
    href="https://github.com/cachix/cachix-action/commit/0fe030c2864be690428363af3bc7016b7b1925d8"><code>0fe030c</code></a>
    dist</li>
    <li><a
    href="https://github.com/cachix/cachix-action/commit/792dafcfd01b48d3df8424b641db396602252fc3"><code>792dafc</code></a>
    deps: bump dependencies</li>
    <li><a
    href="https://github.com/cachix/cachix-action/commit/b690244fb5c76a5486c33b0fbbc6fd55c857d1fe"><code>b690244</code></a>
    ci: improve Nix compatibility test coverage</li>
    <li><a
    href="https://github.com/cachix/cachix-action/commit/f495f3ffa2f3810a92e5cc0abc2c5d6a2a07ec82"><code>f495f3f</code></a>
    Merge pull request <a
    href="https://redirect.github.com/cachix/cachix-action/issues/217">#217</a>
    from cachix/dependabot/github_actions/actions/checkout-7</li>
    <li><a
    href="https://github.com/cachix/cachix-action/commit/9ee3c77d45d24a8b7557d22cbba3454f2a4f8a7b"><code>9ee3c77</code></a>
    chore(deps): bump actions/checkout from 6 to 7</li>
    <li>See full diff in <a
    href="https://github.com/cachix/cachix-action/compare/5f2d7c5294214f71b873db4b969586b980625e71...38b082610b782e7e93e209c35fd730d399dee866">compare
    view</a></li>
    </ul>
    </details>
    <br />
    
    
    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>
    
  • dd167cc build(deps): bump flatpak/flatpak-github-actions/flatpak-builder from 6.7 to 6.8 (#14115) (@mitchellh)
    Bumps
    [flatpak/flatpak-github-actions/flatpak-builder](https://github.com/flatpak/flatpak-github-actions)
    from 6.7 to 6.8.
    <details>
    <summary>Release notes</summary>
    <p><em>Sourced from <a
    href="https://github.com/flatpak/flatpak-github-actions/releases">flatpak/flatpak-github-actions/flatpak-builder's
    releases</a>.</em></p>
    <blockquote>
    <h2>v6.8</h2>
    <ul>
    <li>Add saveCache flag</li>
    <li>Add ability to override artifact name</li>
    <li>Add buildDebugBundle flag</li>
    <li>Update tests, documentation and dependencies</li>
    </ul>
    </blockquote>
    </details>
    <details>
    <summary>Commits</summary>
    <ul>
    <li><a
    href="https://github.com/flatpak/flatpak-github-actions/commit/79327416609af08178ad73b352877e51450790b3"><code>7932741</code></a>
    Update all dependencies and regenerate dist</li>
    <li><a
    href="https://github.com/flatpak/flatpak-github-actions/commit/09e3d61868ecd92a1c5b298a31bcc4bae17ae217"><code>09e3d61</code></a>
    readme: Don't specify setting cache key to github.sha (<a
    href="https://redirect.github.com/flatpak/flatpak-github-actions/issues/261">#261</a>)</li>
    <li><a
    href="https://github.com/flatpak/flatpak-github-actions/commit/23e622281a14ba5350ce2ab1ae700ac7d08cc841"><code>23e6222</code></a>
    Update runtime versions and docker images to latest</li>
    <li><a
    href="https://github.com/flatpak/flatpak-github-actions/commit/a3ab43f58191aa8dc105e572c0a62eaac0a7555a"><code>a3ab43f</code></a>
    flatpak-builder: Add saveCache flag</li>
    <li><a
    href="https://github.com/flatpak/flatpak-github-actions/commit/8e357b1556f526e3642244bdf1a6d585be36de54"><code>8e357b1</code></a>
    ci: Remove unnecessary 'needs' from debug bundle job</li>
    <li><a
    href="https://github.com/flatpak/flatpak-github-actions/commit/26e19caa3a954b1d36898a0e239a67d8e856f99c"><code>26e19ca</code></a>
    ci: Add test for artifact-name</li>
    <li><a
    href="https://github.com/flatpak/flatpak-github-actions/commit/06d246b4d5459d93c166243236f8a086d5578746"><code>06d246b</code></a>
    flatpak-builder: Add ability to override artifact name</li>
    <li><a
    href="https://github.com/flatpak/flatpak-github-actions/commit/a2622647717d8185d0f8cf01bb1ea2341e357ae0"><code>a262264</code></a>
    ci: Add job that uses build-debug-bundle</li>
    <li><a
    href="https://github.com/flatpak/flatpak-github-actions/commit/f7362292df659c06960a8c0dc309ab5990454a29"><code>f736229</code></a>
    flatpak-builder: Add buildDebugBundle flag</li>
    <li><a
    href="https://github.com/flatpak/flatpak-github-actions/commit/3b10954431df173eb3b564bb9adfddf3842ff91c"><code>3b10954</code></a>
    ci: Update actions to versions using Node 24</li>
    <li>See full diff in <a
    href="https://github.com/flatpak/flatpak-github-actions/compare/401fe28a8384095fc1531b9d320b292f0ee45adb...79327416609af08178ad73b352877e51450790b3">compare
    view</a></li>
    </ul>
    </details>
    <br />
    
    
    [![Dependabot compatibility
    score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=flatpak/flatpak-github-actions/flatpak-builder&package-manager=github_actions&previous-version=6.7&new-version=6.8)](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>
    
  • 06178ee terminal/search: resume a complete search when history is prepended (@mitchellh)
    A search that had already exhausted a screen's PageList never picked up
    history pages prepended afterwards by incremental snapshot restore.
    
    The lower level PageListSearch and so on could already handle this, we
    just needed to let it know that more history existed to search. This
    fixes that.
    
  • b0481f5 terminal/search: resume a complete search when history is prepended (#14123) (@mitchellh)
    A search that had already exhausted a screen's PageList never picked up
    history pages prepended afterwards by incremental snapshot restore.
    
    The lower level PageListSearch and so on could already handle this, we
    just needed to let it know that more history existed to search. This
    fixes that.
    

September 1, 2026

Runs: 1, 2
Summary: 2 runs • 7 commits • 4 authors

Changes

  • 38c984e build(deps): bump softprops/action-gh-release from 3.0.2 to 3.0.3 (@dependabot[bot])
    Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 3.0.2 to 3.0.3.
    - [Release notes](https://github.com/softprops/action-gh-release/releases)
    - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
    - [Commits](https://github.com/softprops/action-gh-release/compare/3d0d9888cb7fd7b750713d6e236d1fcb99157228...efb35369e0ad2afab669f228072c1b0d510eae64)
    
    ---
    updated-dependencies:
    - dependency-name: softprops/action-gh-release
      dependency-version: 3.0.3
      dependency-type: direct:production
      update-type: version-update:semver-patch
    ...
    
  • d4a5ff5 macOS: fix window cascading (@bo2themax)
  • d2e2488 build(deps): bump softprops/action-gh-release from 3.0.2 to 3.0.3 (#14098) (@mitchellh)
    Bumps
    [softprops/action-gh-release](https://github.com/softprops/action-gh-release)
    from 3.0.2 to 3.0.3.
    <details>
    <summary>Release notes</summary>
    <p><em>Sourced from <a
    href="https://github.com/softprops/action-gh-release/releases">softprops/action-gh-release's
    releases</a>.</em></p>
    <blockquote>
    <h2>v3.0.3</h2>
    <p><code>3.0.3</code> is a maintenance release with updated
    dependencies. It also safely
    classifies malformed GitHub API errors to avoid secondary failures (<a
    href="https://redirect.github.com/softprops/action-gh-release/issues/822">#822</a>).</p>
    <h2>What's Changed</h2>
    <h3>Bug fixes 🐛</h3>
    <ul>
    <li>fix: safely classify GitHub API errors by <a
    href="https://github.com/chenrui333"><code>@​chenrui333</code></a> in <a
    href="https://redirect.github.com/softprops/action-gh-release/pull/822">softprops/action-gh-release#822</a></li>
    </ul>
    <h3>Other Changes 🔄</h3>
    <ul>
    <li>dependency updates</li>
    </ul>
    </blockquote>
    </details>
    <details>
    <summary>Changelog</summary>
    <p><em>Sourced from <a
    href="https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md">softprops/action-gh-release's
    changelog</a>.</em></p>
    <blockquote>
    <h2>3.0.3</h2>
    <p><code>3.0.3</code> is a maintenance release with updated
    dependencies. It also safely
    classifies malformed GitHub API errors to avoid secondary failures (<a
    href="https://redirect.github.com/softprops/action-gh-release/issues/822">#822</a>).</p>
    <h2>What's Changed</h2>
    <h3>Bug fixes 🐛</h3>
    <ul>
    <li>fix: safely classify GitHub API errors by <a
    href="https://github.com/chenrui333"><code>@​chenrui333</code></a> in <a
    href="https://redirect.github.com/softprops/action-gh-release/pull/822">softprops/action-gh-release#822</a></li>
    </ul>
    <h3>Other Changes 🔄</h3>
    <ul>
    <li>dependency updates</li>
    </ul>
    <h2>3.0.2</h2>
    <p><code>3.0.2</code> is a patch release focused on release reliability
    and compatibility. It
    reuses existing draft releases when publishing prereleases, supports
    replacing
    release assets on Gitea, hardens streamed asset uploads, and provides
    clearer
    release-creation diagnostics. It also includes TypeScript, coverage, and
    tooling
    maintenance merged since <code>3.0.1</code>.</p>
    <p>This release fixes <a
    href="https://redirect.github.com/softprops/action-gh-release/issues/795">#795</a>,
    <a
    href="https://redirect.github.com/softprops/action-gh-release/issues/438">#438</a>,
    and <a
    href="https://redirect.github.com/softprops/action-gh-release/issues/803">#803</a>.
    The upload transport hardening covers the
    historical failure reported in <a
    href="https://redirect.github.com/softprops/action-gh-release/issues/790">#790</a>,
    although current hosted Node 24 runners did
    not reproduce it naturally. The diagnostics work is related to <a
    href="https://redirect.github.com/softprops/action-gh-release/issues/786">#786</a>
    and does not
    claim a reproducible release-creation fix.</p>
    <h2>What's Changed</h2>
    <h3>Exciting New Features 🎉</h3>
    <ul>
    <li>feat: improve release error reporting and test coverage by <a
    href="https://github.com/chenrui333"><code>@​chenrui333</code></a> in <a
    href="https://redirect.github.com/softprops/action-gh-release/pull/813">softprops/action-gh-release#813</a></li>
    </ul>
    <h3>Bug fixes 🐛</h3>
    <ul>
    <li>fix: publish existing draft releases as prereleases by <a
    href="https://github.com/godfengliang"><code>@​godfengliang</code></a>
    in <a
    href="https://redirect.github.com/softprops/action-gh-release/pull/801">softprops/action-gh-release#801</a></li>
    <li>fix: upload small checksum assets reliably by <a
    href="https://github.com/chenrui333"><code>@​chenrui333</code></a> in <a
    href="https://redirect.github.com/softprops/action-gh-release/pull/815">softprops/action-gh-release#815</a></li>
    <li>fix: replace existing release assets on Gitea by <a
    href="https://github.com/chenrui333"><code>@​chenrui333</code></a> in <a
    href="https://redirect.github.com/softprops/action-gh-release/pull/816">softprops/action-gh-release#816</a></li>
    <li>fix: clarify release creation 404 errors by <a
    href="https://github.com/chenrui333"><code>@​chenrui333</code></a> in <a
    href="https://redirect.github.com/softprops/action-gh-release/pull/817">softprops/action-gh-release#817</a></li>
    </ul>
    <h3>Other Changes 🔄</h3>
    <ul>
    <li>chore(deps): upgrade TypeScript to 7 by <a
    href="https://github.com/chenrui333"><code>@​chenrui333</code></a> in <a
    href="https://redirect.github.com/softprops/action-gh-release/pull/812">softprops/action-gh-release#812</a></li>
    <li>chore(deps): remove unused TypeScript tooling by <a
    href="https://github.com/chenrui333"><code>@​chenrui333</code></a> in <a
    href="https://redirect.github.com/softprops/action-gh-release/pull/814">softprops/action-gh-release#814</a></li>
    <li>dependency, Node 24 pin, and CI maintenance merged since
    <code>3.0.1</code></li>
    </ul>
    <h2>3.0.1</h2>
    <ul>
    <li>maintenance release with updated dependencies</li>
    </ul>
    <!-- raw HTML omitted -->
    </blockquote>
    <p>... (truncated)</p>
    </details>
    <details>
    <summary>Commits</summary>
    <ul>
    <li><a
    href="https://github.com/softprops/action-gh-release/commit/efb35369e0ad2afab669f228072c1b0d510eae64"><code>efb3536</code></a>
    release 3.0.3 (<a
    href="https://redirect.github.com/softprops/action-gh-release/issues/840">#840</a>)</li>
    <li><a
    href="https://github.com/softprops/action-gh-release/commit/6441963a7597ab67f36fea0287a7ae58a9bfd8fe"><code>6441963</code></a>
    chore(deps): bump the npm group with 2 updates (<a
    href="https://redirect.github.com/softprops/action-gh-release/issues/839">#839</a>)</li>
    <li><a
    href="https://github.com/softprops/action-gh-release/commit/e5ee6bc58a36b838b92fc1217f2e4b414b5abcc8"><code>e5ee6bc</code></a>
    chore(deps): bump esbuild from 0.28.1 to 0.28.2 in the npm group (<a
    href="https://redirect.github.com/softprops/action-gh-release/issues/837">#837</a>)</li>
    <li><a
    href="https://github.com/softprops/action-gh-release/commit/d1e66170d32c9ec7bbcb7fae044d3d686ce304d3"><code>d1e6617</code></a>
    chore(deps): bump undici from 6.27.0 to 6.28.0 (<a
    href="https://redirect.github.com/softprops/action-gh-release/issues/831">#831</a>)</li>
    <li><a
    href="https://github.com/softprops/action-gh-release/commit/64037519ba20f54c01bc1dc90342c929aac5a2fa"><code>6403751</code></a>
    chore(deps): bump the npm group with 2 updates (<a
    href="https://redirect.github.com/softprops/action-gh-release/issues/835">#835</a>)</li>
    <li><a
    href="https://github.com/softprops/action-gh-release/commit/7c7184b6876126a5df15adc5b679dc450a393725"><code>7c7184b</code></a>
    chore(deps): bump postcss from 8.5.19 to 8.5.25 (<a
    href="https://redirect.github.com/softprops/action-gh-release/issues/833">#833</a>)</li>
    <li><a
    href="https://github.com/softprops/action-gh-release/commit/0f3f0d2943676d58f9698b3ab590c2056023d77d"><code>0f3f0d2</code></a>
    chore(deps): bump brace-expansion from 5.0.8 to 5.0.9 (<a
    href="https://redirect.github.com/softprops/action-gh-release/issues/832">#832</a>)</li>
    <li><a
    href="https://github.com/softprops/action-gh-release/commit/77fb938f2f95e717ce6705d2909af527263360a0"><code>77fb938</code></a>
    chore(deps): bump prettier from 3.9.5 to 3.9.6 in the npm group (<a
    href="https://redirect.github.com/softprops/action-gh-release/issues/830">#830</a>)</li>
    <li><a
    href="https://github.com/softprops/action-gh-release/commit/5a6f51711ce2ba103b78f5e9550f810679f11e0e"><code>5a6f517</code></a>
    chore(deps): bump brace-expansion from 5.0.7 to 5.0.8 (<a
    href="https://redirect.github.com/softprops/action-gh-release/issues/828">#828</a>)</li>
    <li><a
    href="https://github.com/softprops/action-gh-release/commit/a3c91c98f80000f5b06c7fc0327c54f51c6ab7d8"><code>a3c91c9</code></a>
    chore(deps): bump the github-actions group with 2 updates (<a
    href="https://redirect.github.com/softprops/action-gh-release/issues/825">#825</a>)</li>
    <li>Additional commits viewable in <a
    href="https://github.com/softprops/action-gh-release/compare/3d0d9888cb7fd7b750713d6e236d1fcb99157228...efb35369e0ad2afab669f228072c1b0d510eae64">compare
    view</a></li>
    </ul>
    </details>
    <br />
    
    
    [![Dependabot compatibility
    score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=softprops/action-gh-release&package-manager=github_actions&previous-version=3.0.2&new-version=3.0.3)](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>
    
  • b7a680b macOS: fix window cascading (#14106) (@mitchellh)
    Regression from https://github.com/ghostty-org/ghostty/pull/13722
    
  • 451e224 macOS: clean up for #14106 (@bo2themax)
  • 3c1ef5b macOS: clean up for #14106 (#14111) (@mitchellh)
    I don't know what happened to me, but I didn't notice that I should
    delete this🫪
    
  • 20abdb5 Update VOUCHED list (#14101) (@ghostty-vouch[bot])
    Triggered by [discussion
    comment](https://github.com/ghostty-org/ghostty/discussions/14100#discussioncomment-18229353)
    from @jcollie.
    
    Vouch: @jzillmann
    

August 31, 2026

Runs: 1, 2, 3, 4, 5
Summary: 5 runs • 60 commits • 8 authors

Changes

  • 300a0df Add the Serbian and Serbian Latin translations (@kostich)
  • 74e0bfd Register code ownership (@kostich)
  • 7aa4767 Add new translations to locales file (@kostich)
  • 635abb7 Update po/sr.po (@kostich)
  • e8ba5d2 Standardize how config/setting/preference is translated (@kostich)
  • 1ae448c Fix translation of sequences (@kostich)
  • 2a0371b Apply batched suggestions from code review (@kostich)
  • 17a2474 Use the correct accusative form for inanimata (@kostich)
  • e3969ab Align translations for current and to left/right (@kostich)
  • 84c8e7d Align translation for Focus (@kostich)
  • a542359 libghostty: use caller allocation on native freestanding (@Uzaaft)
    Native freestanding targets have neither an OS page allocator nor a usable default SMP allocator. Use the allocator supplied through libghostty for terminal page storage and make a missing C allocator fail with out-of-memory instead of instantiating hosted allocation machinery. Document that native freestanding C callers must supply an allocator for allocating operations.
    
  • 3376153 build: support native freestanding libghostty-vt (@Uzaaft)
    Native freestanding targets cannot emit shared libraries and do not provide an OS page size, stack unwinder, hosted SIMD dependencies, or filesystem-backed Kitty graphics. Build only the static artifact for those targets, define the minimum alignment used for terminal pages, disable hosted-only defaults, and install the public headers with the archive.
    
  • 10b7158 ci: cross-compile freestanding libghostty-vt (@Uzaaft)
  • fc7bfa6 ci: move freestanding build into test workflow (@Uzaaft)
  • 028af92 terminal: clarify page allocator fallback (@Uzaaft)
  • e8709b1 Merge remote-tracking branch 'upstream/main' into add-serbian-translation (@kostich)
  • 90f7759 Fix HTML/URL acronyms as agreed (@kostich)
  • 8bf7e51 Regenerate sr@latin.po from sr.po (@kostich)
  • 5e02d00 ci: require freestanding libghostty-vt builds (@Uzaaft)
  • 458f079 Use the informal form (@kostich)
  • 2c854a1 freestanding support (#14076) (@mitchellh)
  • 149c9f5 terminal: extract whole-terminal search orchestration from the search thread (@mitchellh)
  • 32601cd terminal/c: add search wrapper implementing the whole-terminal search API (@mitchellh)
  • cdef14a Remove X-Generator from the sr.po file (@kostich)
  • f0c918f terminal/c: allow freeing a search and its terminal in any order (@mitchellh)
  • f920291 libghostty: add ghostty_search_* terminal search C API (@mitchellh)
  • 674abd8 example: add c-vt-search demonstrating the terminal search C API (@mitchellh)
  • 76d9fce libghostty: set the search needle via ghostty_search_set, drop GhosttySearchOptions (@mitchellh)
  • 4b51f52 libghostty: add terminal search API (#14097) (@mitchellh)
    This exposes the terminal search API through libghostty C and Zig APIs.
    
    This was previously available through the Zig APIs but forced our
    threading model. I've now extracted the full terminal search state to a
    new `terminal.search.TerminalSearch` structure so threading isn't
    forced. The C API is completely new.
    
    ## Example (C)
    
    ```c
    GhosttySearch search;
    ghostty_search_new(NULL, &search, terminal);
    
    GhosttyString needle = { (const uint8_t *)"error", 5 };
    ghostty_search_set(search, GHOSTTY_SEARCH_OPT_NEEDLE, &needle);
    ghostty_search_run(search);
    
    // Find bar chrome: "k of n"
    size_t total, idx;
    ghostty_search_get(search, GHOSTTY_SEARCH_DATA_TOTAL_MATCHES, &total);
    
    // Enter: select the next match (wraps, scrolls the viewport if needed)
    ghostty_search_set(search, GHOSTTY_SEARCH_OPT_SELECT_NEXT, NULL);
    ghostty_search_get(search, GHOSTTY_SEARCH_DATA_SELECTED_INDEX, &idx);
    
    ghostty_search_free(search);
    ```
    
  • 8168115 Add Serbian translation (#13842) (@00-kat)
    ## Summary
    - Adds Serbian translations for both Cyrillic (`sr`) and Latin
    (`sr@latin`) scripts, registered in `src/os/i18n_locales.zig` and
    `CODEOWNERS`.
    - `po/sr@latin.po` is generated from `po/sr.po` with `msgfilter
    recode-sr-latin` and should not be translated by hand.
    - Replaces the closed #13030; strings are rebased onto current `main`.
    
    Cc @slowdub for a review.
    
    EDIT: AI disclosure: I used Cursor (Grok 4.6) for mechanical repo work
    only, not for writing the Serbian translations. The agent fetched
    ghostty-org/ghostty, branched from current main, ran msgmerge on
    po/sr.po against the template, generated po/sr@latin.po with msgfilter
    recode-sr-latin, registered sr / sr@latin in src/os/i18n_locales.zig and
    CODEOWNERS, rebased my three commits onto later main, pushed the branch,
    and opened this PR (I had intended to open the PR myself, s***** thing
    ignored my instructions). I translated and reviewed sr.po and the Latin
    file is a recode of that catalog, not a separate translation since
    Serbian Cyrillic can be perfectly transcoded to the Latin script via
    [recode-sr-latin](https://linux.die.net/man/1/recode-sr-latin).
    
  • d23af9e Merge branch 'ghostty-org:main' into main (@mohshami)
  • 80b8e49 Merge branch 'ghostty-org:main' into main (@mohshami)
  • 5546750 Merge branch 'ghostty-org:main' into main (@mohshami)
  • 1510d2b Merge branch 'ghostty-org:main' into main (@mohshami)
  • b5817a3 Merge branch 'ghostty-org:main' into main (@mohshami)
  • f6244f7 Merge branch 'ghostty-org:main' into main (@mohshami)
  • 320ba75 Merge branch 'ghostty-org:main' into main (@mohshami)
  • 1054be4 Merge branch 'ghostty-org:main' into main (@mohshami)
  • 6758251 Merge branch 'ghostty-org:main' into main (@mohshami)
  • 768bc2e Merge branch 'ghostty-org:main' into main (@mohshami)
  • 4c696b9 Merge branch 'ghostty-org:main' into main (@mohshami)
  • 9af9348 Merge from upstream (@mohshami)
  • 58f43d5 Merge branch 'ghostty-org:main' into main (@mohshami)
  • c8c4526 Merge branch 'ghostty-org:main' into main (@mohshami)
  • 81d28be Merge branch 'ghostty-org:main' into main (@mohshami)
  • 5f54958 terminal: fix living item over-count in RefCountedSet.addWithId (@mitchellh)
    Reported in https://github.com/ghostty-org/ghostty/discussions/14064
    
    I validated this myself manually. The zero-ref branch of `addWithIdContext`
    incremented `living` unconditionally even if `upsert` resolved the value
    to an item that was already alive under a different ID.
    
    This would cause `living` to be invalid for each time this happened and
    the downstream effect was that `count()` drifted. I couldn't find any
    crashing or invalid effect except that this caused requested style memory
    to be over-provisioned.
    
  • abac4c2 Merge branch 'ghostty-org:main' into main (@mohshami)
  • 0dc2032 Merge branch 'ghostty-org:main' into main (@mohshami)
  • 0254a7f Merge branch 'ghostty-org:main' into main (@mohshami)
  • dfccdb2 Implement needed modifications for issue #12600 (@mohshami)
    For middle-click-action
    * Kept the option "primary-paste" instead of "paste-primary" to keep
    backwards compatibility
    * Added the option "clipboard-paste"
    
    For copy-on-select
    * Added the both, none and primary options
    
    Updated config documentation
    
    Run zig fmt
    
    Move true/false options for copy-on-select to the compatibility handler
    
    Update src/config/Config.zig
    
    
    Update src/config/Config.zig
    
    
    Update src/config/Config.zig
    
    
    Update src/config/Config.zig
    
    
    Update src/config/Config.zig
    
    
    Update src/config/Config.zig
    
    
    Update src/Surface.zig
    
    
    Update src/Surface.zig
    
    
    Update src/config/Config.zig
    
    
    Update src/config/Config.zig
    
    
    Update src/config/Config.zig
    
    
    Update src/config/Config.zig
    
    
    Update src/config/Config.zig
    
    
    Update src/Surface.zig
    
    
    Update src/Surface.zig
    
    
    Reorder switch items
    
    Apply comment from kat
    
    Remove redundent code
    
  • e80ce2e Fix build error (@mohshami)
  • f6113ea Implement needed modifications for issue #12600, more flexible copy-on-select and middle-click-action (#12604) (@mitchellh)
    For middle-click-action
    * Kept the option "primary-paste" instead of "paste-primary" to keep
    backwards compatibility
    * Added the option "clipboard-paste"
    
    For copy-on-select
    * Added the both, none and primary options
    
    Updated config documentation
    
    Note: No AI was used, Even though I don't know Zig, I looked at the code
    and the modifications seemed easy enough
    
    Closes #12600
    
  • c290639 terminal: fix living item over-count in RefCountedSet.addWithId (#14081) (@mitchellh)
    Reported in https://github.com/ghostty-org/ghostty/discussions/14064
    
    I validated this myself manually. The zero-ref branch of
    `addWithIdContext` incremented `living` unconditionally even if `upsert`
    resolved the value to an item that was already alive under a different
    ID.
    
    This would cause `living` to be invalid for each time this happened and
    the downstream effect was that `count()` drifted. I couldn't find any
    crashing or invalid effect except that this caused requested style
    memory to be over-provisioned.
    
    cc @qwerasd205 since its ref counted set, but I did this work manually
    ❤️
    
  • 0525c18 i18n: adjust and extend Ukrainian translation (@chernetskyi)
  • c50288c i18n: address comments for Ukrainian translation (@chernetskyi)
  • 2a51bdf i18n: return Ghostty to Ukrainian translation (@chernetskyi)
  • 1026a00 i18n: adjust Ukrainian translations (@chernetskyi)
  • d4d8f62 i18n: adjust and extend Ukrainian translation (#13854) (@trag1c)
  • e8aa098 Update VOUCHED list (#14092) (@ghostty-vouch[bot])
    Triggered by [discussion
    comment](https://github.com/ghostty-org/ghostty/discussions/14091#discussioncomment-18212381)
    from @pluiedev.
    
    Denounce: @thomas-trijindev
    
  • ec3e384 Sync CODEOWNERS vouch list (#14090) (@ghostty-vouch[bot])
    Sync CODEOWNERS owners with vouch list.
    
    ## Added Users
    
    - @jakeriksen
    - @Kleshzz
    

August 30, 2026

Runs: 1, 2, 3, 4, 5, 6
Summary: 6 runs • 15 commits • 7 authors

Changes

  • c181983 build: update Sparkle to 2.9.6 and pin SPM (@bo2themax)
  • 7fd93e0 build: update Sparkle to 2.9.6 and pin SPM (#14082) (@mitchellh)
  • 3e2c0fa gtk: do not warn when gtk-xft-dpi is -1 (@mgsloan)
    Before this change, ghostty frequently logs the following warning, even though a `gtk-xft-dpi` value of `-1` is valid and indicates default scaling.
    
    ```
    warning(gtk_ghostty_surface): gtk-xft-dpi has invalid value (-1), using default
    ```
    
    From [the gtk docs](https://docs.gtk.org/gtk4/property.Settings.gtk-xft-dpi.html):
    
    > The font resolution, in 1024 * dots/inch.
    >
    > -1 to use the default value.
    
  • 860cfb1 Address review feedback (@mgsloan)
  • 8af6897 gtk: do not warn when gtk-xft-dpi is -1 (#14085) (@jcollie)
    Before this change, ghostty frequently logs the following warning, even
    though a `gtk-xft-dpi` value of `-1` is valid and indicates default
    scaling.
    
    ```
    warning(gtk_ghostty_surface): gtk-xft-dpi has invalid value (-1), using default
    ```
    
    From [the gtk
    docs](https://docs.gtk.org/gtk4/property.Settings.gtk-xft-dpi.html):
    
    > The font resolution, in 1024 * dots/inch.
    >
    > -1 to use the default value.
    
  • 6d850fe Update VOUCHED list (#14084) (@ghostty-vouch[bot])
    Triggered by [discussion
    comment](https://github.com/ghostty-org/ghostty/discussions/14083#discussioncomment-18204946)
    from @jcollie.
    
    Vouch: @mgsloan
    
  • 97f57ed renderer: vsync unfocused surfaces while dirty (@j-c-m)
    6ae1784f4
    
    Unfocused surfaces stopped the CVDisplayLink and encoded a GPU
    frame on every PTY wakeup. A burst of close writes became that many
    Metal submits instead of one vsync.
    
    Keep the link running while the surface is visible and dirty or
    animating, whether or not it is focused. Idle surfaces still park.
    Focus continues to gate cursor blink, custom-shader animation, and
    QoS.
    
  • 166d2fe build: update Sparkle to 2.9.4 (@Svector-anu)
  • 090fca4 terminal/kitty: validate POSIX shared memory names (@mitchellh)
    Update shared memory name validation according to the new spec:
    
    https://github.com/kovidgoyal/kitty/commit/22042970cf3a4668d02a1a7bcccca778ec864c21
    
  • 7035647 build: update Sparkle to 2.9.4 (#14072) (@mitchellh)
    Update the macOS Sparkle dependency from 2.9.0 to 2.9.4.
    
    This keeps the Swift package resolution and all tag/tip release workflow
    downloads aligned on the same version. Sparkle 2.9.2 included fixes for
    GHSA-g3hp-f6mg-559v and GHSA-hg88-v3cw-3qrh; 2.9.4 is the current stable
    release.
    
    Validation:
    - verified the 2.9.4 release contains
    `Sparkle-for-Swift-Package-Manager.zip`
    - verified the lockfile revision matches the 2.9.4 tag
    - `jq empty` on `Package.resolved`
    - `git diff --check`
    
    I could not run Xcode package resolution locally because the active
    developer directory is Command Line Tools rather than a full Xcode
    installation.
    
  • ec7929c terminal/kitty: validate POSIX shared memory names (#14080) (@mitchellh)
    Update shared memory name validation according to the new spec:
    
    
    https://github.com/kovidgoyal/kitty/commit/22042970cf3a4668d02a1a7bcccca778ec864c21
    
  • 83c5671 renderer: vsync unfocused surfaces while dirty (#14068) (@mitchellh)
    A follow on for #14035, we can now fix a long standing
    effiency/performance bug now that we park the display link while idle.
    This actually could cause "animated" un-focused windows to use more GPU
    than their focused counterparts. (AI Agent interfaces seem to love
    animation).
    
    6ae1784f4
    
    Unfocused surfaces stopped the CVDisplayLink and encoded a GPU frame on
    every PTY wakeup. A burst of close writes became that many Metal submits
    instead of one vsync.
    
    Keep the link running while the surface is visible and dirty or
    animating, whether or not it is focused. Idle surfaces still park.
    
  • 98cd670 Update VOUCHED list (#14079) (@ghostty-vouch[bot])
    Triggered by [discussion
    comment](https://github.com/ghostty-org/ghostty/discussions/14078#discussioncomment-18203195)
    from @jcollie.
    
    Vouch: @and-rs
    
  • 094d175 deps: Update iTerm2 color schemes (@mitchellh)
  • 0a76c31 Update iTerm2 colorschemes (#14077) (@jcollie)
    Upstream release:
    https://github.com/mbadolato/iTerm2-Color-Schemes/releases/tag/release-20260824-153547-75c93ee
    

August 29, 2026

Runs: 1, 2
Summary: 2 runs • 5 commits • 3 authors

Changes

  • 7b47213 Update VOUCHED list (#14074) (@ghostty-vouch[bot])
    Triggered by
    [comment](https://github.com/ghostty-org/ghostty/issues/14072#issuecomment-5463405035)
    from @bo2themax.
    
    Vouch: @Svector-anu
    
  • 6cd684d gtk: fix stale pointers to property bindings (@dkinzler)
    Previously, the property binding created in `Surface.bindIsSplit` would
    get freed automatically when the source object (the SplitTree widget)
    got finalized. A subsequent call to `bindIsSplit` could then cause a
    crash by using the stale pointer to the binding. This bug could e.g. be
    triggered by dragging the surface from a single-surface tab to another
    tab.
    
    We now create an extra reference to the binding object so that Surface
    essentially owns the binding and is responsible for freeing it.
    
    Updated the binding in `SurfaceScrolledWindow` to use the same pattern.
    That one was probably fine, because the binding is only created once,
    but let's be safe.
    
  • caf48a4 main: fix inverted allow_stack_tracing condition (@jcollie)
    The Zig 0.16.0 update dropped the negation from the std default
    (!strip_debug_info), disabling stack traces in every unstripped build.
    
    AI disclosure: Claude Fable was used to diagnose the problem and find the
    fix. Commit message was written by me.
    
    Claude-Session: https://claude.ai/code/session_01QfzQME46DQXwMWa43bQaa3
    
  • 069497e gtk: fix stale pointers to property bindings (#14065) (@jcollie)
    Fixes #14037 where dragging the surface from a tab with just a single
    surface to another tab causes a crash.
    
    The cause of the crash is a stale pointer to the property binding
    created in `Surface.bindIsSplit`. When the surface is moved,
    `SplitTree.moveSplit` first updates the two split tree data structures
    of the source/target tab and then calls `bindIsSplit` to bind the
    `is-split` property of the moved surface to the `SplitTree` widget in
    the target tab. When `bindIsSplit` is called, the `SplitTree` widget in
    the source tab has already been destroyed (because the source tab is now
    empty) which causes the old binding to be freed automatically and the
    pointer `Surface.is_split_binding` becomes stale. `bindIsSplit` then
    tries to run `is_split_binding.unbind()` which causes the crash.
    
    When you create a binding with `bindProperty`, the binding itself owns
    the initially created reference and it gets freed when the source or
    target object of the binding is finalized. To prevent this, we now
    create an extra reference to the binding object so that the Surface
    widget owns it and is responsible for freeing it. The binding can still
    get severed automatically, but the binding object itself will not be
    destroyed. This is the solution mentioned in the [GObject
    docs](https://docs.gtk.org/gobject/method.Object.bind_property.html).
    Alternatively, using a WeakRef for the pointer would have also worked.
    
    Updated the binding in `SurfaceScrolledWindow` to use the same pattern.
    That one was probably fine, because the binding should only be created
    once, but it doesn't hurt to be safe.
    
    I reproduced the crash on KDE, on Hyprland I just got a glib critical
    error message about the invalid pointer. That probably has to do with
    what exactly happens to the freed memory, or maybe differing versions.
    
    #### AI Disclosure
    
    Code and comments were written by myself, used GPT5.6 in researching
    gobject binding lifecycles.
    
  • 3baff3a main: fix inverted allow_stack_tracing condition (#14069) (@jcollie)
    The Zig 0.16.0 update dropped the negation from the std default
    (!strip_debug_info), disabling stack traces in every unstripped build.
    
    AI disclosure: Claude Fable was used to diagnose the problem and find
    the fix. Commit message was written by me.
    
    
    Claude-Session: https://claude.ai/code/session_01QfzQME46DQXwMWa43bQaa3
    

August 28, 2026

Runs: 1, 2
Summary: 2 runs • 4 commits • 3 authors

Changes

  • 777929a macOS: review windows when closing multiple tabs (@bo2themax)
  • 4540d49 macOS: review windows when closing multiple tabs (#14062) (@mitchellh)
    We can also make close undoable when quitting, i'll add it as a follow
    up pr.
    
    <img width="573" height="450" alt="Xnip2026-08-28_19-25-02"
    src="https://github.com/user-attachments/assets/3b4f34f4-9ee6-4180-beb7-f90e98c8aa40"
    />
    
  • eb722cb terminal: mark the previous row dirty when clearing its spacer head (@fornwall)
    Erasing a wrapped wide character at the start of a row (ECH or DCH)
    also clears the spacer head it left at the end of the previous row,
    but that row was never marked dirty. With both rows visible, an
    incremental render kept the stale spacer head on screen until
    something unrelated redrew that row.
    
    The clearing happens in the row-start branch of splitCellBoundary.
    clearCells doesn't do dirty tracking, and both callers only mark
    the cursor row, so mark the previous row at the point it's mutated.
    
    The added dirty assertions fail without the fix.
    
  • 76e568b terminal: mark the previous row dirty when clearing its spacer head (#14054) (@mitchellh)
    Erasing a wrapped wide character at the start of a row (`ECH` or `DCH`)
    also clears the spacer head it left at the end of the previous row, but
    that row was never marked dirty. With both rows visible, an incremental
    render kept the stale spacer head on screen until something unrelated
    redrew that row.
    
    The clearing happens in the row-start branch of `splitCellBoundary`.
    `clearCells` doesn't do dirty tracking, and both callers only mark the
    cursor row, so mark the previous row at the point it's mutated.
    
    The added dirty assertions fail without the fix.
    
    ## AI Disclaimer
    Claude did the heavy lifting - identifying the root cause, generating
    code and description. I reviewed and iterated on it to move around and
    tweak tests, comments and reduce verboseness. Verified the end user
    visible behaviour improvement with a script that coloured the wide
    character, which made the stale rendering visible until a switch to the
    alt screen and back cleared it it.
    

About

A friendly changelog for Ghostty’s tip (nightly) version releases

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages