5
5
import 'dart:math' as math;
6
6
7
7
import 'package:meta/meta.dart' ;
8
+ import 'package:ui/src/engine/keyboard_binding.dart' ;
8
9
import 'package:ui/ui.dart' as ui;
9
10
10
11
import '../engine.dart' show registerHotRestartListener;
@@ -73,7 +74,7 @@ class SafariPointerEventWorkaround {
73
74
}
74
75
75
76
class PointerBinding {
76
- PointerBinding (this .glassPaneElement)
77
+ PointerBinding (this .glassPaneElement, this ._keyboardConverter )
77
78
: _pointerDataConverter = PointerDataConverter (),
78
79
_detector = const PointerSupportDetector () {
79
80
if (isIosSafari) {
@@ -86,9 +87,9 @@ class PointerBinding {
86
87
static PointerBinding ? get instance => _instance;
87
88
static PointerBinding ? _instance;
88
89
89
- static void initInstance (DomElement glassPaneElement) {
90
+ static void initInstance (DomElement glassPaneElement, KeyboardConverter keyboardConverter ) {
90
91
if (_instance == null ) {
91
- _instance = PointerBinding (glassPaneElement);
92
+ _instance = PointerBinding (glassPaneElement, keyboardConverter );
92
93
assert (() {
93
94
registerHotRestartListener (_instance! .dispose);
94
95
return true ;
@@ -107,6 +108,7 @@ class PointerBinding {
107
108
108
109
PointerSupportDetector _detector;
109
110
final PointerDataConverter _pointerDataConverter;
111
+ KeyboardConverter _keyboardConverter;
110
112
late _BaseAdapter _adapter;
111
113
112
114
/// Should be used in tests to define custom detection of pointer support.
@@ -137,15 +139,23 @@ class PointerBinding {
137
139
}
138
140
}
139
141
142
+ @visibleForTesting
143
+ void debugOverrideKeyboardConverter (KeyboardConverter keyboardConverter) {
144
+ _keyboardConverter = keyboardConverter;
145
+ _adapter.clearListeners ();
146
+ _adapter = _createAdapter ();
147
+ _pointerDataConverter.clearPointerState ();
148
+ }
149
+
140
150
_BaseAdapter _createAdapter () {
141
151
if (_detector.hasPointerEvents) {
142
- return _PointerAdapter (_onPointerData, glassPaneElement, _pointerDataConverter);
152
+ return _PointerAdapter (_onPointerData, glassPaneElement, _pointerDataConverter, _keyboardConverter );
143
153
}
144
154
if (_detector.hasTouchEvents) {
145
- return _TouchAdapter (_onPointerData, glassPaneElement, _pointerDataConverter);
155
+ return _TouchAdapter (_onPointerData, glassPaneElement, _pointerDataConverter, _keyboardConverter );
146
156
}
147
157
if (_detector.hasMouseEvents) {
148
- return _MouseAdapter (_onPointerData, glassPaneElement, _pointerDataConverter);
158
+ return _MouseAdapter (_onPointerData, glassPaneElement, _pointerDataConverter, _keyboardConverter );
149
159
}
150
160
throw UnsupportedError ('This browser does not support pointer, touch, or mouse events.' );
151
161
}
@@ -239,14 +249,20 @@ class _Listener {
239
249
240
250
/// Common functionality that's shared among adapters.
241
251
abstract class _BaseAdapter {
242
- _BaseAdapter (this ._callback, this .glassPaneElement, this ._pointerDataConverter) {
252
+ _BaseAdapter (
253
+ this ._callback,
254
+ this .glassPaneElement,
255
+ this ._pointerDataConverter,
256
+ this ._keyboardConverter,
257
+ ) {
243
258
setup ();
244
259
}
245
260
246
261
final List <_Listener > _listeners = < _Listener > [];
247
262
final DomElement glassPaneElement;
248
263
final _PointerDataCallback _callback;
249
264
final PointerDataConverter _pointerDataConverter;
265
+ final KeyboardConverter _keyboardConverter;
250
266
251
267
/// Each subclass is expected to override this method to attach its own event
252
268
/// listeners and convert events into pointer events.
@@ -570,7 +586,8 @@ class _PointerAdapter extends _BaseAdapter with _WheelEventListenerMixin {
570
586
_PointerAdapter (
571
587
super .callback,
572
588
super .glassPaneElement,
573
- super .pointerDataConverter
589
+ super .pointerDataConverter,
590
+ super .keyboardConverter,
574
591
);
575
592
576
593
final Map <int , _ButtonSanitizer > _sanitizers = < int , _ButtonSanitizer > {};
@@ -602,13 +619,27 @@ class _PointerAdapter extends _BaseAdapter with _WheelEventListenerMixin {
602
619
String eventName,
603
620
_PointerEventListener handler, {
604
621
bool useCapture = true ,
622
+ bool checkModifiers = true ,
605
623
}) {
606
624
addEventListener (target, eventName, (DomEvent event) {
607
625
final DomPointerEvent pointerEvent = event as DomPointerEvent ;
626
+ if (checkModifiers) {
627
+ _checkModifiersState (event);
628
+ }
608
629
handler (pointerEvent);
609
630
}, useCapture: useCapture);
610
631
}
611
632
633
+ void _checkModifiersState (DomPointerEvent event) {
634
+ _keyboardConverter.synthesizeModifiersIfNeeded (
635
+ event.getModifierState ('Alt' ),
636
+ event.getModifierState ('Control' ),
637
+ event.getModifierState ('Meta' ),
638
+ event.getModifierState ('Shift' ),
639
+ event.timeStamp! ,
640
+ );
641
+ }
642
+
612
643
@override
613
644
void setup () {
614
645
_addPointerEventListener (glassPaneElement, 'pointerdown' , (DomPointerEvent event) {
@@ -654,7 +685,7 @@ class _PointerAdapter extends _BaseAdapter with _WheelEventListenerMixin {
654
685
_convertEventsToPointerData (data: pointerData, event: event, details: details);
655
686
_callback (pointerData);
656
687
}
657
- }, useCapture: false );
688
+ }, useCapture: false , checkModifiers : false );
658
689
659
690
_addPointerEventListener (domWindow, 'pointerup' , (DomPointerEvent event) {
660
691
final int device = _getPointerId (event);
@@ -680,7 +711,7 @@ class _PointerAdapter extends _BaseAdapter with _WheelEventListenerMixin {
680
711
_convertEventsToPointerData (data: pointerData, event: event, details: details);
681
712
_callback (pointerData);
682
713
}
683
- });
714
+ }, checkModifiers : false );
684
715
685
716
_addWheelEventListener ((DomEvent event) {
686
717
_handleWheelEvent (event);
@@ -767,21 +798,35 @@ class _TouchAdapter extends _BaseAdapter {
767
798
_TouchAdapter (
768
799
super .callback,
769
800
super .glassPaneElement,
770
- super .pointerDataConverter
801
+ super .pointerDataConverter,
802
+ super .keyboardConverter,
771
803
);
772
804
773
805
final Set <int > _pressedTouches = < int > {};
774
806
bool _isTouchPressed (int identifier) => _pressedTouches.contains (identifier);
775
807
void _pressTouch (int identifier) { _pressedTouches.add (identifier); }
776
808
void _unpressTouch (int identifier) { _pressedTouches.remove (identifier); }
777
809
778
- void _addTouchEventListener (DomEventTarget target, String eventName, _TouchEventListener handler) {
810
+ void _addTouchEventListener (DomEventTarget target, String eventName, _TouchEventListener handler, { bool checkModifiers = true ,} ) {
779
811
addEventListener (target, eventName, (DomEvent event) {
780
812
final DomTouchEvent touchEvent = event as DomTouchEvent ;
813
+ if (checkModifiers) {
814
+ _checkModifiersState (event);
815
+ }
781
816
handler (touchEvent);
782
817
});
783
818
}
784
819
820
+ void _checkModifiersState (DomTouchEvent event) {
821
+ _keyboardConverter.synthesizeModifiersIfNeeded (
822
+ event.altKey,
823
+ event.ctrlKey,
824
+ event.metaKey,
825
+ event.shiftKey,
826
+ event.timeStamp! ,
827
+ );
828
+ }
829
+
785
830
@override
786
831
void setup () {
787
832
_addTouchEventListener (glassPaneElement, 'touchstart' , (DomTouchEvent event) {
@@ -910,7 +955,8 @@ class _MouseAdapter extends _BaseAdapter with _WheelEventListenerMixin {
910
955
_MouseAdapter (
911
956
super .callback,
912
957
super .glassPaneElement,
913
- super .pointerDataConverter
958
+ super .pointerDataConverter,
959
+ super .keyboardConverter,
914
960
);
915
961
916
962
final _ButtonSanitizer _sanitizer = _ButtonSanitizer ();
@@ -920,13 +966,27 @@ class _MouseAdapter extends _BaseAdapter with _WheelEventListenerMixin {
920
966
String eventName,
921
967
_MouseEventListener handler, {
922
968
bool useCapture = true ,
969
+ bool checkModifiers = true ,
923
970
}) {
924
971
addEventListener (target, eventName, (DomEvent event) {
925
972
final DomMouseEvent mouseEvent = event as DomMouseEvent ;
973
+ if (checkModifiers) {
974
+ _checkModifiersState (event);
975
+ }
926
976
handler (mouseEvent);
927
977
}, useCapture: useCapture);
928
978
}
929
979
980
+ void _checkModifiersState (DomMouseEvent event) {
981
+ _keyboardConverter.synthesizeModifiersIfNeeded (
982
+ event.getModifierState ('Alt' ),
983
+ event.getModifierState ('Control' ),
984
+ event.getModifierState ('Meta' ),
985
+ event.getModifierState ('Shift' ),
986
+ event.timeStamp! ,
987
+ );
988
+ }
989
+
930
990
@override
931
991
void setup () {
932
992
_addMouseEventListener (glassPaneElement, 'mousedown' , (DomMouseEvent event) {
0 commit comments