summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-15 20:04:22 +0900
committerAdam Malczewski <[email protected]>2026-06-15 20:04:22 +0900
commitedf1192629be0978ed5e572bc119b7fa942fbe8f (patch)
treed6efbf5acfb101241babdbc1dba955ab559a4d97
parent310ef9b53f0ab8396e15e6f9e077df5399508539 (diff)
downloadunbox-edf1192629be0978ed5e572bc119b7fa942fbe8f.tar.gz
unbox-edf1192629be0978ed5e572bc119b7fa942fbe8f.zip
docs: record screenshot + wallpaper decisions (plan §2, glossary, tasks)
- notes/plan.md §2: three settled-decision rows (screencopy/xdg-output in kernel; stb_image arbitrary-image decode + absolute-path fix; native ext-wallpaper + input_transparent flag + bundled default). - GLOSSARY: canonical 'wallpaper' term (user-confirmed). - tasks.md: 'just landed' milestone for screenshots + wallpaper.
-rw-r--r--GLOSSARY.md6
-rw-r--r--notes/plan.md3
-rw-r--r--tasks.md18
3 files changed, 27 insertions, 0 deletions
diff --git a/GLOSSARY.md b/GLOSSARY.md
index bc8e555..da161ba 100644
--- a/GLOSSARY.md
+++ b/GLOSSARY.md
@@ -71,6 +71,12 @@
| **restore** | Return a minimized toplevel to the normal layer at its prior geometry and focus it; its preview leaves the dock. | unminimize, unhide |
| **reveal** | The proportional, finger-following show/hide of the stage dock driven by the edge swipe (fraction 0..1); release snaps fully open or closed. | slide, animate (bare) |
+## Wallpaper (ext-wallpaper)
+
+| Term | Meaning | Aliases to avoid |
+|---|---|---|
+| **wallpaper** | The desktop background image, composited in the `background` scene layer below every window by ext-wallpaper (standard tier). Config-driven (`[wallpaper]` in `unbox.toml`: `path`/`fit`/`color`), hot-reloaded; an input-transparent ui surface; falls back to a bundled default image when no `path` is set. | background (bare), desktop background, backdrop |
+
## Workflow
| Term | Meaning | Aliases to avoid |
diff --git a/notes/plan.md b/notes/plan.md
index 6e1d824..ed74877 100644
--- a/notes/plan.md
+++ b/notes/plan.md
@@ -68,6 +68,9 @@ solves), and the trigger that would reopen it.
| **VT switching (Ctrl+Alt+Fn) is kernel-hardwired** before the key_filter (`wlr_session_change_vt`) | It is the session escape hatch — must work even if an extension throws or greedily consumes keys; not a rebindable feature (user decision) | — |
| **Stage dock** (ext-stage-dock, standard) = the Stage-Manager-style left-edge dock of minimized-window **previews**, revealed by a left-edge **swipe**. **Fork B**: previews are toplevel snapshots imported as textures INTO the ui substrate's RMLUi context and shown as `<img>` in ONE RML document | Closest to the iPad Stage Manager north star; one ui surface animates as a unit via RCSS; reuses the slice-3 dmabuf/EGLImage bridge in reverse (wlr pixels → RMLUi texture) instead of two-layer scene/RML lockstep | Cross-context texture import proves infeasible on crocus → fall back to Fork A (previews as `wlr_scene` snapshot nodes) |
| **Mechanism in kernel/core, policy in ext-stage-dock.** Kernel ui substrate gains: preview-snapshot, list/container bindings, a gesture-CLAIM input path. ext-xdg-shell gains: `Toplevel::hide()/show()` (≠ unmap), `geometry()`, `scene_tree()`. ext-stage-dock owns: the "minimized" set, dock layout, gesture recognition, easing | Keeps "kernel names no feature" — snapshot/claim/list-bindings are generic primitives; minimize-to-dock is the only policy and lives in one standard extension | — |
+| **Screenshot capability = `wlr-screencopy-v1` + `xdg-output-v1` globals created in the KERNEL** (user decision) | They are policy-free Wayland plumbing (wlroots wires them to the kernel-owned outputs/renderer), exactly like the existing compositor/subcompositor/data-device globals — so they pattern with those, not with shell extensions. `grim` works against them; the final image is the standard `wlr_scene_output_commit` composite (RML documents are scene-buffer nodes, captured correctly). The kernel still names no feature | A capture path needs compositor-side POLICY (e.g. interactive region UI) → that policy moves to an extension, globals stay in kernel |
+| **Substrate decodes arbitrary raster images via vendored `stb_image`** (user-approved dep) — `<img src>` and `decorator: image()` load PNG/JPEG/BMP/GIF/TGA from any absolute path | The RMLUi render interface previously decoded ONLY uncompressed TGA; a desktop needs real wallpapers + (later) favicons. stb_image is single-header public-domain, no system package; warnings isolated to its own TU. A SubstrateSystemInterface JoinPath override keeps absolute paths from being slash-stripped during RmlUi URL resolution | A heavier codec need (animated/SVG) appears → add a real decoder dep |
+| **Wallpaper = native config-driven `ext-wallpaper` (standard tier)** showing `[wallpaper]` image in the `background` scene layer; bundled default image (`assets/ext-wallpaper/default.jpg`) when none configured. Needs the kernel's new **`UiSurfaceSpec::input_transparent`** flag (a full-screen background ui surface must NOT steal clicks — the substrate's press-ownership is a per-rect, pre-bus test) | Native (vs requiring swaybg) fits the unbox config+RCSS+hot-reload idiom and the RML-compositing "wallpaper is an RML element" direction; input_transparent is the long-anticipated passthrough primitive (also unblocks the dock drag-out). swaybg still works too (ext-layer-shell background band) | Multi-output (one image per output) wanted → extend ext-wallpaper + an output-enumeration/box API |
| **RML compositing (ADOPTED — Phase 0 spike PASSED GO on real Haswell+crocus; supersedes the compositing half of row 51).** RMLUi is the CONTENT compositor: toplevels, layer-shell clients (incl. wallpaper), and UI chrome are all RMLUi elements backed by LIVE, SHARED GL textures (zero per-frame copy via the existing shared EGLDisplay). Layout/animation/3D effects are RCSS. wlroots stays the foundation + plane manager (backend/output/renderer/seat, hardware cursor plane, fullscreen-video scanout bypass). Lost wlr_scene damage/scanout is mitigated by OUR dirty-gated rendering (idle ≈ no work) + damage-limited compositing + a deferred fullscreen scanout bypass. **Contract decision (user): RCSS is the single source of truth for ALL layout + animation; C++/extensions DRIVE the document through a TYPED substrate API but never own placement geometry directly — the typed-symbol rule governs cross-extension dependency discovery, not the RCSS styling vocabulary.** Spike report: `reports/rml-compositing-spike.md`; Phase-1 design: `notes/rml-compositing-phase1.md` | The appeal is Hyprland-grade window effects via DECLARATIVE RCSS (layout, transitions, 3D transforms, blur/shaders) with hot-reload — and RmlUi already does transform-aware hit-testing + RTT/filters, while slice 3 + the stage dock already proved dmabuf/EGLImage texture handoff on this exact crocus HW. Doing windows in RMLUi means tiling/effects/stage-manager are all RCSS policy on top. **Phase 0 proved on the real CF-AX3 GPU class: zero-copy live import, RCSS 3D transform on live pixels, input accurate through the transform, per-subsurface surface trees, idle dirty-gate, FBO→dmabuf present; ~30fps under a 4-window load, fill-bound (~10–15ms whole-output composite) with damage limiting as the known recovery** | A Phase-2 implementation blocker on the real seat (perf regresses below budget after damage limiting + scanout bypass, or the RCSS-only contract proves unworkable for a real tiling/effects extension) → fall back to wlr_scene compositing + transient snapshot-through-RMLUi effects |
## 3. Architecture
diff --git a/tasks.md b/tasks.md
index 22ef29e..72b60fe 100644
--- a/tasks.md
+++ b/tasks.md
@@ -5,6 +5,24 @@
## Now
+**Just landed — screenshots + wallpaper (user-driven, real-seat/nested VERIFIED):**
+- **Screenshots (grim):** kernel creates `wlr_screencopy_manager_v1` +
+ `wlr_xdg_output_manager_v1` (policy-free plumbing, like data-device). grim
+ captures the standard `wlr_scene_output_commit` composite (RML docs are
+ scene-buffer nodes → captured). Verified nested: `grim` → valid 1280×720 PNG.
+- **Arbitrary image decode:** vendored `stb_image` (user-approved); substrate
+ `LoadTexture` now decodes PNG/JPEG/… (was TGA-only), and a SubstrateSystemInterface
+ `JoinPath` override stops RmlUi stripping the leading `/` of an absolute path, so
+ `decorator: image('/abs')` AND `<img src='/abs'>` both load. Kernel ui_pixel tests.
+- **`ext-wallpaper` (NEW, standard tier):** `[wallpaper]` in unbox.toml
+ (path/fit/color), shown in the `background` layer, hot-reloaded (drop+recreate
+ inline doc); bundled default `assets/ext-wallpaper/default.jpg` when no path set.
+ Needed a new kernel **`UiSurfaceSpec::input_transparent`** flag (a full-screen
+ background surface must not steal clicks — substrate press-ownership is per-rect,
+ pre-bus). Verified nested: configured image + bundled default both render; input
+ passes through. swaybg (layer-shell) still works too. GAP: multi-output (primary
+ only). Commits on feat/rml-compositing.
+
**ACTIVE (core, user-driven) — Slice 13: RML COMPOSITING (Phase 0 GO → Phase 2 impl).** Big direction
change: RMLUi becomes the content compositor — toplevels + layer-shell (incl.
wallpaper) + chrome are RML elements backed by LIVE, SHARED GL textures, with