Skip to content

41-windows: tabbed windows by touch (G6), drop on the dock strip (G7), one window registry for the dock + (G22), Image editor dock tab (G24) - #358

Open
AlexZ005 wants to merge 20 commits into
feat/41from
feat/41-windows
Open

AlexZ005 wants to merge 20 commits into
feat/41from
feat/41-windows

Conversation

@AlexZ005

Copy link
Copy Markdown
Collaborator

Roadmap 41 (1.32 preview review) — lane 41-windows: G6, G7, G22, G24. Base feat/41; includes feat/41-modals (z scale) merged.

What

  • G6 — tabbed floating windows by touch. The tab strip claims the touch gesture (touch-action:none on the strip, its tab scroller and tabs — with auto Chrome turned the drag into a pan and sent pointercancel after ~2 moves), captures the pointer, ends cleanly on cancel. On touch a tab name is the group's grip. Long-press (or right-click) a tab → Ungroup this tab / Dock this tab / Close.
  • G7 — drop on the dock's tab strip. A lone window, a torn-out tab or a whole group over the docked strip shows a caret between tabs, outlines the strip and turns the window 0.6 opaque; the drop docks at that index (bottomDock.placeDockTabs). The dock body is no longer a drop target (the 44px bottom edge still is). dragWindow places the window at pointer − grab offset (no drift after a clamp) and only bounds it by the viewport while dragging, so it moves over the dock and drawers like the Objects window; the bottom chrome (not the dock) applies on release.
  • G22 — one window registry. dockMenu.DOCK_WINDOWS feeds both the phone Windows sheet and the desktop dock "+". The desktop "+" now lists every window (Node editor and Image editor included) and adds and removes: docked rows are marked with "Remove", floating rows say "Dock", closed rows "Open".
  • G24 — the Image editor as a dock tab (Profiler's docked/floating split; the open state moved to the leaf image/imageEditorState.js, re-exported).

Forks + the recommendations taken: lane QUESTIONS file (touch tab drag = move group; strip + edge are the dock targets; Image editor floats by default).

Proof

suite lane base feat/40-int
window-groups-touch (G6, N6 unfolded + folded CDP touch, desktop) ALL PASS 19 FAIL
dock-strip-drop (G7 + G24) ALL PASS FAIL (no caret / ghost / index; window 223-371 px off the cursor)
dock-add-registry (G22) ALL PASS 9 FAIL (no Node editor)

Regressions green on the lane: window-tabs-move, tab-group-geometry, tab-group-stacking, tab-strip-zorder, shader-window, window-bottom-clamp, dock-chrome-40, image-editor, uv-editor, dock-tab-drag. Suites moved to the new contracts: dock-chrome §7/11.2 (G22), dock-tab-drag 7.1 (premise).
Not this branch: dock-chrome 10.1 (41-modals' z-28 cue; the test still expects 30), docking + shader-editor texture checks (red on base too).
svelte-check 300/40 (baseline) · check:tokens · check:zindex · vitest 1967/1967 · build green. Screenshots (dark + light) in the lane evidence folder.

🤖 Generated with Claude Code

AlexZ005 and others added 20 commits October 11, 2026 02:44
…ogo, What's new tops every button

- src/styles/ui.css: ONE ordered scale, lowest first: --z-canvas < --z-canvas-overlay < --z-chrome
  (FABs, Controls pill, side drawers) < --z-selection (phone strip) < --z-dock < --z-sheet <
  --z-window (40..44) < --z-phone-bar < --z-hud < --z-side-panel < --z-chrome-top (logo, undo/redo,
  Connect, notes/notifications/peers/profile) < --z-popover (main menu, profile, Add, search) <
  --z-toast-low < --z-modal < --z-onboarding (What's new, Welcome, tours) < --z-portal (selects,
  context menus, drag ghosts) < --z-toast. Old names stay as aliases (--z-drawer/-bottom/-viewport/
  -menu) so a branch written before the scale still resolves.
- every page-level hard-coded z-index moved onto it (80 sites: Users 996-999, Connect/PhoneShell
  300, Add/ObjectSearch 999/1000, ThemedSelect 9999, drag chips 1400, Sheet 60/61/42/43,
  PhoneShell 36-44, HUD 38/46, FABs z-30, Inspector z-50, ...); in-component stacking stays < 30.
- G3b: the logo is --z-chrome-top, so Settings and every app modal cover it (was --z-menu 1300 over
  --z-modal 1100); What's new is --z-onboarding at every width (no focusStack, no wn-sheet hack).
- G20 (scale half): the phone selection strip sits on --z-selection, under docks and sheets, and no
  longer rises with the bar over an open main/profile/Add menu.
- scripts/check-zindex.cjs + `npm run check:zindex` + a CI step: a page-level literal (>= 30)
  fails; `z-ok: <reason>` marks the numbers code reads back (windowFocus, docking).
- mobile-ui-fixes: the wn-sheet checks become "the changelog outranks the logo at every width".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ls, toasts stay for outcomes

- inventory: all 826 toast call sites on feat/40-int classified (STATUS-41-modals.md) — 12 become
  modals, 5 reconnect toasts go to G21, the rest stay toasts (passive outcomes, failures, peer requests).
- SessionPrompts.svelte: "Restore previous session?" and the too-large-scene ingest gate were
  STATE-MIRRORED sticky toasts in Toasts.svelte; now compact true modals (ConfirmModal's look) open
  exactly while their store holds a value. X / Esc / outside = Dismiss (restore) or Cancel (gate).
- confirmDialog (showConfirm / showChoice) for the one-shot questions: Delete flow, delete a group and
  its children, update / delete a prefab, rebuild discarding vertex edits or a sculpt, leave a session
  to join another, join on another server, export everything with nothing selected, create a local copy.
- peer REQUESTS (load a session, take control, see a private scene) stay cards like approvals.
- suites: toast-to-modal (new; counterfactual red on feat/40-int); gltf-export-selection,
  overload-guard, settings-autorestore-colors, touch-actions, ingest-gate, invite-link-live read the
  dialogs instead of the toasts.
- z-scale-layering: the desktop What's new window is clamped below the top bar, so the logo check
  applies only where the window overlaps it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ner queries)

- ui/SettingRow: the row is an inline-size container (`container: sr`), its grid moves to `.sr-body`.
  Under 560 px of ROW a wide control (flagged `wide`, segmented, slider, or two pieces such as a
  control and its status badge) drops under the label at full width; under 420 px every control but a
  lone switch does. Replaces the 640 px VIEWPORT rule, which never fired on an unfolded phone or in a
  narrow desktop window — reduced-width.jpg's "Voice typing provider" / "Speech / to / text" column.
- containment makes the row the containing block of fixed descendants; nothing in a row is
  (ThemedSelect portals to <body> in the non-modal Settings dialog).
- settings-narrow (new): every page at Settings widths 360 / 540 / 700 / 900, the N6 folded and
  unfolded, and desktop — every row keeps >= 180 px of text beside its control or spans the row,
  no control overflows; SHOTS=<dir> writes one screenshot per page and width.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…never toasts

- $lib/connectionStatus.js: ONE {tone, words} — grey idle, yellow (pulsing) connecting / dialling /
  reconnecting, green connected (stays green through a signaling outage, the words say it), red past
  GIVE_UP_ATTEMPTS (6, ~1 min on the 27-F backoff). Pure connectionStatusOf + vitest.
- peerHandler: the "Lost the peer server", "closed the link", "Cannot reach … Retrying" and
  "Reconnected" toasts are gone (a phone tab switch raised three). Past the threshold ONE
  notification-centre entry per outage; the fallback-to-public notice is a notification too; the
  store ticks on open so the dot turns back. Retry behaviour is unchanged (never gives up).
- phone chip (#ps-connect-chip): dot + chevron (+ mic in a call), no text — fits beside the bell and
  the peers (space-connect-svelte.jpg); title + aria-label carry the words.
- desktop bar: a status dot (#connect-status) leads the bar in place of the "Reconnecting · 12 s"
  badge (its tooltip keeps the elapsed time); the connected chip drops its text label.
- the cloud plugin mounts nothing into the pill any more (mountProfile / mountConnectDrawer) and none
  of its toasts are about reconnecting — no cloud change.
- signaling-reconnect: rewritten to the new contract (no toasts, dot tones, one notification) + a
  phone section (no text on the chip, a drop and return raise no toast).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…amed from --z-bottom)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…reenshot pass

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…us-warn fill token; --ink-warn is a text ink)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…a window on the dock's tab strip at a caret

G6: the group tab strip claims the touch gesture (touch-action:none on the strip, its tab
scroller and tabs; it had auto, so Chrome turned the drag into a pan and sent pointercancel
after ~2 moves), captures the pointer and ends cleanly on cancel. On touch a tab is the
group's grip (drag = move the group); long-press (or right-click) a tab -> Ungroup this tab /
Dock this tab / Close.

G7: dragging a lone window, a torn-out tab or a whole group over the docked tab strip shows a
caret between the tabs, outlines the strip and turns the window 0.6 opaque; the drop docks at
that index (bottomDock.placeDockTabs). The dock body is no longer a drop target (the 44px
bottom edge still is). dragWindow places the window at pointer - grab offset (no drift after a
clamp) and only bounds it by the viewport while dragging, so it passes over the dock and
drawers like the Objects window; the bottom chrome (not the dock) applies again on release.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
DOCK_FAMILY gains 'imageEditor' (title + icon); the dock '+' menu and the phone views sheet
list it (DOCK_EXTRA_VIEWS — not the toolbar roster, Controls builds that from DOCK_VIEWS).
ImageEditorWindow gets the Profiler's docked/floating split: imageEditorDocked (default
floating), the dockModeArm consumer, a dock occupant, header Dock button, bottomDockable,
the tab x through registerDockCloser (asks on unsaved edits), an empty state when opened
from '+' with no image, and the phone stacking rules for the docked panel too. The open
state moved to the leaf image/imageEditorState.js (re-exported, API unchanged) so the dock
can address it. Suite dock-strip-drop covers G7 + G24.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… scale (check:zindex clean)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e name)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…one sheet lists (one registry), and adds/removes

