- Zig 96.6%
- Nix 3.4%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
On Windows the registry's change notification came for the first switch between light and dark and not for the ones after, so the window kept the colors of the first switch. Windows sends every top-level window WM_SETTINGCHANGE on each switch, which wakes the application, so takeIfNewer now reads the two values each time it is called and keeps the notification only to wake it without a message. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01BivPw4GP4cNYFxvVdC256f |
||
| .forgejo/workflows | ||
| dbus | ||
| examples | ||
| LICENSES | ||
| protocols | ||
| shaders | ||
| src | ||
| .gitignore | ||
| build.zig | ||
| build.zig.zon | ||
| build.zig.zon.nix | ||
| CONTRIBUTING.md | ||
| flake.lock | ||
| flake.nix | ||
| README.md | ||
| REUSE.toml | ||
zig-aerie
Windows, a GPU renderer and text, in Zig 0.17, for programs that draw their own interface. It is the stack underneath harrier, a terminal emulator, made into a library so that other programs can draw with it too. The first of those is grebe, a history browser for git.
The API documentation, generated from the doc comments, is at https://jeff.jcollie.page/zig-aerie/.
It runs on Linux under Wayland, and on Windows. It is new: what it offers is what harrier needed, and its interfaces will move as more programs use it.
What it does
-
platform: Wayland, without libwayland or libxkbcommon. Windows go through zig-wayland-native and the keyboard through zig-xkb:- fractional scaling, and server-side decorations where the compositor offers them;
- keys reported with both the text they type and the key they are, key repeat, dead keys and the Compose key;
- input methods through text-input-v3;
- the clipboard and the primary selection;
- drag and drop, both ways;
- cursor shapes, activation tokens, the desktop's bell, and global hotkeys where the compositor has them.
An application owns its loop:
Platform.waitsleeps until the compositor, key repeat, or any file descriptor of the application's own has something, andnextEventhands out what came. -
platform: Windows, on window messages, through zigwin32, speaking the same events: per-monitor DPI, keys with their text and an evdev code and keysym made from the scancode and virtual key, the clipboard in any format with HTML and bitmaps converted, drag and drop through OLE, the window menu, progress on the taskbar button, and a title bar the application draws in the client area while Windows keeps its snap layouts on the maximize button.waitwaits on the message queue and any handle of the application's own. -
gpu: Vulkan, through dma-bufs. A frame is instanced quads — solid rectangles, glyphs out of two atlases, images, and lines at any angle and discs, whose edges are antialiased in the fragment shader — drawn with one pipeline. There is nowl_displayfor a Vulkan swapchain, so the frame is drawn into exportable images the compositor reads directly, in a layout (DRM format modifier) both sides share.- Without modifier support (RADV on Polaris and older, say), the buffer is a linear dma-buf, and the frame is copied into it on the GPU.
- Sync is explicit (linux-drm-syncobj) where the compositor offers it, and implicit otherwise.
- Where no memory can be shared at all, the frame is read back into shared memory.
- On Windows, the frame is copied into a swapchain on the window's Win32 surface.
Canvasbuilds a frame: rectangles, shaped text and images, each cut to a clip rectangle on the CPU as it is added, so a scrolled view draws only inside its place. The same frame can be drawn on the CPU (gpu.cpu), for a drag icon or a test that compares pictures. -
text: fonts, shaped.- Fonts are found the way fontconfig finds them, by
zig-font-config, scanned once for every family an
application uses. Windows has no fontconfig configuration, so one is
written naming its font directories, with
monospace,sans-serif,serifandemojias Windows' own fonts. - A
Familyis a fontconfig name in four styles, each a fallback list. - Text is shaped by zig-font-shaper, a port of HarfBuzz, into glyphs placed in fractional pixels, each with the byte offset of the cluster it came from, so a click finds its place in the text.
- Glyphs are drawn by zig-font-renderer, color ones
too:
COLR,SVG, and the bitmap emoji ofCBDTandsbix. - Emoji are drawn in color. A character UTS #51 shows as an emoji, or one followed by U+FE0F, is drawn from the first font in the fallback order that has it in color; one shown as text, such as ❤ alone, from the first that has it as an outline.
- Fonts are found the way fontconfig finds them, by
zig-font-config, scanned once for every family an
application uses. Windows has no fontconfig configuration, so one is
written naming its font directories, with
-
decor: a title bar and frame, for a compositor that draws none — GNOME's. It draws the title, the close, maximize and minimize buttons, and a border to resize by, and turns presses on them into moves, resizes and clicks. An application can keep room in the bar for buttons of its own, and give it a subtitle — a location, say, cut at its start so that the end of a path and the host before it are what show. -
desktop: the desktop's preferences, from the XDG desktop portal's Settings interface over D-Bus, through mdbus: light or dark, contrast, reduced motion, the accent color, and every other setting the desktop publishes, by namespace and key. AWatcherreads them once and then follows their changes on a thread of its own, and an application waits on its file descriptor beside the platform's. With no portal there are no settings, and the application keeps its defaults.
Using it
Add it to build.zig.zon:
zig fetch --save git+https://git.jcollie.dev/jeff/zig-aerie.git
and import its module:
const aerie = b.dependency("aerie", .{ .target = target, .optimize = optimize });
exe.root_module.addImport("aerie", aerie.module("aerie"));
The module links libc on Linux: the Vulkan loader and its drivers are C
libraries, and are loaded with dlopen. It builds for Windows with the GNU
ABI, -Dtarget=x86_64-windows-gnu, which needs nothing but Zig.
examples/demo.zig is a whole program in under three hundred lines: a
window with a title bar, proportional and monospace text, and a redraw at
every size and scale the compositor gives it.
Building and running
With Nix, everything is in the development shell:
$ nix develop
$ zig build test # the tests
$ zig build run # the demo
$ zig build docs # the API documentation, into zig-out/docs
aerie-demo --snapshot FILE draws the demo's frame on the CPU and writes it
to FILE as a PPM, without a window.
Without Nix you need Zig 0.17.0, and at run time a Vulkan loader and driver and a Wayland compositor, or Windows with a Vulkan driver.
Not yet
- Right-to-left text. Lines are laid out in the order the text comes; there is no bidirectional algorithm.
Where this lives
The code is at https://git.jcollie.dev/jeff/zig-aerie, and mirrored on Tangled at https://tangled.org/jcollie.dev/zig-aerie:
git clone https://git.jcollie.dev/jeff/zig-aerie.git
Report issues and send pull requests on the Tangled mirror. See CONTRIBUTING.md for what to know before changing it.
License
MIT; see LICENSES/MIT.txt. The project follows
REUSE: every file says what it is licensed under.
protocols/gtk-shell.xml is GTK's, under the LGPL 2.1 or later, and is read
only by the build, which generates Zig from it.
References cited
- The Khronos Group. Vulkan 1.4 Specification. https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html
- The Khronos Group. SPIR-V Specification. https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html
- Snektron. vulkan-zig [Computer software]. https://github.com/Snektron/vulkan-zig
- The Wayland project. The Wayland Protocol. https://wayland.freedesktop.org/docs/book/
- The Wayland project. Wayland and wayland-protocols [Computer software]. freedesktop.org. https://gitlab.freedesktop.org/wayland/wayland-protocols
- xdg-activation-v1, ext-background-effect-v1 [Wayland protocols]. wayland-protocols.
- The GTK Team. gtk-shell.xml [Wayland protocol]. GTK. https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gdk/wayland/protocol/gtk-shell.xml
- Brabant, A. xx-hotkey-v1 and vicinae-hotkey-v1 [Wayland protocols]. vicinae-wayland-protocols. https://github.com/vicinaehq/vicinae-wayland-protocols
- The Linux kernel developers. Buffer Sharing and Synchronization (dma-buf). https://docs.kernel.org/driver-api/dma-buf.html
- The Linux kernel developers. drm_fourcc.h and input-event-codes.h. Linux kernel source. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi
- The xkbcommon project. libxkbcommon [Computer software] and The XKB keymap text format, V1. https://xkbcommon.org/doc/current/keymap-text-format-v1.html
- X.Org Foundation. keysymdef.h. xorgproto. https://gitlab.freedesktop.org/xorg/proto/xorgproto/-/blob/master/include/X11/keysymdef.h
- Microsoft. Clipboard Formats, HTML Clipboard Format and BITMAPV5HEADER structure. Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/dataxchg/clipboard-formats
- marlersoft. zigwin32 [Computer software]. https://github.com/marlersoft/zigwin32
- Microsoft. OpenType Specification. https://learn.microsoft.com/en-us/typography/opentype/spec/
- Fontconfig [Computer software]. freedesktop.org. https://gitlab.freedesktop.org/fontconfig/fontconfig
- Unicode Consortium. Unicode Emoji (Unicode Technical Standard #51). https://www.unicode.org/reports/tr51/
- Sandlund, J. uucode [Computer software]. https://github.com/jacobsandlund/uucode
- Hashimoto, M., & Ghostty contributors. Ghostty [Computer software], whose glyph atlas this one is ported from. https://github.com/ghostty-org/ghostty
- Jylänki, J. (2010). A Thousand Ways to Pack the Bin — A Practical Approach to Two-Dimensional Rectangle Bin Packing. https://github.com/juj/RectangleBinPack/blob/master/RectangleBinPack.pdf
- Rougier, N. P. freetype-gl [Computer software]. https://github.com/rougier/freetype-gl
- Vanderson, D., & contributors. dvui [Computer software], whose Vulkan backend's dma-buf presentation this adapts. https://github.com/david-vanderson/dvui
- Gibson, E., & contributors. wio [Computer software], whose native Wayland backend the platform follows. https://git.jcollie.dev/jeff/wio
- Zig contributors. The Zig programming language [Computer software]. https://ziglang.org/
- Free Software Foundation Europe. REUSE Specification, Version 3.3. https://reuse.software/spec-3.3/
- Flatpak and XDG Desktop Portal contributors. XDG Desktop Portal documentation: Settings. https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Settings.html
- Pennington, H., et al. D-Bus Specification. freedesktop.org. https://dbus.freedesktop.org/doc/dbus-specification.html
- Ollie, J. C. zig-wayland-native, zig-xkb, zig-font, zig-font-config, zig-font-renderer, zig-font-shaper, mdbus and zig-dbus-service [Computer software]. https://git.jcollie.dev/jeff