Commit Graph

533 Commits (main)

Author SHA1 Message Date
Jacob Sandlund 2ff05c9ffb Merge remote-tracking branch 'origin/main' into harfbuzz-positions 2025-12-28 17:24:58 -06:00
-k e63a4ab774
build: fix pkgs for FBSD port runs 2025-12-28 07:21:58 -05:00
Jacob Sandlund e41dbe84fc shaping: Use position offsets for HarfBuzz 2025-12-24 16:23:16 -06:00
-k d0767a089a
build: fix `simdutf`/`highway` flags 2025-12-21 17:11:34 -05:00
Mitchell Hashimoto c92a003325
pkg/{highway,simdutf}: disable ubsan
This causes linker issues for some libghostty users. I don't know why we
never saw these issues with Ghostty release builds, but generally
speaking I think its fine to do this for 3rd party code unless we've
witnessed an issue. And these deps have been stable for a long, long
time.
2025-11-24 21:18:49 -08:00
Qwerasd 6d65abc489 fix(pkg/freetype): fully correct load flags
These now properly match the FreeType API- compared directly in the unit
tests against the values provided by the FreeType header itself.

This was ridiculously wrong before, like... wow.
2025-11-24 17:57:02 -07:00
Qwerasd 3cd6939af6 pkg/freetype: add failing unit tests for LoadFlags 2025-11-24 17:35:53 -07:00
Qwerasd 6a9c869f9d Partially revert 25856d6 since it broke pkg/freetype tests 2025-11-24 17:24:47 -07:00
Pyry Takala 5bfeba6603 Fix LoadFlags struct bit alignment to match FreeType API
The struct was missing padding at bit position 8, causing all subsequent flag fields (bits 9+) to be misaligned by one bit position.

See: https://freetype.org/freetype2/docs/reference/ft2-glyph_retrieval.html#ft_load_xxx
2025-11-24 23:34:47 +00:00
Pyry Takala d4c2376c2d Fix LangSet.hasLang() to compare against FcLangEqual instead of FcTrue
FcLangSetHasLang returns FcLangResult enum values:
- FcLangEqual (0): Exact match
- FcLangDifferentTerritory (1): Same language, different territory
- FcLangDifferentLang (2): Different language

The previous comparison to FcTrue (1) caused:
- Exact matches (0) to incorrectly return false
- Partial matches (1) to incorrectly return true

This fix changes the comparison to FcLangEqual (0) so hasLang()
correctly returns true only for exact language matches.

Fixes emoji font detection which relies on checking for 'und-zsye'
language tag support.
2025-11-24 20:34:07 +00:00
Jeffrey C. Ollie ec55cbc879
wuffs: protect against crafted images that cause overflows
Fixes #9579

Protect against panics caused by integer overflows by using functions
that allow integer overflows to be caught instead of causing a panic.

