fix(core): defer pointerdown tab activation under the HTML5 drag backend (DV-37)#1453
Open
mathuo wants to merge 2 commits into
Open
fix(core): defer pointerdown tab activation under the HTML5 drag backend (DV-37)#1453mathuo wants to merge 2 commits into
mathuo wants to merge 2 commits into
Conversation
With the HTML5 drag backend a tab is natively `draggable`, and a native drag arms from the same pointerdown+move gesture. Activating an inactive tab on pointerdown synchronously moves focus and relayouts the tab strip, and Firefox aborts a pending native drag when that happens — so a drag started on an inactive tab never begins (#932). Defer the pointerdown activation one frame when the HTML5 backend is live, so `dragstart` arms first; a plain click still activates on the next frame, which is imperceptible. The pointer backend has no native drag to pre-empt and stays synchronous. The deferred activation is cancelled on dispose and skipped if the tab is removed within the frame. jsdom cannot drive a native drag, so the added test asserts the observable contract (deferred-then-applied under html5, synchronous under pointer); real Firefox drag behaviour requires manual verification. Fixes DV-37 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011JE1SmW4mWp6AdoNVbHprb
`tsc --build` rejects assigning `undefined` to the `MutableDisposable.value` setter (typed `IDisposable`). The clear was unnecessary — a rAF handle that has already fired cancels to a no-op, and the next pointerdown (or dispose) replaces the stored disposable — so remove it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011JE1SmW4mWp6AdoNVbHprb
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



This fixes a Firefox-only, native-HTML5-drag bug that cannot be reproduced in an automated test — see "Why no e2e test" below. Please drag an inactive tab in Firefox to confirm the drag now starts.
Problem (DV-37 / #932)
With the HTML5 drag backend (the default for mouse on desktop), a tab is natively
draggableand a native drag arms from the same pointerdown+move gesture. Onpointerdownof an inactive tab,tabs.tssynchronously callsopenPanel(panel)— moving focus and relaying out the tab strip. Firefox aborts a pending native drag when focus/layout changes mid-gesture, so a drag started on an inactive tab never begins (it just activates and snaps back). Chrome is more lenient, so it works there.Fix
Defer the pointerdown activation one frame (
requestAnimationFrame) only when the HTML5 backend is live, sodragstartarms first. A plain click still activates on the next frame (imperceptible). The pointer backend has no native drag to pre-empt and stays fully synchronous. The deferred activation is cancelled on dispose and skipped if the tab is removed within the frame.Scope is deliberately minimal to respect the "bug fixes must not change expected behaviour" rule: the only change is a one-frame deferral on the mouse/HTML5 activation path; timing of the end state is preserved, and every other activation route (pointer backend, edge groups, shift-to-float, keyboard, programmatic) is untouched.
Why no e2e test (I checked empirically)
I installed Firefox and tested whether Playwright could reproduce this. Playwright cannot initiate a native HTML5
dragstartin any browser here —mouse.down/move/upand the dedicatedlocator.dragTo()both producedragstart=0in both Chromium and Firefox against the native backend. Since a green Chromium control is impossible, the harness can't distinguish the Firefox bug from its own inability to start a native drag, and syntheticDragEventdispatch would bypass the exact native-initiation timing that is the bug. So this genuinely requires a human dragging in Firefox.Test
tabActivationPointerDown.spec.tsasserts the observable contract of the fix in jsdom:v8-branch, passes here — verified.)openPanel.Full
dockview-coresuite: 1227 passed.Fixes DV-37
🤖 Generated with Claude Code
Generated by Claude Code