Add panel-wide styles and the Morph hub (#26)

Panel appearance now applies to the whole panel, with seven styles: Floating, Capsules, Notch, Edge to edge, Fused islands, Adaptive and Morph.

- Share composition, geometry, and motion through the renderer-independent `ferese-panel` crate, including native materials, input regions, and Settings previews.
- Add the Morph hub with media, calendar, notifications, controls, workspace previews, hover feedback, and attached mode. Keep recording and low-battery status visible and respect window clearance.
- Cache workspace preview geometry, draw thumbnails directly, centralize Morph transitions, and keep rendering settings local to each shell instance.
- Put Record Screen in the Morph header and show the display control only when an external monitor is connected. Update panel documentation, the desktop screenshot, and native check style names.

Local validation included 660 compositor tests, 191 shell tests, isolated preview-cache checks, GPU Morph captures at 1×/1.25×/1.5×, formatting, and Clippy with warnings denied. The final header change passed all 23 Morph tests. Release workflow jobs are skipped for this PR.
This commit is contained in:
Samuel Onoja authored and GitHub committed 2026-10-12 01:31:34 +01:00
1 parent 42c3b290dd
commit e22f0ebef9
131 files changed
+12562 -1634

No files matched your search

+7 -1
View File
@@ -69,6 +69,12 @@ The main spring responds more quickly than the viewport spring, allowing a windo
Bounce must be strictly between −1 and 1. Negative values produce overdamping; positive values require `overshoot #true` so the crossing policy permits the requested bounce. Duration and speed must be finite and positive, and the resolved stiffness and damping must remain finite and positive too. If the configuration fails these checks, Ferese keeps the last accepted settings.
The [Morph panel](panel-configuration.md#morph) uses the same spring solver,
with its own response and the shared speed and reduced-motion settings. Content
is laid out at the destination size while the shape expands around it, and
fades handle changes between views. The space kept clear of windows stays
unchanged throughout; regular status popups continue to use the main shell spring.
The global speed setting scales elapsed spring time, so 0.5 takes twice as long and 2.0 takes half as long. It applies to both compositor and Ferese shell motion. Setting `reduced-motion #true` takes precedence over enabled animations and applies the destination directly. Neither setting controls animations that applications draw inside their own windows.
## Passing a gesture’s velocity into the release
@@ -107,7 +113,7 @@ These slides use the viewport spring through [workspace navigation](../composito
An application’s surface lifetime does not always match the duration of its visible exit. Window entrance starts when content is available, but on unmap the live surface can disappear before a closing animation would finish. Ferese retains content for that exit, moving toward 98% of the current bounds while opacity, emphasis, and shadow fade to zero.
Closing during resize also retains the resize snapshots and their handoffs. Their progress must continue during close so the old buffer does not remain frozen over the exiting image. Retaining a picture is only part of the work; the presentation state that determines how it blends with the newer content has to continue advancing too.
Closing during resize also retains the resize snapshots and their handoffs. Their progress must continue during close so the old buffer does not remain frozen over the exiting image. The presentation state must keep advancing so the retained image can blend with the newer content.
Shell popups keep their surface until the closing motion settles, then destroy it. If you reopen the same panel during close, Ferese retargets that existing motion. Switching from Battery to Wi-Fi is different: the surface stays, but the new panel gets its own entrance. This behavior lives in [panel lifecycle handling](../shell/ferese-shell/src/status_ui/lifecycle.rs) and avoids a destroy-then-create gap between panels.