Commit Graph

12716 Commits (macos-disclaim)

Author SHA1 Message Date
Mitchell Hashimoto 17775fa857
update comments 2025-10-19 13:22:18 -07:00
Mitchell Hashimoto 5156723070
termio: posix_spawn based process launching 2025-10-19 13:09:54 -07:00
Mitchell Hashimoto 633bf5f021
cli: _macos-disclaim 2025-10-19 13:09:54 -07:00
Mitchell Hashimoto 73158249e3
termio: use a union to represent how a process is started 2025-10-19 13:09:54 -07:00
Mitchell Hashimoto 6af40f8783
os: posix spawn API 2025-10-19 13:09:54 -07:00
Mitchell Hashimoto be608ea2d1
renderer: don't allow the scrollbar state to block the renderer (#9270)
This fixes the source of a deadlock that some tip users have hit. If our
surface mailbox is full and there is a dirty scrollbar state, then
drawFrame would block forever trying to queue to the surface mailbox.

We now fail instantly if the queue is full and keep the scrollbar state
dirty. We can try again on the next frame, it's not a critical thing to
get updated.
2025-10-18 21:34:27 -07:00
Mitchell Hashimoto 3a9eedcd15
renderer: don't allow the scrollbar state to block the renderer
This fixes the source of a deadlock that some tip users have hit. If our 
surface mailbox is full and there is a dirty scrollbar state, then
drawFrame would block forever trying to queue to the surface mailbox.

