Skip to content

backend: fizzy's native backend is a package of its own - #312

Merged
foxnne merged 2 commits into
mainfrom
backend/package
Oct 10, 2026
Merged

foxnne merged 2 commits into
mainfrom
backend/package

Conversation

@foxnne

@foxnne foxnne commented Oct 9, 2026 •

Copy link
Copy Markdown
Collaborator

Part of #281

What changes

Fizzy's native backend is now a package of its own, backend/, beside sdk/. It is the first step toward a plain dvui app on fizzy's backend without the rest of fizzy (fizzyedit/example-app's run-dvui). Nothing changes in behaviour.

  • Moved, unchanged: src/backend/native/** → backend/src/**, i.e. SDLBackend, GpuRenderer, viewport_map, platform/** with its Objective-C, and the shaders. The layout under src/ is the same, so no relative import or @embedFile inside it changes.
  • backend/build.zig.zon pins SDL (fizzyedit/sdl_zig), zig-objc and zigwin32. They leave the root build.zig.zon ("one pin, held by whoever uses it"). It pins no dvui: the caller's dvui is passed in, so dvui stays pinned in sdk/ alone.
  • backend/build.zig is build/exe.zig's fizzyNativeDvui and platformModule, moved:
    • backendModule(dep, dvui, opts) wires the backend under a dvui built in custom mode;
    • platformModule(dep, dvui, backend, opts) gives the platform pieces to an app on this backend or dvui's SDL3 one;
    • objcModule and win32Module are fizzy's own way to zig-objc and zigwin32.
    • addPlatformObjC(dep, root_module, opts) adds the platform's Objective-C to an app's executable, where fizzy compiled it before. The platform module does not carry it, because it calls back into the platform's Zig by name, and a compile that imports the backend without reaching that Zig fails to link. backend: health counters the native backend keeps current #309's test of the backend alone did exactly that. The backend's own macos_monitor.m stays on its module, where what it calls resolves.
    • The backend's std-only tests (unit_tests, now with backend: health counters the native backend keeps current #309's Health.zig) run under its own zig build test and still under fizzy's.
  • Fizzy depends on it by path (.fizzy_backend, listed in .paths for URL consumers). The docs that said where SDL is pinned (docs/DEPENDENCIES.md, docs/MACOS_LIVE_RESIZE.md), CLAUDE.md's map and comments that named the old paths are updated.

Left for the next steps in #281: the viewports API, which is generic but still in fizzy's glue file, moves in its own PR to keep this one a pure move. After that come Popout's general half and run-dvui.

Merged with main after #309 (backend health counters), #314 (SDL pin) and #315 (Linux): their edits come along into backend/, and #314's pin is the one in backend/build.zig.zon.

SDK impact

  • None. Plugins never link the backend; test-sdk-version passes unchanged.

Verified

  • macOS:
    • On the merge with main: zig build 43/43; test 512/513 (1 skipped), with the backend's unit-test roots still run; test-integration 44/44 steps, 358 tests; check-web; test-sdk-version.
    • The backend's own zig build test: 46 tests.
    • An explicit -Dtarget=aarch64-macos build (43/43), which takes the path that hands the macOS SDK to the Objective-C.
    • scripts/check-examples.sh against this tree: example-plugin 28/28; example-app minimal, studio, endless 30/30, studio as data 31/31. So backend/ reaches a URL consumer.
    • CLAUDE.md's build-graph acceptance test (plugins/image, clean, ReleaseFast): no Velopack, and not the backend's SDL, in its zig-pkg.
    • The app in a sandbox profile, on the merge: Metal renderer, fizzy's SDL live-resize patch active, the native menu bar built (4 menus, 21 items: the platform's Objective-C linked and working), window and glass as before.
  • Windows: cross-build (-Dtarget=x86_64-windows-gnu) 41/41; not run natively.
  • Linux: CI.
  • Web: check-web only (the web backend is unchanged).

🤖 Generated with Claude Code

`src/backend/native` becomes `backend/`, a package beside `sdk/`: SDLBackend, GpuRenderer,
viewport_map, platform/** and the shaders, with SDL, zig-objc and zigwin32 pinned in its own
build.zig.zon. Its build.zig wires it under the caller's dvui (`backendModule`, `platformModule`)
and attaches its Objective-C to its own modules rather than to fizzy's executable; dvui stays
pinned in sdk/ alone. Fizzy depends on it by path and reaches objc and win32 through it. No change
in behaviour: the first step toward an app on dvui and this backend without the rest of fizzy.
@foxnne

foxnne commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

Heads-up from #314: it moves the root build.zig.zon .sdl pin from sdl_zig fizzy-1.0.3+3.4.16-8 (a02dda8) to fizzy-1.0.3+3.4.16-9 (5e41c70, hash sdl-1.0.3+3.4.16-i4QD0UwUqgA04UDxXFbmfpE1e2Oo6wwX0LJuIMG82mis): Wayland frame-inset fixes, no API change for the backend. This PR moves that pin into backend/build.zig.zon, so whichever lands second should carry the -9 URL and hash into the other's location.

foxnne added a commit that referenced this pull request Oct 10, 2026
…#314)

Part of #280 (step C2b landed on the forks).

Moves fizzy's `.sdl` pin to sdl_zig `fizzy-1.0.3+3.4.16-9` (SDL
`fizzy-3.4.16-9`), which fixes six problems in SDL patch 6 (Wayland
frame insets, the margins fizzy draws its Linux window shadow in):

| Fix | SDL commit | Shown by the suite |
|---|---|---|
| A window SDL makes again (e.g. for an OpenGL renderer) keeps its
insets | `9258288` | yes |
| An opaque window's opaque region is its frame, not its shadow |
`0ca75f2` | yes |
| The compositor's toplevel bounds are widened by the insets before the
clamp | `0426af9` | no: weston never sends bounds |
| The input band is a creation property,
`SDL_PROP_WINDOW_CREATE_WAYLAND_FRAME_INPUT_MARGIN_NUMBER` (default 8) |
`91b7a29` | yes |
| The insets are published from creation, not only after show |
`883f5c8` | yes |
| A window hidden and shown again is framed again | `011a2dc` | yes (new
bug, found while testing) |

Fork PRs: fizzyedit/SDL#4 → `fizzy-3.4.16-9`, fizzyedit/sdl_zig#4 →
`fizzy-1.0.3+3.4.16-9`.
- [Red](https://github.com/fizzyedit/sdl_zig/actions/runs/38000927122):
with only the test commit, every new assertion fails at scale 1 and 2.
-
[Green](https://github.com/fizzyedit/sdl_zig/actions/runs/38001031572):
with the fixes, all 9 Wayland tests pass at both scales.

Fizzy's own use (`linux_titlebar.zig`) is unchanged: it keeps the
default band, and its insets now also survive a recreate.

**For later:** upstream SDL `main` gained its own version of frame
insets on 2026-09-24. It isn't in `release-3.4.x`, and it has none of
these fixes. `docs/DEPENDENCIES.md` now says to move fizzy to upstream's
API at the rebase onto a release that has it, keeping only what upstream
lacks as patches.

**#312 overlaps:** it moves this pin from the root `build.zig.zon` into
`backend/build.zig.zon`. Whichever PR lands second carries the `-9` pin
into the other's location.

## Verified

On macOS (arm64), in a fresh workspace on `main`:

| Gate | Result |
|---|---|
| `zig build` | 43/43 steps |
| `zig build test` | 75/75 steps |
| `zig build test-integration` | 35/35 steps, 354/354 tests |
| `zig build check-web` | 16/16 steps |
| `zig build test-sdk-version` | 12/12 steps |
| `zig build -Dtarget=x86_64-linux-gnu` | 54/54 steps (builds the
changed Wayland code) |

Not verified: the fixes on a real GNOME desktop with fizzy itself. The
evidence is the fork's suite under headless weston. The SDK fingerprint
doesn't move, since plugins never link SDL.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@foxnne
foxnne marked this pull request as ready for review October 10, 2026 00:57
@foxnne
foxnne enabled auto-merge (squash) October 10, 2026 01:06
The move redone on main: #309's Health.zig and its test, #314's SDL pin (now in
backend/build.zig.zon) and #315's Linux edits come along into backend/. The platform's
Objective-C is linked into the executable again (addPlatformObjC), not carried by the platform
module: it calls back into the platform's Zig, which #309's test of the backend alone never
reaches, so that test failed to link. Drops the .sb/ sandbox profile this branch had picked up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@foxnne
foxnne merged commit 0e3fbd9 into main Oct 10, 2026
10 checks passed
@foxnne
foxnne deleted the backend/package branch October 10, 2026 01:32
@foxnne foxnne mentioned this pull request Oct 10, 2026
2 of 8 tasks
foxnne added a commit that referenced this pull request Oct 10, 2026
## What changes

`sdk_version` goes from 0.2.19 to 0.2.20. Merging tags `sdk-v0.2.20`,
publishes its tarball,
and asks the store plugins to repin.

**Why now.** The plugin boundary's fingerprint has not moved since
`sdk-v0.2.19`
(`0x7b455e7a…` both), so plugins built against 0.2.19 still load. But
`core/` and `sdk/replay`
changes merged since then reach plugins only through a release, and the
agent plugin
(`fizzyedit/agent`, private until it can pin a released SDK) needs one
of them: #295's
profiler on request.

## SDK impact

- [ ] None
- [ ] Core-only or additive: reaches plugins at the next SDK release
- [ ] Fingerprint moved: recorded in `sdk/src/version.zig`,
`sdk_version` untouched, PR labelled `sdk`
- [x] SDK release: bumps `sdk_version`, lists the `sdk` PRs since the
last `sdk-v*` tag

**The `sdk` PRs since `sdk-v0.2.19`:** none; the fingerprint is
unchanged.

**What reaches plugins (`core/`, `sdk/`):**
- #295: the profiler records on request (`core.profile.want`) and
reports as ZON
(`core.profile.report`). `Profiler` grew a field (`abi` 3 → 4), so a
plugin records its own
sections into the host's profiler again only once rebuilt against this
release.
- #310: `replay.Input.synthetic`, which tells a tape's key from the
OS's.
- #293: the replay `Player` plays and seeks every bundled demo exactly.
- #313: `core.dialogs` changes for a run of the real app that plays a
tape to a verdict.
- #312: `core/gfx`'s programs and the liquid-glass shader, now that the
native backend is a
  package of its own.
- #292: `sdk/plugin_sdk.zig` honours `FIZZY_PLUGIN_USE_LLVM`, for
measuring a plugin's rebuild
  loop per code generator.

## Verified

- [x] macOS:
  - `zig build` and `test-sdk-version` on this head.
  - `scripts/pack-sdk.sh` packs `fizzy-sdk-v0.2.20.tar.gz`.
- Every store plugin (fresh clones of pixi, zig, drive, atlas and
ghostty `main`) builds
against this tree's `sdk/` with `zig build --fork=<sdk>` (31/31 and
28/28 steps), installing
into a throwaway profile. The fork matched, and the built plugin reports
`pinned fizzy SDK: 0.2.20`. With the fingerprint unchanged, the repins
should open as plain
    version bumps.
- The agent plugin (path dependency on `main`'s `sdk/`) builds, 21/21
steps.
- [ ] Windows:
- [ ] Linux: CI.
- [ ] Web:

## Follow-ups

- Each repin PR merged and its plugin tagged (the plugin repos' tags
stay the maintainer's).
- `fizzyedit/agent` repins from its local path to the `sdk-v0.2.20`
tarball.
- fizzyedit/example-plugin repins once `PLUGIN_DISPATCH_TOKEN` can reach
it (#281, still open).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant