Decision 0088
0088. The face renders through wgpu, because that is what carries an alpha channel
Architecture decision record 0088: 0088. The face renders through wgpu, because that is what carries an alpha channel
Status: accepted. Supersedes ADR-0087, whose decision was right on what it knew and wrong within the hour, and amends the renderer clause of ADR-0047.
Context
ADR-0087 accepted that tacid-shell cannot be translucent, because tiny-skia reaches Wayland
through softbuffer, whose every buffer is wl_shm::Format::Xrgb8888 — no alpha channel,
hardcoded. That is true and remains true. What the record got wrong is the conclusion, and it named
its own three reasons for not switching to wgpu. Each was checked afterwards and each failed.
“No face on the boot where the driver is broken.” This is ADR-0047’s strongest argument and it does not apply to the shell. Hyprland renders through aquamarine, which has no software renderer; a machine that cannot give this shell a graphics device cannot give it a compositor either. What a person gets on that machine is a tty and the terminal interface — already true, already documented, already the reason ADR-0020 puts the TUI first. Requiring a device for the shell costs nothing that is not already gone.
“Not verifiable here.” Mesa ships lavapipe, a Vulkan implementation that runs on the processor:
one ICD path in the environment and checks.*.face has a device on any machine, with no card. The
glass became a measurement instead of a claim in the same afternoon the objection was written.
“Let the compositor do it instead.” Hyprland 0.56.2 has no layerrule opacity — asked of its
own parser, which answers config option <layerrule:opacity> does not exist. A layer surface’s
alpha is the client’s to supply or nobody’s.
And the thing that decided it: iced_wgpu asks its surface for PostMultiplied, then
PreMultiplied, and settles for Auto only if it can have neither. It is trying to carry alpha.
The software path was never going to.
Decision
tacid-shell renders through wgpu, and through nothing else. ALPHA_SURVIVES in theme.rs
is now true, and the three things that followed from it being false are reversed: surfaces draw
at the tokens’ glass.opacity, the window paints nothing so the compositor sees what no container
covered, and the command box hugs its content because what is left over is the desktop.
No fallback renderer, deliberately. A shell built with both would pick tiny-skia on a machine
with no device and not say so, and a shell that cannot know which renderer it got cannot know
whether its own alpha means anything — which is the failure this pair of records is about, arriving
a second time by a different road. With one renderer the question does not exist.
The check measures the composite arithmetically. Not a threshold: a * surface + (1 - a) * ground, both read out of the theme the machine generates, against the pixel on the screen. Two
guards make it mean something. The desktop behind is the palette’s accent, because the terminals’
own background is seven levels from surface and fourteen percent of that is under the noise — an
opaque sheet photographed over one of them satisfied every threshold this check had. And the band
is asserted to be able to tell glass from opaque before it is asked which one it sees.
Consequences
The face is glass: rounded, translucent, with the compositor’s blur behind it and the same material in the notification daemon’s surfaces. The screenshot shows a terminal through the sheet of keys and the desktop through its corners.
The shell will not start where there is no Vulkan or GLES device. On a machine with a compositor that cannot happen; where it can, the machine has no compositor either.
Several hundred crates enter the shell’s lock file. They enter nowhere else: the shell has been its own workspace since ADR-0047 and the daemons neither build nor link it.
tacid-shell now needs the Vulkan loader on its rpath. The loader is a stub that finds the
machine’s driver at run time, so this adds a small library and no graphics stack to the closure.
Blending is in the encoded values and not in linear light, which is written down because it was measured rather than reasoned: predicting the composite in linear light was out by thirty-seven levels over a bright ground.
Alternatives rejected
Keep ADR-0087. It is a record that says the design cannot have what the design asks for, on three grounds none of which survived being checked. Leaving it accepted would make every later reader inherit the same three.
Both renderers, choosing at run time. iced does not say which one it selected, so the choice would have to be inferred — by probing for an adapter before starting, which answers a slightly different question than the one that matters. A guess about one’s own renderer is how this started.
Draw opaque and let the compositor blend the layer. There is no such rule in this compositor.
A wallpaper for the check that is not the accent. Nothing else in the palette is far enough
from surface for fourteen percent of the difference to clear the noise. The green looks like a
fixture because it is one.