[Web] Update modifier state when Meta key is seen as Process key (#50779)
## Description
On Web, browsers can emit key events with a logical key sets to `Process` when the physical key is MetaLeft. Because the modifier state is 0 despite Meta key being pressed this will trigger an assert.
This PR adds some logic for this specific case. Maybe a more slightly broader solution will be needed (using the same logic for all modifiers ?). I focused on MetaLeft because it was directly reported on https://github.com/flutter/flutter/issues/141186.
## Related Issue
Fixes https://github.com/flutter/flutter/issues/141186.
## Tests
Adds 1 test.
diff --git a/lib/web_ui/lib/src/engine/raw_keyboard.dart b/lib/web_ui/lib/src/engine/raw_keyboard.dart
index d4aa87b..54ba7ae 100644
--- a/lib/web_ui/lib/src/engine/raw_keyboard.dart
+++ b/lib/web_ui/lib/src/engine/raw_keyboard.dart
@@ -123,6 +123,10 @@
} else if (event.key == 'Meta' && operatingSystem == OperatingSystem.linux) {
// On Chrome Linux, metaState can be wrong when a Meta key is pressed.
_lastMetaState |= _modifierMeta;
+ } else if (event.code == 'MetaLeft' && event.key == 'Process') {
+ // When Meta key is pressed, browsers can emit an event whose key is 'Process'.
+ // See https://github.com/flutter/flutter/issues/141186.
+ _lastMetaState |= _modifierMeta;
}
}
final Map<String, dynamic> eventData = <String, dynamic>{
diff --git a/lib/web_ui/test/engine/raw_keyboard_test.dart b/lib/web_ui/test/engine/raw_keyboard_test.dart
index 7c7ff00..cece887 100644
--- a/lib/web_ui/test/engine/raw_keyboard_test.dart
+++ b/lib/web_ui/test/engine/raw_keyboard_test.dart
@@ -153,7 +153,7 @@
});
// Regression test for https://github.com/flutter/flutter/issues/125672.
- test('updates meta state for Meta key and wrong DOM event metaKey value', () {
+ test('updates meta state for Meta key and wrong DOM event metaKey value (Linux)', () {
RawKeyboard.initialize();
Map<String, dynamic>? dataReceived;
@@ -181,6 +181,38 @@
RawKeyboard.instance!.dispose();
}, skip: operatingSystem != OperatingSystem.linux);
+ // Regression test for https://github.com/flutter/flutter/issues/141186.
+ test('updates meta state for Meta key seen as "Process" key', () {
+ RawKeyboard.initialize();
+
+ Map<String, dynamic>? dataReceived;
+ ui.PlatformDispatcher.instance.onPlatformMessage = (String channel, ByteData? data,
+ ui.PlatformMessageResponseCallback? callback) {
+ dataReceived = const JSONMessageCodec().decodeMessage(data) as Map<String, dynamic>?;
+ };
+
+ // Purposely send a DOM event where Meta key is pressed but event.metaKey is not set to true.
+ // This can happen when the Meta key is seen as the 'Process' key.
+ final DomKeyboardEvent event = dispatchKeyboardEvent(
+ 'keydown',
+ key: 'Process',
+ code: 'MetaLeft',
+ location: 1,
+ keyCode: 229,
+ );
+ expect(event.defaultPrevented, isFalse);
+ expect(dataReceived, <String, dynamic>{
+ 'type': 'keydown',
+ 'keymap': 'web',
+ 'code': 'MetaLeft',
+ 'key': 'Process',
+ 'location': 1,
+ 'metaState': 0x8,
+ 'keyCode': 229,
+ });
+ RawKeyboard.instance!.dispose();
+ });
+
test('dispatches repeat events', () {
RawKeyboard.initialize();