Skip to content
This repository was archived by the owner on Nov 12, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mseries/BUG-FIX-ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ Ranked by how often the owner hits it, how small the fix is, and what it depends
| P2 | Ambient keyboard lighting has a successful sensor/API check, but lock/lid transitions and suspend/resume are not qualified. | Verify that the helper leaves the light alone while locked or closed, then resumes safely after unlock/open and suspend. | Needs interactive check |
| P2 | The transformed desktop can play through the Apple speaker safety/DSP chain using packages already available in Ubuntu resolute, but the factory image does not install them or the matching PipeWire LV2 plugin. Correction 2026-10-13: Ubuntu does ship that plugin, in `libspa-0.2-modules-extra`, so it can be installed rather than built; untested with the Asahi chain. AVD firmware and its VA-API bridge are also absent. | Package the tested audio chain into the Ubuntu image without bypassing speakersafetyd; separately identify compatible AVD kernel, firmware, userspace sources, and licensing. | Image packaging gap |
| P2 | Wi-Fi firmware provisioning and resume recovery are present in the image layer but lack a fresh end-to-end test on an M1 Pro booted from that image. | Confirm firmware source, connect, suspend/resume repeatedly, and capture service/kernel logs from the factory image. | Needs image test |
| P2 | App windows do not consistently follow the rounded shape of the Mac's built-in display, and the current GTK window-radius tweak does not cover every application. The Gala screen-corner mask only rounds the display boundary; it does not round individual windows. | Define and implement a system-level window-surface policy for the built-in display, then qualify native GTK, libadwaita, and third-party windows, including client-side decorations, maximized/fullscreen windows, dialogs, popovers and external displays. Keep application content intact and document any surfaces the compositor cannot clip cleanly. Apple HIG guidance supports system-consistent, system-provided window framing, but does not publish one mandatory numeric radius for all app windows: [Windows](https://developer.apple.com/design/human-interface-guidelines/windows). | New; needs implementation and visual qualification |
| P2 | App windows do not consistently follow the rounded shape of the Mac's built-in display, and the current GTK window-radius tweak does not cover every application. The Gala screen-corner mask only rounds the display boundary; it does not round individual windows. | Define and implement a system-level window-surface policy for the built-in display, then qualify native GTK, libadwaita, and third-party windows, including client-side decorations, maximized/fullscreen windows, dialogs, popovers and external displays. Keep application content intact and document any surfaces the compositor cannot clip cleanly. Apple HIG guidance supports system-consistent, system-provided window framing, but does not publish one mandatory numeric radius for all app windows: [Windows](https://developer.apple.com/design/human-interface-guidelines/windows). | Built 2026-10-23 in the Rust compositor (branch `claude/compositor-corners`: screen mask, window clip shader, hug-the-display rule, popups, panels, per-output policy; see `SDK-CORNERS.md` section 7). Not installed; needs the owner's visual qualification on the built-in display and the app matrix |
| P2 | The blue and red palette still feels harsh in use, especially for accents and error/destructive states, despite the existing softened GTK overrides. Current overrides do not necessarily reach every app or toolkit. | Review the reds and blues on the M1 Pro display and move them toward a calmer pastel treatment where appropriate. Apply through shared theme/system settings so native and installed apps follow when supported; check text and icon contrast, selection/focus visibility, and error/warning/success distinction. Record toolkit-specific exceptions rather than assuming one GTK stylesheet covers every app. | New; needs palette review |
| P2 | The network usage/speed readouts in the network menu and panel do not always recover correctly when Ethernet is present across suspend/resume or reboot. | Reproduce separately for suspend/resume and reboot with Ethernet connected. Compare the network indicator and panel readout with interface counters before sleep, immediately after wake/startup, and after the interface settles; inspect sampling timer/baseline resets and interface re-enumeration. Verify both displayed rates and the history graph recover without stale spikes or a panel restart. | New; needs reproduction |
| P2 | The network speed readout gives no visual cue when traffic is approaching a saturated link. The owner wants a muted pastel red-orange hue at that point. Current counters aggregate physical-interface throughput but do not determine link capacity or upstream service congestion. | Define “saturated” in measurable terms (for example, sustained utilization near the negotiated interface rate, with a short hold and hysteresis to prevent flicker). Decide whether the cue applies per-interface or to the aggregate readout, then test on Wi-Fi and Ethernet. Use a soft red-orange that remains legible and distinguishable from error states; document that interface utilization cannot by itself prove an ISP/WAN bottleneck. | New; needs saturation definition |
Expand Down
26 changes: 25 additions & 1 deletion mseries/SDK-CORNERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Logical pixels, shared by SDK apps and meant to be read by the compositor:
has a larger radius than the display (`window <= screen`; tested). Maximized and fullscreen SDK windows have radius 0 in their own
stylesheet because an app cannot know whether it is on the built-in display or a square external one; the compositor decides (below).

## 3. Compositor contract (not built in the Rust compositor)
## 3. Compositor contract (built in the Rust compositor 2026-10-23; see section 7)

