Skip to content

The smaller gaps: sized and ranked

0.5.4 research (#117). Eight things an app might expect that the engine does not do. Each was checked against the engine's code and the pinned dependencies (winit 0.30.13, the pinned vello_gpu and glifo), sized, and given a recommendation. Sizes: S is days or less, M about a week, L weeks and a new dependency or a design decision. Nothing here was built; the worthwhile ones are filed as their own issues.

Ranking

# Gap Size Value Verdict
1 Momentum scrolling S to M High on touch, nice with a wheel Do, #136
2 Window transparency and blur-behind M High for frameless windows Do, #137
3 Spring animation S (curve), M (true springs) Medium Do, #138
4 position: sticky M Medium Do, #139
5 Custom cursor images M Medium Do, #140
6 SVG documents L High for icons and illustrations Decide, #141
7 Subpixel (LCD) text L Low Decline
8 Wide gamut and HDR output XL Low today Decline until the renderer supports it

1. Momentum and overscroll scrolling

Found. A scroll view scrolls by wheel, keys, thumb drag and (0.5.4) touch pan, all with no inertia: a flick stops when the finger lifts. Gesture::velocity (touch pan, #113) already reports the release speed, scroll_offset already animates with an easing curve, and since #105 an offset is a paint-time shift, so animating it costs no layout.

Design. On a pan's end (and on a fast wheel burst), animate scroll_offset toward offset + v * tau with an exponential-decay curve, stop on a touch or a manual scroll, and clamp at the ends. Overscroll (a rubber band past the ends, returning with a spring) is a separate, optional second step; it needs the offset allowed outside 0..max while a drag or fling is live.

Risk. Low: the pieces exist. The tuning (friction, velocity cutoff) wants a touch screen, which isn't available here.

2. Window transparency and blur-behind

Found. WindowAttributes never sets transparent, and the surface is configured with the driver's default alpha mode (opaque). winit 0.30 supports with_transparent(true) on X11, Wayland, Windows and macOS, and set_blur only on Wayland with KDE's blur protocol (and macOS), nothing on X11 or Windows.

Design. A window property transparent (set at open, since X11 can only set it then) that asks winit for a transparent window and picks a pre- or post-multiplied alpha mode from the surface's capabilities; the root's own fill may then be translucent or clear, and a frameless window can have rounded corners. blur_behind as a best-effort second property where the platform has it. This is the missing half of the custom-windowing work (0.5.0), where a framework draws its own title bar and corners.

Risk. Medium: premultiplied alpha through the whole renderer (the renderer draws straight alpha into the target; the persistent-target copy and the snapshot path need checking), and compositor behaviour differs per platform.

3. Spring animation

Found. MotionCurve is Linear or a cubic Bézier: a fixed duration, no overshoot beyond what a Bézier with control points past 1 gives, and an animation interrupted midway restarts from the current value with no memory of its velocity, so a retargeted animation visibly stalls.

Design. Two steps. First, a spring easing (stiffness and damping, or a bounce and duration pair as in Apple's and Material's APIs): an analytic damped-spring curve over a computed settling time, which gives overshoot with the existing fixed-duration machinery (S). Second, true springs: Animated<T> keeps a velocity so a retarget continues the motion (M; needs a per-value velocity and a step-integrated, rather than closed-form, tick).

Risk. Low for the first step.

4. Sticky positioning

Found. Nothing in layout or paint. Scroll offsets became a single paint-time shift (Tree::scroll_shift, #105), which is exactly the place sticky needs to live.

Design. A sticky property (an inset from the scroller's edge) on a child of a scroll view: scroll_shift for that child clamps so it stops at the edge until its own container scrolls away, by the CSS rules (relative to the nearest scrolling ancestor, bounded by its parent's box). Hit testing, damage and accessibility bounds already read scroll_shift, so they follow.

Risk. Medium: the damage tracker sees a sticky node move with every scroll frame; headers are small, so the cost is small.

5. Custom cursors

Found. The Cursor enum names the OS's own cursors (default, pointer, text, resize and so on). winit 0.30 has CustomCursor::from_rgba and ActiveEventLoop::create_custom_cursor on X11, Wayland, Windows and macOS.

Design. A cursor property taking (rgba, width, height, hotspot_x, hotspot_y) (the shape Window.set(icon=...) already takes for the window icon), created on the event loop where winit allows it and cached by content. The engine owns no decoding.

Risk. Low to medium: cursor creation needs the event loop, so it goes through the same waker path as window creation.

6. SVG documents

Found. A path node takes SVG path data and a view_box (a single icon, such as a Material Symbol, works today); there is no document: no groups, no per-element fills or strokes, no gradients, no clipping, no text. usvg/resvg are not in the lockfile; vello_svg targets vello, not the vello_gpu the engine renders with.

Options. (a) Leave it to the framework: parse SVG in Python and build path nodes (works for flat icons, and keeps the engine free of a parser). (b) An engine-side svg node using usvg to flatten a document into paths, fills, strokes and gradients and paint them as one retained scene (a new dependency and a walk of its tree, and usvg does the hard parts: use, style, units, text-to-paths). (c) Rasterize with resvg to an image node (a dependency, and blurry when scaled; fine for fixed sizes).

Recommendation. Decide between (a) and (b) with the owner; (b) is the useful one and is L. Filed as a decision issue.

7. Subpixel (LCD) text

Found. glifo, the glyph renderer, positions glyphs at subpixel offsets (horizontal buckets) and caches them in an atlas, but renders grayscale coverage only: no LCD filtering, and the blending is not subpixel-aware.

Verdict: decline. It would mean changing the glyph renderer upstream, and its value is falling: HiDPI (#102) makes grayscale text sharp, and LCD text is wrong on rotated, scaled or translucent content anyway. Revisit only if the renderer grows it.

8. Wide gamut and HDR output

Found. Colours are 8-bit sRGB (r, g, b, a) throughout, the surface format is an 8-bit one (#128), and the renderer's gradient interpolation is fixed to sRGB; vello_gpu has no output colour management.

Verdict: decline. Wide gamut needs a colour-managed pipeline (float colours, a Rgba16Float surface, and per-platform colour-space declarations), HDR needs more, and neither exists in the renderer. Park it until vello_gpu supports it; the colour API ((r, g, b, a) bytes) would need a floating-point sibling first.