[Win32, Keyboard] Correctly process modifier events in IME mode (flutter/engine#30919)

This commit is contained in:
Tong Mu 2022-01-19 16:05:08 -08:00 committed by GitHub
parent 205398943b
commit 0fecfd79eb
2 changed files with 41 additions and 10 deletions

View File

@ -126,6 +126,10 @@ uint64_t KeyboardKeyEmbedderHandler::GetPhysicalKey(int scancode,
uint64_t KeyboardKeyEmbedderHandler::GetLogicalKey(int key,
bool extended,
int scancode) {
if (key == VK_PROCESSKEY) {
return VK_PROCESSKEY;
}
// Normally logical keys should only be derived from key codes, but since some
// key codes are either 0 or ambiguous (multiple keys using the same key
// code), these keys are resolved by scan codes.
@ -220,6 +224,15 @@ void KeyboardKeyEmbedderHandler::KeyboardHookImpl(
}
}
if (result_logical_key == VK_PROCESSKEY) {
// VK_PROCESSKEY means that the key press is used by an IME. These key
// presses are considered handled and not sent to Flutter. These events must
// be filtered by result_logical_key because the key up event of such
// presses uses the "original" logical key.
callback(true);
return;
}
UpdateLastSeenCritialKey(key, physical_key, result_logical_key);
// Synchronize the toggled states of critical keys (such as whether CapsLocks
// is enabled). Toggled states can only be changed upon a down event, so if
@ -248,15 +261,6 @@ void KeyboardKeyEmbedderHandler::KeyboardHookImpl(
pressingRecords_.erase(record_iter);
}
if (result_logical_key == VK_PROCESSKEY) {
// VK_PROCESSKEY means that the key press is used by an IME. These key
// presses are considered handled and not sent to Flutter. These events must
// be filtered by result_logical_key because the key up event of such
// presses uses the "original" logical key.
callback(true);
return;
}
FlutterKeyEvent key_data{
.struct_size = sizeof(FlutterKeyEvent),
.timestamp = static_cast<double>(

View File

@ -1545,7 +1545,7 @@ TEST(KeyboardTest, MultibyteCharacter) {
tester.Responding(false);
// Gothic Keyboard layout. (We need a layout that yields non-BMP characters
// without IME, which that is actually very rare.)
// without IME, which is actually very rare.)
// Press key W of a US keyboard, which should yield character '𐍅'.
tester.InjectMessages(
@ -1617,6 +1617,33 @@ TEST(KeyboardTest, NeverRedispatchShiftRightKeyDown) {
EXPECT_EQ(key_calls.size(), 0);
}
// Pressing modifiers during IME events should work properly by not sending any
// events.
//
// Regression test for https://github.com/flutter/flutter/issues/95888 .
TEST(KeyboardTest, ImeModifierEventsAreIgnored) {
KeyboardTester tester;
tester.Responding(false);
// US Keyboard layout.
// To make the keyboard into IME mode, there should have been events like
// letter key down with VK_PROCESSKEY. Omit them in this test since they don't
// seem significant.
// Press CtrlRight in IME mode.
tester.SetKeyState(VK_RCONTROL, true, false);
tester.InjectMessages(
1,
WmKeyDownInfo{VK_PROCESSKEY, kScanCodeControl, kExtended, kWasUp}.Build(
kWmResultZero));
EXPECT_EQ(key_calls.size(), 1);
EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, 0, 0, "",
kNotSynthesized);
clear_key_calls();
}
TEST(KeyboardTest, DisorderlyRespondedEvents) {
KeyboardTester tester;