Also protect against DOS from images that might not cause an
overflow but do consume an absurd amount of memory by limiting
images to a maximum size of 4GiB (which is the maximum size of
`image-storage-limit`).
2025-11-13 14:20:19 -06:00
Ēriks Remess 82a5c177fe gtk4-layer-shell: reenable ubsan 2025-10-10 14:40:56 +03:00
Ēriks Remess ce47a85bf7 gtk4-layer-shell: version from build.zig.zon 2025-10-10 14:40:42 +03:00
Mitchell Hashimoto 0112607532
Zig 0.15: zig build test macOS 2025-10-03 07:10:43 -07:00
Mitchell Hashimoto 7ec57aeebd
Zig 0.15: zig fmt 2025-10-03 07:10:43 -07:00
Mitchell Hashimoto d02770d292
zig-15: build binary builds 2025-10-03 07:10:41 -07:00
Qwerasd efc6e0d673 fix(font/coretext): always prevent shaper from emitting rtl
The solution we had before worked in most cases but there were some
which caused problems still. This is what HarfBuzz's CoreText shaper
backend does, it uses a CTTypesetter with the forced embedding level
attribute. This fixes the failure case I found that was causing non-
monotonic outputs which can have all sorts of unexpected results, and
causes a crash in Debug modes because we assert the monotonicity while
rendering.
2025-10-02 15:32:21 -06:00
Qwerasd d6063428bd font/coretext: tiny shaper improvements
Reduce potential allocation while processing glyphs by ensuring capacity
in the buffer ahead of time and also using CTRunGet*Ptr functions first
and only allocating for those if that didn't work (it should almost
always work in practice.)
2025-10-02 14:06:58 -06:00
Mitchell Hashimoto 0bddaed53b
fix(font): Improve FreeType glyph measurements and add unit tests for face metrics (#8738)
Follow-up to #8720 adding

* Two improvements to FreeType glyph measurements:
- Ensuring that glyphs are measured with the same hinting as they are
rendered, ref
[#8720#issuecomment-3305408157](https://github.com/ghostty-org/ghostty/pull/8720#issuecomment-3305408157);
- For outline glyphs, using the outline bbox instead of the built-in
metrics, like `renderGlyph()`.
* Basic unit tests for face metrics and their estimators, using the
narrowest and widest fonts from the resource directory, Cozette Vector
and Geist Mono.

---

I also made one unrelated change to `freetype.zig`, replacing
`@alignCast(@ptrCast(...))` with `@ptrCast(@alignCast(...))` on line
173. Autoformatting has been making this change on every save for weeks,
and reverting the hunk before each commit is getting old, so I hope it's
OK that I use this PR to upstream this decree from the formatter.
2025-09-29 12:24:42 -07:00
Paal Øye-Strømme bd9bc5f1b9 deps: removing utf8proc
utf8proc is no longer being used

Per #808, it should be removed.

Link: https://github.com/ghostty-org/ghostty/discussions/6931
Link: https://github.com/ghostty-org/ghostty/discussions/2563
2025-09-23 17:38:03 +02:00
azhn a9c5a05e5b deps: Allow dynamic-linking of spirv-cross
- Use the pkg-config name of 'spirv-cross-c-shared' exported by the upstream SPIRV-Cross build
2025-09-23 20:49:22 +10:00
Mitchell Hashimoto 17498ce122
build: many more lazy dependencies, defer deps add unless needed
This makes more dependencies lazy. This has a practical effect of
reducing the number of dependencies that need to be downloaded when
running certain zig build steps.

This is all limited because we're blocked on an upstream Zig issue:
https://github.com/ziglang/zig/issues/21525 This prevents us from
fully avoiding downloading many dependencies, but at least they're
relatively small.

One major improvement here is the usage of `lazyImport` for
`zig-wayland` that prevents downloading `zig_wayland` unconditionally on
all platforms. On macOS, we don't download this at all anymore.

Another, weirder change is that all our transitive dependencies are now
marked lazy (e.g. glslang's upstream source) even if the glslang build
always requires it. This was necessary because without this, even if we
simply referenced glslang in the root build.zig, it would force the
source package to download unconditionally. This no longer happens.
2025-09-21 13:26:09 -07:00
Mitchell Hashimoto a453681615
renderer: create explicit sampler state for custom shaders
The GLSL to MSL conversion process uses a passed-in sampler state for
the `iChannel0` parameter and we weren't providing it. This magically
worked on Apple Silicon for unknown reasons but failed on Intel GPUs.

In normal, hand-written MSL, we'd explicitly create the sampler state as
a normal variable (we do this in `shaders.metal` already!), but the
Shadertoy conversion stuff doesn't do this, probably because the exact
sampler parameters can't be safely known.

This fixes a Metal validation error when using custom shaders:

```
-[MTLDebugRenderCommandEncoder validateCommonDrawErrors:]:5970: failed 
assertion `Draw Errors Validation Fragment Function(main0): missing Sampler 
binding at index 0 for iChannel0Smplr[0].
```
2025-09-18 09:25:37 -07:00
Daniel Wennberg e1b2f6f021 Use same hinting flags for measurement and rendering 2025-09-17 23:04:59 -07:00
Jeffrey C. Ollie 3cce5d26d7
wuffs: simplify the build 2025-08-20 10:08:24 -05:00
Mitchell Hashimoto c979ece916
build-system: Replace deprecated usages of root_source_file on addTests (#8031)
Yet another low-hanging fruit
2025-07-22 15:28:11 -07:00
Jayson Reis d5995ac45c
build-system: Replace deprecated usages of root_source_file on addTests 2025-07-23 00:03:44 +02: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
Mitchell Hashimoto 9bdc29e00f
pkg/oniguruma: fix memory leak for failed regex searches
Found by Valgrind:

```
==265734== 320 bytes in 8 blocks are definitely lost in loss record 13,786 of 15,141
==265734==    at 0x5A65810: malloc (in /nix/store/l431jn8ahj09g5c1arrl7q6wcxngg21q-valgrind-3.24.0/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==265734==    by 0x3D799EB: onig_region_resize (.cache/zig/p/N-V-__8AAHjwMQDBXnLq3Q2QhaivE0kE2aD138vtX2Bq1g7c/src/regexec.c:923)
==265734==    by 0x3D81BCA: onig_region_resize_clear (.cache/zig/p/N-V-__8AAHjwMQDBXnLq3Q2QhaivE0kE2aD138vtX2Bq1g7c/src/regexec.c:949)
==265734==    by 0x3DA814F: search_in_range (.cache/zig/p/N-V-__8AAHjwMQDBXnLq3Q2QhaivE0kE2aD138vtX2Bq1g7c/src/regexec.c:5454)
==265734==    by 0x3DA7F25: onig_search (.cache/zig/p/N-V-__8AAHjwMQDBXnLq3Q2QhaivE0kE2aD138vtX2Bq1g7c/src/regexec.c:5414)
==265734==    by 0x382E7E8: regex.Regex.searchAdvanced (regex.zig:61)
==265734==    by 0x382E974: regex.Regex.search (regex.zig:48)
==265734==    by 0x382EC08: terminal.StringMap.SearchIterator.next (StringMap.zig:40)
==265734==    by 0x39ADDCD: renderer.link.Set.matchSetFromLinks (link.zig:320)
==265734==    by 0x39AE5C7: renderer.link.Set.matchSet (link.zig:95)
==265734==    by 0x39BCCE1: renderer.generic.Renderer(renderer.OpenGL).rebuildCells (generic.zig:2307)
==265734==    by 0x39C3BDB: renderer.generic.Renderer(renderer.OpenGL).updateFrame (generic.zig:1228)
==265734==    by 0x3993E88: renderer.Thread.renderCallback (Thread.zig:607)
==265734==    by 0x3993CFF: renderer.Thread.wakeupCallback (Thread.zig:524)
==265734==    by 0x39C522E: callback (async.zig:679)
==265734==    by 0x39C522E: watcher.async.AsyncEventFd(api.Xev(.io_uring,backend.io_uring)).waitPoll__anon_592685__struct_596870.callback (async.zig:181)
==265734==    by 0x3970EAE: backend.io_uring.Completion.invoke (io_uring.zig:804)
==265734==    by 0x3973AD8: backend.io_uring.Loop.tick___anon_586861 (io_uring.zig:193)
==265734==    by 0x3973BCD: backend.io_uring.Loop.run (io_uring.zig:84)
==265734==    by 0x3978673: dynamic.Xev(&.{ .io_uring, .epoll }[0..2]).Loop.run (dynamic.zig:172)
==265734==    by 0x3978972: renderer.Thread.threadMain_ (Thread.zig:263)
==265734==    by 0x3954580: renderer.Thread.threadMain (Thread.zig:202)
==265734==    by 0x39279CA: Thread.callFn__anon_573552 (Thread.zig:488)
==265734==    by 0x38F4594: Thread.PosixThreadImpl.spawn__anon_570448.Instance.entryFn (Thread.zig:757)
==265734==    by 0x6E567EA: start_thread (pthread_create.c:448)
==265734==    by 0x6ED9FB3: clone (clone.S:100)
==265734==
```
2025-07-20 14:17:03 -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 c990d35d6d
macos: add benchmark tests to our Xcode project 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto 20bb71c627
libghostty: export benchmark CLI API 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto 01b2545d1d
macos: fix signpost API to use proper mach header base addr 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto d30771ecff
pkg/macos: use new @ptrcast for os.log 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto 8506637ae6
macos: add signpost API 2025-07-09 15:06:23 -07:00
Qwerasd 87f35bd1c1 renderer/opengl: explicit texture options
This sets up for a couple improvments (see TODO comments) and also sets
the glyph atlas textures to nearest neighbor sampling since we can do
that now that we never scale glyphs.
2025-07-05 22:10:39 -06: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
Qwerasd e441094af0 font: add constraint logic to rasterizers
This is in preparation to move constraint off the GPU to simplify our
shaders, instead we only need to constrain once at raster time and never
again.

This also significantly reworks the freetype renderGlyph function to be
generally much cleaner and more straightforward.

This commit doesn't actually apply the constraints to anything yet, that
will be in following commits.
2025-07-04 15:47:28 -06: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
Leah Amelia Chen 5fa737834b
gtk(wayland): prevent gtk4-layer-shell crash on old versions
Supersedes #7154

In gtk4-layer-shell versions < 1.0.4, the app could crash upon opening
a quick terminal window on certain compositors that implement the
`xdg_wm_dialog_v1` protocol. The exact reason is a bit complicated,
but is nicely summarized in the upstream issue (wmww/gtk4-layer-shell#50).

The circumstances that could cause this crash to occur should gradually
diminish as distros update to newer gtk4-layer-shell versions, but this
is known to crash on Fedora 41 and Hyprland, which could be a sizable
chunk of our userbase given that this would also occur on GNOME/Mutter
and KDE/KWin. The diff should be minimal enough that this can be removed
or reverted once this band-aid fix is no longer necessary.
2025-06-28 16:41:19 +02:00
Qwerasd 5cb175ff63 renderer/OpenGL: use compressed texture formats for images
BPTC is required to be available OpenGL >= 4.2 and our minimum is 4.3 so
this is safe in terms of support. I tested briefly in a VM and didn't
encounter any problems so this should just be a complete win.

(Note: texture data is already automatically compressed on Metal)
2025-06-25 16:27:23 -04:00
Qwerasd 03bdb92292 renderer: clean up `image.zig`, reduce repetitive code 2025-06-25 16:27:23 -04:00
Qwerasd df8dc33ab6 renderer: unify `image.zig`
The code in metal/image.zig and opengl/image.zig was virtually identical
save for the texture options, so I've moved that to the GraphicsAPI and
unified them in to renderer/image.zig
2025-06-23 13:12:17 -06:00
Qwerasd 5bfdb1b9cf
The Big Renderer Rework (#7620)
It's here, the long-foretold and long-procrastinated renderer rework!
Hopefully this makes it easier to adapt and modify the renderer in the
future and ensures feature parity between Metal and OpenGL. Despite
having been a lot of work to write initially, with the abstraction layer
in place I feel like working on the renderer will be a much more
pleasant experience going forward.

## Key points
- CPU-side renderer logic is now mostly unified via a generic
`Renderer`.
- A graphics API abstraction layer over OpenGL and Metal has been
introduced.
- Minimum OpenGL version bumped to `4.3`, so can no longer be run on
macOS; I used the nix VM stuff for my testing during development. (Edit
by @mitchellh: Note for readers that Ghostty still works on macOS, but
the OpenGL backend doesn't, only the Metal one)
- The OpenGL backend now supports linear blending! Woohoo! The default
`alpha-blending` has been updated to `linear-corrected` since it's
essentially a strict improvement over `native`. The default on macOS is
still `native` though to match other mac apps in appearance, since macOS
users are more sensitive to text appearance.
- Custom shaders can now be hot reloaded.
- The background color is once again drawn by us, so custom shaders can
interact with it properly. In general, custom shaders should be a little
more robust.

## The abstraction layer
The general hierarchy of the abstraction layer is as such:
```
 [ GraphicsAPI ] - Responsible for configuring the runtime surface
    |     |        and providing render `Target`s that draw to it,
    |     |        as well as `Frame`s and `Pipeline`s.
    |     V
    | [ Target ] - Represents an abstract target for rendering, which
    |              could be a surface directly but is also used as an
    |              abstraction for off-screen frame buffers.
    V
 [ Frame ] - Represents the context for drawing a given frame,
    |        provides `RenderPass`es for issuing draw commands
    |        to, and reports the frame health when complete.
    V
 [ RenderPass ] - Represents a render pass in a frame, consisting of
   :              one or more `Step`s applied to the same target(s),
 [ Step ] - - - - each describing the input buffers and textures and
   :              the vertex/fragment functions and geometry to use.
   :_ _ _ _ _ _ _ _ _ _/
   v
 [ Pipeline ] - Describes a vertex and fragment function to be used
                for a `Step`; the `GraphicsAPI` is responsible for
                these and they should be constructed and cached
                ahead of time.

 [ Buffer ] - An abstraction over a GPU buffer.

 [ Texture ] - An abstraction over a GPU texture.
```
More specific documentation can be found on the relevant structures.

## Miscellany
Renderers (which effectively just means the generic renderer) are now
expected to only touch GPU resources in `init`, certain lifecycle
functions such as the `displayRealized`/`displayUnrealized` callbacks
from GTK-- and `drawFrame`; and are also expected to be thread-safe.
This allows the renderer thread to build the CPU-side buffers
(`updateFrame`) even if we can only *draw* from the app thread.

Because of this change, we can draw synchronously from the main thread
on macOS when necessary to always have a frame of the correct size
during a resize animation. This was necessary to allow the background to
be drawn by our GPU code (instead of setting a background color on the
layer) while still avoiding holes during resize.

The OpenGL backend now theoretically has access to multi-buffering, but
it's disabled (by setting the buffer count to 1) because it
synchronously waits for frames to complete anyway which means that the
extra buffers were just a waste of memory.

## Validation
To validate that there are no significant or obvious problems, I
exercised both backends with a variety of configurations, and visually
inspected the results. Everything looks to be in order.

The images are available in a gist here:
https://gist.github.com/qwerasd205/c1bd3e4c694d888e41612e53c0560179

## Memory
Here's a comparison of memory usage for ReleaseFast builds on macOS,
between `main` and this branch.
Memory figures given are values from Activity Monitor measuring windows
of the same size, with two tabs with 3 splits each.

||Before|After|
|-:|-|-|
|**Memory**|247.9 MB|224.2 MB|
|**Real Memory**|174.4 MB|172.5 MB|

Happily, the rework has slightly *reduced* the memory footprint- likely
due to removing the overhead of `CAMetalLayer`. (The footprint could be
reduced much further if we got rid of multi-buffering and satisfied
ourselves with blocking for each frame, but that's a discussion for
another day.)

If someone could do a similar comparison for Linux, that'd be much
appreciated!

## Notes / future work
- There are a couple structures that *can* be unified using the
abstraction layer, but I haven't gotten around to unifying yet.
Specifically, in `renderer/(opengl|metal)/`, there's `cell.zig` and
`image.zig`, both of which are substantially identical between the two
backends. `shaders.zig` may also be a candidate for unification, but
that might be *overly* DRY.
- ~~I did not double-check the documentation for config options, which
may mention whether certain options can be hot-reloaded; if it does then
that will need to be updated.~~ Fixed: be5908f
- The `fragCoord` for custom shaders originates at the top left for
Metal, but *bottom* left for OpenGL; fixing this will be a bit annoying,
since the screen texture is likewise vertically flipped between the two.
Some shaders rely on the fragcoord for things like falling particles, so
this does need to be fixed.
- `Target` should be improved to support multiple types of targets right
now it only represents a framebuffer or iosurface, but it should also be
able to represent a texture; right now a kind of messy tagged union is
used so that steps can accept both.
- Custom shader cursor uniforms (#6912) and terminal background images
(#4226, #5233) should be much more straightforward to implement on top
of this rework, and I plan to make follow-up PRs for them once this is
merged.
- I *do* want to do a rework of the pipelines themselves, since the way
we're rendering stuff is a bit messy currently, but this is already a
huge enough PR as it is- so for now the renderer still uses the same
rendering passes that Metal did before.
- We should probably add a system requirements section to the README
where we can note the minimum required OpenGL version of `4.3`, any even
slightly modern Linux system will support this, but it would be good to
document it somewhere user-facing anyway.

# TODO BEFORE MERGE
- [x] Have multiple people test this on both macOS and linux.
- [ ] ~~Have someone with a better dev setup on linux check for memory
leaks and other problems.~~ (Skipped, will merge and let tip users
figure this out, someone should *specifically* look for memory leaks
before the next versioned release though.)
- [x] Address any code review feedback.
2025-06-21 22:00:01 -06:00
-k 89b39775e5 build: fix `fontconfig` paths on FreeBSD 2025-06-21 14:11:50 -07:00
Qwerasd ea7a91e2ba style(renderer): explicit error sets 2025-06-20 15:18:41 -06:00
Qwerasd ea1e507af7 unwrap unnecessary @"" identifiers 2025-06-20 15:18:41 -06:00
Qwerasd 371d62a82c renderer: big rework, graphics API abstraction layers, unified logic
This commit is very large, representing about a month of work with many
interdependent changes that don't separate cleanly in to atomic commits.

The main change here is unifying the renderer logic to a single generic
renderer, implemented on top of an abstraction layer over OpenGL/Metal.

I'll write a more complete summary of the changes in the description of
the PR.
2025-06-20 15:18:41 -06:00
Qwerasd 3d692e46f4 license: update copyright notices to include contributors
Updates all copyright notices to include "Ghostty contributors" to
reflect the fact that Mitchell is not the sole copyright owner.

Also adds "Ghostty contributors" to the author section in the manpages,
linking https://github.com/ghostty-org/ghostty/graphs/contributors for
proper credit.
2025-06-10 10:20:26 -06:00
Leah Amelia Chen 6959fa8438
gtk(wayland): explicitly set layer name
Even though gtk4-layer-shell's documentation claims that "nobody quite
knows what it's for", some compositors (like Niri) can define custom
rules based on the layer name and it's beneficial in those cases to
define a distinct name just for our quick terminals.
2025-05-30 19:26:18 +02:00
Leah Amelia Chen 6fac355363
gtk(wayland): fallback when on-demand mode isn't supported
This shouldn't be a real problem anymore since as of now (May 2025)
all major compositors support at least version 4, but let's do this
just in case.
2025-05-30 19:26:18 +02:00
Mitchell Hashimoto 0f1860f066
build: use a libc txt file to point to correct Apple SDK
This fixes an issue where Ghostty would not build against the macOS 15.5 SDK.

What was happening was that Zig was adding its embedded libc paths to
the clang command line, which included old headers that were
incompatible with the latest (macOS 15.5) SDK. Ghostty was adding the
newer paths but they were being overridden by the embedded libc paths.

The reason this was happening is because Zig was using its own logic to
find the libc paths and this was colliding with the paths we were
setting manually. To fix this, we now use a `libc.txt` file that
explicitly tells Zig where to find libc, and we base this on our own SDK
search logic.
2025-05-29 15:04:05 -07:00
Qwerasd 2384bd69cc style: use decl literals
This commit changes a LOT of areas of the code to use decl literals
instead of redundantly referring to the type.

These changes were mostly driven by some regex searches and then manual
adjustment on a case-by-case basis.

I almost certainly missed quite a few places where decl literals could
be used, but this is a good first step in converting things, and other
instances can be addressed when they're discovered.

I tested GLFW+Metal and building the framework on macOS and tested a GTK
build on Linux, so I'm 99% sure I didn't introduce any syntax errors or
other problems with this. (fingers crossed)
2025-05-26 21:50:14 -06:00
Qwerasd ea79fdea11 fix(OpenGL): use sRGB texture format for gamma correct interpolation
otherwise images will be too dark when scaled
2025-05-15 12:44:44 -06:00
Jeffrey C. Ollie e8c845b758
core: fixup callconv(.C) -> callconv(.c)
https://ziglang.org/download/0.14.0/release-notes.html#Calling-Convention-Enhancements-and-setAlignStack-Replaced
2025-05-07 08:41:09 -05:00
Mitchell Hashimoto 89728070e9
pkg/harfbuzz: update 8.4 => 11.0
This updates our bundled Harfbuzz from 8.4 to 11.0. The changes from 8
to 11 include a number of correctness and performance improvements.
Packaged releases tend to dynamically link so this won't affect
existing users, but build-from-source users hopefully get an
improvement.
2025-03-24 10:04:11 -07:00
Mitchell Hashimoto 8cc5ee39d0
pkg/glfw: update to HEAD as of 2025-03-24
We have always tracked a post-3.4 release, this brings us up to date.
There's no real motivation beyond this other than keeping up to date
since we're already on non-release versions anyways.
2025-03-24 09:56:55 -07:00
Qwerasd 6f84a5d682 font/freetype: disable SVG glyphs, simplify color check
We don't currently support rendering SVG glyphs so they should be
ignored when loading. Additionally, the check for whether a glyph is
colored has been simplified by just checking the pixel mode of the
rendered bitmap.

This commit also fixes a bug caused by calling the color check inside of
`renderGlyph`, which caused the bitmap to be freed creating a chance for
memory corruption and garbled glyphs.
2025-03-19 12:43:18 -06:00
Mitchell Hashimoto 4d0bf303c6
ci: zig fmt check
This adds a CI test to ensure that all Zig files are properly formatted.
This avoids unrelated diff noise in future PRs.
2025-03-18 13:58:49 -07:00
Mitchell Hashimoto 5ad8ea6b22
pkg/macos: clean up for Zig 0.14, consolidate C imports into one decl
Fixes #6727

The major change in this commit is to consolidate all the C imports in
a single decl in main.zig. This is required for Zig 0.14. Without it,
the problem in #6727 will happen. I was never able to minimize why this
happens in order to open a Zig bug.

Beyond this, I fixed the build.zig and build.zig.zon to work with Zig
0.14 so that we can test building `pkg/macos` in isolation. There are no
downstream impacting changes in the build.zig files.
2025-03-15 07:02:53 -07:00
Mitchell Hashimoto cfea2ea12c
build: mark most dependencies as lazy
Lazy dependencies are only fetched if the build script would actually
reach a usage of that dependency at runtime (when the `lazyDependency`
function is called). This can save a lot of network traffic, disk uage,
and time because we don't have to fetch and build dependencies that we
don't actually need.

Prior to this commit, Ghostty fetched almost everything for all
platforms and configurations all the time. This commit reverses that to
fetching almost nothing until it's actually needed.

There are very little downsides to doing this[1]. One downside is `zig
build --fetch` doesn't fetch lazy dependencies, but we don't rely on
this command for packaging and suggest using our custom shell script
that downloads a cached list of URLs (`build.zig.zon.txt`).

This commit doesn't cover 100% of dependencies, since some provide no
benefit to make lazy while the complexity to make them lazy is higher
(in code style typically).

Conversely, some simple dependencies are marked lazy even if they're
almost always needed if they don't introduce any real complexity to the
code, because there is very little downside to do so.

[1]: https://ziggit.dev/t/lazy-dependencies-best-dependencies/5509/5
2025-03-14 13:32:19 -07:00
Mitchell Hashimoto 221f905a1c
pkg/glfw
Closes #6702

This removes our mach-glfw dependency and replaces it with an in-tree
pkg/glfw that includes both the source for compiling glfw as well as the
Zig bindings. This matches the pattern from our other packages.

This is based on the upstream mach-glfw work and therefore includes the
original license and copyright information.

The reasoning is stated in the issue but to summarize for the commit:

  - mach-glfw is no longer maintained, so we have to take ownership
  - mach-glfw depended on some large blobs of header files to enable
    cross-compilation but this isn't something we actually care about,
    so we can (and do) drop the blobs
  - mach-glfw blobs were hosted on mach hosts. given mach-glfw is
    unmaintained, we can't rely on this hosting
  - mach-glfw relied on a "glfw" package which was owned by another
    person to be Zig 0.14 compatible, but we no longer need to rely on
    this
  - mach-glfw builds were outdated based on latest Zig practices
2025-03-13 20:52:33 -07:00
Mitchell Hashimoto a542e63582
pkg/gtk4-layer-shell: disable ubsan 2025-03-13 09:14:37 -07:00
Mitchell Hashimoto bdb66984b6
for iOS simulator builds for apple M1 as base CPU model 2025-03-13 07:13:13 -07:00
Mitchell Hashimoto b96a5d702b
fix mach-glfw on windows 2025-03-12 16:29:17 -07:00
Mitchell Hashimoto 816ff8cef0
fix tests building on Linux 2025-03-12 11:29:13 -07:00
Mitchell Hashimoto 601acf4059
pkg/highway: upgrade to fix compilation issues on LLVM18 2025-03-12 11:03:54 -07:00
Mitchell Hashimoto 7e9be00924
working on macos 2025-03-12 10:15:14 -07:00
Mitchell Hashimoto 2408d4c6a9
more fixes 2025-03-12 09:59:24 -07:00
Mitchell Hashimoto 86d3f18707
pkg/oniguruma: fix build 2025-03-12 09:10:17 -07:00
Mitchell Hashimoto bd848a27d2
update all packages to new hash for caching 2025-03-12 07:30:01 -07:00
Mitchell Hashimoto 2466de4556
pkg: update to new build.zig.zon format and hash values 2025-03-11 15:00:47 -07:00
Mitchell Hashimoto 7e2286eb8c
Zig 0.14 2025-03-11 14:39:04 -07:00
azhn 35aab1a302 build: use pkgconfig name for gtk4-layer-shell system integration
By linking using the pkg-config name we gain the compiler flags in pkgconf
for linking, specifically the -I <headers> to include system-installed
headers. This allows the gtk4-layer-shell pkg to not require the source
files specified in the `pkg/gtk4-layer-shell/build.zig.zon`.

pkg(gtk4-layer-shell): Refactor to allow dynamic linking

Refactored `pkg/gtk4-layer-shell/build.zig` to have similar structure
to `pkg/oniguruma/build.zig`.

Now dynamic link using pkgconfig, this adds pkgconfig compiler flags.
So we are now using system-installed headers to resolve @cInclude().
2025-03-09 02:46:33 +11:00
Mitchell Hashimoto e8c20b5501
pkg/libintl: fix missing symbols 2025-03-07 13:42:00 -08:00
Mitchell Hashimoto dd95f727ec
build: add libintl for macOS builds 2025-03-07 13:41:59 -08:00
Mitchell Hashimoto 67488754d5
pkg/libintl 2025-03-07 13:41:59 -08:00
Leah Amelia Chen cd442eb9e2
gtk: build gtk4-layer-shell ourselves
As of now `gtk4-layer-shell` is unavailable on recent, stable releases
of many distros (Debian 12, Ubuntu 24.04, openSUSE Leap & Tumbleweed, etc.)
and outdated on many others (Nixpkgs 24.11/unstable, Fedora 41, etc.)
This is inconvenient for our users and severely limits where the quick
terminal can be used. As a result we then build gtk4-layer-shell ourselves
by default unless `--system` or `-fsys=gtk4-layer-shell` are specified.
This also allows me to add an idiomatic Zig API on top of the library
and avoiding adding even more raw C code in the GTK apprt.

Since we now build gtk4-layer-shell it should be theoretically available
on all Linux systems we target. As such, the `-Dgtk-layer-shell` build
option has been removed. This is somewhat of an experimental change as
I don't know if gtk4-layer-shell works perfectly across all distros, and
we can always add the option back if need be.
2025-03-07 17:52:06 +01:00
Mitchell Hashimoto 8231ebb770
build: mirror most of our direct dependencies
This adds a new script `update-mirror.sh` which generates the proper
blob format for R2 (or any blob storage) to mirror all of our
dependencies.

It doesn't automate updating build.zig.zon but on an ongoing basis this
should be easy to do manually, and we can strive to automate it in the
future.

I omitted iTerm2 color themes because we auto-update that via CI and
updating all of the machinery to send it to our mirror and so on is a
pain. Additionally, this doesn't mirror transitive dependencies because
Zig doesn't have a way to fetch those from a mirror instead (unless you
pre-generate a full cache like packagers but that's not practical for
day to day development).

It's hugely beneficial just to get most of our dependencies mirrored.
2025-02-14 10:06:15 -08:00
Jeffrey C. Ollie f32ad5216b build: generate a build.zig.zon.txt file for easy zig fetch scripting
This fixes a regression in 1.1.1/1.1.2 where our PACKAGING docs mention
using `fetch-zig-cache.sh` but it was removed. This commit adds it back,
generating its contents from the build.zig.zon file (via zon2nix which
we use for our Nix packaging).

For packagers, there are no dependency changes: you still need Zig and
POSIX sh. For release time, Ghostty has a new dependency on `jq` but
otherwise the release process is the same. The check-zig-cache.sh script
is updated to generate the new build.zig.zon.txt file.
2025-02-14 09:23:51 -08:00
Julia 9c8c53bffb
use main buffer and copy data to fbo texture (opengl) (#5294)
NEEDS REVIEW

continuation of #5037
resolves #4729 

renders all shaders to the default buffer and then copies it to the
designated custom shader texture.

this is a draft pr because:
- it introduces a new shader "pipeline" which doesnt fit in with how the
system was designed to work (which is only rendering to the fbo)
- im not sure if this is the best way to achieve shaders being able to
sample their output while also drawing to the screen. the cusom fbo
(previous implementation) was useful in that it modularized the custom
shader stage in rendering

---------

Co-authored-by: Mitchell Hashimoto <m@mitchellh.com>
2025-01-23 20:57:14 +00:00
Qwerasd c2da843dfd fix(wuffs): don't premul alpha when loading images
It seems like the raw data version of the kitty graphics transmit
operation is meant to be unassociated (aka straight) alpha, though I
can't find any definitive documentation either way- but in any case
unassociated alpha is more common in image formats and makes the
handling easier for the rest of it.

Also removed a redundant call to `decode_frame_config`, since it's
called implicitly when we call `decode_frame` right after.
2025-01-17 14:38:38 -05:00
Qwerasd fca336c32d Metal: blend in Display P3 color space, add option for linear blending
This commit is quite large because it's fairly interconnected and can't
be split up in a logical way. The main part of this commit is that alpha
blending is now always done in the Display P3 color space, and depending
on the configured `window-colorspace` colors will be converted from sRGB
or assumed to already be Display P3 colors. In addition, a config option
`text-blending` has been added which allows the user to configure linear
blending (AKA "gamma correction"). Linear alpha blending also applies to
images and makes custom shaders receive linear colors rather than sRGB.

In addition, an experimental option has been added which corrects linear
blending's tendency to make dark text look too thin and bright text look
too thick. Essentially it's a correction curve on the alpha channel that
depends on the luminance of the glyph being drawn.
2025-01-13 13:50:29 -08:00
Jan200101 0493b79caf
don't make library building logic public 2025-01-03 22:42:29 +01:00
Jan200101 1dc9157727
always link system freetype2 using pkg-config 2025-01-03 22:42:01 +01:00
Jan200101 72e0fb14fe
don't build freetype2 when system integration is enabled 2025-01-03 22:41:15 +01:00
Jan200101 dc90ef776e
don't build oniguruma when system integration is enabled 2025-01-03 21:27:22 +01:00
Jan200101 9d286de834
don't build fontconfig when system integration is enabled 2025-01-03 18:39:11 +01:00
Mitchell Hashimoto 7eb35d7275
Fix: Correct version strings for simdutf and cimgui to match vendored files (#4468)
The cimgui version listed does not match the upstream commit or the
vendored cimgui files
Checking the upstream `git log` the commit corresponds to `commit
e391fe2e66eb1c96b1624ae8444dc64c23146ef4 (tag: v1.90.6-docking)` however
the `build.zig.zon` is outdated.
The vendored cimgui files also contain the header
```cpp
// This file is automatically generated by generator.lua from
// https://github.com/cimgui/cimgui based on imgui.h file version "1.90.6" 19060
// from Dear ImGui https://github.com/ocornut/imgui with imgui_internal.h api
// docking branch
```

I wasn't too clear with what the comment meant:
```
// This should be kept in sync with the submodule in the cimgui source
// code to be safe that they're compatible.
```
and assumed it was referring to the vendored cimgui files, added a
comment pointing out where to find the cimgui source mentioned.
2025-01-03 09:13:52 -08:00
azhn 65a0fa4f35 Fix: Update pkg/simdutf/build.zig.zon to match vendored version 2025-01-03 18:22:24 +11:00
azhn 29f040716c Fix cimgui version string to match pkg/cimgui/vendor/ and the upstream version 2025-01-03 17:47:50 +11:00
Mitchell Hashimoto 405fe377d2
wuffs: update, add jpeg decoding, add simple tests (#4250)
1. Update wuffs to v0.4.0-alpha.9
2. Add JPEG decoding
3. Add basic unit tests for image decoding
4. Add CI jobs to run wuffs unit tests.
2025-01-02 15:24:28 -08:00
Jeffrey C. Ollie 22c2fe9610
wuffs: use common struct to return decoded image data 2025-01-01 22:48:30 -06:00
Jeffrey C. Ollie 652079b26c
wuffs: update, add jpeg decoding, add simple tests 2025-01-01 22:48:30 -06:00
Jan200101 5957e1101c
don't build harfbuzz when system integration is enabled 2024-12-31 21:09:13 +01:00
Mitchell Hashimoto c74966e07e
build: change object story domain to ghostty.org 2024-12-20 08:58:46 -08:00
Qwerasd 5cd214066d font(coretext): tolerate fonts without OS/2 tables
This creates big problems if we don't, since a lot of symbols end up
falling back to Apple Gothic, which doesn't have an OS/2 table.
2024-12-16 14:52:07 -05:00
Qwerasd 8a5d484729 font: more robust extraction of vertical metrics from tables
Previously always assuming the typo metrics were good caused some fonts
to have abnormally short cell heights.
2024-12-13 13:00:03 -05:00
Qwerasd fb50143cec font(coretext): add metrics test case for CT, fix variable font init
Variable font init used to just select the first available predefined
instance, if there were any, which is often not desirable- using
createFontDescriptorFromData instead of createFontDescritorsFromData
ensures that the default variation config is selected. In the future we
should probably allow selection of predefined instances, but for now
this is the correct behavior.

I found this bug when adding the metrics calculation test case for
CoreText, hence why fixing it is part of the same commit.
2024-12-11 21:14:21 -05:00
Qwerasd bd18452310 font: unify metrics calculations & separate sprite metrics
Unify grid metrics calculations by relying on shared logic mostly based
on values directly from the font tables, this deduplicates a lot of code
and gives us more control over how we interpret various metrics.

Also separate metrics for underlined, strikethrough, and overline
thickness and position, and box drawing thickness, so that they can
individually be adjusted as the user desires.
2024-12-11 16:55:52 -05:00