We now fail instantly if the queue is full and keep the scrollbar state
dirty. We can try again on the next frame, it's not a critical thing to
get updated.
2025-10-18 21:30:11 -07:00
tdslot be0da4845c
🌐 i18n(locale): add lithuanian language support (#8711)
Co-authored-by: Andrius Budvytis <154380884+abudvytis@users.noreply.github.com>
2025-10-18 19:27:39 +02:00
Mitchell Hashimoto dffa4f4fc7
macos: use stable display UUID for quick terminal screen tracking (#9256)
NSScreen instances can be garbage collected at any time, even for
screens that remain connected, making NSMapTable with weak keys
unreliable for tracking per-screen state.

This changes the quick terminal to use CGDisplay UUIDs as stable
identifiers, keyed in a strong dictionary. Each entry stores the window
frame along with screen dimensions, scale factor, and last-seen
timestamp.

**This should make quick terminal size restore more stable than 1.2.2.**

Rules for pruning:
- Entries are invalidated when screens shrink or change scale
- Entries persist and update when screens grow (allowing cached state to
work with larger resolutions)
- Stale entries for disconnected screens expire after 14 days.
- Maximum of 10 screen entries to prevent unbounded growth
2025-10-17 21:14:56 -07:00
Mitchell Hashimoto ea505ec51d
macos: use stable display UUID for quick terminal screen tracking
NSScreen instances can be garbage collected at any time, even for
screens that remain connected, making NSMapTable with weak keys
unreliable for tracking per-screen state.

This changes the quick terminal to use CGDisplay UUIDs as stable
identifiers, keyed in a strong dictionary. Each entry stores the
window frame along with screen dimensions, scale factor, and last-seen
timestamp.

Rules for pruning:
- Entries are invalidated when screens shrink or change scale
- Entries persist and update when screens grow (allowing cached state
  to work with larger resolutions)
- Stale entries for disconnected screens expire after 14 days.
- Maximum of 10 screen entries to prevent unbounded growth
2025-10-17 21:04:23 -07:00
Mitchell Hashimoto 3e6bda1fff
ci: run release-tip even if prior step failed 2025-10-17 21:03:23 -07:00
Mitchell Hashimoto 5bf05dfe31
macos: make terminal smaller to account for legacy scrollbar (#9255)
https://github.com/ghostty-org/ghostty/discussions/9254

When the preferred scrollbar style is "legacy", the scrollbar takes up
space that offsets the actual terminal. To prevent reflow, we detect
this before the scrollbar becomes visible and shrink our terminal width
to prepare for it.

This doesn't account for the style changing at runtime, yet.

## Demo

Notice even before scrollbars, the `gh` output doesn't wrap.


https://github.com/user-attachments/assets/8716ff4d-0660-48b1-aadb-0d31e0b70fcd
2025-10-17 20:18:10 -07:00
Mitchell Hashimoto 5b7f145640
macos: make terminal smaller to account for legacy scrollbar
When the preferred scrollbar style is "legacy", the scrollbar takes up
space that offsets the actual terminal. To prevent reflow, we detect
this before the scrollbar becomes visible and shrink our terminal width
to prepare for it.

This doesn't account for the style changing at runtime, yet.
2025-10-17 20:08:03 -07:00
Mitchell Hashimoto e4db7f5487
font: Default to light hinting in FreeType (#9253)
This changes the default FreeType load target to `FT_LOAD_TARGET_LIGHT`,
giving the hinter a lighter touch in line with the default behavior in
most other GTK apps, and adds a load flag such that the old hinting
behavior can be restored via config.

As discussed in
https://github.com/ghostty-org/ghostty/issues/8674#issuecomment-3417082534.
However, this doesn't close that issue, as it still doesn't respect
custom Fontconfig settings. It's just a stopgap solution bringing
Ghostty's defaults more in line with the typical results of not
customizing Fontconfig.
2025-10-17 17:14:57 -07:00
Daniel Wennberg ad9f9dc11e font: Default to light hinting in FreeType 2025-10-17 15:04:04 -07:00
Mitchell Hashimoto 3b8e683d96
renderer: force a full rebuild on any font grid change (#9252)
Fixes #2731 (again)

This regressed in 1.2 due to the renderer rework missing porting this. I
believe this issue is still valid even with the rework since the font
grid changes the atlas and if there are still cached cells that
reference the old atlas coordinates it will produce garbage.
2025-10-17 14:51:30 -07:00
Mitchell Hashimoto 1cc22f93ca
renderer: force a full rebuild on any font grid change
Fixes #2731 (again)

This regressed in 1.2 due to the renderer rework missing porting this. I
believe this issue is still valid even with the rework since the font
grid changes the atlas and if there are still cached cells that
reference the old atlas coordinates it will produce garbage.
2025-10-17 14:46:58 -07:00
Mitchell Hashimoto 063070915f
gtk: Scrollbars (#9245)
Fixes #111 

This builds on the prior work and adds scrollbars to the GTK
application. After this PR, both the macOS and GTK applications support
scrollbars and #111 can be closed.

## TODO

- [x] Verify that with text coming out if we manually scroll to the
bottom we bind to the bottom
- [x] Valgrind checks
2025-10-17 09:21:57 -07:00
Mitchell Hashimoto ed443bc6ed
gtk: Scrollbars 2025-10-17 09:19:02 -07:00
Mitchell Hashimoto a2e95ce7b5
macOS: Remove hidden titlebar safe area and pad document height in SurfaceScrollView (#9241)
Fixes #9233. The issue was that the content view was effectively
truncated by `SurfaceScrollView`s safe area insets covering the titlebar
(I suppose the scroll view doesn't inherit the `ignoresSafeArea`
modifier on `TerminalSplitTreeView` because it's not actually a node in
that tree, it just contains a subview that is). I think it's OK to zero
these insets unconditionally, as I don't think the frame size passed
down from `SurfaceWrapper` will ever overlap with a visible titlebar.

This PR also fixes a somewhat related issue I discovered along the way.
In many cases, the mouse wouldn't work on the first row of text, whether
trying to select text or interact with TUI elements like neovim
bufferlines/tablines. When looking at the inspector while moving the
mouse around, you'd see the mouse position jump discontinuously from a
y-coordinate of 10-20 pixels to -3, i.e., no longer within the surface.

The problem turned out to be that the height of the document view only
included the text lines, not the window padding, while the content view
is sized to the surface including padding. If you imagine the
metaphorical sliding of the viewport up and down the document, and you
require the text to snap to a fixed grid on the viewport, it's clear
that the document must have the same top and bottom padding as the
viewport, otherwise the math breaks at the ends. Sure enough, adding
this padding fixed the problem.

To properly reproduce these issues and see the effect of the fixes, it's
helpful to change the system settings to always show scroll bars
(Appearance -> Show scroll bars -> Always). That's what connecting an
external mouse was all about. You should also remove the debug banner or
use a release build, otherwise the banner takes the place of the hidden
titlebar and conceals the issue.
2025-10-17 06:34:25 -07:00
Daniel Wennberg 51b2374616 Add window padding to scrollView document height 2025-10-17 00:14:21 -07:00
Daniel Wennberg ffead466c7 Remove hidden titlebar safe area for SurfaceScrollView 2025-10-17 00:06:00 -07:00
Mitchell Hashimoto 58699c7992
macOS: remove background from SurfaceScrollView (#9234)
<img width="1157" height="126" alt="image"
src="https://github.com/user-attachments/assets/07f67e6c-76b3-4d7d-ba44-37e85b8660cc"
/>
2025-10-16 14:56:47 -07:00
Lars cc91e2ad16
macOS: remove background from SurfaceScrollView 2025-10-16 23:52:07 +02:00
Mitchell Hashimoto 0e0bbfaa61
macOS: Scrollbars (#9232)
Completes #111 for macOS

This builds on #9225 and adds the native, macOS GUI scrollbars for
terminals.

This doesn't do GTK, but all the groundwork is there to make this easy
on GTK, depending on how scrollviews work there. I have to look into
that still. But in theory all the information and controls we provide
out of core are generic to _any_ scrollbar drawing.

## Demo


https://github.com/user-attachments/assets/85683bf9-1117-4f32-aaec-d926edd68c39

## Details

- The scrollbars respect your macOS system settings on style, color,
visibility.
- A new configuration `scrollbar` controls whether scrollbars are
visible (defaults to `system` allowing the system to choose).
- There is a new keybind action `scroll_to_row:N` that lets you jump to
an absolute row number N. This is implemented efficiently. This is how
grabbing the knob and scrolling works.
2025-10-16 14:09:33 -07:00
Mitchell Hashimoto 4b34b2389a
config: add `scrollbar` config to control when scrollbars appear 2025-10-16 14:06:48 -07:00
Mitchell Hashimoto 7207ff08d5
macos: SurfaceScrollView 2025-10-16 14:06:46 -07:00
Mitchell Hashimoto 2937aff513
gtk: mark scrollbar as unimplemented 2025-10-16 09:36:47 -07:00
Mitchell Hashimoto c86266cd90
input: scroll_to_row action 2025-10-16 09:11:03 -07:00
Mitchell Hashimoto 135136f733
terminal: PageList scroll to absolute row function 2025-10-16 09:11:03 -07:00
Mitchell Hashimoto da7736cd44
renderer: emit scrollbar apprt event when scrollbar changes 2025-10-15 21:45:01 -07:00
Mitchell Hashimoto 5a9bd0e49e
snap: update to Zig 0.15.2 2025-10-15 20:04:37 -07:00
dependabot[bot] 3ffbd87a0f
build(deps): bump cachix/install-nix-action from 31.8.0 to 31.8.1 (#9226)
Bumps
[cachix/install-nix-action](https://github.com/cachix/install-nix-action)
from 31.8.0 to 31.8.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/cachix/install-nix-action/releases">cachix/install-nix-action's
releases</a>.</em></p>
<blockquote>
<h2>v31.8.1</h2>
<h2>What's Changed</h2>
<ul>
<li>nix: 2.32.0 -&gt; 2.32.1 by <a
href="https://github.com/github-actions"><code>@​github-actions</code></a>[bot]
in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/258">cachix/install-nix-action#258</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/cachix/install-nix-action/compare/v31...v31.8.1">https://github.com/cachix/install-nix-action/compare/v31...v31.8.1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fd24c48048"><code>fd24c48</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/258">#258</a>
from cachix/create-pull-request/patch</li>
<li><a
href="a55fd2d847"><code>a55fd2d</code></a>
nix: 2.32.0 -&gt; 2.32.1</li>
<li>See full diff in <a
href="7ab6e7fd29...fd24c48048">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=cachix/install-nix-action&package-manager=github_actions&previous-version=31.8.0&new-version=31.8.1)](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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-15 19:43:35 -07:00
dependabot[bot] 123d23682a
build(deps): bump namespacelabs/nscloud-setup-buildx-action from 0.0.19 to 0.0.20 (#9227)
Bumps
[namespacelabs/nscloud-setup-buildx-action](https://github.com/namespacelabs/nscloud-setup-buildx-action)
from 0.0.19 to 0.0.20.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/namespacelabs/nscloud-setup-buildx-action/releases">namespacelabs/nscloud-setup-buildx-action's
releases</a>.</em></p>
<blockquote>
<h2>v0.0.20</h2>
<h2>What's Changed</h2>
<ul>
<li>Add wait-for-builder input to eagerly start build clusters and wait
for them by <a
href="https://github.com/annervisser"><code>@​annervisser</code></a> in
<a
href="https://redirect.github.com/namespacelabs/nscloud-setup-buildx-action/pull/11">namespacelabs/nscloud-setup-buildx-action#11</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/annervisser"><code>@​annervisser</code></a>
made their first contribution in <a
href="https://redirect.github.com/namespacelabs/nscloud-setup-buildx-action/pull/11">namespacelabs/nscloud-setup-buildx-action#11</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/namespacelabs/nscloud-setup-buildx-action/compare/v0...v0.0.20">https://github.com/namespacelabs/nscloud-setup-buildx-action/compare/v0...v0.0.20</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="91c2e65377"><code>91c2e65</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-setup-buildx-action/issues/11">#11</a>
from namespacelabs/add-wait-for-builder-input-to-eager...</li>
<li><a
href="459dd43ae1"><code>459dd43</code></a>
Add wait-for-builder input to eagerly start build clusters and wait for
them</li>
<li>See full diff in <a
href="7020d7d8e6...91c2e65377">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=namespacelabs/nscloud-setup-buildx-action&package-manager=github_actions&previous-version=0.0.19&new-version=0.0.20)](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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-15 19:43:22 -07:00
Mitchell Hashimoto e1b527fb9a
core: PageList tracks minimum metadata for rendering a scrollbar (#9225)
Related to #111

This adds the necessary logic and data for the `PageList` data structure
to keep track of **total length** of the screen, **offset** into the
viewport, and **length** of the viewport. These three values are
necessary to _render_ a scrollbar. This PR updates the renderer to grab
this information but stops short of actually drawing a scrollbar (which
we'll do with native UI), in the interest of having a PR that doesn't
contain too many changes.

**This doesn't yet draw a scrollbar, these are just the internal changes
necessary to support it.**

## Background

The `PageList` structure is very core to how we represent terminal
state. It maintains a doubly linked list of "pages" (not literally
virtual memory pages, but close). Each page stores cell information,
styles, hyperlinks, etc fully self-contained in a contiguous sets of VM
pages using offset addresses rather than full pointers. **Pages are not
guaranteed to be equal sizes.** (This is where scrollbars get difficult)

Because it is a linked list structure of non-equal sized nodes, it isn't
amenable to typical scrollbar behavior. A scrollbar needs to know: full
size, offset, and length in order to draw the scrollbar properly.
Getting these values naively is `O(N)` within the data structure that is
on the hottest IO performance path in all of Ghostty.

## Implementation

### PageList

We now maintain two cached values for **total length** and **viewport
offset**.

The total length is relatively straightforward, we just have to be
careful to update it in every operation that could add or remove rows.
I've done this and ensured that every place we update it is covered with
unit test coverage.

The viewport offset is nasty, but I came up with what I believe is a
good solution. The viewport when arbitrarily scrolled is defined as a
direct pointer to the linked list node plus a row offset into that node.
The only way to calculate offset from the top is `O(N)`.

But we have a couple shortcuts:

1. If the viewport is at the bottom (most common) or top, calculating
the offset is `O(1)`: bottom is `total_rows - active_rows`, both readily
available. And top is `0` by definition.

2. Operations on the PageList typically add or remove rows. We don't do
arbitrary linked list surgery. If we instrument those areas with delta
updates to our cache, we can avoid the `O(N)` cost for most operations,
including scrolling a scrollbar. The only expensive operation is a full,
arbitrary jump (new node pointer).

Point 1 was quick to implement, so I focused all the complexity on point
2. Whenever we have an operation that adds or removes rows (for example
pruning the scroll back, adding more, erase rows within the active area,
etc.) then I do the math to calculate the delta change required for the
offset if we've already calculated it, and apply that directly.

### Renderer

The other issue was how to notify the apprts of scrollbar state. Sending
messages on any terminal change within the IO thread is a non-option
because (1) sending messages is slow (2) the terminal changes a lot and
(3) any slowness in the IO thread slows down overall terminal
throughput.

The solution was to **trigger scrollbar notifications with the renderer
vsync**. We read the scrollbar information when we render a frame,
compare it to renderer previous state, and if the scrollbar changed,
send a message to the apprt _after the frame is GPU-renderer_.

The renderer spends _most_ of its time sleeping compared to the IO
thread, and has more opportunities for optimizing its awake time.
Additionally, there's no reason to update the scrollbar information if
the renderer hasn't rendered the new frames because the user can't even
see the stuff the scrollbar wants to scroll to. We're talking about
millisecond scale stuff here at worst but it adds up.

## Performance

No noticeable performance impact for the additional metrics:

<img width="1012" height="738" alt="image"
src="https://github.com/user-attachments/assets/4ed0a3e8-6d76-40c1-b249-e34041c2f6fd"
/>

## AI Usage

I used Amp to help audit the codebase and write tests. I wrote all the
main implementation code manually. I came up with the main design
myself. Relevant threads:

-
https://ampcode.com/threads/T-95fff686-75bb-4553-a2fb-e41fe4cd4b77#message-0-block-0
-
https://ampcode.com/threads/T-48e9a288-b280-4eec-83b7-ca73d029b4ef#message-91-block-0

## Future

This is just the internal changes necessary to _draw_ a scrollbar. There
will be other changes we'll need to add to handle grabbing and actually
jumping the scrollbar. I have a good idea of how to implement those
performantly as well.
2025-10-15 19:42:49 -07:00
Mitchell Hashimoto 014a2e0042
termio: color change operations must gracefully handle renderer mailbox full (#9224)
Fixes #9191

This changes our color change operations from writing to the renderer
mailbox directly to using our `rendererMailboxWriter` function which
handles the scenario where the mailbox is full by yielding the lock,
waking up the renderer, and retrying later.

This is a known deadlock scenario we've worked around since the private
beta days, but unfortunately this slipped through and I didn't catch it
in review.

What happens here is it's possible with certain escape sequences for the
IO thread to saturate other mailboxes with messages while holding the
terminal state lock. This can happen to any thread. This ultimately
leads to starvation and all threads deadlock.

Our IO thread is the only thread that produces this kind of massive
stream of events while holding the lock, so we have helpers in it to
attempt to queue (cheap, fast) and if that fails then to yield the lock,
wakeup the target thread, requeue, and grab the lock again (expensive,
slow).
2025-10-15 16:01:26 -07:00
Mitchell Hashimoto 3665040b59
Selection dragging should not process when terminal screen changes (#9223)
This hasn't caused any known bugs but leads to selection memory
corruption and assertion failures in runtime safe modes. When the
terminal screen changes (primary to secondary) and we have an active
dragging mode going either by moving the mouse or our selection tick
timer, we should halt.

We still keep the mouse state active which lets selection continue once
the screen switches back.
2025-10-15 15:47:08 -07:00
Mitchell Hashimoto d460800a17
chore: typos should ignore build artifacts (#9222) 2025-10-15 15:44:51 -07:00
Jeffrey C. Ollie 1caab0c208
nix: make sure zon2nix uses Zig 0.15 in generated files (#9220) 2025-10-15 11:56:07 -07:00
Jeffrey C. Ollie c91bfb9dd5
bump version for development (#9218) 2025-10-15 11:55:30 -07:00
Jeffrey C. Ollie bdd2e4d734
build: more Zig 0.15.2 updates (#9217)
- update nixpkgs now that Zig 0.15.2 is available in nixpkgs
- drop hack that worked around compile failures on systems with more
than 32 cores
- enforce patch version of Zig
2025-10-15 11:55:11 -07:00
Jon Parise e5247f6d10
termio: reimplement OSC 7 URI handling (#9193)
This reimplements the MAC address-aware URI parsing logic used by the
OSC 7 handler and adds an additional .raw_path option that returns the
full, unencoded path string (including query and fragment values), which
is needed for compliant kitty-shell-cwd:// handling.

Notably, this implementation takes an options-based approach that allows
these additional behaviors to be enabled at runtime. It also leverages
two std.Uri.parse guarantees:

1. Return slices point into the original text string.
2. .raw components don't require unescaping (.percent_encoded does).

The implementation is in a new 'os.uri' module because its now generic
enough to not be hostname-oriented.

We use os.uri.parseUri and its parsing options to reimplement our OSC 7
file-style URI handling. This has two advantages:

First, it fixes kitty-shell-cwd scheme handling. This scheme expects the
full, unencoded path string, whereas the file scheme expects normal URI
percent encoding. This was preventing paths containing "special" URI
characters (like "path?") from working correctly in our bash, zsh, and
elvish shell integrations, which report working directories using the
kitty-shell-cwd scheme. (fish uses file URIs, which work as expected.)

Second, we can greatly simplify our hostname and path string handling
because we can now rely on the "raw" std.Uri component form to always
provide the correct representation.

Lastly, this lets us remove the previous URI-related code from the
os.hostname module, restoring its focus to hostname-related functions.

See: #5289
2025-10-14 12:12:45 -07:00
Jeffrey C. Ollie 54b021f6d6
core: update zf to remove zg transitive dep (#9208) 2025-10-14 12:04:42 -07:00
Mitchell Hashimoto 3d837cbbce
macos: "Check for updates" cancels whatever the current update state is (#9203)
This mainly allows users who have a pending update but didn't install it
for some time to re-check to see if there is something newer in the mean
time.
2025-10-14 07:31:31 -07:00
Mitchell Hashimoto 9f726492ac
macOS: release builds from source using `zig build` uses ReleaseLocal (#9201)
This fixes codesign issues that are common. The official release process
does not use this, but it is useful for local builds.
2025-10-14 07:13:05 -07:00
Mitchell Hashimoto 06ad3b77b7
Zig 0.15.2 (#9200) 2025-10-14 07:11:10 -07:00
Mitchell Hashimoto 6eb26da3b7
macos: fix failing xcode tests 2025-10-14 06:55:10 -07:00
Peter Guy 41bb8d7af0
fix make clean: change dir name from zig-cache to .zig-cache (#9192)
`make clean` was not removing the `.zig-cache` directory. Instead it was
removing the `zig-cache` directory.
2025-10-14 06:46:24 -07:00
Mitchell Hashimoto 75734a4d07
macos: clarify the "ready to install update" state
- The copy is updated to better explain what the user should do next.
- The symbol is updated to make it clear the update isn't yet installed.
2025-10-13 21:06:01 -07:00
Mitchell Hashimoto 17a20e5b1c
termio: don't start scroll timer if its already active (#9195)
This might fix #9191, but since I don't have a reproduction I can't be
sure. In any case, this is a bad bug that should be fixed.

The issue is that we weren't checking our scroll timer completion state.
This meant that if `start_scroll_timer` was called multiple times within
a single loop tick, we'd enqueue our completion multiple times, leading
to various undefined behaviors.

If we don't enqueue anything else in the interim, this is safe by
chance. But if we enqueue something else, then we'd hit a queue
assertion failure and honestly I'm not totally sure what would happen.

I wasn't able to trigger the "bad" case, but I was able to trigger the
benign case very easily. Our other timers such as the renderer cursor
timer already have this protection.

Let's fix this and continue looking...
2025-10-13 20:44:32 -07:00