| Age | Commit message (Collapse) | Author |
|
RmlUi only starts a transition on a class/definition change, never on the
inline data-style-transform the dock uses for slide, so keyboard/minimize/restore
open-close had stopped animating (snapped). Own the animation in C++ instead: a
pure SlideAnimator that every path flows through -- keyboard/minimize/restore play
it, a touch drag scrubs it (pause + set position from the finger), and release
resumes easing from the current position to the snap target. Duration + easing are
read from the #panel RCSS 'transition' via transition_timing(), so they stay
hot-reloadable and any named RmlUi tween works. Drives slide per frame via
request_frames; the surface now hides when the close animation completes (replaces
the old transitionend path). Body=drag-handle / panel=transform split preserved.
|
|
Drag from the left edge to open, or drag the open dock back to close;
finger-following with a 50%-or-fling snap on release. New gesture::Controller
pure core converges both input paths onto one RevealRecognizer: OPEN via the
kernel touch bus (dock hidden at down), CLOSE via UiSurface::bind_drag (the
visible dock captures the touch). Slide is value-driven (data-style-transform)
and eased only when not dragging.
Two real-seat fixes found via per-frame logging:
- Flicker: RmlUi projects a drag event's coords into the DRAGGED element's
transformed frame. We had drag:drag on the same <body> we translate by
slide, so the reported x fed back into slide and ping-ponged every frame.
Fix: body is a stationary drag handle; an inner .panel carries the transform.
- Direction: drag_start now seeds the recognizer from the dock's current
fraction (1 + slide/width) instead of a hardcoded value, so a drag opens or
closes correctly from any state.
|
|
- **ext-stage-dock**: exports a `Service` interface with `toggle_visible()`.
The extension inherits from it and registers via `provide_service` in
`activate()`. The method slides the dock in/out (using the existing RCSS
transition) regardless of slot count; showing an empty dock is valid.
- **ext-keybindings**: new `Action::dock_toggle_visible` action, mapped from
`"dock-toggle-visible"` in `unbox.toml [[keybind]]`, dispatched to the
stage-dock Service. Default binding: `Super+d`.
- **Manifest**: ext-keybindings now `depends_on {"xdg-shell", "stage-dock"}`.
- **Build**: subdir order swapped so ext-stage-dock builds before
ext-keybindings; `ext_stage_dock_dep` is a link-time dep of the
ext-keybindings library and transitively exposed via `ext_keybindings_dep`.
- **Tests**: glue tests install ext-stage-dock alongside ext-xdg-shell;
policy test expects 6 default bindings. All 10/10 green on build +
build-asan.
Configure in unbox.toml:
[[keybind]]
keys = "Super+d"
action = "dock-toggle-visible"
|
|
Turn the card-hugging dock into a full-height left rail.
- C++ (extension.cpp/dock_layout.hpp): the surface is now the full OUTPUT HEIGHT
(hug reverted; content_height helpers/tests dropped) and kDockWidth widened
240 -> 288 (~20%). Cards unchanged at 224dp. set_visible still hides the rail
when empty, so it only appears when there are minimized windows.
- RCSS (dock.rcss): body.dock fills the surface (width:100% height:100%) as a flex
COLUMN scroll container with a `horizontal-gradient(#000000ff #00000000)`
decorator — fully-opaque black at the left screen edge fading to transparent
across the wider rail. Cards centered both axes (align-items:center + a
`div.rail` margin:auto wrapper that vertically centers when they fit and
collapses gracefully — no flex-center+overflow strand — scrolling when they
overflow). Scrollbars hidden (scrollbarvertical/horizontal size 0).
- RML (dock.rml): a `div.rail` wrapper around the data-for slot list enables the
center-or-scroll pattern.
Accepted caveat (quick path): the full-height 288px surface consumes pointer/touch
across the left strip while shown; the deferred input-transparent UiSurfaceSpec
flag is the real fix. Real-seat verified via live RML/RCSS hot-reload.
ext-stage-dock 2/2 green on build + build-asan.
|
|
(hot-reloadable)
- The dock's inline kDockRml C++ string is gone; the document now lives in
assets/ext-stage-dock/dock.rml (structure) + dock.rcss (styles), loaded via
UiSurfaceSpec::rml_path = "ext-stage-dock/dock.rml". The bind_list*/event setup
in activate() is unchanged (the substrate re-applies it across hot-reloads).
- Build wiring (top-level meson.build): install_subdir the top-level assets/ tree
to <datadir>/unbox/<unit>/, and -DUNBOX_ASSET_DIR_DEFAULT=<prefix>/<datadir>/unbox
so an installed unbox finds its assets with no env. Dev runs set
UNBOX_ASSET_DIR=<repo>/assets + UNBOX_DEV=1 to read the source tree and arm the
hot-reload watcher.
Real-seat verified: editing dock.rcss (border-radius 10dp<->70dp) updates the live
dock with NO recompile and NO restart. ext-stage-dock 2/2 green on build +
build-asan. Design iteration on the dock is now edit-a-file.
|
|
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.
|
|
Replaces the panel-with-inset-image card with the window preview as the card
itself, rounded on all four corners.
- div.slot is a rounded overflow:hidden clip container (explicit 224x140dp box,
#2e2e32 rounded placeholder for not-yet-rendered previews).
- A full-bleed child <div class="thumb"> carries the preview via
data-style-decorator="'image( ' + row.preview + ' )'" with `cover center
center` (shorthand order verified against vendored RmlUi DecoratorTiled). As a
child of the rounded overflow:hidden slot, its image clips to the rounded
corners — RmlUi does NOT clip an element's own decorator to its own
border-radius, so the decorator must live on the clipped child.
- Title overlay disabled (display:none) but kept in the markup + the
{{ row.title }} binding/getter stay live, for a later text redesign.
- Card height 140 (kCardHeight); surface-hug content heights 156/304/600 updated.
- Preserved: d1 slot-enter animation, transparent strip, surface hugs the stack.
Real-seat verified: a clean rounded window thumbnail in the dock. ext-stage-dock
2/2 green on build + build-asan.
|
|
empty
Builds on the kernel per-pixel-alpha + set_size-resize capabilities.
- Transparent strip: body.dock background #1c1c1ee6 -> transparent, so the
windows beneath show through everywhere the cards don't cover; cards keep their
solid #2e2e32 panel. data-attr-src preview, Noto Sans, and the d1 slot-enter
animation are intact.
- Surface hugs the card stack: height = surface_height(count) =
max(1, 2*pad + count*card + (count-1)*gap) (0->1px hidden, 1->140, 2->272, …),
never the full output height, so the transparent area doesn't needlessly
capture input. The empty dock is a positive 1px hidden placeholder (the substrate
rejects 0 geometry); grows/shrinks via set_size on minimize/restore.
- Fix: re-minimize after the dock empties was a no-op. do_restore relied on
on_toplevel_focused re-firing, but a restored window was never seat-defocused,
so focus() is a seat no-op and the event never fires — leaving focused_ stale,
so the next Super+M's focused_ guard rejected it (a new toplevel mapping
unstuck it). Fix: set focused_ = tl directly in restore. No kernel change.
Tests: new policy cases (surface_height always positive; hug heights 0/140/272/536)
and a glue minimize->restore->minimize 1->0->1 cycle with has_focused() probe.
ext-stage-dock 2/2 green on build + build-asan (no sanitizer reports). Real-seat
verified: transparent strip, dock visible, cards float, re-minimize works.
Edits confined to packages/ext-stage-dock/.
|
|
Real-seat (nested) showed the dock compositing but slots blank. Three bugs in the
inline dock document, all caught in the live RmlUi log:
- <img src="{{ row.preview }}"> never bound — RmlUi interpolates {{ }} only in
TEXT, not attributes, so it tried to load a texture literally named
"{{ row.preview }}". Fixed with data-attr-src="row.preview".
- font-family: sans-serif -> "No font face defined" (substrate only loads Noto
Sans). Fixed to the loaded face.
- transform-origin: top left -> RCSS parse error. Fixed to RmlUi-valid syntax.
Verified real-seat: minimizing two foot windows shows two preview cards in the
dock with the actual window snapshots visible; the live log is free of the three
[rmlui] errors. Super+M works repeatedly with >1 window ("works once" was the
single-window no-op: nothing left to focus/minimize). Suites green build + asan.
|
|
Layers animation on c2's static pipeline with zero data-model / contract change
(c2 glue test passes unchanged). The dock body slides in from the left edge on
empty->non-empty via an RCSS transition on transform:translateX driven by a bound
`open` bool (data-class-open); slide-out defers set_visible(false) until the
slide's transitionend so the close is seen. Each freshly instanced preview card
plays a one-shot @keyframes (scale 0.72->1.0 + fade, transform-origin top-left =
"scales down into a spot"). Dock stays a 240px left-edge strip (animation is a
transform inside the surface, never a resize) so windows stay clickable.
Key finding: RmlUi 6.2 dispatches animationend/transitionend as real events, and
the substrate's data-event-* path binds a listener for ANY registered event — so
data-event-transitionend routes into bind_event with NO kernel change. The ONLY
remaining gap for the literal cross-screen window->dock flight is a single
input-transparent UiSurfaceSpec flag (a kernel boundary decision, NOT built).
Restore stays instant in d1 (animated grow-back is e1's drag-out).
10/10 suites green on build + build-asan (asan clean). Visual feel is real-seat.
|
|
ext-stage-dock activate() now wires the full static pipeline: track toplevels via
the ext-xdg-shell Service; Super+M (stopgap keybinding) minimizes the focused
window -> snapshot a Preview from its scene_tree(), push a slot, hide() the live
node, refocus another window; the dock is one overlay UiSurface rendering the
slots via the b2 list bindings (data-for over {preview src, title}); tapping a
slot fires bind_list_event -> show()+focus() the window and drop its slot/Preview.
Storing the Toplevel* across minimize is safe because hide() keeps it mapped;
slots are dropped on on_toplevel_unmapped. Teardown is reverse-declaration-order
(subscriptions first, surface before slots), asan-clean.
host-bin installs ext-stage-dock (standard, depends_on xdg-shell; hidden until it
holds a minimized window). Headless glue test (real in-process xdg client) proves
the model + scene-node enable bit true->false->true, slots 0->1->0. RML carries
dock/slot classes as d1's RCSS animation hooks. Stopgaps: Super+M (to migrate into
an ext-keybindings action + a stage-dock Service post-d1); favicon deferred
(needs an XDG icon-theme dep — to surface to the user).
10/10 suites green on build + build-asan. Visual/tap path is real-seat (pending).
|
|
New standard extension (id "stage-dock", depends_on xdg-shell). Ships the unit
skeleton (factory-only public header, minimal no-op activate, meson + suite) and
the two PURE DECISION CORES, doctest-hard with no kernel/wlroots:
- src/reveal.hpp: reversible left-edge swipe recognizer (stream -> reveal fraction
[0,1]; release -> open/close commit by threshold + fling velocity).
- src/dock_layout.hpp: reveal-fraction -> on-screen dock box (slides -dock_width
.. 0) + slot capacity / content-height / per-slot rect math.
Real wiring (RML doc, snapshot, minimize/restore) lands in c2/d1/e1. Root
meson.build gains the subdir; host-bin registration deferred to c2.
ext-stage-dock suite green (17 cases / 74 assertions). Edits in packages/ext-stage-dock/ + root meson.build subdir.
|