Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
6774f57
app: the crash reporter's docs say a plugin's panic is forwarded (#436)
foxnne Oct 15, 2026
3fe6d6f
sdk: release 0.2.27 (#439)
foxnne Oct 15, 2026
0129bdb
zig: builtin.target.os, .cpu and .abi in place of builtin.os (#435)
foxnne Oct 15, 2026
641b76a
ci: check-examples packs without macOS AppleDouble files (#443)
foxnne Oct 15, 2026
b9ba48a
build: an app lists the fizzy plugins it links (#441)
foxnne Oct 15, 2026
b169188
sdk: a plugin can open a document beside the person (#442)
foxnne Oct 15, 2026
09e13c1
app: an untitled document survives a crash or a restart (#447)
foxnne Oct 15, 2026
5651df9
core: a kept frost reads again under a region's swap (#450)
foxnne Oct 16, 2026
523a89f
core: a canvas the person has not moved fits its pane; Fit to View pu…
foxnne Oct 16, 2026
a254595
core: viewport buttons are glass bubbles; Fit to View is one (#446)
foxnne Oct 16, 2026
1265f60
sdk: the file tree keeps its own folders; files.reveal shows new file…
foxnne Oct 16, 2026
760ea13
core: a row carried out of a tree is the OS's glass, and stays still …
foxnne Oct 16, 2026
0dfdb01
markdown: an inline render no longer shrinks for a frame as it change…
foxnne Oct 16, 2026
c45686c
ci: compiled shaders are built in CI and checked against their HLSL (…
foxnne Oct 16, 2026
07d8b03
app: a link-only build, which loads no plugin at runtime (#445)
foxnne Oct 16, 2026
21e4ccb
tape: steps of a document's history, and a deflated binary form (#453)
foxnne Oct 16, 2026
357a063
shaders: the glass written once, its Metal and GLSL generated (#424)
foxnne Oct 16, 2026
18ce8bb
docs: Fizzy is MIT again; licensing and trademark policy (#440)
foxnne Oct 16, 2026
2180f21
sdk: owners report a document's steps, and apply recorded ones (#456)
foxnne Oct 16, 2026
ae3d39f
tape: a live tape with no ops finishes instead of crashing (#457)
foxnne Oct 16, 2026
22d397c
app: a refused plugin says whether its mode or its SDK shape differs …
foxnne Oct 16, 2026
d1f3586
sdk: release 0.2.28 (#455)
foxnne Oct 16, 2026
66040f9
app: a track per document, recorded behind FIZZY_TRACKS (#459)
foxnne Oct 16, 2026
f6d248b
app: workspaces are views of the app's, behind FIZZY_WORKSPACES (#461)
foxnne Oct 16, 2026
fc1246f
app: tracks measured, with delta checkpoints and a cap (#460)
foxnne Oct 16, 2026
fdb212e
layout: a document lands in any place as a view would (#462)
foxnne Oct 16, 2026
6b527e7
layout: the region picker groups views by the place they are made for…
foxnne Oct 16, 2026
68f6f97
layout: the picker's buttons are named for tapes and agents (#468)
foxnne Oct 16, 2026
ebada7e
layout: a split of a carded place opens even halves (#465)
foxnne Oct 16, 2026
8a8eac7
layout: removing a half that was split again keeps its column (#467)
foxnne Oct 16, 2026
83304c2
layout: the picker lists a view under the place showing it (#470)
foxnne Oct 16, 2026
f6a8f2d
app: workspaces carry an old panes.zon over into the layout (#464)
foxnne Oct 16, 2026
88233a9
layout: test the picker's empty header (#473)
foxnne Oct 16, 2026
3a8031f
app: undo and redo show a document's transport (#472)
foxnne Oct 16, 2026
ef30c0c
sdk: who made each step: Author, act, and the host's author map (#474)
foxnne Oct 16, 2026
6de2df8
app: whose frame it is, and bubbles that say who (#475)
foxnne Oct 16, 2026
0d071c3
layout: a pane writing its tabs back no longer reads freed ids (#476)
foxnne Oct 17, 2026
2606073
text: every step is reported, with the top, and only one hand's typin…
foxnne Oct 17, 2026
6eec457
sdk: release 0.2.29 (#477)
foxnne Oct 17, 2026
7b538aa
ci: compile the unit tests before running them (#469)
foxnne Oct 17, 2026
46ddcd8
zig/0.17: merge main (40 commits, to #469)
foxnne Oct 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,17 @@ jobs:
- name: Fetch dependencies (with retries)
shell: bash
run: bash scripts/ci-retry.sh zig build --fetch
# Every test binary is compiled before any of them runs, so no compiler is alive beside a
# running test. On Windows, Zig 0.16 spawns each child inheriting every inheritable handle
# the build runner holds, the pipes it is making for its other children included. A
# compiler spawned while a test's pipes exist keeps a copy of that test's stdout: the test
# passes and exits, but its stdout reaches EOF only when the compiler exits, and the runner
# gives up after a minute with "test runner failed to respond", on whichever tiny test was
# unlucky, about one run in thirty. `check` is exactly the compiles `test` needs, so the
# step after it spawns only test binaries, which live for milliseconds.
- name: Compile tests
shell: bash
run: bash scripts/ci-retry.sh zig build check --summary all
- name: Run tests
shell: bash
run: bash scripts/ci-retry.sh zig build test --summary all
Expand Down Expand Up @@ -211,6 +222,12 @@ jobs:
if: matrix.name == 'macOS'
run: bash scripts/ci-retry.sh zig build -Dnative-backend=sdl3 -Dno-emit --summary all

# A link-only app (`-Ddynamic-plugins=false`): its gates on loading plugins at runtime are
# comptime, so only a build with it off shows that build still compiles.
- name: Compile a link-only app
if: matrix.name == 'Linux'
run: bash scripts/ci-retry.sh zig build -Ddynamic-plugins=false -Dno-emit --summary all

# The suites for SDL's patches on macOS (FizzyGPU's Metal tests; the rest are Linux's), when
# SDL's patches or pins changed: see the `sdl` job. Is there a Metal device? The probe says,
# and the suite then requires Metal, so a runner with one can't skip the Metal tests. (On
Expand Down
133 changes: 133 additions & 0 deletions .github/workflows/shaders.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# The SPIR-V and DXIL fizzy's native backend embeds (Vulkan, D3D12), compiled from their HLSL here
# rather than on someone's machine, and checked against what is committed.
#
# Each `X.hlsl` beside compiled forms of it (`compiled/{spv,dxil,msl,glsl}/X.*`) is compiled by
# `scripts/compile-shaders.sh` and compared byte for byte. A difference fails the job and uploads the fresh
# files as the `compiled-shaders` artifact, laid out as the repository has them: download it and
# commit them. Before this, nothing noticed when the HLSL changed and the compiled files did not,
# and Windows and Linux quietly drew the previous glass (#242, #373).
#
# The toolchain: SDL_shadercross, pinned, with the DirectXShaderCompiler release it pins itself
# (Microsoft's prebuilt v1.9.2602, by SHA-256), as shadercross's own CI builds it. Nothing heavy is
# built here: SPIRV-Cross and shadercross, a few minutes, cached by the pin. The shaders that had
# not changed since they were compiled (the backend's defaults) reproduce with it byte for byte,
# SPIR-V and DXIL: it is the toolchain they were made with.

name: Shaders

on:
pull_request:
paths:
- "**/*.hlsl"
- "**/shaders/compiled/**"
- "scripts/compile-shaders.sh"
- ".github/workflows/shaders.yml"
push:
branches: [main]
paths:
- "**/*.hlsl"
- "**/shaders/compiled/**"
- "scripts/compile-shaders.sh"
- ".github/workflows/shaders.yml"
workflow_dispatch:

env:
SHADERCROSS_REPO: libsdl-org/SDL_shadercross
# Its build-scripts/download-prebuilt-DirectXShaderCompiler.cmake pins DXC v1.9.2602.
SHADERCROSS_SHA: 1ff05bec573988a98ef9e0260b4da44f512b8367

jobs:
compile:
runs-on: ubuntu-24.04
timeout-minutes: 150
steps:
- uses: actions/checkout@v4

- name: Cached shadercross
id: cache
uses: actions/cache@v4
with:
path: ~/shadercross
key: shadercross-${{ env.SHADERCROSS_SHA }}-prebuilt-dxc-1

- name: Toolchain
run: |
sudo apt-get update -y
sudo apt-get install -y ninja-build cmake spirv-tools

# Every run: shadercross links SDL, cached or not (setup-sdl caches its own build).
- name: SDL
id: sdl
uses: libsdl-org/setup-sdl@main
with:
version: 3-latest
cmake-generator: Ninja
install-linux-dependencies: true

- name: Build shadercross (prebuilt DXC)
if: steps.cache.outputs.cache-hit != 'true'
run: |
git clone --filter=blob:none "https://github.com/$SHADERCROSS_REPO" sc
git -C sc checkout "$SHADERCROSS_SHA"
git -C sc submodule update --init --depth 1 external/SPIRV-Cross
# Microsoft's release of DXC, as shadercross pins it (version and SHA-256).
cmake -P sc/build-scripts/download-prebuilt-DirectXShaderCompiler.cmake
dxc_root="$PWD/sc/external/DirectXShaderCompiler-binaries"
cmake -S sc/external/SPIRV-Cross -B spirv_cross_build -GNinja \
-DCMAKE_BUILD_TYPE=Release -DSPIRV_CROSS_SHARED=ON -DSPIRV_CROSS_STATIC=ON \
-DCMAKE_INSTALL_PREFIX="$HOME/shadercross"
cmake --build spirv_cross_build
cmake --install spirv_cross_build
cmake -S sc -B sc/build -GNinja \
-DCMAKE_BUILD_TYPE=Release \
-DSDLSHADERCROSS_VENDORED=OFF \
-DSDLSHADERCROSS_CLI=ON \
-DSDLSHADERCROSS_SHARED=ON \
-DSDLSHADERCROSS_STATIC=OFF \
-DSDLSHADERCROSS_WERROR=OFF \
-DSDLSHADERCROSS_INSTALL=ON \
-DSDLSHADERCROSS_INSTALL_RUNTIME=ON \
-DDirectXShaderCompiler_ROOT="$dxc_root" \
-Dspirv_cross_c_shared_ROOT="$HOME/shadercross:$HOME/shadercross/share/spirv_cross_c_shared" \
-DCMAKE_INSTALL_PREFIX="$HOME/shadercross"
cmake --build sc/build --parallel
cmake --install sc/build
# The compiler shadercross loads at run time, beside it.
find "$dxc_root" -name 'lib*.so*' -exec cp -L {} "$HOME/shadercross/lib/" \;
ls "$HOME/shadercross/lib"

- name: Compile and compare
run: |
export PATH="$HOME/shadercross/bin:$PATH"
export LD_LIBRARY_PATH="$HOME/shadercross/lib:${{ steps.sdl.outputs.prefix }}/lib:$LD_LIBRARY_PATH"
shadercross --help > /dev/null 2>&1 || { echo "shadercross does not run"; ldd "$HOME/shadercross/bin/shadercross"; exit 1; }
command -v spirv-cross
failed=0
bash scripts/compile-shaders.sh out || failed=1
stale=0
while IFS= read -r fresh; do
committed=${fresh#out/}
if cmp -s "$committed" "$fresh"; then
echo "ok $committed"
else
echo "::error file=$committed::$committed is not what its HLSL compiles to: download the compiled-shaders artifact and commit it"
echo " committed $(stat -c %s "$committed") bytes, compiled $(stat -c %s "$fresh")"
stale=1
fi
case $fresh in
*.spv) spirv-val "$fresh" || { echo "::error file=$committed::$fresh does not validate"; failed=1; } ;;
esac
done < <(find out -type f | sort)
echo "stale=$stale" >> "$GITHUB_ENV"
echo "failed=$failed" >> "$GITHUB_ENV"

- name: Upload the fresh compiled shaders
if: env.stale == '1' || env.failed == '1'
uses: actions/upload-artifact@v4
with:
name: compiled-shaders
path: out/

- name: Fail on stale or broken compiled shaders
if: env.stale == '1' || env.failed == '1'
run: exit 1
13 changes: 10 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,16 @@ Full contract: **[`docs/PLUGINS.md`](docs/PLUGINS.md)**. Living reshape plan: **

Which plugins an executable links in is build data: `build/sdk.zig`'s `bundledPluginsModule`
generates `bundled_plugins` (`pub const modules = .{ @import("workbench"), … }`) and the
runtime iterates it — nothing in `app/` or `src/` names a plugin except the workbench (its
state still lives on the Editor). An app built on fizzy adds its own with `defer-app` +
`fizzy.buildApp(fizzy_dep, &.{ .{ .name, .module = dep.module("plugin") } })`; see
runtime iterates it. Nothing in `app/` or `src/` registers a plugin by name, though two are
imported as libraries and so always built: workbench (its state still lives on the Editor, so
every list must include it) and markdown (the store draws READMEs with it). An app built on
fizzy lists every plugin it links with `defer-app` + `fizzy.buildApp(fizzy_dep, &.{
fizzy.plugins.workbench, fizzy.plugins.text, .{ .name, .module = dep.module("plugin") } })`:
fizzy's own are entries with no module, built for each executable (`build/plugins.zig`'s
`link`), and only those listed register or get a dylib. `.@"dynamic-plugins" = false` (or
`-Ddynamic-plugins=false`) makes an app link-only: no plugin dylib is built, and nothing loads
at runtime (fizzy's dylibs, the user plugins directory, the store, a web page's `?plugin=`),
all decided at comptime (`App.loads_plugins`). See
[`fizzyedit/example-app`](https://github.com/fizzyedit/example-app), which bundles
`fizzyedit/example-plugin`.

Expand Down
7 changes: 7 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,13 @@ maintainer makes the SDK **live** on the site (below).
| Plans | private, in [`fizzyedit/plans`](https://github.com/fizzyedit/plans): issues, and a long design as `plans/<NAME>_PLAN.md` opening with a status line (`Status: proposed`, `in progress, fizzyedit/fizzy#N`, or `done`) |
| The forks fizzy builds on | `docs/DEPENDENCIES.md` |
| Releases | `RELEASING.md` |
| Licensing, and the name | `LICENSING.md`, `TRADEMARKS.md` |

## Licensing contributions

Fizzy is MIT (`LICENSING.md`), and a contribution comes in under the license it goes out under:
opening a PR offers its change under MIT. There is no contributor license agreement. Code
copied from elsewhere must carry a license compatible with MIT, and keeps its notice.

## Habits reviewers ask for

Expand Down
Loading
Loading