From fea415faa02f408905934bbf4ef019f9ca7c9030 Mon Sep 17 00:00:00 2001 From: Bruno Leroux Date: Fri, 12 May 2023 23:46:17 +0200 Subject: [PATCH] [Web+Linux] Fix pressing Meta keys throws (flutter/engine#41694) ## Description This PR fixes Meta keys throwing exception on Chrome Linux. The assertions throws because the DOM event sent when Meta keys is pressed is not coherent when Meta is the only pressed key. ## Related Issue Fixes https://github.com/flutter/flutter/issues/125672 ## Tests Adds 1 test. --- .../web_ui/lib/src/engine/raw_keyboard.dart | 4 +++ .../web_ui/test/engine/raw_keyboard_test.dart | 30 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/engine/src/flutter/lib/web_ui/lib/src/engine/raw_keyboard.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/raw_keyboard.dart index b2e2edc7cf7..b299437b21f 100644 --- a/engine/src/flutter/lib/web_ui/lib/src/engine/raw_keyboard.dart +++ b/engine/src/flutter/lib/web_ui/lib/src/engine/raw_keyboard.dart @@ -6,6 +6,7 @@ import 'dart:async'; import 'dart:typed_data'; import '../engine.dart' show registerHotRestartListener; +import 'browser_detection.dart'; import 'dom.dart'; import 'keyboard_binding.dart'; import 'platform_dispatcher.dart'; @@ -133,6 +134,9 @@ class RawKeyboard { _lastMetaState |= modifierNumLock; } else if (event.key == 'ScrollLock') { _lastMetaState |= modifierScrollLock; + } else if (event.key == 'Meta' && operatingSystem == OperatingSystem.linux) { + // On Chrome Linux, metaState can be wrong when a Meta key is pressed. + _lastMetaState |= _modifierMeta; } } final Map eventData = { diff --git a/engine/src/flutter/lib/web_ui/test/engine/raw_keyboard_test.dart b/engine/src/flutter/lib/web_ui/test/engine/raw_keyboard_test.dart index 1cfae7fe706..d9f4cd0fe40 100644 --- a/engine/src/flutter/lib/web_ui/test/engine/raw_keyboard_test.dart +++ b/engine/src/flutter/lib/web_ui/test/engine/raw_keyboard_test.dart @@ -7,6 +7,7 @@ import 'dart:typed_data'; import 'package:quiver/testing/async.dart'; import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; +import 'package:ui/src/engine/browser_detection.dart'; import 'package:ui/src/engine/dom.dart'; import 'package:ui/src/engine/raw_keyboard.dart'; import 'package:ui/src/engine/services.dart'; @@ -151,6 +152,35 @@ void testMain() { RawKeyboard.instance!.dispose(); }); + // Regression test for https://github.com/flutter/flutter/issues/125672. + test('updates meta state for Meta key and wrong DOM event metaKey value', () { + RawKeyboard.initialize(); + + Map? dataReceived; + ui.window.onPlatformMessage = (String channel, ByteData? data, + ui.PlatformMessageResponseCallback? callback) { + dataReceived = const JSONMessageCodec().decodeMessage(data) as Map?; + }; + + // Purposely send an incoherent DOM event where Meta key is pressed but event.metaKey is not set to true. + final DomKeyboardEvent event = dispatchKeyboardEvent( + 'keydown', + key: 'Meta', + code: 'MetaLeft', + ); + expect(event.defaultPrevented, isFalse); + expect(dataReceived, { + 'type': 'keydown', + 'keymap': 'web', + 'code': 'MetaLeft', + 'key': 'Meta', + 'location': 0, + 'metaState': 0x8, + 'keyCode': 0, + }); + RawKeyboard.instance!.dispose(); + }, skip: operatingSystem != OperatingSystem.linux); + test('dispatches repeat events', () { RawKeyboard.initialize();