Skip to content

fix(windows): keep a drag alive when the cursor leaves the view - #11

Merged
Y-PLONI merged 1 commit into
Otzaria:masterfrom
Nathaniel-260:fix/windows-drag-cancelled-on-pointer-exit
Aug 27, 2026
Merged

fix(windows): keep a drag alive when the cursor leaves the view#11
Y-PLONI merged 1 commit into
Otzaria:masterfrom
Nathaniel-260:fix/windows-drag-cancelled-on-pointer-exit

Conversation

@Nathaniel-260

@Nathaniel-260 Nathaniel-260 commented Aug 26, 2026

Copy link
Copy Markdown

The bug

On Windows, dragging the mouse out of the WebView while a button is held ends the gesture. This breaks text-selection extension, drag-and-drop, and mousemove-driven UI.

Root cause

MouseRegion.onExit fires when the cursor crosses the widget bounds, including mid-drag. Flutter continues routing the captured pointer sequence to the Listener, but forwarding that exit as WebView2 LEAVE makes Chromium end the in-flight gesture.

Fix

  • Defer LEAVE while any mouse button is down, then send it after the final button-up or cancellation.
  • Clear the deferred leave when the cursor re-enters during the same drag, so WebView2 sees no unmatched enter/leave pair.
  • Translate Flutter mouse cancellation to the matching button-up before the deferred leave. WebView2 has no mouse-cancel event; this releases native button state and prevents later moves from retaining a button-down virtual key.
  • Keep ordinary hover enter/leave behavior unchanged.

The implementation deliberately leaves the WebView2 LEAVE arguments at zero, as required by its SendMouseInput contract.

Tests

custom_platform_view_drag_test.dart covers dragging out, forwarding out-of-bounds cursor positions, releasing/cancelling outside, re-entry during a drag, right-button drags, and ordinary hover behavior.

Validation after rebasing onto current master:

  • flutter analyze
  • flutter test (44 tests)

@Y-PLONI
Y-PLONI force-pushed the fix/windows-drag-cancelled-on-pointer-exit branch 2 times, most recently from 22a2ae1 to 25b534e Compare August 27, 2026 11:35
MouseRegion.onExit forwarded LEAVE unconditionally, including while a
mouse button was still held. WebView2 turns that into WM_MOUSELEAVE and
Chromium ends the gesture in flight, so dragging past the edge of the
view -- how a selection is extended on every platform -- drops the
selection the user is making. Flutter keeps routing those drag moves to
this view until the button comes up, so the pointer has not actually
gone anywhere as far as the gesture is concerned.

Withhold the LEAVE while any button is down and deliver it on button-up
or cancellation; swallow the matching ENTER when the cursor comes back
first, so the native hover state stays paired.

WebView2 has no mouse-cancel event. Translate Flutter cancellation to
the matching button-up before delivering the deferred LEAVE, which clears
the native button state. Leave arguments remain zero as required by
WebView2 SendMouseInput.
@Y-PLONI
Y-PLONI force-pushed the fix/windows-drag-cancelled-on-pointer-exit branch from 25b534e to 2656a71 Compare August 27, 2026 11:35
@Y-PLONI
Y-PLONI merged commit 4d7700a into Otzaria:master Aug 27, 2026
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.

2 participants