dockMenu.DOCK_WINDOWS (Node editor + DOCK_VIEWS + Image editor) is THE window registry: the
phone Windows sheet and the desktop strip's "+" both read it. The desktop list was DOCK_VIEWS
(no Node editor) minus every docked view; now it is every window, docked rows marked with a
Remove hint (closes it), floating rows Dock, closed rows Open. The floating Node editor's own
"+" passes exclude:['flow'] and builds per open. dock-chrome section 7 moved to the new
contract; new suite dock-add-registry compares the desktop rows against the real phone sheet.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s cap), never return a pending confirm promise, object-delete reads the group modal

- settings-narrow (360/540/700/900) + settings-narrow-devices (folded/unfolded/desktop) share
  settingsNarrowShared.cjs; seven sizes in one file ran past run.cjs's 480 s kill, which surfaced as
  'Target page, context or browser has been closed'.
- toast-to-modal: requestDeleteObjectGraph is async now (it awaits the answer), so the evaluate must not
  return it — it waited for a click that never came until the runner killed it.
- object-delete: the group delete asks in a modal (G16).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ll; 2.5 asserts the pill nudge

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…2 hint (Animation … Dock)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ar 160px whichever way has room

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…'s first BUTTON (the status dot leads now); toast-to-modal reads plain-string toasts whole

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant