Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

[Web, keyboard] Locale layout mapping #34625

Merged
merged 91 commits into from
Nov 30, 2022
Merged
Show file tree
Hide file tree
Changes from 89 commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
8cf086a
WIP
dkwingsmt Jun 27, 2022
21c50f0
WIP: Better debug log
dkwingsmt Jun 28, 2022
0883f87
Merge remote-tracking branch 'origin/main' into web-layout-detection
dkwingsmt Jun 28, 2022
22d2ccf
Merge remote-tracking branch 'origin/main' into web-layout-detection
dkwingsmt Jul 1, 2022
3c05c3d
WIP
dkwingsmt Jul 1, 2022
becbf08
Merge branch 'web-layout-detection' of https://github.com/dkwingsmt/e…
dkwingsmt Jul 1, 2022
e82bc25
Merge remote-tracking branch 'origin/main' into web-layout-detection
dkwingsmt Jul 7, 2022
416f574
Finish logic (untested)
dkwingsmt Jul 7, 2022
5ed152d
Use third_party for layouts
dkwingsmt Jul 13, 2022
cb3b06d
Update gen
dkwingsmt Jul 13, 2022
e7a6473
Fix filtering bugs
dkwingsmt Jul 13, 2022
b88d06f
Format
dkwingsmt Jul 13, 2022
2175a4a
Merge remote-tracking branch 'origin/main' into web-layout-detection
dkwingsmt Oct 10, 2022
4f1083f
Merge remote-tracking branch 'dkwingsmt/web-layout-detection' into we…
dkwingsmt Oct 10, 2022
0a85ed9
Fix build
dkwingsmt Oct 11, 2022
4b0d8e4
Add scripts
dkwingsmt Oct 11, 2022
d4920f4
Try license
dkwingsmt Oct 11, 2022
249542c
Copyright
dkwingsmt Oct 11, 2022
3c4cac8
Rename license
dkwingsmt Oct 11, 2022
84703c7
Use case insensitive
dkwingsmt Oct 11, 2022
1a7b3d9
more lower case
dkwingsmt Oct 11, 2022
8798bbc
Sort. Migrate to better types.
dkwingsmt Oct 12, 2022
f05dc33
Fix template
dkwingsmt Oct 12, 2022
f5704c5
Marshall and unmarshall
dkwingsmt Oct 12, 2022
c1a964b
Comments
dkwingsmt Oct 13, 2022
35d42b1
Gen types file
dkwingsmt Oct 17, 2022
162e790
gen json
dkwingsmt Oct 17, 2022
0227c4c
engine compilable
dkwingsmt Oct 18, 2022
66eb8a8
Merge remote-tracking branch 'origin/main' into web-layout-detection
dkwingsmt Oct 24, 2022
9d8e1ce
benchmark_detector
dkwingsmt Oct 25, 2022
ca87473
Move github to separate file
dkwingsmt Oct 25, 2022
f1f5b80
Merge remote-tracking branch 'origin/main' into web-layout-detection
dkwingsmt Oct 27, 2022
f329b68
Merge remote-tracking branch 'origin/main' into web-layout-detection
dkwingsmt Oct 31, 2022
b894f71
Generate full mapping
dkwingsmt Oct 31, 2022
49198b0
Merge remote-tracking branch 'origin/main' into web-layout-detection
dkwingsmt Oct 31, 2022
0a40d4d
test cases
dkwingsmt Nov 1, 2022
ae05f6b
Unified dead key
dkwingsmt Nov 1, 2022
a6eb42d
Correct key
dkwingsmt Nov 1, 2022
1a80988
remove duplicate file
dkwingsmt Nov 1, 2022
7f985ee
letter in test cases
dkwingsmt Nov 1, 2022
013ea9a
Merge remote-tracking branch 'origin/main' into web-layout-detection
dkwingsmt Nov 8, 2022
9cec217
Compile
dkwingsmt Nov 9, 2022
0010a73
int keycode, and fix compile
dkwingsmt Nov 9, 2022
ca82c56
Correct gen directory
dkwingsmt Nov 10, 2022
d0a7c45
Heuristic
dkwingsmt Nov 10, 2022
5638316
Merge remote-tracking branch 'origin/main' into web-layout-detection
dkwingsmt Nov 14, 2022
3a68127
Heuristic benchmark
dkwingsmt Nov 14, 2022
4953e1f
Reorganize logical key
dkwingsmt Nov 14, 2022
d2636a3
Move to common
dkwingsmt Nov 15, 2022
4d78abf
Docs
dkwingsmt Nov 15, 2022
d089597
Combine into bin
dkwingsmt Nov 15, 2022
1343f01
Remove layout_types
dkwingsmt Nov 15, 2022
d0cd62c
Rename to locale_keymap
dkwingsmt Nov 15, 2022
d4fbac1
Rename class
dkwingsmt Nov 15, 2022
cf2df77
Rename to heuristicMapper
dkwingsmt Nov 15, 2022
af178f6
Format
dkwingsmt Nov 15, 2022
b2a63bf
Fix license
dkwingsmt Nov 15, 2022
0c51f44
Fix test
dkwingsmt Nov 15, 2022
7675615
Test license
dkwingsmt Nov 15, 2022
f594a0d
Fix tests
dkwingsmt Nov 15, 2022
c4d0aab
Fix import as
dkwingsmt Nov 16, 2022
5dc792a
Fix analyze problem
dkwingsmt Nov 16, 2022
0c5dffe
Fix license
dkwingsmt Nov 16, 2022
6450c92
Update license pattern
dkwingsmt Nov 16, 2022
0ab2d9c
The MIT license
dkwingsmt Nov 16, 2022
ec0a719
License diff
dkwingsmt Nov 16, 2022
f1334ce
Fix license
dkwingsmt Nov 17, 2022
c0ba71e
Update signature
dkwingsmt Nov 17, 2022
2809d26
readme
dkwingsmt Nov 17, 2022
8b36170
fix signature?
dkwingsmt Nov 17, 2022
3754b08
fix signature?
dkwingsmt Nov 17, 2022
f7de833
Fix license count
dkwingsmt Nov 17, 2022
7857246
Merge remote-tracking branch 'origin/main' into web-layout-detection
dkwingsmt Nov 17, 2022
3b938c3
Merge remote-tracking branch 'origin/main' into web-layout-detection
dkwingsmt Nov 18, 2022
1582aa2
Merge remote-tracking branch 'origin/main' into web-layout-detection
dkwingsmt Nov 27, 2022
b1bce40
Merge remote-tracking branch 'origin/main' into web-layout-detection
dkwingsmt Nov 27, 2022
edfdd0f
Fix build
dkwingsmt Nov 28, 2022
13e6fb4
Compression
dkwingsmt Nov 28, 2022
f970ce1
Fix _eventKeyIsKeyname
dkwingsmt Nov 28, 2022
de98688
remove gitignore
dkwingsmt Nov 28, 2022
fdd3225
Fix nullable
dkwingsmt Nov 28, 2022
0e32e71
Fix doc
dkwingsmt Nov 28, 2022
0d570e2
Merge remote-tracking branch 'origin/main' into web-layout-detection
dkwingsmt Nov 28, 2022
a507c33
Add underscore lead. Make everything lower case. Print by line.
dkwingsmt Nov 28, 2022
3cfaf33
Better event code encoding
dkwingsmt Nov 28, 2022
c33c9f2
Signature
dkwingsmt Nov 28, 2022
cedb9bf
Comment. Change dead key mapping to the last.
dkwingsmt Nov 28, 2022
fe356c0
Better digit heuristic. Better _eventKeyIsKeyName
dkwingsmt Nov 29, 2022
884e783
en-in test
dkwingsmt Nov 29, 2022
3c48e3d
Remove unnecessary build change
dkwingsmt Nov 29, 2022
e27af08
Better order
dkwingsmt Nov 29, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ci/analyze.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ echo ""

