Skip to content

fix!: Do not delegate onDragCancel to onDragEnd by default - #3934

Merged
spydon merged 2 commits into
flame-engine:mainfrom
rumitvn:fix/on-drag-cancel-no-delegate
Aug 5, 2026
Merged

fix!: Do not delegate onDragCancel to onDragEnd by default#3934
spydon merged 2 commits into
flame-engine:mainfrom
rumitvn:fix/on-drag-cancel-no-delegate

Conversation

@rumitvn

@rumitvn rumitvn commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Description

DragCallbacks.onDragCancel used to delegate to onDragEnd by default:

void onDragCancel(DragCancelEvent event) => onDragEnd(event.toDragEnd());

But the two events mean different things. onDragEnd is the natural end of a drag and carries
velocity for fling detection, while onDragCancel means that the gesture was interrupted (another
recognizer won the arena, a second pointer triggered a scale takeover, a system event, etc.) and has
no meaningful velocity. Forwarding a cancel to onDragEnd makes a drag-to-dismiss component apply
its action even though the drag was actually cancelled. The old "very rare event" comment is no
longer true either: with MultiDragScaleDispatcher every two finger pinch cancels the individual
pointer drags.

onDragCancel now only resets isDragged (the same state that onDragEnd clears) without
forwarding. Anyone who wants the old behavior can override onDragCancel and call
onDragEnd(event.toDragEnd()), as the updated doc comment and the migration guide describe.

The examples and the Klondike tutorial that relied on the old delegation have been updated to handle
onDragCancel explicitly, otherwise a cancelled drag would leave a mouse joint alive, a ball with
its drag paint, or a card floating in the middle of the table.

Checklist

  • I have followed the Contributor Guide when preparing my PR.
  • I have updated/added tests for ALL new/updated/fixed functionality.
  • I have updated/added relevant documentation in docs and added dartdoc comments with ///.
  • I have updated/added relevant examples in examples or docs.

Breaking Change?

  • Yes, this PR is a breaking change.
  • No, this PR is not a breaking change.

Migration instructions

onDragEnd is no longer called when a drag is cancelled, only onDragCancel is. If you were
relying on the old behavior, forward the event yourself:

@override
void onDragCancel(DragCancelEvent event) {
  super.onDragCancel(event);
  onDragEnd(event.toDragEnd());
}

If a cancelled drag should instead be reverted, put that logic in onDragCancel without calling
onDragEnd. See doc/flame/migration.md for the full entry.

Related Issues

Closes #3926

@spydon spydon left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is a breaking change it's not going to be something we pull in now, it is listed among the V2 issues: #1938
Specifically: #3926

@luanpotter luanpotter added the v2 A feature or fix needed before the release of V2 label Jul 19, 2026
rumitvn and others added 2 commits August 5, 2026 21:50
A cancellation is semantically different from a natural drag end: it has no
velocity and means the gesture was interrupted (another recognizer won the
arena, a scale takeover occurred, etc.). Delegating to onDragEnd made
drag-to-dismiss style components apply their action on a cancel. With
MultiDragScaleDispatcher every pinch cancels the individual pointer drags, so
this is no longer the rare event the old comment claimed.

onDragCancel now just resets isDragged; override it and call onDragEnd to keep
the old behavior. Updated the docs and the tests that asserted delegation, and
added a test isolating the new behavior.

Closes flame-engine#3926
Adds the onDragCancel migration entry to doc/flame/migration.md and updates
the examples and the Klondike tutorial that relied on a cancelled drag being
delivered as an onDragEnd.
@spydon
spydon force-pushed the fix/on-drag-cancel-no-delegate branch from dd7d162 to d1950a0 Compare August 5, 2026 19:56
@spydon spydon changed the title fix!: onDragCancel should not delegate to onDragEnd by default fix!: Do not delegate onDragCancel to onDragEnd by default Aug 5, 2026
@spydon
spydon merged commit d5be112 into flame-engine:main Aug 5, 2026
8 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v2 A feature or fix needed before the release of V2

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: onDragCancel should not delegate to onDragEnd by default

3 participants