Skip to content

feat(home-v2): draggable tabs and browser tab gestures - #351

Merged
QuickMythril merged 1 commit into
mainfrom
feat/home-v2-tab-drag
Aug 24, 2026
Merged

feat(home-v2): draggable tabs and browser tab gestures#351
QuickMythril merged 1 commit into
mainfrom
feat/home-v2-tab-drag

Conversation

@QuickMythril

Copy link
Copy Markdown
Member

Summary

Parity review P-4 — tab dragging plus the cheap v1 gestures, built on #350's tab model:

  • Drag to reorder (mirrors the v1 TopBar implementation): pointer capture on the tab, 5px start threshold, live reorder as the pointer crosses sibling midpoints, and click suppression after a completed drag so releasing doesn't also activate the dragged tab. The close button is exempt from capture so it still gets ordinary clicks.
  • Groups reorder independently: internal page tabs reorder among themselves and app tabs among themselves, keeping pages grouped ahead of apps (per feat(home-v2): allow multiple internal pages open as tabs #350's model).
  • New reorder-tab / reorder-internal ProductActions: toIndex is the clamped final index within the group; unchanged index returns the same state object (so live dragging is cheap), unknown tab/page throws TAB_NOT_FOUND. Order persists through the existing product serialization — no shell-state format change.
  • Gestures: middle-click closes a tab (app or internal); double-click on the strip's empty area opens the configured new tab; ArrowLeft/ArrowRight/Home/End move focus between tab buttons without activating (Enter/Space still activates) — the v1 focus-only roving pattern.

Deliberately deferred: drag-out-to-detach / move-tab-to-new-window. The main-process windows:openTabInNewWindow plumbing exists but carries a v1-shaped route-history payload the v2 renderer never reads, and v2 windows currently share one persisted shell state — detaching needs a real multi-window state design first. Logged in the parity tracker as a follow-up alongside the tab context menu.

Testing

  • Renderer tsc clean; test:home-v2-foundation (extended with reorder/clamp/no-op/unknown-id and internal-group cases), test:home-v2-browser-chrome pass; build:renderer succeeds. Drag feel itself needs a hands-on check on your dev build — midpoint live-reorder should feel like Home 1.

🤖 Generated with Claude Code

Adds reorder-tab / reorder-internal ProductActions (clamped final
index, same-state no-op, groups reorder independently so internal
pages stay ahead of app tabs) and a pointer-capture drag in TabStrip
mirroring v1: 5px start threshold, live reorder at sibling midpoints,
click suppression after a completed drag, close-button exempt from
capture. Gestures: middle-click (auxclick) closes app or internal
tabs, double-click on the empty strip opens the configured new tab,
and ArrowLeft/Right/Home/End move focus between tab buttons without
activating (Enter/Space still activates). Order persists via the
existing product serialization. Drag-out-to-detach is deferred: v2
windows share one persisted shell state and the existing
windows:openTabInNewWindow payload is v1-shaped.

Parity review P-4 (projects/qortium-home-2.1/parity-review-2026-08-24).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@QuickMythril
QuickMythril merged commit bebdb47 into main Aug 24, 2026
6 checks passed
@QuickMythril
QuickMythril deleted the feat/home-v2-tab-drag branch August 24, 2026 17:18
QuickMythril added a commit that referenced this pull request Aug 24, 2026
PR #351 called setPointerCapture on the tab CONTAINER in pointerdown.
Chromium then targets the compatibility click at the capture element, so
the inner button[role=tab] never received it and no tab — internal page
or app — could be switched with a mouse. Reproduced against the packaged
build with CDP Input.dispatchMouseEvent: a real click left settings
active, while element.click() on the same node switched correctly.

Every existing smoke activates tabs with element.click(), which emits no
pointer events, so the entire drag interaction was untested by anything
capable of catching this and CI stayed green.

Drag now tracks pointermove/pointerup/pointercancel on window for the
duration of the gesture instead of capturing, which keeps click
targeting intact, still follows the pointer outside the strip, and
detaches on unmount. Click suppression after a completed reorder is
unchanged.

Adds smoke:desktop:home-v2-tabs — genuine input against the AppImage,
asserting both that a real click switches tabs and that drag still
reorders (verified: dashboard welcome settings -> welcome dashboard
settings).

Parity review I0 (projects/qortium-home-2.1/parity-review-2026-08-24).

Co-authored-by: Claude Opus 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