"$DART" analyze --fatal-infos --fatal-warnings "$FLUTTER_DIR/flutter_frontend_server"

(cd "$FLUTTER_DIR/tools/gen_web_locale_keymap"; "$DART" pub get)
"$DART" analyze --fatal-infos --fatal-warnings "$FLUTTER_DIR/tools"

(cd "$FLUTTER_DIR/testing/skia_gold_client"; "$DART" pub get)
Expand Down
2 changes: 1 addition & 1 deletion ci/licenses.sh
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ function verify_licenses() (

local actualLicenseCount
actualLicenseCount="$(tail -n 1 flutter/ci/licenses_golden/licenses_flutter | tr -dc '0-9')"
local expectedLicenseCount=17 # When changing this number: Update the error message below as well describing all expected license types.
local expectedLicenseCount=19 # When changing this number: Update the error message below as well describing all expected license types.

if [[ $actualLicenseCount -ne $expectedLicenseCount ]]; then
echo "=============================== ERROR ==============================="
Expand Down
58 changes: 56 additions & 2 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
@@ -1,6 +1,31 @@
UNUSED LICENSES:


====================================================================================================
ORIGIN: ../../../flutter/third_party/web_locale_keymap/License.txt
TYPE: LicenseType.mit
----------------------------------------------------------------------------------------------------
MIT License

Copyright (c) 2015 - present Microsoft Corporation

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
====================================================================================================
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
USED LICENSES:

Expand Down Expand Up @@ -565,6 +590,35 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
====================================================================================================

====================================================================================================
LIBRARY: web_locale_keymap
ORIGIN: ../../../flutter/third_party/web_locale_keymap/lib/web_locale_keymap/key_mappings.g.dart + ../../../flutter/third_party/web_locale_keymap/License.txt
TYPE: LicenseType.mit
FILE: ../../../flutter/third_party/web_locale_keymap/lib/web_locale_keymap.dart
FILE: ../../../flutter/third_party/web_locale_keymap/lib/web_locale_keymap/key_mappings.g.dart
FILE: ../../../flutter/third_party/web_locale_keymap/lib/web_locale_keymap/locale_keymap.dart
----------------------------------------------------------------------------------------------------
Copyright (c) 2022 Google LLC

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
====================================================================================================

====================================================================================================
LIBRARY: accessibility
ORIGIN: ../../../flutter/third_party/accessibility/ax/ax_export.h + ../../../LICENSE
Expand Down Expand Up @@ -3763,4 +3817,4 @@ shall not be used in advertising or otherwise to promote the sale,
use or other dealings in these Data Files or Software without prior
written authorization of the copyright holder.
====================================================================================================
Total license count: 17
Total license count: 19
2 changes: 1 addition & 1 deletion ci/licenses_golden/tool_signature
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Signature: 027af91b165acaa447651bfca8c7c704
Signature: f6d8146c82d268e2e2549bf5019ebf07

148 changes: 86 additions & 62 deletions lib/web_ui/lib/src/engine/keyboard_binding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'package:meta/meta.dart';
import 'package:ui/ui.dart' as ui;
import 'package:web_locale_keymap/web_locale_keymap.dart' as locale_keymap;

import '../engine.dart' show registerHotRestartListener;
import 'browser_detection.dart';
Expand Down Expand Up @@ -54,16 +55,6 @@ final Map<int, _ModifierGetter> _kLogicalKeyToModifierGetter = <int, _ModifierGe
_kLogicalMetaRight: (FlutterHtmlKeyboardEvent event) => event.metaKey,
};

// ASCII for a, z, A, and Z
const int _kCharLowerA = 0x61;
const int _kCharLowerZ = 0x7a;
const int _kCharUpperA = 0x41;
const int _kCharUpperZ = 0x5a;
bool isAlphabet(int charCode) {
return (charCode >= _kCharLowerA && charCode <= _kCharLowerZ)
|| (charCode >= _kCharUpperA && charCode <= _kCharUpperZ);
}

const String _kPhysicalCapsLock = 'CapsLock';

const String _kLogicalDead = 'Dead';
Expand Down Expand Up @@ -98,9 +89,24 @@ Duration _eventTimeStampToDuration(num milliseconds) {
return Duration(milliseconds: ms, microseconds: micro);
}

// Returns a function that caches the result of `body`, ensuring that `body` is
// only run once.
ValueGetter<T> _cached<T>(ValueGetter<T> body) {
T? cache;
return () {
return cache ??= body();
};
}

class KeyboardBinding {
KeyboardBinding._() {
_setup();
_addEventListener('keydown', allowInterop((DomEvent domEvent) {
final FlutterHtmlKeyboardEvent event = FlutterHtmlKeyboardEvent(domEvent as DomKeyboardEvent);
return _converter.handleEvent(event);
}));
_addEventListener('keyup', allowInterop((DomEvent event) {
return _converter.handleEvent(FlutterHtmlKeyboardEvent(event as DomKeyboardEvent));
}));
}

/// The singleton instance of this object.
Expand All @@ -117,8 +123,23 @@ class KeyboardBinding {
}
}

