| Age | Commit message (Collapse) | Author |
|
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.
|
|
Diagnosed live (nested unbox + grim screenshots). Two bugs stopped any window
from showing; both fixed and visually confirmed (multi-window, live-updating,
focus highlight, RCSS tiling).
1. kernel (ui_substrate.cpp, adopt_node) — STABLE TEXTURE ID across re-imports.
The live import did glDeleteTextures+glGenTextures every commit, minting a NEW
GL id each frame. But RmlUi's image()/<img> decorator caches the texture HANDLE
it gets from LoadTexture(uri) ONCE, so after the first re-import it drew a
DELETED texture -> blank. Now node.tex is allocated ONCE and just re-pointed at
the new EGLImage (dmabuf) / re-uploaded (shm) on each re-import, destroying the
previous EGLImage after the rebind. The id stays constant => RmlUi's cached
handle stays valid => the window updates live. (Reimport counting unchanged.)
2. ext-window-field assets — the window texture is painted via an RCSS image()
DECORATOR bound with data-style-decorator (the stage-dock pattern), NOT an
<img src="{{ w.live_uri }}">: RmlUi does not substitute a data binding inside
an img src, so the literal "{{ w.live_uri }}" was reaching the texture loader
("Could not load texture"). Also `contain` (was `cover`) so the whole window
shows instead of cropping its center.
Verified: foot composites as a surface element in the window field and updates
live (a ticking clock); a 2nd window tiles with the focused one highlighted.
kernel + ext-window-field suites green; build-asan kernel green (no leak/UB).
Follow-up: a kernel regression test asserting the texture id is stable across
re-imports (no test caught this — RmlUi caching is the subtlety).
|
|
NEW core unit (id "window-field", depends_on "xdg-shell"), installed by host-bin
ONLY under --rml-compositing / UNBOX_RML_COMPOSITING (default off; the classic
wlr_scene path stays the default until RML compositing is signed off on hardware).
It composites application toplevels as RCSS surface elements inside ONE ui
surface (the window field) instead of as wlr_scene nodes:
- activate(): fetch ext-xdg-shell Service (typed), create the window-field
UiSurface at SceneLayer::normal sized to the primary output, subscribe to
on_output_added + on_toplevel_mapped/unmapped/focused.
- on map: Toplevel::wl_surface() -> UiSubstrate::create_surface_element(); the
toplevel is Toplevel::hide()'d out of wlr_scene (the surface element is now the
sole compositor of its pixels; the substrate drives its frame callbacks);
appended to bind_list("wins") (live_uri = source_uri(), focused, title, app_id).
- on unmap: drop the SurfaceElement + row. on focus: flip the focused flag.
- Layout/animation are RCSS (assets/ext-window-field/field.{rml,rcss}): a wrapping
flex field where the focused window dominates and the rest tile below, animated
on a transition. No geometry from C++ (the user's contract decision).
- Keyboard focus stays ext-xdg-shell's job; pointer/touch input-back is automatic
in the kernel; this unit wires no seat calls.
Wiring (orchestrator): root meson subdir, host-bin install behind the flag +
ext_window_field_dep. Headless glue test (40 assertions): map tracks the window +
drives hide(), 2nd map, focus flip via the Alt+Tab path, unmap removes it; no-GL
degrade asserted. build + build-asan green; host-bin links; no regressions.
Known gaps (change-requests): click-to-focus a BACKGROUND window needs a kernel
"surface-element pressed -> notify owner" hook (next); wallpaper needs
ext-layer-shell surface exposure (Wave 3b).
|