The compositor is the only layer that can make every app, including third-party and client-side-decorated windows, follow the curve.
It should read the same `corners` tokens and implement:
Expand Down Expand Up @@ -72,3 +72,27 @@ number in `tokens.json` and this file. The current 14 came from eye-tuning (rais
3. Calibration pass and a record of the result.
4. Qualify native GTK, libadwaita, Electron/Chromium and X11 windows, CSD and SSD, maximized, fullscreen, dialogs and popovers, and an
external display, with screenshots.

## 7. Receipt: compositor implementation (2026-10-23, branch `claude/compositor-corners`)

What it does (`rust/pantheon-compositor`, `src/corners.rs` = numbers and policy, `src/corner_render.rs` = drawing):

- Reads `corners` from `rust/msdk/data/tokens.json` at start-up through the `msdk` crate (`CornerTokens::load`), including `style`.
- **Screen mask:** four premultiplied-black bitmaps (not a shader) in the four display corners, front-most after the pointer, so above windows, dock, panels and the lock screen; built-in output only.
- **Window clip:** each toplevel's surface elements that touch a corner box are drawn through a GLES texture shader (signed distance of a circle or of a superellipse, antialiased over one pixel). Only the pixels inside the four corner boxes of the *geometry* rectangle change, so client-drawn shadows outside the geometry, the interior and the client's size are untouched. Opaque regions exclude the corner boxes (so the corners blend), and clipped elements are never scanned out directly. `circular` is exponent 2; `continuous` is exponent 3 with the corner box 1.2x the radius (`CONTINUOUS_EXPONENT`, `CONTINUOUS_EXTENT` in `corners.rs`; eye-tuning, like the radii, is the owner's call).
- **Hug the display (geometry based, no placement state):** a toplevel corner within 1 px of a display corner uses `screen`; a corner on a screen edge but not a display corner is square; every other corner uses `window`. This covers maximized (with a top bar the top corners sit under the bar, so they are square and the bottom ones follow the display), fullscreen, tiled halves and quarters, and a floating window dragged into a corner. Radii are capped at half the shorter side.
- **Popups and menus:** `popover` on all four corners (X11 override-redirect windows are treated as popups). Dialogs are toplevels, so `window`.
- **Panels and the dock:** a corner is rounded (`window`) only if it touches no screen edge. A full-width top bar therefore stays square and a floating dock is rounded.
- **Per-output policy:** only the built-in output is rounded; every other output is square (no clipper, no mask, no cost). Built-in means the connector names the display configuration already treats as the laptop panel (`eDP-*`, plus `LVDS-*`, `DSI-*`); the nested development window (`winit`) counts as built-in so the corners can be seen without a second display.

Verified (2026-10-23):

- `cargo fmt --check`, `cargo clippy --all-targets -D warnings` (default features and `native-drm`) clean; `cargo test -p pantheon-compositor --features native-drm`: 183 + 19 passed, 28 of them new (which corner gets which radius for floating, maximized with and without the bar, fullscreen, tiled halves and quarters with and without the bar, one pixel of slack, external outputs, popups, bar and dock, tiny surfaces, token loading, the distance function, the mask bitmap and its area).
- The nested compositor starts and draws, in a private Xvfb with its own D-Bus and runtime directory (software GL, not the Asahi GPU): a plain GTK 3 window gets 12 px corners against the wallpaper; the same window maximized and fullscreen is cut at the display curve, flush with the black mask; no shader error in the log. The shader first applied to nothing on the nested output because Winit renders a vertically flipped frame (`Transform::Flipped180`); `gl_FragCoord` is now mapped for `Normal` and `Flipped180` frames. Rotated frames are drawn unclipped.

Not verified:

- **Visual acceptance on the built-in display** (curve match against the glass, light/dark, the 14 and 12 values, the continuous shape): needs the owner's eyes. Nothing was installed and nothing was loaded: the owner's running session still has the old compositor binary; the new build lives only in the shared cargo target (`debug/pantheon-compositor`) of the worktree `~/Projects/mseries-corners`.
- The **native DRM path on the Asahi GPU**: it compiles (`MultiRenderer` hands out the render device's GLES renderer and frame) but was not run there. It assumes the native frame is `Normal` (as in Smithay's DRM compositor) and that the clip shader works on the Honeykrisp driver; if the shader fails to compile the log says so and windows stay square.
- Surfaces that are **not** clipped: Snap Assist thumbnails and the workspace/overview gesture previews (scaled copies), and X11 windows are clipped only through the same Wayland surface elements XWayland provides (not separately qualified). Direct scanout of a clipped window is intentionally off while it has rounded corners. Chromium/Electron, libadwaita, CSD with shadows, dialogs and popovers on real apps are not yet qualified (work item 4); a window that straddles two outputs is clipped per output with that output's rules.
- Damage when only the radii change without a geometry change (a token edit) is not tracked; the radii are read once at start-up, so a restart applies a changed token.
1 change: 1 addition & 0 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rust/pantheon-compositor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ wayland-server = "0.31.14"
zbus = "=5.19.0"
gio = "0.22"
xcursor = "0.3"
msdk = { path = "../msdk" }
image = { version = "0.25", default-features = false, features = ["png", "jpeg", "webp"] }

[dependencies.smithay]
Expand Down
Loading
Loading