Repository navigation
Glass: one material for everything, in fizzy's backend and core (off by default) #6
Description
One glass material for everything. It's off by default, and every glass surface in fizzy follows it. It lives in fizzy's backend and core, not in dvui: dvui and its stock backends are untouched.
Why. It started with a phone web report: a focused chip showed over a place's corner button. The draw-order half of that was a dvui bug (fixed in fizzyedit/fizzy#540, with the cleanup in fizzyedit/fizzy#544). The trigger half was the button appearing whenever the pointer came near the corner (#535 covers modals; the corner design below covers the rest). Beyond that, we want glass to be switchable: Liquid Glass, frost, blur, plain transparency, or off. Today every glass control calls the liquid-glass path directly, and glass_look keeps separate looks for drops and text.
Prototypes for the corner: https://claude.ai/artifact/MotGphK5UyeH9sQ6NHeYZk (static mockups, not renders).
The direction (decided)
- One material for everything. In-app glass (pills, cards, bubbles, in-app windows), fizzy's OS windows, the main window, and a window dragged out of it all show one look.
glass_look's forDrops/forText split goes. - No dvui change. dvui never draws glass: OS windows get their material from fizzy's backend, and in-app glass is drawn by
core. A plain dvui app on the SDL or web backends sees nothing new. A dvui-level control can be proposed upstream later, from working code, with-Dbackend=fizzy(a private plan). core/material.zigholds it, app-wide.Material { kind: Kind = .none, opacity: f32 = 1 }, whereKind = { none, transparent, blur, frost, liquid }, plusKindsandeffective(offered). The app publishes the effective value, and every glass shape reads it, asnative_glass.offered()works today. The default.noneis a plain opaque window: glass is off by default.- Fizzy's backend says what this platform offers, and publishes the effective kind into
core. The rule: a backend offers a kind if every surface it puts glass on can show it. The effective kind is the requested one, or else the best offered kind below it (liquid → frost → blur → transparent → none).- macOS 26: liquid, frost, blur, transparent.
- Older macOS: frost, blur, transparent.
- Windows: frost (Acrylic/Mica), transparent.
- Linux: blur where the compositor has it, transparent.
- Web: liquid, frost, blur, transparent. The canvas is its only surface, and fizzy's shader draws all of them.
- A glass control is a shape first and a material second. Code draws a shape (a bubble, pane, card or pill) through
core.corefills it in the effective material's look, so in-app glass falls back exactly as the OS windows do. Nothing outsidecorepicks a material, so plugins follow it for free.native_glass.offered()becomes true only for.liquid.
Steps (one PR each)
- backend + core: the
Materialtype and the offered kinds, with no behaviour change. Done, core: one window material, and the kinds each backend can show fizzy#546.core/material.zigholds the type and the published value.backend/reports what the platform offers (macOS 26 liquid, Windows frost, Linux blur where the compositor has it, the web every kind) and publishes the effective kind. No dvui repin. Owned by the dvui-dev session; it replaces the dvui-branch draft core: one window material, and the kinds each backend can show fizzy#546. - core: glass shapes draw in the effective material. Done, app: every glass draws in the window material fizzy#549 (fizzy-1d). Stacked on the step above.
glassBubbles,frostPaneandglass_buttonread the effective material fromcore/material.zig.dialogs.carriedCardgrows into the shared "card of glass, OS-drawn when offered" call, and the demo/agent overlay pills move onto it.glass_lookdrops forDrops/forText.BlurBackdropalso captures from the front-to-back block and front lists, since today glass inside a block blurs nothing of it.
- layout: a place's corner is always shown, and only the corner reveals the button (option A). Done, layout: a place's corner is glass, and turns into its button fizzy#555, layout: a place's corner is a small bubble peeking past its curve fizzy#578.
- A quarter of material sits in the card's rounded corner, in its padding.
- The full bubble shows only when the pointer is on that corner, and never under a modal (keeping layout: corner button stays dark under a modal; Output tabs on the left fizzy#535's rule).
- On touch: the first tap reveals the button with a hint, a second tap opens the picker, holding lifts the view, and it hides after about 3s or at the next touch elsewhere.
- layout: a place with a tab strip docks the button in it (option C). Flat chrome at the strip's end, glass on hover. This needs a seam in
Layoutfor "a surface drew a strip", not a workbench special case. - backend: apply the effective material to every OS window. For a plain dvui app, done: its main window and OS windows (backend: plain dvui app windows made of the window material fizzy#565) and its in-app floating windows (#589, on backend: fizzy's in-app glass is the backend's, core re-exports it fizzy#586 and backend: a plain dvui app's frame draws through FrameTarget fizzy#590). Fizzy's own windows, which fizzy dresses itself (
app_dresses_windows), are what's left. The main window, floats, and the carry window. Popout moves onto the tear-off path (a private plan) as that lands. Owned by the dvui-dev session. - settings: Glass (kind) and window opacity, calling the backend's setter. Closes fizzyedit/work#28.
- Store plugins with their own glass (pixi's canvas bubbles, the dropper orb) move onto
core's shape calls at their next repin.
Also landed (2026-10-18/19)
- fizzy's in-app glass is the backend's (backend: fizzy's in-app glass is the backend's, core re-exports it fizzy#586):
FrameTarget,BlurBackdrop,LiquidField,liquid_glass,liquid_blob,programs,motioninbackend/src/glass/,corere-exporting every name. - A plain dvui app's frame through
FrameTarget(#590), so its glass can read back what's under it. - One dvui-dev hook after all, against "No dvui change" above:
Backend.floatingWindowBackground(dvui-dev3d90fdd, taggedfizzy-sdk-0.2.30-8, fizzy'sdocs/DEPENDENCIES.mditem 14), so the backend can draw an in-app floating window's background in the material. The user OK'd dvui changes that are explained, contained and documented. dvui's stock backends still see no change. - A light theme's tint, and the glass floor (#589): a light theme's colour covers 0.3/0.7 as much (fizzy's default ratio); glass never goes below
glass_look.min_opacity, only a clear window goes to 0. - A tape's captions in the material (#625).
- Measured 2026-10-19: every material holds 120 fps in Debug; earlier drops were GPU contention. Details in
plans/MULTI_WINDOW_PLAN.md(a private plan).
Coordination
- New glass drawing goes through
glassBubbles/frostPane/glass_button/carriedCard. No new direct liquid-glass ornative_glasscalls outsidecore. - The windowing stack (#492, backend: OS windows for the floating windows that ask, or all by choice fizzy#501, macos: a float's full screen at the display's rate, clear and rounded fizzy#504, macos: the pointer reaches the window it is over, not one behind it fizzy#510, the tear-off work) and the material type land in either order.
- The material work rides the Zig 0.17 migration, into
zig/0.17, but it needs no dvui-dev branch.
Activity