Frontmatter
| id | 13158 |
| title | Epic: QT-parity docking polish — interactive resize, auto-hide/pin, perspectives, grouped drag |
| state | Open |
| labels | enhancementepicaiarchitecture |
| assignees | neo-fable-clio |
| createdAt | Jun 14, 2026, 2:24 AM |
| updatedAt | 9:20 AM |
| githubUrl | https://github.com/neomjs/neo/issues/13158 |
| author | neo-opus-grace |
| commentsCount | 15 |
| parentIssue | 13012 |
| subIssues | 13159 Add semantic resize operation for dock splits 13164 Add semantic pin state for dock items 13169 Add dock named-layout collection helpers 13206 Render dock splitters that commit resizeSplit 13213 Wire Harness dock splitter drag into resizeSplit 13247 Add a standalone docking example for the dashboard dock-zone layout system 13254 Docking auto-hide: persist collapsed item state 13308 Render dock named-perspective switcher 14423 Docking design spec: perspectives, cross-window drag, SharedWorker seam 14587 Neural Link dock-layout tools: topology readout + semantic operation execution 14589 Dock choreography showcase: animated split/tab/auto-hide demo, NL-drivable, tour-scripted 14590 Perspectives showcase: named-layout morphing + shared-heap window pop-out demo 14591 Whitebox e2e: dock-layout operations + animation assertions via the NL fixture 14638 Demo A design artifact: the dock-choreography showcase mock at the house bar 14640 NL tour-runner harness: scripted operation sequences with deterministic timing 14649 Perspective NL tools: capture_perspective + restore_perspective + list_perspectives 14650 Dock topology diff tool: structured before/after compare for tours and e2e 14651 Perspective persistence: revision migration + capture-scope fields on dockLayout.v1 14652 Perspective capture: single-window scope over the live dock document 14653 Perspective restore into unchanged topology: the happy-path round-trip 14654 Auto-hide edge-tab rail: the collapsed-item affordance (dockZone v1 seam → UI) 14660 Auto-hide reveal/dismiss interaction: hover-reveal, pointer-away dismiss, pin escape 14661 Demo A tour script: the three-scene choreography as tour-runner content 14667 Perspective capture: whole-topology scope across the multi-window workspace 14668 Perspective restore into changed topology: reconciliation + the fail-closed contract 14669 Named perspective store: JSON-first persistence + lifecycle for dockLayout v2 records 14670 CrossWindowDragTarget: the receiving-window contract implementation 14768 transferItem executor operation: atomic cross-document item transfer 14769 Dock workspace cross-window participation: source hooks + target wiring 14770 Grouped drag executor operations: moveNode + transferNode 14771 Tab overflow affordance: hidden-tab projection on heavy tabs nodes 14772 Cross-window drag showcase: the two-window transfer demo scene 14773 dockPerspective.v1 vs shipped dockLayout.v2: reconcile the schema naming 14779 Dock transition animation layer: animated split/tab/auto-hide projections 14789 Flagship fusion demo: cockpit → docked panel → OS window → share, one tour 14850 Dock tab-drag: draggable headers + within-container reorder commit 14857 Dock cross-zone tab drag: functional tab-into model move (hit-test → moveItem) 14866 Dock dockPreview.v1 producer + unit test (compute half) 14886 Wire dockPreview.v1 producer into live drag: hover-affordance render + drop-routing e2e 14929 Animated dock re-layout: FLIP transitions on every committed dockZone operation 14930 Human-drag showcase beat + dock-guide affordance polish pass 14934 Docking epic closure gate: experience-parity matrix vs the Qt-ADS interaction inventory 14945 Scale changed-topology slot assignment across live restore paths 14959 Dock drop-indicator menu: candidate-set producer extension + DockDropIndicators + the cold-open drag beat 14969 Dock-zone surfaces never load the dashboard token scope — the motion contract is invisible on both 14989 Pin DockMotion geometry witnesses to one logical item across reprojection 15056 Dock example: perspective toolbar consumes ~51% viewport height (missing flex reset) 15098 Tab-native overflow: Neo.tab.plugin.Overflow owns the hidden-tab projection 15099 Dense-workstation showcase: the ~20-tab big-screen scene, themed + toured 15137 Make preserved-identity DockFlip moves clip-safe and immediate 15144 Promote the dense workstation to a standalone app 15147 Harden DockFlip boundary oracles and reconcile the DockMotion seed 15164 Compact Workstation tourbar controls and clear story fill 15165 Make Workstation dock composition adapt to viewport width 15166 Expose Workstation splitters and unify dock pane chrome 15172 Make dock edge-band geometry host-relative on both axes 15171 Dock projection: migrate remaining consumers to the identity reconciler 15178 Dock Demo B: preserve CounterPane across changed-topology retirement 15189 Stop cross-window transfers from invalidating dockZone.v1 |
| subIssuesCompleted | 59 |
| subIssuesTotal | 59 |
| contentTrust | |
| projected | |
| quarantined | 0 |
| signals | [] |
| blockedBy | [] |
| blocking | [] |
| milestone | v13.2 |
Problem scope
The QT-grade docking foundation (#13030 scoping anchor) has landed its core layer: the
neo.harness.dockZone.v1model contract, the semantic-operation executor (Neo.dashboard.DockZoneModel), the split/tab rendering adapter (Neo.dashboard.DockLayoutAdapter), and the cancelable drag-to-dock preview affordances — across #13061→#13142, with layout persistence (#13147/#13153) in flight. Neo now has dock-everywhere edge zones, nested splits, tabbed slots, and drag-preview, all as worker-owned serializable JSON with multi-window object permanence.What remains, measured against a mature QT/WPF-class docking system, is the polish / parity layer — interactions an enterprise desktop-to-web migration audience treats as table stakes, which the foundation deliberately deferred:
sizes, but the adapter projects staticflexonly;HarnessDockZoneModel.md§Split Projection explicitly defers a resizable splitter that writes size changes back through a semantic operation.pinnableitem hint and four edge zones, but there is no collapsed-to-sidebar auto-hide state (show on hover/click): the single most visible QT docking affordance still absent.neo.harness.dockLayout.v1already modelslayoutId+title+revision, but there is no layout store or switcher to save and fast-switch named workspace layouts.Why an epic, not a single ticket: each gap is an independent one-PR leaf with its own contract question, but they share one convergent outcome (QT-parity on the existing model) and one guardrail set. This is the follow-up phase to the #13030 foundation — sequenced after the foundation leaves (incl. persistence #13147/#13153) land, and it does not touch their in-flight lanes.
Demand basis is unchanged from #13030 / #13012: the enterprise desktop-to-web (QT/WPF-class ISV) migration market, treated as a market hypothesis, not single-source, with the harness operator cockpit and the Portal learning workspace as the in-repo second consumers named in the dock-zone contract's §Demand Validation. Per the #13012 partner guardrail, partner specifics stay out of this body.
Intended solution shape
One convergent direction: additive on the existing
dockZone.v1model — not a redesign, and explicitly not a coresrc/layout/Docklift (the contract's §Ownership Boundary keeps this insrc/dashboard/until a second non-dashboard consumer proves reuse). Each gap maps to an affordance the foundation already anticipated:DockLayoutAdapter-projected children, committing through a new semantic size operation onDockZoneModel(never a pointer handler mutating persistedsizes);DockPreviewoverlay;dockLayout.v1wrapper, with fail-closed restore;Neo.tab.Containeroverflow affordance.The claimer of each leaf runs
structural-pre-flight+ticket-createand settles that leaf's contract question at claim time; this body is the convergent shape, not the per-sub breakdown.Out of scope
src/layout/Dockprimitive — deferred until a second non-dashboard consumer demands it (contract §Ownership Boundary).Binding guardrails (ADR 0020 §4)
Gesture-proof guardrail (added 2026-07-05, from the #14591 audit — operator-attributed planning miss): a runtime-interaction leaf (anything a pointer touches: drag, drop, resize, reveal, tour) ships its e2e gesture spec in the same PR — "live gesture rides a later leaf" is not an accepted evidence line on this epic anymore. Model-tier leaves (pure executors/validators) keep unit floors. The Grid DnD e2e family is the proven template.
DOMRect, screen coordinates,dockPreview,windowId, live components, functions, or credentials in any serialized layout (HarnessDockZoneModel.md§Serializable vs Runtime State).SortZone/DragCoordinator/Windowpipeline; preview state stays runtime-only and converts to a semantic operation on drop.Related
learn/agentos/HarnessDockZoneModel.md. Substrate:src/dashboard/DockZoneModel.mjs,src/dashboard/DockLayoutAdapter.mjs,apps/agentos/view/DockPreview.mjs.Authored by @neo-opus-grace (Grace).
Closure Gate (binding — #14934)
This epic MUST NOT be resolved without an item-by-item experience-parity matrix against ADR 0029 §4.1's interaction-grain inventory (drag proxy · drop-indicator overlays · per-option preview · tab insertion cues · escape-cancel · commit animation) plus the surviving §4 capability rows. Every matrix row requires an evidence link — a recorded interaction, an e2e spec, or a live demo beat — never a bare assertion. Rationale: four independent analysis passes scored the drag experience "landed" at capability-list altitude while the standing bar (operator, 2026-07-02: "do not under-estimate QT docking — Qt-Advanced-Docking-System-class") is experience-parity; sub-issues-closed ≠ scope-met. Known-open rows at gate creation: escape-cancel (unowned gap), commit animation (#14929), affordance/proxy flagship polish (#14930).