static void debugClearInstance() {
_instance = null;
}

/// The platform as used in the initialization.
///
/// By default it is derived from [operatingSystem].
@protected
OperatingSystem get localPlatform {
return operatingSystem;
}

KeyboardConverter get converter => _converter;
late final KeyboardConverter _converter;
late final KeyboardConverter _converter = KeyboardConverter(
_onKeyData,
localPlatform,
);
final Map<String, DomEventListener> _listeners = <String, DomEventListener>{};

void _addEventListener(String eventName, DomEventListener handler) {
Expand Down Expand Up @@ -154,16 +175,6 @@ class KeyboardBinding {
return result!;
}

void _setup() {
_addEventListener('keydown', allowInterop((DomEvent event) {
return _converter.handleEvent(FlutterHtmlKeyboardEvent(event as DomKeyboardEvent));
}));
_addEventListener('keyup', allowInterop((DomEvent event) {
return _converter.handleEvent(FlutterHtmlKeyboardEvent(event as DomKeyboardEvent));
}));
_converter = KeyboardConverter(_onKeyData, onMacOs: operatingSystem == OperatingSystem.macOs);
}

void _reset() {
_clearListeners();
_converter.dispose();
Expand Down Expand Up @@ -211,10 +222,30 @@ class FlutterHtmlKeyboardEvent {
// [dispatchKeyData] as given in the constructor. Some key data might be
// dispatched asynchronously.
class KeyboardConverter {
KeyboardConverter(this.performDispatchKeyData, {this.onMacOs = false});
KeyboardConverter(this.performDispatchKeyData, OperatingSystem platform)
: onMacOs = platform == OperatingSystem.macOs,
_mapping = _mappingFromPlatform(platform);

final DispatchKeyData performDispatchKeyData;
// Whether the current platform is macOS, which affects how certain key events
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it the case that onMacOS is only used to differentiate things for macOS, or are these keyboard quirks also present on iOS?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice find. I've tested it on my iPad and I confirm that they also present on iOS. I'm changing it to onDarwin.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me make it a separate PR after this PR.

// are comprehended.
final bool onMacOs;
// Maps logical keys from key event properties.
final locale_keymap.LocaleKeymap _mapping;

static locale_keymap.LocaleKeymap _mappingFromPlatform(OperatingSystem platform) {
switch (platform) {
case OperatingSystem.iOs:
case OperatingSystem.macOs:
return locale_keymap.LocaleKeymap.darwin();
case OperatingSystem.windows:
return locale_keymap.LocaleKeymap.win();
case OperatingSystem.android:
case OperatingSystem.linux:
case OperatingSystem.unknown:
return locale_keymap.LocaleKeymap.linux();
}
}

// The `performDispatchKeyData` wrapped with tracking logic.
//
Expand Down Expand Up @@ -273,29 +304,14 @@ class KeyboardConverter {
(metaDown ? _kDeadKeyMeta : 0);
}

// Whether `event.key` should be considered a key name.
// Whether `event.key` is a key name, such as "Shift", or otherwise a
// character, such as "S" or "ж".
//
// The `event.key` can either be a key name or the printable character. If the
// first character is an alphabet, it must be either 'A' to 'Z' ( and return
// true), or be a key name (and return false). Otherwise, return true.
static bool _eventKeyIsKeyname(String key) {
assert(key.isNotEmpty);
return isAlphabet(key.codeUnitAt(0)) && key.length > 1;
}

static int _characterToLogicalKey(String key) {
// Assume the length being <= 2 to be sufficient in all cases. If not,
// extend the algorithm.
assert(key.length <= 2);
int result = key.codeUnitAt(0) & 0xffff;
if (key.length == 2) {
result += key.codeUnitAt(1) << 16;
}
// Convert upper letters to lower letters
if (result >= _kCharUpperA && result <= _kCharUpperZ) {
result = result + _kCharLowerA - _kCharUpperA;
}
return result;
// A key name always has more than 1 code unit, and they are all alnums.
// Character keys, however, can also have more than 1 code unit: en-in
// maps KeyL to L̥/l̥. To resolve this, we check the second code unit.
static bool _eventKeyIsKeyName(String key) {
return key.length > 1 && key.codeUnitAt(0) < 0x7F && key.codeUnitAt(1) < 0x7F;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't you just say key.length > 2? Are there any names that are only two characters?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, such as Fn and F1. And I'm not sure if there are characters of 3 or more code units.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, OK. LGTM then.

}

static int _deadKeyToLogicalKey(int physicalKey, FlutterHtmlKeyboardEvent event) {
Expand All @@ -307,10 +323,6 @@ class KeyboardConverter {
return physicalKey + _getModifierMask(event) + _kWebKeyIdPlane;
}

static int _otherLogicalKey(String key) {
return kWebToLogicalKey[key] ?? (key.hashCode + _kWebKeyIdPlane);
}

// Map from pressed physical key to corresponding pressed logical key.
//
// Multiple physical keys can be mapped to the same logical key, usually due
Expand Down Expand Up @@ -369,22 +381,33 @@ class KeyboardConverter {
final String eventKey = event.key!;

final int physicalKey = _getPhysicalCode(event.code!);
final bool logicalKeyIsCharacter = !_eventKeyIsKeyname(eventKey);
final String? character = logicalKeyIsCharacter ? eventKey : null;
final int logicalKey = () {
final bool logicalKeyIsCharacter = !_eventKeyIsKeyName(eventKey);
final ValueGetter<int> logicalKey = _cached<int>(() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for using _cached here instead of late final:

late final int logicalKey = () {
  // ...
}();

Copy link
Contributor Author

@dkwingsmt dkwingsmt Nov 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function might not be evaluated: if the event is a key up event, the logical key is simply the pressed logical key, and this is not needed at all. In this case, I'm hoping not to run the function body, since it's not a trivial amount of work. And as far as I understand, late still always evaluate the value. (I can add a comment to it.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the docs, the late keyword makes the field lazy, which means the right-hand-side won't run until you access the field. At least that's my understanding.

https://dart.dev/null-safety/understanding-null-safety#lazy-initialization

// Mapped logical keys, such as ArrowLeft, Escape, AudioVolumeDown.
final int? mappedLogicalKey = kWebToLogicalKey[eventKey];
if (mappedLogicalKey != null) {
return mappedLogicalKey;
}
// Keys with locations, such as modifier keys (Shift) or numpad keys.
if (kWebLogicalLocationMap.containsKey(event.key)) {
final int? result = kWebLogicalLocationMap[event.key!]?[event.location!];
assert(result != null, 'Invalid modifier location: ${event.key}, ${event.location}');
return result!;
}
if (character != null) {
return _characterToLogicalKey(character);
// Locale-sensitive keys: letters, digits, and certain symbols.
if (logicalKeyIsCharacter) {
final int? localeLogicalKeys = _mapping.getLogicalKey(event.code, event.key, event.keyCode);
if (localeLogicalKeys != null) {
return localeLogicalKeys;
}
}
// Dead keys that are not handled by the locale mapping.
if (eventKey == _kLogicalDead) {
return _deadKeyToLogicalKey(physicalKey, event);
}
return _otherLogicalKey(eventKey);
}();
// Minted logical keys.
return eventKey.hashCode + _kWebKeyIdPlane;
});

assert(event.type == 'keydown' || event.type == 'keyup');
final bool isPhysicalDown = event.type == 'keydown' ||
Expand All @@ -406,7 +429,7 @@ class KeyboardConverter {
timeStamp: timeStamp,
type: ui.KeyEventType.up,
physical: physicalKey,
logical: logicalKey,
logical: logicalKey(),
character: null,
synthesized: true,
),
Expand Down Expand Up @@ -441,7 +464,7 @@ class KeyboardConverter {
timeStamp: timeStamp,
type: ui.KeyEventType.up,
physical: physicalKey,
logical: logicalKey,
logical: logicalKey(),
character: null,
synthesized: true,
));
Expand Down Expand Up @@ -474,7 +497,7 @@ class KeyboardConverter {
switch (type) {
case ui.KeyEventType.down:
assert(lastLogicalRecord == null);
nextLogicalRecord = logicalKey;
nextLogicalRecord = logicalKey();
break;
case ui.KeyEventType.up:
assert(lastLogicalRecord != null);
Expand All @@ -499,7 +522,7 @@ class KeyboardConverter {
_kLogicalKeyToModifierGetter.forEach((int testeeLogicalKey, _ModifierGetter getModifier) {
// Do not synthesize for the key of the current event. The event is the
// ground truth.
if (logicalKey == testeeLogicalKey) {
if (logicalKey() == testeeLogicalKey) {
return;
}
if (_pressingRecords.containsValue(testeeLogicalKey) && !getModifier(event)) {
Expand All @@ -525,17 +548,18 @@ class KeyboardConverter {
// Update key guards
if (logicalKeyIsCharacter) {
if (nextLogicalRecord != null) {
_startGuardingKey(physicalKey, logicalKey, timeStamp);
_startGuardingKey(physicalKey, logicalKey(), timeStamp);
} else {
_stopGuardingKey(physicalKey);
}
}

final String? character = logicalKeyIsCharacter ? eventKey : null;
final ui.KeyData keyData = ui.KeyData(
timeStamp: timeStamp,
type: type,
physical: physicalKey,
logical: lastLogicalRecord ?? logicalKey,
logical: lastLogicalRecord ?? logicalKey(),
character: type == ui.KeyEventType.up ? null : character,
synthesized: false,
);
Expand Down
2 changes: 2 additions & 0 deletions lib/web_ui/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ environment:
dependencies:
js: 0.6.4
meta: ^1.7.0
web_locale_keymap:
path: ../../third_party/web_locale_keymap

web_unicode:
path: ../../third_party/web_unicode
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/test/engine/pointer_binding_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void testMain() {
return KeyboardConverter((ui.KeyData key) {
keyDataList.add(key);
return true;
});
}, OperatingSystem.linux);
}

test('ios workaround', () {
Expand Down
Loading