diff --git a/lib/web_ui/lib/src/engine/dom.dart b/lib/web_ui/lib/src/engine/dom.dart index 3ef7e820f91c7..bde13096d7b18 100644 --- a/lib/web_ui/lib/src/engine/dom.dart +++ b/lib/web_ui/lib/src/engine/dom.dart @@ -1142,6 +1142,10 @@ extension DomWheelEventExtension on DomWheelEvent { class DomTouchEvent extends DomUIEvent {} extension DomTouchEventExtension on DomTouchEvent { + external bool get altKey; + external bool get ctrlKey; + external bool get metaKey; + external bool get shiftKey; List? get changedTouches => js_util .getProperty?>(this, 'changedTouches') ?.cast(); diff --git a/lib/web_ui/test/engine/pointer_binding_test.dart b/lib/web_ui/test/engine/pointer_binding_test.dart index 130c53f33e740..b713a93e19161 100644 --- a/lib/web_ui/test/engine/pointer_binding_test.dart +++ b/lib/web_ui/test/engine/pointer_binding_test.dart @@ -234,6 +234,19 @@ void testMain() { expect(events[1].buttons, equals(0)); expect(events[1].client.x, equals(0)); expect(events[1].client.y, equals(0)); + + context.pressAllModifiers(); + event = expectCorrectType(context.primaryDown(clientX: 100, clientY: 101)); + expect(event.getModifierState('Alt'), true); + expect(event.getModifierState('Control'), true); + expect(event.getModifierState('Meta'), true); + expect(event.getModifierState('Shift'), true); + context.unpressAllModifiers(); + event = expectCorrectType(context.primaryDown(clientX: 100, clientY: 101)); + expect(event.getModifierState('Alt'), false); + expect(event.getModifierState('Control'), false); + expect(event.getModifierState('Meta'), false); + expect(event.getModifierState('Shift'), false); }); test('_TouchEventContext generates expected events', () { @@ -330,6 +343,19 @@ void testMain() { expect(events[0].changedTouches![1].identifier, equals(105)); expect(events[0].changedTouches![1].client.x, equals(322)); expect(events[0].changedTouches![1].client.y, equals(323)); + + context.pressAllModifiers(); + event = expectCorrectType(context.primaryDown(clientX: 100, clientY: 101)); + expect(event.altKey, true); + expect(event.ctrlKey, true); + expect(event.metaKey, true); + expect(event.shiftKey, true); + context.unpressAllModifiers(); + event = expectCorrectType(context.primaryDown(clientX: 100, clientY: 101)); + expect(event.altKey, false); + expect(event.ctrlKey, false); + expect(event.metaKey, false); + expect(event.shiftKey, false); }); test('_MouseEventContext generates expected events', () { @@ -419,6 +445,19 @@ void testMain() { expect(event.buttons, equals(0)); expect(event.client.x, equals(400)); expect(event.client.y, equals(401)); + + context.pressAllModifiers(); + event = expectCorrectType(context.primaryDown(clientX: 100, clientY: 101)); + expect(event.getModifierState('Alt'), true); + expect(event.getModifierState('Control'), true); + expect(event.getModifierState('Meta'), true); + expect(event.getModifierState('Shift'), true); + context.unpressAllModifiers(); + event = expectCorrectType(context.primaryDown(clientX: 100, clientY: 101)); + expect(event.getModifierState('Alt'), false); + expect(event.getModifierState('Control'), false); + expect(event.getModifierState('Meta'), false); + expect(event.getModifierState('Shift'), false); }); // ALL ADAPTERS @@ -2420,6 +2459,15 @@ abstract class _BasicEventContext implements PointerSupportDetector { bool get isSupported; + // Accepted modifier keys are 'Alt', 'Control', 'Meta' and 'Shift'. + // https://www.w3.org/TR/uievents-key/#keys-modifier defines more modifiers, + // but only the four main modifiers could be set from MouseEvent, PointerEvent + // and TouchEvent constructors. + bool altPressed = false; + bool ctrlPressed = false; + bool metaPressed = false; + bool shitPressed = false; + // Generate an event that is: // // * For mouse, a left click @@ -2437,6 +2485,20 @@ abstract class _BasicEventContext implements PointerSupportDetector { // * For mouse, release LMB // * For touch, a touch up DomEvent primaryUp({double clientX, double clientY}); + + void pressAllModifiers() { + altPressed = true; + ctrlPressed = true; + metaPressed = true; + shitPressed = true; + } + + void unpressAllModifiers() { + altPressed = false; + ctrlPressed = false; + metaPressed = false; + shitPressed = false; + } } mixin _ButtonedEventMixin on _BasicEventContext { @@ -2622,6 +2684,10 @@ class _TouchEventContext extends _BasicEventContext ), ) .toList(), + 'altKey': altPressed, + 'ctrlKey': ctrlPressed, + 'metaKey': metaPressed, + 'shiftKey': shitPressed, }, ); } @@ -2757,6 +2823,10 @@ class _MouseEventContext extends _BasicEventContext 'button': button, 'clientX': clientX, 'clientY': clientY, + 'altKey': altPressed, + 'ctrlKey': ctrlPressed, + 'metaKey': metaPressed, + 'shiftKey': shitPressed, } ]; return js_util.callConstructor( @@ -2835,6 +2905,10 @@ class _PointerEventContext extends _BasicEventContext 'clientX': clientX, 'clientY': clientY, 'pointerType': pointerType, + 'altKey': altPressed, + 'ctrlKey': ctrlPressed, + 'metaKey': metaPressed, + 'shiftKey': shitPressed, }); }