Commit Graph

221 Commits

Author SHA1 Message Date
Mitchell Hashimoto
262c8517be Bump version to 1.2.3 2025-10-23 09:26:01 -07:00
Mitchell Hashimoto
7071a22cb5 v1.2.2 2025-10-08 10:02:24 -07:00
Mitchell Hashimoto
436bc4c2b9 Set version to 1.2.1 2025-10-06 10:07:14 -07:00
Mitchell Hashimoto
d231e94535 Snap: Do not leak snap variables or snap paths into children (#8771)
Avoid leaking snap environment values and in particular the `$SNAP*`
values to the children that we run from the terminal.

Do this programmatically instead of the launcher, since ghostty needs
know the environment it runs in, while it must not leak the info to the
children.

We've also another leak on snap, that creates a more visible problem
(wrong matching of children applications) that is the apparmor security
profile.

I've handled it at
cc3b46f600
but that requires some love in order to fully decouple the snap option
to the build, to avoid including it in non-snap builds, so an help would
be appreciated there.

> This PR was contains code (in `filterSnapPaths`) that was improved by
DeepSeek.
2025-09-29 12:58:24 -07:00
Mitchell Hashimoto
510f4e474c Set version to 1.2.0 2025-09-15 08:25:54 -07:00
azhn
ac07cf5270 Use ghostty-specific themes release 2025-09-13 06:52:44 +10:00
Jeffrey C. Ollie
a88e6cd428 renderer: add LUT-based implementation of isSymbol (#8528)
The LUT-based lookup gives a ~20%-30% speedup over the "naive" isSymbol
implementation.

<img width="1206" height="730" alt="Screenshot From 2025-09-04 22-45-10"
src="https://github.com/user-attachments/assets/09a8ef3a-8b4b-43ba-963a-849338307251"
/>
<img width="1206" height="730" alt="Screenshot From 2025-09-04 22-41-54"
src="https://github.com/user-attachments/assets/27962a88-f99c-446d-b986-30f526239ba3"
/>

Fixes #8523
2025-09-05 12:04:28 -05:00
Jeffrey C. Ollie
e024b77ad5 drop the new LUT type as no performance advantage detected 2025-09-05 07:58:05 -05:00
Jeffrey C. Ollie
a7da96faee add two LUT-based implementations of isSymbol 2025-09-05 07:58:01 -05:00
Leah Amelia Chen
93debc439c gtk: the Future is Now 2025-09-05 10:10:52 +02:00
Leah Amelia Chen
ac52af27d3 gtk: nuke the legacy apprt from orbit
We don't really have any large outstanding regressions on -ng to warrant
keeping this alive anymore. ¡Adiós!
2025-09-05 00:21:41 +02:00
Mitchell Hashimoto
f87213c2f6 build: add run-valgrind and test-valgrind steps
This adds two explicit `zig build` steps: `run-valgrind` and
`test-valgrind` to run the Ghostty exe or tests under Valgrind,
respectively.

This simplifies the manual Valgrind calls in a few ways:

1. It automatically sets the CPU to baseline, which is a frequent and
   requirement for Valgrind on newer CPUs, and generally safe.

2. It sets up the rather complicated set of flags to call Valgrind with,
   importantly setting up our suppressions.

3. It enables pairing it with the typical and comfortable workflow of
   specifying extra args (with `--`) or flags like `-Dtest-filter` for
   tests.
2025-08-20 11:43:48 -07:00
Jeffrey C. Ollie
63869d8e37 ci: switch to debian 13 2025-08-14 22:42:26 -05:00
Mitchell Hashimoto
a148adc5e4 apprt: make gtk-ng the default apprt on Linux 2025-08-14 12:43:15 -07:00
Leah Amelia Chen
5fbdb8c459 build: allow disabling i18n
GNU gettext simply is a PITA on certain platforms (i.e. Windows, musl
Linux, etc.) and currently it's not possible to cleanly remove i18n
from the build process, making building Ghostty on the aforementioned
platforms difficult. By providing users with a way to opt-out of the
i18n mechanisms (or opt-in, on platforms where i18n is disabled by
default) we can make sure that people at least have *some* way of
building Ghostty before i18n mechanisms can be integrated neatly.
2025-08-06 14:54:02 +08:00
Mitchell Hashimoto
b389171476 Add per-font size adjustment, don't adjust nf symbol font or emoji font; use non-Mono symbols nerd font (#7953)
This adds functionality for choosing different normalization metrics for
each fallback font. It's not exposed as a config option, but could be in
the future, which would probably go a long way towards addressing
concerns like #7929.

The currently available reference metrics are, in priority order:
`ic_width, ex_height, cap_height, line_height, em_size`. The default
value is `ic_width`.

By priority order, I mean that if the chosen metric is not defined in
the fallback font, we move to the next metric in the list---we don't
normalize by an estimated metric from the fallback font (however, we're
happy to use an estimated metric from the primary font, that's how
`ic_width` normalization between CJK and Latin fonts work). This extends
the pattern that was used between `ic_width` and `ex_height` in the
existing hardcoded rule. `line_height` is always defined, so the buck
stops there.

What motivated me to implement this was the fact that, with the existing
hardcoded rule, the embedded symbols-only Nerd Font was always scaled up
by a factor of 1.2, which turned out to be an important reason why it's
been difficult to make icon scaling work to everyone's satisfaction.
Accordingly, the symbols-only font is the first to take advantage of the
new functionality. If this PR is merged, #7917 is no longer needed. (To
limit the scope of this PR, it only includes the minimal changes to let
icon scaling take advantage of this functionality. I may submit a
follow-up PR with some further icon scaling improvement enabled by
this.)
2025-07-26 07:08:44 -07:00
Qwerasd
92fa2228e9 font: use non-mono symbols nerd font for embedded symbols
I changed my mind, this is a pretty small change and relevant to the
intent of the PR. This brings the appearance of the embedded symbols
much closer to patched fonts.

With this, the sizes of most symbols are nearly identical to a patched
font, the only big difference is positioning (and TBH I think we do a
better job positioning than the patcher does, since we have knowledge
about the cell size).
2025-07-25 12:41:00 -06:00
Qwerasd
c0ee4a252a font: revert switch to non-mono symbols nerd font
This change might be good, but it is incomplete and not relevant to the
PR that it's a part of. I'll explore making this change separately after
this, since it might be a good idea.

(It's incomplete since the attribute data was not re-generated based on
the non-mono file.)
2025-07-24 17:52:41 -06:00
Mitchell Hashimoto
b50c1c4fa0 New icon for Linux GTK app that aligns with the Gnome HIG
This adds a new icon for the GTK-based application that adheres (mostly)
to the Gnome Human Interface Guidelines (HIG). The icon is designed to
fit in better with other Gnome applications. 

While there isn't a single standard "native" style amongst Linux
applications, I believe this better fits the general Linux desktop
ecosystem over our macOS icon.

The icon itself is undeniably Ghostty. The core design language is the
same and I don't think ayone will mistake it for anything else. I wanted
to keep the brand the same, but making it fit in better aligns with
Ghostty's goal of being "platform native".
2025-07-23 10:00:55 -07:00
Jayson Reis
acc2ea724f build-system: Replace deprecated usages of addStaticLibrary with addLibrary (#8029)
Hi there, this is just a low-hanging fruit and it also prepares the way
for the future 0.15, which removes addStaticLibrary.
Please, let me know what to do on the `// TODO` comments.
2025-07-22 14:47:18 -07:00
Daniel Wennberg
ce507f35df Use em size as nerd font reference metric 2025-07-17 17:04:47 -07:00
Mitchell Hashimoto
015efcf9e5 Introducing gtk-ng, the next evolution of our GTK apprt (#7961)
Surprise, @ghostty-org/gtk! Hopefully a happy one.

This PR introduces the boilerplate for a new apprt I'm calling `gtk-ng`.
The `gtk-ng` apprt is still GTK, but built up from first principles
using the GObject type system, Blueprint files, etc. This will
ultimately replace and become `gtk` (the `-ng` suffix will be stripped
once we fully replace our existing GTK apprt).

In this PR, the `gtk-ng` apprt does nothing more but show a "Hello,
Ghostty" GTK window. It doesn't run a terminal, yet. 😄 I want to
use this PR to introduce the boilerplate and share my motivations.

Since `gtk-ng` and `gtk` are separate apprts, I can PR small,
reviewable, and risky changes into `gtk-ng` rather than opening some
mega-PR that replaces everything all at once. Simultaneously, we can
continue to iterate on and maintain our shipping `gtk` apprt without
dealing with conflicts.

> [!IMPORTANT]
>
> To reiterate, this PR doesn't change anything about our `gtk` apprt.
Builds by default will still use the `gtk` apprt and we can continue to
build both `gtk` and `gtk-ng` side by side (actually, a very important
property until we can be confident we've reached parity).

## A Refactor, Not a Rewrite

The primary goal of this apprt is to _primarily_ be a **refactor, not a
rewrite.**

As much as possible, I'm going to be bringing over a lot of the same
logic from `gtk` as long as it fits and makes sense, but applying it to
our new structure and lifecycle. For example in this PR you can see how
we handle style manager, cgroups, etc. and how that fits within the new
`GhosttyApplication` class.

Our GTK apprt from a business logic standpoint is _pretty damn good_ and
_pretty damn stable_. There's no need to rock that boat and try to
rewrite core logic such as input handling, X11/Wayland stuff, etc. It
just has to be massaged into the new structure.

## Why? 

**Object-oriented, reference-counted systems are good for UI,
actually.** Experience iterating on the non-trivial macOS application
has really reaffirmed that OOP and memory managed systems are really,
really nice for GUI. I'm not a huge OOP fan in general, but it fits GUI
patterns extremely well. And memory management of any form (GC, Ref
Counts, etc.) is important in GUIs where "objects" are handed off to
various owners at different times, the most concrete example being:
splits moving across windows or into an undo management system.

**Blueprint and UI definitions have been a success.** These were
introduced in an incremental way into the `apprt/gtk` (thanks ❤️ )
and have been great. But our existing non-GObject system makes it hard
to go _all in_ on them, e.g. bindings. Moving to a full GObject-based
system will let us fully adopt this.

**`zig-gobject` is good and stable.** This didn't really exist when we
started the GTK apprt (see the long history below). Since adopting it,
its proven to be an excellent, stable dependency. I'm ready to go all-in
on it.

**Memory management has been a challenge.** Our mix of GObject and
non-GObject lifetimes within the GTK apprt has consistently been a
source of memory leaks at best and crashes at worst. For example,
`Window`, `Surface`, `Tab`, etc. have weird lifetimes that we try to
pair alongside their GTK counterparts and its nasty and I don't think
anyone who maintains this will disagree. By representing all of these
concepts as GObject or Widget subclasses, we'll align all their
lifetimes as expected.

**Personally, I've grown a lot, particularly from working on the macOS
side.** I think all of us as programmers can agree that _programming in
multiple languages makes us better programmers_. Similarly, building the
macOS app has shown me patterns and techniques that would make our
GTK-based application better. I'd like to bring those to the GTK side.
(Likewise, I've improved the macOS side from periods of time working on
the GTK side and I suspect that might happen again!)

### Longer Background

It's easy to rewrite. And I think our maintainers know that I'm not a
fan of rewrites. I think its the wrong decision most of the time. It is
easy to look at "legacy" code (especially code you didn't write
yourself), be disgusted, and think you can rewrite it all better. But no
engineer sets out to create technical debt, and I think its worth
respecting how and why some code came to be before embarking on
something new. This section does that.

#### The Beginning

Ghostty started as a pure Zig-based GLFW app, with no concept of
"apprt". It was Linux-only, and X11-only. At some point, I refactored
out the "apprt" system in order to introduce GTK4 (GTK4 came before any
macOS work). For the initial GTK4 work, I decided to just call into the
libgtk C APIs directly. There were various contributing factors for this
decision:

1. Zig was _rapidly_ changing, and we were on nightly Zig. This was
around the Zig 0.11, 0.12 times. Taking on new Zig dependencies was
really dangerous because Zig nightly could break all of us at any
moment.

2. [`zig-gobject`](https://github.com/ianprime0509/zig-gobject) was
brand new and unstable. Given point 1, I discarded it and did straight C
APIs.

3. Ghostty itself was very simple. We didn't support tabs, we didn't
support splits. We were still primarily concerned with making the
terminal stable. We weren't on the "native UI" part of our roadmap quite
yet. This was our initial foray in that direction.

4. On a personal level, I hadn't done real native GUI programming in a
_long_ time (on any platform). Recall the macOS apprt didn't exist yet,
either. Jumping into "plain old Zig" with "plain old C APIs" was a
practical, no-nonsense way for me to get going.

Given all this, I still believe I (it was only me then) made the right
decision for the time.

#### Zig, GTK apprt Stabilization

Eventually, the factors listed above changed: (1) Zig stabilized more
and Ghostty moved to stable Zig for various reasons. (2) `zig-gobject`
became a mature, stable library. (3) Ghostty the application has become
increasingly complex (in a good way, we support a ton of awesome
"platform UI" features).

Socially, the @ghostty-org/gtk subsystem team was created and is filled
with people who are experienced with GTK and Linux in general. This team
introduced more idiomatic GTK concepts into the project such as
blueprint files, a `zig-gobject` migration, and more.

The @ghostty-org/gtk subsystem maintainers have done an awesome job
iterating on this change within the existing `apprt/gtk`. This has been
often frustrating, but it was a pragmatic approach to move us towards
the future and let us ship new features into GTK4 to pursue our platform
UI goals.

#### GUI Maturity

We're now at the point where the core Ghostty terminal (the core,
terminal emulation) is incredibly stable. We don't have exact numbers
but we can confidently assume its used by thousands of people everyday
for real, professional work.

As such, most of the changes within the 1.1 and 1.2 cycle have been at
the apprt/GUI layer, introducing significantly more complexity:
localization, more X11/Wayland integrations, more text to native
elements like the process exit overlay, etc.

I recently rewrote the entire terminal, tab, and split data model in the
macOS app to give us a better foundation for future functionality, and
to improve our memory management story (surface leaks were a common
problem before, and they haven't happened since since the lifetime of a
surface is so much more obvious). This also let me iterate more quickly
on more features such as undo/redo, but will also more easily enable
things like split titles, merging splits into tabs/windows, etc. (not
done yet).

I think its time for this type of change within the GTK apprt as well.
We have the collective real world experience and we've put in the work
in iteration to understand what needs to be done.
2025-07-16 12:28:57 -07:00
Mitchell Hashimoto
ecb77fb8bc apprt/gtk-ng: gresource creation, resource registration in Application 2025-07-16 09:40:34 -07:00
Mitchell Hashimoto
2f9660c02c apprt/gtk-ng: boilerplate 2025-07-16 09:40:34 -07:00
Jeffrey C. Ollie
959b2c8d7f linux/systemd: add comments explaining need for app- prefix 2025-07-16 10:53:19 -05:00
Jeffrey C. Ollie
2435cee11b linux/systemd: add an app- prefix to the systemd unit
The XDG Freedesktop Portal has a _major_ undocumented requirement for
programs that are launched/controlled by `systemd` to interact with the
Portal. The unit _must_ be named `app-<appid>.service`. The Portal uses
the systemd unit name figure out what the program's application ID is
and it will only look at unit names that begin with `app-`. I can find
no place that this is documented other than by inspecting the code or the
issue and PR that introduced this feature. See the following code:

7d4d48cf07/src/xdp-utils.c (L152-L220)

This may fix many people's issues with getting global shortcuts
to work.

Note that this is a breaking change if you have been using Ghostty
compiled from source since #7433 was merged. You will need to ensure
that any Ghosty systemd unit files _not_ prefixed with `app-` are
deleted.

Original discussion/PR in the XDG Desktop Portal repository:

https://github.com/flatpak/xdg-desktop-portal/issues/579
https://github.com/flatpak/xdg-desktop-portal/pull/719

Originally discussed on Discord:

https://discord.com/channels/1005603569187160125/1394845362186879026

Co-authored-by: ambareeshbalaji@gmail.com
2025-07-16 10:26:30 -05:00
Mitchell Hashimoto
658567bbbd fix webdata build, run it in CI
This fixes our build for `-Demit-webdata`. Turns out we weren't 
running this in CI so this adds that there.
2025-07-12 06:46:00 -07:00
Mitchell Hashimoto
9fa26387ef build: zig build test runs Xcode tests on macOS
Related to #7879

This commit updates `zig build test` to run Xcode tests, too. These run
in parallel to the Zig tests, so they don't add any time to the test.

The Xcode tests will _not_ run when: (1) the target is not macOS, or (2)
the `-Dtest-filter` option is non-empty. This makes it so that this
change doesn't affect non-macOS and doesn't affect the general dev cycle
because you usually will run `-Dtest-filter` when developing a core
feature.

I didn't add a step to only run Xcode tests because I find that when I'm
working in Xcode I'm probably going to run the tests from there anyways.
The integration with `zig build test` is just a convenience, especially
around CI.

Speaking of CI, this change also makes it so this will run in CI.
2025-07-10 21:08:51 -07:00
Mitchell Hashimoto
68418ecd53 Modernize our benchmarks (#7891)
This PR modernizes our benchmarks. This PR focuses on the benchmark
_framework_ and not the benchmarks themselves. That will come in later
PRs.

We now produce two binaries with `-Demit-bench`: `ghostty-bench` and
`ghostty-gen`. The former is our benchmark tool. The latter is our
synthetic data generation tool. The benchmarking CLI usually takes in
data from the synthetic generator but we want to do that offline because
synthetic data generation can be slow and CPU intensive and mess up our
benchmarks.

Our previous benchmark-specific binaries (like
`ghostty-bench-codepoint-width`) are all gone. This is all executed as
subcommands in the format similar to Ghostty users: `ghostty-bench
+codepoint-width --other --args`.

Previously, synthetic data generation was a mess and all unified with
`ghostty-bench-stream` which is just nasty. A dedicated CLI now gets us
args like `ghostty-gen +osc --p-valid=0.5`. Neat!

## Signposts and Xcode/Instruments on macOS

The benchmark framework now automatically emits
[signposts](https://developer.apple.com/documentation/os/recording-performance-data)
around the code that is under test. This is surfaced in Instruments as a
region that you can visualize and zoom in on so you can omit any of the
other overhead.

Additionally, I've integrated benchmarks with libghostty and our Xcode
project so you can just right click a benchmark to open it in
Instruments.

These are macOS-specific niceties but the core benchmarking tool is
platform-agnostic.

## Generalized CLI Actions

The `src/cli/action.zig` file was generalized so that it can be shared
amongst our three action-ized binaries. The Ghostty-specific actions are
now in `src/cli/ghostty.zig`. As an added bonus, our action parsing is
now fully unit tested.

I don't like mixing refactors in with other tasks in PRs but in this
case this one was done to enable not one but two other consumers in the
same PR, so I think it fits.

## TODO

Some things I want to do before merge.

- [ ] Add flags to `ghostty-bench` to configure once mode vs duration
mode
2025-07-09 21:42:53 -07:00
Mitchell Hashimoto
cc0d7acaef build: make the xcframework step dsym aware, even though we don't use it
This was in pursuit of trying to get line numbers in `zig build run` on
macOS to work, but I wasn't able to figure that out and this wasn't the
right path because static libs can't have dsyms. But, it may still be
useful to make the xcframework step dsym aware for future use so I'm
PRing this.
2025-07-09 21:35:02 -07:00
Mitchell Hashimoto
74b94ef30a remove src/bench 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto
a28b7e9205 synthetic cli (ghostty-gen) 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto
b5ff0442d4 bench: remove old benchmarks we converted 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto
b8f5cf9d52 initial ghostty-bench program 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto
1739418f6f cli: make the action parser (+foo) generic and reusable 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto
d8e7a6634e build: temporarily disable stderr capture on distcheck 2025-07-09 10:22:50 -07:00
Jeffrey C. Ollie
13805f7cc5 build: disable fuzzy matching for msgmerge
CI is currently configured to fail if there are any fuzzy matches in
translation files. This change prevents `msgmerge` from creating any
fuzzy matches when translations are updated.
2025-07-08 22:17:20 -05:00
Jeffrey C. Ollie
b8d5c1cf42 build: update zig build update-translations
- The order of the arguments to xgettext influences the output. Since
  directorty walking does not guarantee that files will be listed in
  a deterministic order (especially when run on different systems) the
  translation files would see a lot of churn depending on who updated
  them last.

  In this update the files are sorted so that the arguments to xgettext
  are always in the same order. This should reduce churn in the future.

- Mark all of the files as inputs so that the Zig build system caching
  will work properly.
2025-07-08 15:21:19 -05:00
Jeffrey C. Ollie
5b1d390379 gtk: rebuild gresources.c/h if CSS or icons change 2025-07-07 10:38:08 -05:00
Mitchell Hashimoto
984d123fe4 macos: support configuration via CLI arguments
This makes it so `zig build run` can take arguments such as
`--config-default-files=false` or any other configuration. Previously,
it only accepted commands such as `+version`.

Incidentally, this also makes it so that the app in general can now take
configuration arguments via the CLI if it is launched as a new instance
via `open`. For example:

    open -n Ghostty.app --args --config-default-files=false

This previously didn't work. This is kind of cool.

To make this work, the libghostty C API was modified so that
initialization requires the CLI args, and there is a new C API to try to
execute an action if it was set.
2025-07-05 21:31:23 -07:00
Mitchell Hashimoto
8c3caee15c macOS: zig build run disables window saved state 2025-07-05 19:58:17 -07:00
Mitchell Hashimoto
b799462745 Better Glyph Constraint Logic (#7809)
This is a big'un.

- **Glyph constraint logic is now done fully on the CPU** at the
rasterization stage, so it only needs to be done once per glyph instead
of every frame. This also lets us eliminate padding between glyphs on
the atlas because we're doing nearest-neighbor sampling instead of
interpolating-- which ever so slightly increases our packing efficiency.
- **Special constraints for nerd font glyphs** are applied based roughly
on the constraints they use in their patcher. It's a simplification of
what they do, the largest difference being that they scale groups of
glyphs based on a shared bounding box so that they maintain relative
size to one another, but that would require loading all glyphs on the
group and I'd want to do that on font load TBH and at that point I'd
basically be re-implementing the nerd fonts patcher in Zig to patch
fonts at load time which is way beyond the scope I want to have. (Fixes
#7069)
- These constraints allow for **perfectly sized and centered emojis**,
this is very nice.
- **Changed the default embedded fonts** from 4 copies (regular, italic,
bold, bold italic) of a patched (and outdated) JetBrains Mono to a
single JetBrains Mono variable font and a single Nerd Fonts Symbols Only
font. This cuts the weight of those down from 9MB to 3MB!
- **FreeType's `renderGlyph` is significantly reworked**, and the new
code is, IMO, much cleaner- although there are probably some edge case
behavior differences I've introduced.

> [!NOTE]
> One breaking change I definitely introduced is changing the
`monochrome` freetype load flag config from its previous completely
backwards meaning to instead the correct one (I also changed the
default, so this won't affect any user who hasn't touched it, but users
who set the `monochrome` flag will find their fonts quite crispy after
this change because they will have no anti-aliasing anymore)

### Future work

Following this change I want to get to work on automatic font size
matching (a la CSS
[`font-size-adjust`](https://developer.mozilla.org/en-US/docs/Web/CSS/font-size-adjust)).
I set the stage for that quite some time ago so it shouldn't be too much
work and it will be a big benefit for users who regularly use multiple
writing systems and so have multiple fonts for them that aren't
necessarily size-compatible.
2025-07-05 14:37:46 -07:00
Mitchell Hashimoto
0929f39e89 build: xcodebuild properly sets up resources 2025-07-05 13:36:31 -07:00
Mitchell Hashimoto
8653229607 ci: don't use the new macOS app emit yet 2025-07-05 07:26:02 -07:00
Mitchell Hashimoto
8b44d0b3bb build: make zig build run on macOS work with an empty zig-out 2025-07-05 07:22:42 -07:00
Mitchell Hashimoto
5fc0bbc58f build: add -Demit-macos-app 2025-07-05 07:05:36 -07:00
Mitchell Hashimoto
91ee75ae4d build: add -Dxcframework-target to specify the target for builds 2025-07-04 15:01:14 -07:00
Mitchell Hashimoto
3793dac313 build: zig build run only builds xcframework for current arch 2025-07-04 14:56:25 -07:00
Mitchell Hashimoto
fb9c52ecf4 Nuke GLFW from Orbit
This deletes the GLFW apprt from the Ghostty codebase.

The GLFW apprt was the original apprt used by Ghostty (well, before
Ghostty even had the concept of an "apprt" -- it was all just a single
application then). It let me iterate on the core terminal features,
rendering, etc. without bothering about the UI. It was a good way to get
started. But it has long since outlived its usefulness.

We've had a stable GTK apprt for Linux (and Windows via WSL) and a
native macOS app via libghostty for awhile now. The GLFW apprt only
remained within the tree for a few reasons:

  1. Primarily, it provided a faster feedback loop on macOS because
     building the macOS app historically required us to hop out of the
     zig build system and into Xcode, which is slow and cumbersome.

  2. It was a convenient way to narrow whether a bug was in the
     core Ghostty codebase or in the apprt itself. If a bug was in both
     the glfw and macOS app then it was likely in the core.

  3. It provided us a way on macOS to test OpenGL.

All of these reasons are no longer valid. Respectively:

  1. Our Zig build scripts now execute the `xcodebuild` CLI directly and
     can open the resulting app, stream logs, etc. This is the same
     experience we have on Linux. (Xcode has always been a dependency of
     building on macOS in general, so this is not cumbersome.)

  2. We have a healthy group of maintainers, many of which have access
     to both macOS and Linux, so we can quickly narrow down bugs
     regardless of the apprt.

  3. Our OpenGL renderer hasn't been compatible with macOS for some time
     now, so this is no longer a useful feature.

At this point, the GLFW apprt is just a burden. It adds complexity
across the board, and some people try to run Ghostty with it in the real
world and get confused when it doesn't work (it's always been lacking in
features and buggy compared to the other apprts).

So, it's time to say goodbye. Its bittersweet because it is a big part
of Ghostty's history, but we've grown up now and it's time to move on.
Thank you, goodbye.

(NOTE: If you are a user of the GLFW apprt, then please fork the project
prior to this commit or start a new project based on it. We've warned
against using it for a very, very long time now.)
2025-07-04 14:12:18 -07:00
Mitchell Hashimoto
7bd90e6ec4 Build system can build macOS app bundle and open it
`zig build run` on macOS now builds the app bundle via the `xcodebuild`
CLI and runs it. The experience for running the app is now very similar
to Linux or the prior GLFW build, where the app runs, blocks the zig
command, and logs to the terminal.

`xcodebuild` has its own build cache system that we can't really hook
into so it runs on every `zig build run` command, but it does cache and
I find its actually relatively fast so I think this is a good
replacement for the glfw-based system.
2025-07-04 13:32:15 -07:00