Problem
DragCallbacks.onDragCancel currently delegates to onDragEnd by default:
void onDragCancel(DragCancelEvent event) => onDragEnd(event.toDragEnd());
These two events are semantically different:
onDragEnd: the user lifted their finger naturally; carries velocity info for fling detection.
onDragCancel: the gesture was interrupted (another recognizer won the arena, a second finger caused a scale takeover, a system event, etc.); no meaningful velocity.
Calling onDragEnd from onDragCancel conflates the two. A drag-to-dismiss component would incorrectly "apply the action" when the drag was actually cancelled. Calls from cancel always produce zero velocity in DragEndDetails, which can cause subtle bugs.
The comment in the source calls cancellations "very rare", but with MultiDragScaleDispatcher (PR #3782) this is no longer true: every two-finger pinch gesture cancels the individual pointer drags.
Proposed fix
onDragCancel should reset isDragged directly (the same way onDragEnd does) without forwarding to onDragEnd.
- Users who want identical handling can override
onDragCancel to call onDragEnd themselves.
Impact
This is a breaking change: existing code that relies on onDragCancel triggering onDragEnd will need to be updated.
Related to #1938.
Problem
DragCallbacks.onDragCancelcurrently delegates toonDragEndby default:These two events are semantically different:
onDragEnd: the user lifted their finger naturally; carries velocity info for fling detection.onDragCancel: the gesture was interrupted (another recognizer won the arena, a second finger caused a scale takeover, a system event, etc.); no meaningful velocity.Calling
onDragEndfromonDragCancelconflates the two. A drag-to-dismiss component would incorrectly "apply the action" when the drag was actually cancelled. Calls from cancel always produce zero velocity inDragEndDetails, which can cause subtle bugs.The comment in the source calls cancellations "very rare", but with
MultiDragScaleDispatcher(PR #3782) this is no longer true: every two-finger pinch gesture cancels the individual pointer drags.Proposed fix
onDragCancelshould resetisDraggeddirectly (the same wayonDragEnddoes) without forwarding toonDragEnd.onDragCancelto callonDragEndthemselves.Impact
This is a breaking change: existing code that relies on
onDragCanceltriggeringonDragEndwill need to be updated.Related to #1938.