Fixes: #9416
Specifically:
iCurrentCursorStyle
iPreviousCursorStyle
iCurrentCursorVisible
iPreviousCursorVisible
Visibility calculated and updated independently from the typical cursor
uniform updates to preserve cursor style even when not in the viewport
or set to be hidden
I used Claude-Code to initially navigate and gauge an understanding of
the rendering system. Otherwise I authored the rest of the PR
Specifically:
iCurrentCursorStyle
iPreviousCursorStyle
iCurrentCursorVisible
iPreviousCursorVisible
Visibility calculated and updated independently from the typical cursor
unifrom updates to preserve cursor style even when not in the viewport
or set to be hidden
<img width="638" height="476" alt="Screenshot 2026-01-11 at 1 41 52 PM"
src="https://github.com/user-attachments/assets/bf3457e8-1b1c-4b2d-b6d1-312d48739108"
/>
This PR makes 3 small changes:
1. Makes the surface move grab handle present when the surface is
hovered and the mouse cursor is not hidden.
2. Makes the grab handle partial width, allowing space to more easily
grab the divider for resize (anywhere but the center) and increasing the
grabbable area for the grab handle.
3. Adds appropriate padding to the top of the surface (in the metal
stack so shaders can apply) to give space for the header so that text is
not occluded by the grab handle.
I think it looks good and works well, but I suggest trying it out since
the interaction is the most important part.
Problems I was trying to solve:
1. The old grab bar overlays actual clickable area on TUIs and can make
them hard to use
2. The old bar makes the entire divider also a grab area, making divider
resizing more difficult.
3. The old bar is not always present, making it hard to discover until
you're going to resize something, which then is confusing
4. The old bar is not colored with the style.
https://github.com/user-attachments/assets/588a35b5-ba2f-4074-8edb-e090e0006224
AI Disclosure: I originally did this with Claude, but at this point I've
gone over this code manually enough to feel somewhat familiar. I think
the video and design speak for themselves and the code change is
minimal, but I'm not a Swift programmer, so I can't evaluate whether
this is the best possible solution.
Human Disclosure: I don't have a linux machine to check that the padding
doesn't apply outside of MacOS. I find it hard to believe that it
wouldn't work, but worth calling out.
Namespace now supports cache volumes on macOS.
This enables caching for Zig and Xcode artifacts. We can't do Nix yet
because we can't create `/nix` and there's a chicken/egg with how Nix
installation works on macOS. I'm emailing Namespace support about it...
But still, a big win for Zig and Xcode!
Namespace now supports cache volumes on macOS.
This enables caching for Zig and Xcode artifacts. We can't do Nix yet because
we can't create `/nix` and there's a chicken/egg with how Nix installation
works on macOS. I'm emailing Namespace support about it... But still, a big
win for Zig and Xcode!
**Summary:**
- Add tint overlay to dim terminal windows when inactive, fixes
https://github.com/ghostty-org/ghostty/discussions/10040
- Refactor the liquid glass effect into a dedicated `TerminalGlassView`
class
Note: The tint overlay color and opacity values may not be ideal —
feedback is welcome.
**AI Disclosure:** I used Claude Code to read the macos repo and
understand the liquid glass implementation. Implemented basic tint
overlay mainly by hand. Refactor the code and review changes with Claude
Code.
Double-clicking a tab allows you to edit the tab name inline.
- Implemented an inline editor that allows you to edit the tab title
directly.
- Press Enter to confirm, Esc to cancel.
This PR updates the logic in Terminal `print` to include more cases of
changing a cell to be wide due to a grapheme cluster that needs to be
wide but starts off narrow. The existing case of this is a
text-presentation code point followed by VS16 to make it emoji
presentation. This PR handles more cases that are found in scripts such
as Devanagari where the correct grapheme width calculation sums up
multiple code points of non-zero widths. An example, as seen from
[uucode's issue #1](https://github.com/jacobsandlund/uucode/issues/1) is
`क्ष`, which now with https://github.com/ghostty-org/ghostty/pull/9680
merged is one grapheme cluster instead of two, but the U+0915 (first
code point) is width one and U+0937 (final code point) is also width
one, and the whole cluster should be width 1 + 1 = 2. This is important
to address with the grapheme break change otherwise these scripts would
show with narrow cells, incorrectly.
Before:
<img width="680" height="124" alt="CleanShot 2026-01-27 at 10 31 24@2x"
src="https://github.com/user-attachments/assets/4ff5959d-9c14-4062-8280-83004af38495"
/>
After:
<img width="646" height="118" alt="CleanShot 2026-01-27 at 10 29 10@2x"
src="https://github.com/user-attachments/assets/3ad11afd-2141-46fb-b22b-9fa7b2546366"
/>
---
Note that the logic here just takes `width_zero_in_grapheme` and if it's
not zero width, makes the cell wide. This is actually wrong for
graphemes with `prepend` (usually/always? zero width) followed by a
character that should be narrow width, but that's affecting a much
smaller number of graphemes. To address that, we would need to run the
full `wcwidth` from `uucode` on the grapheme, and compare the width
output with the current cell's `Wide`. I figured it'd be better to
incrementally just handle the bulk of the cases with the
`width_zero_in_grapheme` check.
This also adds tests to make sure moving the cell is handled correctly,
which was not the case for the existing VS16 logic.
There's a lot of code here to handle transferring the graphemes when the
narrow cell should wrap to the next line to become wide. I'd like
feedback on the approach here before attempting to clean anything up, if
desired (pull it out into a separate method?).
AI was used in some of the uucode changes in
https://github.com/ghostty-org/ghostty/pull/9678 (Amp--primarily for
tests), but everything was carefully vetted and much of it done by hand.
This PR was made without AI.
* Use a GitHub action to download the Android NDK
* Use helper functions available on `std.Build` to simplify the build
script.
* Use various Zig-isms to simplify the code.
FYI, using Nix to seems to be a non-starter as getting any Android
development kits from nixpkgs requires accepting the Android license
agreement and allowing many packages to use unfree licenses. And since
the packages are unfree they are not cached by NixOS so the build
triggers massive memory-hungry builds.
* Use a GitHub action to download the Android NDK
* Use helper functions available on `std.Build` to simplify
the build script.
* Use various Zig-isms to simplify the code.
FYI, using Nix to seems to be a non-starter as getting any Android
development kits from nixpkgs requires accepting the Android license
agreement and allowing many packages to use unfree licenses. And since
the packages are unfree they are not cached by NixOS so the build
triggers massive memory-hungry builds.
The PR introduces `lib-vt` Android support as discussed in #10902.
A few more notes:
- Introduces new CI for Android builds as a change requires NDK to be
configured.
- To build locally, it is required to have the NDK installed in the
system and either have the path exported via `ANDROID_NDK_HOME` pointing
to the exact NDK path or `ANDROID_HOME` or `ANDROID_SDK_ROOT` pointing
at the Android SDK path from which the build system will infer the NDK
path and version.
- 16kb page size alignment is configured for Android 15+. Builds are
backward compatible with 4kb page size devices.
Fixes#10548
Escaped characters in selection-word-chars are now correctly parsed,
allowing for characters like `\t` to be included in the set of word
characters.
Fixes#10548
Escaped characters in selection-word-chars are now correctly parsed,
allowing for characters like `\t` to be included in the set of word
characters.