Repository navigation
backend: floats are OS windows again on macOS - #592
Merged
Merged
Conversation
#549 dropped the `pub` from `SDLBackend.viewports` (its doc comment ended up on `glass_look`). fizzy picked its viewports with `@hasDecl(@import("backend"), "viewports")`, which cannot see a non-pub declaration in another file, so it quietly fell back to `viewports_none`: `Popout.enabled()` was false at comptime, and floats, menus and dialogs stayed drawn inside the main window. Restore the `pub` and the comment, and choose viewports by the backend the build linked (a `native_backend` options module from build/exe.zig) rather than by probing for the declaration, so a `viewports` the backend stops exporting is a compile error, not popouts turned off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
foxnne
marked this pull request as ready for review
October 18, 2026 21:36
6 of 10 tasks
foxnne
added a commit
that referenced
this pull request
Oct 19, 2026
…584) Part of #260 (step 5 of `plans/WORKSPACES_PLAN.md`: floats and tear-off). ## What changes Behind `FIZZY_WORKSPACES=1`, a document tab can float. It floats inside a workspace of its own, so the new window is a tabbed area of documents holding just that one. - **Torn off over the desktop** (where floats are OS windows, macOS today): a tab let go over no window of the app's opens a float there, holding a new workspace with that document. Before, nothing happened: a document could not float. - **Dropped on its own pane's middle:** the same, the float opening over the pane. The drop's middle shows the float icon there, as it does for a view over its own place. - **A workspace's only tab carries the workspace** (`State.Documents.alone`, from #462): the workspace itself floats, rather than a new one being made round the document and the old one closing behind it. Already alone in a float nobody split, it doesn't float again; the pane takes the drop. - **Its float closes when the workspace empties** (its last tab closed or carried out), as any float its last view leaves. - **Closing the float gives its documents to the main window's workspace**: the one the person was in, when that is in the main window, else the first there. They go in after its own tabs, in order, and the one the float showed is shown. The emptied workspace then goes. With no workspace in the main window, it goes home as a view, as before. How: `State.Documents` gets one more member, `fold(id) -> bool`, which `ViewDrag.sendHome` asks before sending a closing float's view home. `ViewDrag.floatDocument` floats the view a document carries alone (`carriedView`), or a new one (`houseView`). A new workspace floats out of the pane its photograph was taken in, at that pane's size. With the flag off, `documents` is null, and nothing changes. ## SDK impact - [x] None. `State.Documents` is the app framework's (`app/layout`), not the plugin boundary. ## Verified - [x] `zig build`, `zig build test`, `zig build test-integration`, `zig build check-web`, `zig build test-sdk-version`, `zig build check-tests-reached`, `scripts/check-fmt.sh`. - [x] New integration test, "float: a document tab dropped on its own pane's middle floats in a view holding it". It covers one tab of two floating in a new view, a lone tab floating its workspace, no second float for one already alone, and closing the float folding instead of going home. - [x] macOS, a sandbox profile run with `FIZZY_WORKSPACES=1`, driven through the agent plugin (`fizzy_act`), each checked by `fizzy_screen` and a capture: - `tear-c.txt`, one of two tabs, dropped on its own pane's middle: `Float 1` opens over the pane in an OS window. It holds a new workspace (`Pane 3`) with only `tear-c.txt`, and the pane keeps `tt-b.pixi`. - Closing `tear-c.txt` in the float: the float closes, and the main window is unchanged. - `tt-a.pixi`, its workspace's only tab, dropped on its own pane's middle: that workspace (`Pane 4`) floats, and the emptied half of Main closes into the other. - [x] macOS, with the tear-out fixes since merged into a local build (#591, #592, #594): a tab carried past the window's edge opens its own window, holding a new workspace with just that document (`Float 1`, `Pane 6`, `tear-d.txt`). - [x] Review: `fold` copied the workspace's tab list but not the id strings in it, then emptied the workspace, and `State.setAssignment` frees those strings. It now copies the ids too. The gates pass on the branch merged with current `main`. - [ ] macOS, still to see with a real mouse: a tab torn off over the desktop (my run was interrupted by a person's input), and a float closed from its OS close button folding into the main workspace (the integration test covers the layout side). - [ ] Windows: - [ ] Linux: - [ ] Web: builds; the flag is never on there. ## Follow-ups - A window from ⌘N (step 8) stays open when it empties. The float needs to remember which kind it is then. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On macOS, a float (and a menu, a dialog) opens in an OS window of its own again.
What broke
#549 inserted
pub const glass_look = @import("glass_look");between the doc comment andpub const viewports = @import("viewports.zig");inbackend/src/SDLBackend.zig, and dropped thepubfromviewports.src/backend/backend_native.zigchose its viewports with@hasDecl(@import("backend"), "viewports"); a non-pub declaration is invisible to@hasDeclfrom another file, so fizzy silently tookviewports_none(supported = false) andPopout.enabled()returned false at comptime.The fix
SDLBackend.zig:viewportsispubagain, with its comment.glass_lookgoes private, above it — the same shape backend: a plain app's in-app floating windows are made of the window material #589 gives those lines (nothing reachesbackend.glass_look; everyone usescore.glass_look).build/exe.zighands the executable anative_backendoptions module (fizzy = native_backend == .fizzy), andbackend_native.viewportstakes@import("backend").viewportsdirectly when it is set. Aviewportsthat loses itspubis nowerror: 'viewports' is not marked 'pub'instead of popouts turned off.viewports_none.zig's doc no longer recommends the@hasDeclpattern, and says why.Verified
pubremoved again,zig buildfails atsrc/backend/backend_native.zig:155: 'viewports' is not marked 'pub'.pubrestored by hand): floating the Output view opens an OS window thatfizzy.screenlists asfizzy.window:float:Output; without it the float stays inside the main window.scripts/check-fmt.sh,zig build,zig build test,zig build test-integration(80/80 steps),zig build check-web,zig build test-sdk-version, andzig build -Dnative-backend=sdl3(dvui's own backend still takesviewports_none).scripts/check-examples.shleft to CI.Overlap
#589 rewrites the same three lines of
SDLBackend.zig; whichever lands second has a one-line conflict (keeppubonviewports). #590 touches a different part of the file.SDK
No boundary change; fingerprint and
sdk_versionuntouched.🤖 Generated with Claude Code