@@ -48,13 +48,22 @@ class PointerDataConverter {
4848 // Map from browser pointer identifiers to PointerEvent pointer identifiers.
4949 final Map <int , _PointerState > _pointers = < int , _PointerState > {};
5050
51+ /// This field is used to keep track of button state.
52+ ///
53+ /// To normalize pointer events, when we receive pointer down followed by
54+ /// pointer up, we synthesize a move event. To make sure that button state
55+ /// is correct for move regardless of button state at the time of up event
56+ /// we store it on down,hover and move events.
57+ int _activeButtons = 0 ;
58+
5159 /// Clears the existing pointer states.
5260 ///
5361 /// This method is invoked during hot reload to make sure we have a clean
5462 /// converter after hot reload.
5563 void clearPointerState () {
5664 _pointers.clear ();
5765 _PointerState ._pointerCount = 0 ;
66+ _activeButtons = 0 ;
5867 }
5968
6069 _PointerState _ensureStateForPointer (int device, double x, double y) {
@@ -328,6 +337,7 @@ class PointerDataConverter {
328337 scrollDeltaY: scrollDeltaY,
329338 )
330339 );
340+ _activeButtons = buttons;
331341 break ;
332342 case ui.PointerChange .down:
333343 final bool alreadyAdded = _pointers.containsKey (device);
@@ -426,6 +436,7 @@ class PointerDataConverter {
426436 scrollDeltaY: scrollDeltaY,
427437 )
428438 );
439+ _activeButtons = buttons;
429440 break ;
430441 case ui.PointerChange .move:
431442 assert (_pointers.containsKey (device));
@@ -459,6 +470,7 @@ class PointerDataConverter {
459470 scrollDeltaY: scrollDeltaY,
460471 )
461472 );
473+ _activeButtons = buttons;
462474 break ;
463475 case ui.PointerChange .up:
464476 case ui.PointerChange .cancel:
@@ -485,7 +497,7 @@ class PointerDataConverter {
485497 device: device,
486498 physicalX: physicalX,
487499 physicalY: physicalY,
488- buttons: buttons ,
500+ buttons: _activeButtons ,
489501 obscured: obscured,
490502 pressure: pressure,
491503 pressureMin: pressureMin,
0 commit comments