| Age | Commit message (Collapse) | Author |
|
- 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.
|
|
Floating windows: move (titlebar), resize (two bottom corner grips), and a per-
window close button. Per-window geometry (x,y,w,h,z) is bound STATE applied via
data-style left/top/width/height + z-index; a pure, doctested geometry core
(move / resize_bl / resize_br with anchored-opposite-edge + min-size, field
clamp) computes drag results. Positioning uses left/top (NOT a transform: RmlUi's
data-style does not apply a transform here the way it does left/top/width/height,
and a transform would also offset the drag hit-test). z-order raise on focus;
cascade placement from the client's own size.
Resize-to-tile: a frame-pumped feedback loop configures each client to its on-
screen box (Toplevel::set_size) so the live texture maps 1:1. Policy is config-
driven -- [window-field] resize_mode = off|settle|continuous|debounced in
unbox.toml, hot-reloaded; pure doctested config core.
Windows are shown via <img data-attr-src> (NOT an RCSS image() decorator) so the
kernel's surface-element input-back, click-to-focus, popup placement and box
readback -- all keyed off the <img> src -- work.
host-bin passes the config path + --rml-compositing (the latter selecting server-
side decorations) through to the extensions. tasks.md records the wave.
|
|
real-seat verify + W4/W5 decisions
|
|
Extends the live SurfaceElement to the whole surface TREE and routes input
back to clients.
Surface trees:
- create_surface_element(root) now manages subsurfaces + xdg popups as
per-subsurface child elements (unbox-surface://N.K), each its own live
seq-gated texture at its tree offset; the substrate re-walks the live tree
each dirty tick (wlr_surface_for_each_surface + popup walk), reconciling by
wl_surface identity and dropping a node the instant it leaves the tree.
- Frame-callback duty now walks the WHOLE tree per composited frame.
- Parent-relative child placement (place_child_box, pure core): child <img>
positioned relative to the root img's resolved box, so a moving/resized
parent drags its children; popups unclipped. Caller tracks only the root.
Input-back (automatic; the wm wires no seat calls):
- pure core src/input_core.hpp (port of the spike's spike_input_core):
project_to_screen/unproject_to_local + place_child_box, doctested
(criterion-3 round-trip < 0.01px; affine exact).
- a pointer/touch pick landing on a surface-element node maps the point through
the node img's real RCSS transform via Element::Project, then box->surface-
local, and forwards to that client via wl_seat at surface-local px. Normal
RML picks still fire bind_event/bind_drag unchanged. Cursor stays a wlr plane.
- SurfaceElement::focus_keyboard() (new public method): seat keyboard-focus
MECHANISM only (focus POLICY is the window-field wave); cleared on destroy.
Tests: pure-core doctests + a headless test driving a REAL in-process client
(toplevel root + subsurface + xdg popup): tree composes as >=3 child <img>,
whole-tree frame-done, pointer enter/motion/button + touch at expected surface-
local coords (incl. a rotateY(35) transformed-element case proving Project),
keyboard enter+key. kernel suite 72c/375a green; build-asan 0 records (the
seat/per-node-import/listener lifetimes clean). Spike untouched.
|
|
Phase 2 Wave 1: the live sibling of Preview. A SurfaceElement is backed by a
client wl_surface's current committed buffer, imported zero-copy into the RMLUi
sibling GLES context and served under an unbox-surface://N URI, shown via
<img src> in any UiSurface.
Public contract (ui.hpp):
- class SurfaceElement { source_uri(); width(); height(); } (no refresh()).
- UiSubstrate::create_surface_element(wlr_surface* client) -> unique_ptr;
nullptr on no-GL/import-fail, never throws; `client` is a borrow the caller
must outlive and drop on unmap/destroy (lifetime documented per
listener-lifetime).
Behavior (ported from the in-tree spike, untouched):
- seq-gated re-import (wlr_surface->current.seq), pool-reuse-proof; double-
buffered wlr_buffer_lock/unlock (<=1 pinned, balanced incl. prev==buf).
- frame-callback duty per composited frame so the client keeps drawing (the
stuck-frame fix); a frame stays scheduled while >=1 element exists.
- commit dirties the hosting ui surface (dirty-gate); static client = no work.
- shm-upload + R<->B swizzle fallback when there is no dmabuf path.
Pure-core predicate (surface_element_needs_reimport) doctested; headless
integration test drives a REAL in-process Wayland client (re-import on seq
advance, the pooled same-pointer case, zero idle re-imports, climbing
frame-done). kernel suite + build-asan green on Haswell+crocus. Test-only
wayland-client dep (kernel-tests scope; user-accepted). Scope held: single
surface, no input-back/damage/scene changes (later waves).
|
|
reference
Phase 2 of RML compositing starts here, off main. Brings over from the
throwaway spike branch:
- design/planning: notes/rml-compositing-phase1.md (the Phase 1 design),
notes/plan.md row 71 (ADOPTED/GO + Option-2 contract), GLOSSARY.md terms
(RML compositing, surface element), tasks.md, .gitignore.
- spike sources as IN-TREE REFERENCE only (packages/kernel/src/spike +
build_by_default:false target + the input-core doctest): the proven
mechanics Phase-2 ports (live seq-gated import, Element::Project input-back,
FBO->dmabuf present, dirty-gate). Deleted once Wave 1 lands.
Real Phase-2 implementation lands in subsequent wave commits.
|
|
Major architecture direction (gated by a spike): make the RMLUi substrate the
content compositor — toplevels, layer-shell clients (incl. wallpaper), and UI
chrome become RML elements backed by live, shared GL textures, with layout,
animation, and 3D effects expressed in RCSS. wlroots stays the foundation +
hardware cursor plane + a deferred fullscreen-video scanout bypass. Lost
wlr_scene damage/scanout is mitigated by our own dirty-gated rendering (not a
RMLUi built-in) + the deferred scanout bypass.
- notes/rml-compositing.md: full architecture, the de-risking already done
(shared EGLDisplay; RmlUi transform-aware hit-testing + RTT/filters/shaders;
slice 3 + stage dock proved dmabuf/EGLImage), division of labour, perf
posture, Phase 0 spike acceptance criteria, Phase 1/2, naming proposal.
- notes/plan.md §2: decision row (reopens the compositing half of row 51) with
rationale + explicit spike fallback.
- tasks.md: slice 13 (RML compositing spike) = ACTIVE core; slice 7 (tiling)
DEFERRED behind it; "Now" leads with the pivot.
Roadmap re-scope (earlier this session):
- notes/tiling-spec.md: baseline tiling design (primary/stack, configurable
side + new-window insertion, hot-reloadable [tiling] config) — deferred.
- notes/tiling-layouts-reference.md: dwm layout catalogue for later.
- notes/status-bar-home-screen.md: status bar + iPad-style home screen ideas
(replace the cut window-list taskbar); tasks.md slices 6 (cut), 11, 12.
|
|
Replace the specific builder hostname, username, home path, and the cited
private methodology-source repo with generic wording across ORCHESTRATOR.md,
notes/plan.md, tasks.md, and the PKGBUILD maintainer line. No machine/network
identifiers remain in the tree.
|
|
|
|
|
|
sliver)
Real-seat pixel sampling showed a ~2px vertical sliver of the slot placeholder
(#2e2e32) on the card's RIGHT edge only (full height; other edges flush). A magenta
diagnostic background on the thumb proved the gap was NOT a transparent texture edge
(it stayed placeholder-colored, not magenta) — the thumb BOX was ~2px short on the
right (RmlUi box rounding anchored top-left). The preview texture import is correct.
Fix: the full-bleed thumb now overscans the slot by -2dp on all sides; the rounded
overflow:hidden slot clips the overscan, so the image covers the whole rounded card
with no placeholder edge on any side and corners stay rounded. RCSS-only.
Verified real-seat: image reaches all four edges, zero placeholder sliver.
ext-stage-dock 2/2 green on build + build-asan. Also records the transparency/
card-redesign milestone in tasks.md.
|
|
|
|
|
|
|
|
Slice 10 (stage dock): Stage-Manager-style left-edge dock of minimized-window
previews revealed by a left-edge swipe. Records the Fork-B decision (previews are
toplevel snapshots imported as textures into the RMLUi context, shown as <img> in
one RML document) and the mechanism/policy split (kernel: snapshot + list bindings
+ gesture-claim; ext-xdg-shell: hide/show/geometry/scene_tree; ext-stage-dock:
minimized set, layout, recognition, easing). Adds canonical terms: stage dock,
stage (reserved), preview, favicon, gesture, swipe, minimize, restore, reveal.
|
|
|
|
exports WAYLAND_DISPLAY
ext-keybindings (new core ext) reads unbox.toml: tap-Super spawns fuzzel,
Alt+Tab/Alt+Shift+Tab rotate focus across all toplevels, plus Alt+F1 and
Ctrl+Alt+Backspace (quit). ext-xdg-shell's hardcoded keybinds removed
(migrated to the toml).
Kernel setenv()s WAYLAND_DISPLAY at startup so extension-spawned clients
connect to unbox, not the launching session — fixes fuzzel "no monitors"
on the real seat.
build + build-asan green: third-party Mesa/EGL/DRM + vendored-RmlUi sanitizer
noise suppressed (suppressions/), our code stays leak-checked; a real
libwayland leak in the layer-shell client test fixed.
Harness: spawn-env + sanitizer-noise rules, diagnose-real-seat skill,
GLOSSARY keybinding/action/tap-binding. Real-seat verified on the CF-AX3.
|
|
The ui substrate is now the extension-facing contract (unbox/kernel/ui.hpp):
Host::ui() -> UiSubstrate::create_surface(spec) -> UiSurface with typed
scalar bindings (int/double/bool/string getters), data-event callbacks
(error-isolated per extension), dirty(), geometry/visibility — RMLUi and
GL stay kernel-private. Production sync: glFinish replaced by
EGL_KHR_fence_sync + 2-deep wlr_swapchain. ui_spike retired (orientation
guard + dirty-cycle coverage live on as substrate tests).
Input: ONE kernel routing path feeds pointer AND touch into ui surfaces
with consume-or-pass semantics and implicit-grab ownership (the consumer
of a press owns the matching release; per touch point too) — fixes
drag-release-over-ui sticking. touch-mode: state machine + debounce +
on_touch_mode_changed notification, NO visual scaling (user decision
after hardware hands-on; dp-ratio stays 1.0; see plan §2).
ext-xdg-shell: GrabMachine generalized to pointer-OR-touch interaction
source (touch titlebar drag works; originating-point pinning); fixed the
seat implicit-grab leak (suppressed release after forwarded press
swallowed all later touch-downs — pointer/touch alternation doctested);
factory renamed create(). ext-layer-shell: on_demand keyboard
interactivity via scene hit resolution. host-bin: --ui-demo extension
(temporary acceptance demo on the public contract, dies in slice 6).
User hands-on verified: same surface by mouse and finger, tap counter,
touch-mode neutrality, no click-through, drag alternation, fuzzel
on_demand. 113 doctest cases green, ASan/UBSan clean (our code), idle
RSS ≈78 MiB. Harness: UX-feel hands-on lesson (ORCHESTRATOR §2.6),
nested-run pkill/setsid notes, touch-mode glossary redefinition.
|
|
extensions
The kernel now names NO concrete feature. It owns: the extension host
(install/topological activate, missing-dep/cycle = startup error), the
typed Event/Filter bus (error-isolated: a throwing extension is disabled,
never the session; RAII Subscriptions), the Host API (per-extension
facade: borrows, scene layers, event catalogue, typed services), the
public RAII Listener, and a typed surface→scene-tree registry
(Host::host_surface/scene_tree_for) that replaced the untyped
wlr_surface.data convention both extensions flagged.
- ext-xdg-shell (core): toplevel/popup lifecycle, focus-on-map,
click/tap-to-focus, pointer/touch routing incl. button+axis (the
kernel only moves the cursor and emits — a contract-doc lie caught by
user hands-on), interactive move/resize via pure GrabMachine (fixes
the request-arrives-after-release race: grab requires request ∧
button-down, release always ends it), Alt+F1 cycle,
Ctrl+Alt+Backspace terminate (labwc's default A-Escape=Exit killed
the dev session once — never again; see nested-run skill).
- ext-layer-shell (core): wlr-layer-shell v1 (proto v5) for external
clients; pure doctest-hard arrangement core; fuzzel verified visually
nested (fix: seed outputs from output_layout at activate — events-only
tracking missed pre-activation outputs; plus a scene-node double-free).
- First protocol codegen: vendored wlr-layer-shell XML + wayland-scanner
server-header propagated through kernel_dep; wlr.hpp grew a
namespace→_namespace keyword fix for the generated header.
- Glossary: 'scene layer' (user-approved). New rules earned:
parallel-wave-builds, contract-docs.
- User hands-on verified: typing, click-to-focus, drag-select, scroll,
titlebar drag-move (slow + flick), Alt+F1, fuzzel + arrows, touch tap,
Ctrl+Alt+Backspace. 68 doctest cases green, ASan/UBSan clean (our
code), idle RSS ≈73 MiB.
|
|
Plan A verified on hardware (HD 4400/crocus): RMLUi renders into a GLES
3.2 sibling-context FBO backed by a dmabuf wlr_buffer (wlr_allocator +
EGLImage import), composited as a wlr_scene_buffer with per-frame damage.
Plan B (glReadPixels→shm) implemented and verified as runtime fallback;
auto-engages when any Plan-A precondition fails. Plan C not needed.
- Hello-world RML doc: text, data-bound frame counter, pointer input
proof (hover/:active) — verified upright on screen via screenshot after
fixing the classic FBO Y-flip (buffer-level V-flip keeps display ==
document coords for input); position-aware orientation guard added.
- Temporary spike surface: Options::ui_spike + frame-count/orientation
probes, host-bin --ui-spike flag; replaced by the real ui substrate
contract in slice 4+.
- kernel suite 6 cases / 416 assertions green; ASan/UBSan clean in our
code (Mesa leak noise + 2 benign UBSan downcast reports inside vendored
RMLUi are known); idle RSS ≈83 MiB.
- Deferred (notes/plan.md §7): glFinish→EGL fence + swapchain; dmabuf
render-format negotiation (private API in wlroots 0.20).
|
|
touch added
Server contract (pimpl, create/run/dispatch/terminate) over a faithful
tinywl 0.20.1 port: outputs via wlr_scene, xdg-shell toplevels+popups,
focus, interactive move/resize, keyboard/pointer through wlr_cursor — plus
touch (down/up/motion/cancel/frame via seat notifies with per-point origin
tracking), which tinywl lacks. RAII Listener replaces manual wl_list_remove
bookkeeping; shutdown ordering documented in kernel.md. xkbcommon added as
a system dep. Verified: nested under labwc (output WL-1, foot mapped and
focused on GLES2) and a headless+pixman boot test in the kernel suite.
|
|
vendored
Root meson.build (C++23, WLR_USE_UNSTABLE, ccache-detected) with RMLUi 6.2
as a wrap-file tarball built through the cmake module (no git submodules —
settled decision) and doctest 2.5.2 from wrapdb. kernel unit: extern-"C"
wlr.hpp wrapper (with the C99 [static N] array-param workaround documented
in kernel.md), slice-1 probe contract, doctest suite (1/1 green). host-bin:
composition root printing versions, exit 0. tasks.md slice 1 done.
|
|
Constitution (AGENTS.md), orchestrator workflow with the header-contract
read rule and harness-growth duties (ORCHESTRATOR.md), wlroots-seeded
glossary, 4 safety reflexes, owner-agent briefs, 3 skills, and the living
plan (notes/plan.md) with hardware-verified facts, settled decisions, and
the slice 1-9 roadmap (tasks.md). Slice 0 done; next: toolchain bootstrap.
|