- glassd took the window's scale from any surface placed by Steam's main overlay; SteamVR's panels
(vr.settings 1858 px, vr.ctl 488 px) are placed by it too, so while VR Settings showed, the bar's and the
frame menu's glass were rescaled x2.58 / x9.86 by turns every geometry fetch (the flicker). The scale now
comes from the main surface only.
- Cropped surfaces are stereo: lgs_sg.js reports each panel's u range (beat crops), the daemon passes it
as surfaces[].crop, glassd builds the eye pair around the crop (right copy shifted by the crop width,
each eye clipped to its crop) and the cover panel spans the pair.
Stereo (glassd cap stereo, flag glassStereo, on)
- The window glass was one image both eyes saw on the glass plane, so the room behind it read as a picture
pasted on the glass. glassd now renders each eye's view (SteamVR's eye-to-head offsets, refreshed every
5 s): every region of a stereo surface's texture is a pair, left eye's copy then right eye's, and the
scene graph's panel spans the pair with stereoscopy Parallel.
- Measured on the device with a lab probe (lgs_sg test.stereoProbe): SteamVR splits a Parallel panel at
the middle of the panel's own uv rect, not at the texture's halves; hence the pair layout, and stereo only
where the scene graph shows a surface whole (main, SteamVR's panels). The bar, the frame menu and popups
show crops and stay mono. A slab clipped sideways is left out while it is.
- GPU about 2.9 -> 3.5 ms a frame.
Sidebar without the laser
- frame.menu is no longer laser-only: SteamVR shows it in gamepad mode (laser mouse off) and beside its own
pages; keyed on the gamepad flag its native glass went off and the CSS glass showed. Verified with the
flag forced to gamepad on Home and in VR Settings: the cover stays.
Home -> Library
- The shell stamps the leaving Home view with the moment it starts leaving (only on a way out of Home, kept
across Steam's /library redirect); Home fades on the route exit and the reporter lets its plates go on
that clock. Measured: all Home discs reported leaving in the first report, gone with the page.
- Plates whose element leaves the DOM are reported leaving from the mutation itself (no measuring), not
after a frame-driven tick the new route's render starves.
Glass tuner
- The popup fits Steam's 600 px bar popup cap (rows 76 px: label and value on one line over a 40 px slider);
open()/close() for tests.
Route changes
- Plates fade with their content: the reporter reads a running opacity fade on a plate or its ancestors
(Home -> Friends: the route's 150 ms exit) and reports exitAt/exitMs; glassd fades the plate's coverage
linearly on that clock, optics unchanged (cap exitAt); the daemon keeps a leaving plate for exactly
that fade. A plate whose element left the DOM (Home -> Library stays in one /library route: no fade,
Home unmounts when Library has rendered) goes in 90 ms instead of the 350 ms dematerialize ramp that
left Home's discs over the Library grid.
- The window cover arrives with the route: the shell sets the new route's glass mode in the history
change itself, the reporter reports the mode flip at once (tickNow) with the time it happened, and
glassd springs a kept surface's new cover from then (appearAt now also for main gaining its cover).
- A disc popped at the switch belongs to the page that leaves: it never flips the new page to the crops
layout and goes with the page's fade (lgs_sg.js routeOut).
Sidebar in VR Settings
- The frame menu is a laser-only surface keyed on Steam's gamepad-nav flag, which goes stale on
SteamVR's own pages (the laser works SteamVR's page): the native glass went on and off with every
input Steam saw, its CSS glass in between. On a SteamVR page (the frame's VR Settings action active)
the rule does not apply.
Friends
- The page starts at y 108 (C1a's pad + 40, as Settings' list): the sidebar platter no longer sits
under the search capsule.
Glass tuner (flag glassTune, on)
- A paintbrush circle after the system capsule (its own glass piece and native cover) opens a bar popup
through Steam's own bar popup button: colour (8 swatches) and tint strength, Glass intensity (the
dial), Refraction, Frost, Highlights, Reset to default.
- Daemon action glass.tune (kind ui, its own 40 ms rate, outside the global window): glassd.json at once,
~/.config/glass-shell/tune.json 400 ms after the last change (kept across reboots by request; the
defaults delete it; RT-6 allows exactly this file), the dial file mirrored for the SteamVR pages.
- glassd: tune {refract, frost, light, hue, hueK} applied in drawGlass, eased (40 ms) like the dial now
is; the glass body's neutral moves toward the hue (uHue), per-piece tints stay on top (cap tune).
- The CSS glass follows live: a style per Steam window sets --lgs-dial / --lgs-tune-hue; the material
tints mix the colour in.
The illumination ::after (04-states.css) painted nothing at rest but was computed for every host (46-93 per route,
~25 custom properties and six gradients each) at every style recalc. The generated host entries (fontkit.py --hooks)
now carry a :where() gate (hover, active, focus, focus-within, pressed, focus-in, .lgs-lit): the layer exists only
while lit. rt/06-states.js holds .lgs-lit for 600 ms after hover, focus or press ends, so the 441 ms fade-out still
plays; a top-level @starting-style (02-motion.nowrap.css) ramps the light in from dark. Verified: ramps unchanged
(press in 0/.66/.98/1, out .86/.45/.03), no layer at rest; route changes ~48 -> ~55 fps.
- The room map's fill (push-pull, row fill, mips) runs before a render that
samples it, at most ~15 Hz, instead of after every feed frame (room GPU per
feed frame 0.7 -> 0.19 ms); the feed is decimated 8x (240x135, the room map
sampled it about that coarse already).
- reporter.md, glassd.md, daemon.md: armed/pooled/appearAt, optimistic marks,
standby surfaces and the panel watch, lgs-native per session.
- Frame menu: measured expanded width so Steam's width transition animates;
reporter sends cover.morph end shape + start time, glassd morphs the glass
on the same spring (70 ms native lead).
- Main window: glass-mode change reported from the mutation callback and the
cover marked data-lgs-cover="pending" (no opaque CSS window); glassd springs
covers in/out; daemon keeps lgs-native 1.5 s between modes.
- Launcher: the name plate dissolves in place, then the label fades back.
- IVROverlayView reads system overlays (systemui, HeadsetView) but not
Steam's dmabuf-backed panels
- SteamVR systemui scene graph accepts injected nodes (DOM elements with
buildNode; submit via module 5723's scheduler): reparent-to-panel +
panel-anchor + transform + panel shows live crops of Steam's window at
any 3D offset, and our own dmabuf overlays (needs SetOverlayMouseScale)
- hvgrab: headset-view capture for verification
- device/lgs_core.js + lgs_index.js: inject theme CSS into every Steam gamepadui
popup from SharedJSContext; readable %{Token} classes resolved from Steam's
webpack CSS modules; never persisted (Steam restart/reboot = stock UI)
- device/lgs(.py): on/off/toggle/status CLI; glass-shell.desktop puts
'Liquid Glass' in the dashboard bar's + > Launch Program list
- lab/: locked navigate/click/screenshot/outline/audit tools for the live UI
- glass.py: PC-side driver over the steam-frame-ssh helper