fix(dnd): tear down anchored drop overlay when a drag leaves mid-flight - #1536
Merged
Merged
Conversation
While an HTML5 drag was still active, leaving an anchored drop target (e.g. a tab in a floating group) and moving to dead space — or to a target in a different overlay container — left the drop overlay visible until the drag ended. The HTML5 backend intentionally does not clear the shared anchor container on `dragleave`: doing so would kill the overlay's slide between adjacent targets and churn on the spurious `dragleave`s HTML5 fires when crossing a target's own child elements. But never clearing means the overlay lingers whenever the drag leaves to somewhere that doesn't re-render into that container. Fix: on `dragleave` the target now *schedules* a clear on the anchor container (`DropTargetTargetModel.scheduleClear`) instead of doing nothing. The next target that renders into the same container cancels it (via `getElements`), so the overlay still slides between adjacent targets; but if the drag leaves to dead space or another container, the clear fires and the overlay is torn down. The pointer backend already clears on drag-leave, so this is HTML5-only. This is the root-cause fix for the lingering-overlay class of bug and also covers the cross-container end-of-drag case addressed by the earlier `dragend` safety net (#1534), which now acts as belt-and-suspenders for a drag that ends with no clearing `dragleave` at all. Tests: leaving to dead space tears the overlay down; sliding to another target in the same container preserves it (scheduled clear cancelled); and the #1534 cross-container leave is cleared purely by the leave, with no `dragend`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PjU3r4fnmpLUz7Bx1SjNvP
|
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.



Description
While an HTML5 drag was still active, leaving an anchored drop target (e.g. a tab in a floating group) and moving to dead space — or to a target in a different overlay container — left the drop overlay visible until the drag ended.
Reproduction: a floating group with two tabs; drag one tab over the other (a drop overlay appears on the target tab's edge), then move the mouse off the floating group — the overlay stays.
Cause: the HTML5 backend intentionally does not clear the shared anchor container on
dragleave— doing so would kill the overlay's slide between adjacent targets and churn on the spuriousdragleaves HTML5 fires when crossing a target's own child elements. But never clearing means the overlay lingers whenever the drag leaves to somewhere that doesn't re-render into that container.Fix: on
dragleavethe target now schedules a clear on the anchor container (a new optionalDropTargetTargetModel.scheduleClear) instead of doing nothing. The next target that renders into the same container cancels it (viagetElements), so the overlay still slides between adjacent targets; but if the drag leaves to dead space or another container, the deferred clear fires and the overlay is torn down. The pointer backend already clears on drag-leave, so this is HTML5-only.Relationship to #1534
This is the root-cause fix and also covers the cross-container end-of-drag case addressed by the earlier
dragendsafety net in #1534 (releasing elsewhere first involves leaving the target, which now schedules the clear). The #1534dragendlistener is retained as belt-and-suspenders for the narrow case of a drag that ends with no clearingdragleaveat all (e.g. an ESC-cancel where the browser skipsdragleave).Type of change
Affected packages
dockview-coreHow to test
Steps above (floating group, two tabs, drag one over the other, then leave the group — overlay no longer lingers).
Automated (
droptargetDeferredClear.spec.ts):dragendneeded.Checklist
yarn testpasses (1683 dockview-core tests)tsc --noEmittypecheck cleanbiome format/biome lintcleanscheduleClearis an optional addition to an internal model interface)🤖 Generated with Claude Code
https://claude.ai/code/session_01PjU3r4fnmpLUz7Bx1SjNvP
Generated by Claude Code