Of course #9142 would require a minor follow-up!
* Scale groups can cut across patch sets, but not across fonts. We had
some scale group mixing between Font Awesome and the weather symbols,
which is removed by this PR.[^cp_table_full]
* There's one case where a scale group includes a glyph that's not part
of any patch sets, just for padding out the group bounding box.
Previously, an unrelated glyph from a different font would be pulled in.
Now we use an appropriate stand-in. (See code comment for details.)
* I noticed overlaps weren't being split between each side of the
bounding box, they were added to both sides, resulting in twice as much
padding as specified.
Screenshots showing the extra vertical padding for progress bar elements
due to the second bullet point:
**Before**
<img width="191" height="42" alt="Screenshot 2025-10-11 at 15 33 54"
src="https://github.com/user-attachments/assets/cf288cce-86d3-46fd-ae86-18e5c274b0e4"
/>
**After**
<img width="191" height="42" alt="Screenshot 2025-10-11 at 15 33 20"
src="https://github.com/user-attachments/assets/7ac799c7-bf50-4e65-a74a-f8a2c42d2441"
/>
[^cp_table_full]: Forming and using the merged `cp_table_full` table
should have been a red flag. Such a table doesn't make sense, it would
be a one-to-many map. You need the names of the original fonts to
disambiguate.
Fixes#9076
**Before**
<img width="128" height="57" alt="Screenshot 2025-10-11 at 00 07 09"
src="https://github.com/user-attachments/assets/a6b416d5-dae1-4cea-a836-00640ceaf39b"
/>
**After**
<img width="128" height="57" alt="Screenshot 2025-10-11 at 00 07 31"
src="https://github.com/user-attachments/assets/7d2df7b1-4767-4e2d-84d2-8301da5c6602"
/>
These screenshots show the chevrons mentioned in
https://github.com/ghostty-org/ghostty/discussions/7820#discussioncomment-14617170,
which should be scaled as a group but were not until this PR.
The added code downloads each individual symbol font file from the Nerd
Fonts github repo (making sure to get the version corresponding to the
vendored `font-patcher.py`) and iterates over all of them to build the
correct and complete codepoint mapping table. The table is saved to
`nerd_font_codepoint_tables.py`, which `nerd_font_codegen.py` will reuse
if possible instead of downloading the font files again.
I'm not going to utter any famous last words or anything, but... after
this, I don't think the number of remaining issues with icon
scaling/alignment is _large._
Clicking on desktop notifications sent by Ghostty _should_ cause the
window that sent the notification to come to the top. However, because
the notification that was sent targeted the wrong surface (apprt surface
vs core surface) and the window did not call `present()` on itself the
window would never be brought to the surface, the correct tab would not
be selected, etc.
Fixes#9145
Log messages will include the problematic CSS, simplifying debugging.
Especially helpful since some of our CSS is generated at runtime so it
could be difficult to examine the CSS "source".
```
info(gtk_ghostty_application): loading gtk-custom-css path=/home/ghostty/dev/ghostty/x.css
warning(gtk_ghostty_application): css parsing failed at <data>:2:3-14: gtk-css-parser-error-quark 4 No property named "border-poop"
* {
border-poop: 0;
warning(gtk_ghostty_application): css parsing failed at <data>:1:3-3:1: gtk-css-parser-warning-quark 1 Unterminated block at end of document
* {
border-poop: 0;
```
vs:
```
info(gtk_ghostty_application): loading gtk-custom-css path=/home/ghostty/dev/ghostty/x.css
warning(glib): WARNING: Gtk: Theme parser error: <data>:2:3-14: No property named "border-poop"
warning(glib): WARNING: Gtk: Theme parser warning: <data>:1:3-3:1: Unterminated block at end of document
```
I want to see #7932 get merged, so applied the latest proposed patch.
Will close if the original PR gets some traction, as I do _not_ know Zig
nor this project.
Co-authored-by: rhodes-b <59537185+rhodes-b@users.noreply.github.com>
If an update is available, you can now trigger the full download,
install, and restart from a single command palette action. This allows
for a fully keyboard-driven update process.
While an update is being installed, an option to cancel or skip the
current update is also shown as an option, so that can also be
keyboard-driven.
This currently can't be bound to a keyboard action, but that may be
added in the future if there's demand for it.
**AI Disclosure:** Amp was used considerably. I reviewed all the code
and understand it.
## Demo
https://github.com/user-attachments/assets/df6307f8-9967-40d4-9a62-04feddf00ac2
Sorry, I'm living dangerously here and haven't started a discussion.
New ghostty user. When working interactively with SQL clients you're
often writing semi-colons at the end of statements, e.g. `select * from
table;`
It's super annoying when you double-click to select the word `table` it
actually selects `table;` Anecdotally, this behaviour disagrees with
other terminals I've tried (tho not exhaustive).
Disclosure: Claude wrote this code but, ironically, I "assisted it" by
pointing to the file and function after uncovering issue #30 and
relevant PR.
Fixes#2638Fixes#9056
This changes our update check and notification system to be fully
unobtrusive if a terminal window is open. If a terminal window is open,
update system notifications now appear in the titlebar or the bottom
right corner of the window (if the titlebar is unavailable for any
reason). Importantly, this means no more window popups!
If a terminal window is not open, then explicit update checks will open
the existing, standard, dedicated window that currently exists. This
only triggers for manual update checks while the window is not open,
though. Or at least, that is the intention, I'm not sure if I got all
the logic there 100% correct.
**AI disclosure:** I used Amp considerably on the path to this fix.
Sorry, I wanted to use Codex due to the source, but I wanted to get this
fix out quickly and used a tool I was more familiar with. I manually
modified most of the code and understand it all.
## Demo
Update flows are complex and can do many things, so I built a simulator
to test the various states. This section will show videos of this.
### Happy Path (Full Update Check and Install)
https://github.com/user-attachments/assets/0d9c3396-cad1-4f13-b247-0fcc7382b47e
### Happy Path (No titlebar)
https://github.com/user-attachments/assets/839ffc20-b2d2-459b-9558-29f0f233d7a2
### No Update Available
https://github.com/user-attachments/assets/44650a98-c39b-4119-a8d0-64c21e06b79f
### Error
https://github.com/user-attachments/assets/ab27fe8c-4dd9-48f2-ad4f-23928d6a6829
### First Launch Permission Check
Note: This would show up automatically, not manually triggered.
https://github.com/user-attachments/assets/0add869e-eea8-4600-b119-4a236e77c4bf
## TODO
- [x] Fix progress percentage causing width wiggling
- [x] Fix padding from edges to be aligned on top/bottom and right
Previous PR: #8535 (merged but problem persists)
Issues: #5934
The Ghostty window will always start with the title "Ghostty" at
startup, and then immediately change to the correct window title. This
is a problem when using compositors like Hyprland and Niri if you want
to create rules for floating windows and similar, as the window title
isn't detected at startup.
This fixes the bad behaviour both for title configured in the config
file, and for processes started with the --title argument.
In this fix I've updated the `tags.zig` `closureComputedTitle()`
function to get the title from the passed in config, and use that as a
fallback before the default `Ghostty` fallback.
Previous behaviour as logged by `niri msg event-stream`:
> Window opened or changed: Window { id: 19, title: Some("Ghostty"),
app_id: Some("com.mitchellh.ghostty-debug"), pid: Some(802495),
workspace_id: Some(1), is_focused: true, is_floating: false, is_urgent:
false, layout: WindowLayout { pos_in_scrolling_layout: Some((3, 1)),
tile_size: (2266.0, 1365.0), window_size: (2266, 1365),
tile_pos_in_workspace_view: None, window_offset_in_tile: (0.0, 0.0) } }
Window layouts changed: [(6, WindowLayout { pos_in_scrolling_layout:
Some((4, 1)), tile_size: (2266.0, 1365.0), window_size: (2266, 1365),
tile_pos_in_workspace_view: None, window_offset_in_tile: (0.0, 0.0) })]
Window opened or changed: Window { id: 19, title:
Some("pr-test-title-fix"), app_id: Some("com.mitchellh.ghostty-debug"),
pid: Some(802495), workspace_id: Some(1), is_focused: true, is_floating:
false, is_urgent: false, layout: WindowLayout { pos_in_scrolling_layout:
Some((3, 1)), tile_size: (2266.0, 1365.0), window_size: (2266, 1365),
tile_pos_in_workspace_view: None, window_offset_in_tile: (0.0, 0.0) } }
New behaviour:
> Window opened or changed: Window { id: 20, title:
Some("pr-test-title-fix"), app_id: Some("com.mitchellh.ghostty-debug"),
pid: Some(804534), workspace_id: Some(1), is_focused: true, is_floating:
false, is_urgent: false, layout: WindowLayout { pos_in_scrolling_layout:
Some((3, 1)), tile_size: (2266.0, 1365.0), window_size: (2266, 1365),
tile_pos_in_workspace_view: None, window_offset_in_tile: (0.0, 0.0) } }
Window layouts changed: [(6, WindowLayout { pos_in_scrolling_layout:
Some((4, 1)), tile_size: (2266.0, 1365.0), window_size: (2266, 1365),
tile_pos_in_workspace_view: None, window_offset_in_tile: (0.0, 0.0) })]
This fixes the problem as shown in the output. I have only tested this
on Linux (Arch with Niri).
Release notes at:
https://github.com/vancluever/z2d/blob/v0.9.0/CHANGELOG.md
This release brings our Zig 0.15.x branch into main, now that Ghostty is
on it too.
Additionally, this adds major speedups to the default path (filling with
a solid color using the default operator).
Release notes at:
https://github.com/vancluever/z2d/blob/v0.9.0/CHANGELOG.md
This release brings our Zig 0.15.x branch into main, now that Ghostty is
on it too.
Additionally, this adds major speedups to the default path (filling with a
solid color using the default operator).
Adds the Metal Toolchain as a required Xcode component for building
Ghostty. Also updates the notes about Xcode 26 now that it and Tahoe are
out of Beta.