From adcab21c92d161bf20291997f903119f0fdbae4a Mon Sep 17 00:00:00 2001 From: Matej Knopp Date: Wed, 30 Jun 2021 09:48:00 +0200 Subject: [PATCH 1/4] Do not expect WM_CHAR if control or windows key is pressed --- shell/platform/windows/window_win32.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shell/platform/windows/window_win32.cc b/shell/platform/windows/window_win32.cc index 7b1e007afc95c..9e69316f48cfd 100644 --- a/shell/platform/windows/window_win32.cc +++ b/shell/platform/windows/window_win32.cc @@ -371,8 +371,11 @@ WindowWin32::HandleMessage(UINT const message, // Check if this key produces a character. If so, the key press should // be sent with the character produced at WM_CHAR. Store the produced // keycode (it's not accessible from WM_CHAR) to be used in WM_CHAR. + // As an exception with control or windows key pressed WM_CHAR may not + // come even though the event produced a character (i.e. CTRL + number). const unsigned int character = MapVirtualKey(wparam, MAPVK_VK_TO_CHAR); - if (character > 0 && is_keydown_message) { + if (character > 0 && is_keydown_message && GetKeyState(VK_CONTROL) == 0 && + GetKeyState(VK_LWIN) == 0 && GetKeyState(VK_RWIN) == 0) { keycode_for_char_message_ = wparam; break; } From ce062cfbae25dc37546482178a16c970e9dc07b3 Mon Sep 17 00:00:00 2001 From: Matej Knopp Date: Tue, 6 Jul 2021 20:06:06 +0200 Subject: [PATCH 2/4] Address PR feedback --- shell/platform/windows/window_win32.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/shell/platform/windows/window_win32.cc b/shell/platform/windows/window_win32.cc index 9e69316f48cfd..c4ac57755dcd5 100644 --- a/shell/platform/windows/window_win32.cc +++ b/shell/platform/windows/window_win32.cc @@ -371,14 +371,18 @@ WindowWin32::HandleMessage(UINT const message, // Check if this key produces a character. If so, the key press should // be sent with the character produced at WM_CHAR. Store the produced // keycode (it's not accessible from WM_CHAR) to be used in WM_CHAR. - // As an exception with control or windows key pressed WM_CHAR may not - // come even though the event produced a character (i.e. CTRL + number). - const unsigned int character = MapVirtualKey(wparam, MAPVK_VK_TO_CHAR); + // + // Messages with Control or Win modifiers down are never considered as character + // messages. This allows key combinations such as "CTRL + Digit" to properly + // produce key down events even though `MapVirtualKey` returns a valid character. + // See https://github.com/flutter/flutter/issues/85587. + unsigned int character = MapVirtualKey(wparam, MAPVK_VK_TO_CHAR); if (character > 0 && is_keydown_message && GetKeyState(VK_CONTROL) == 0 && GetKeyState(VK_LWIN) == 0 && GetKeyState(VK_RWIN) == 0) { keycode_for_char_message_ = wparam; break; } + character = 0; unsigned int keyCode(wparam); const unsigned int scancode = (lparam >> 16) & 0xff; const bool extended = ((lparam >> 24) & 0x01) == 0x01; From 167dbb30edf8460910d9185efc3fc2915f5d0573 Mon Sep 17 00:00:00 2001 From: Matej Knopp Date: Tue, 6 Jul 2021 20:06:22 +0200 Subject: [PATCH 3/4] Add unittest --- .../windows/window_win32_unittests.cc | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/shell/platform/windows/window_win32_unittests.cc b/shell/platform/windows/window_win32_unittests.cc index 9680a0488bc67..846c1217796d4 100644 --- a/shell/platform/windows/window_win32_unittests.cc +++ b/shell/platform/windows/window_win32_unittests.cc @@ -84,5 +84,27 @@ TEST(MockWin32Window, KeyDownPrintable) { window.InjectWindowMessage(WM_CHAR, 65, lparam); } +TEST(MockWin32Window, KeyDownWithCtrl) { + MockWin32Window window; + + // Simulate CONTROL pressed + BYTE keyboard_state[256]; + memset(keyboard_state, 0, 256); + keyboard_state[VK_CONTROL] = -1; + SetKeyboardState(keyboard_state); + + LPARAM lparam = CreateKeyEventLparam(30); + + // Expect OnKey, but not OnText, because Control + Key is not followed by + // WM_CHAR + EXPECT_CALL(window, OnKey(65, 30, WM_KEYDOWN, 0, false, true)).Times(1); + EXPECT_CALL(window, OnText(_)).Times(0); + + window.InjectWindowMessage(WM_KEYDOWN, 65, lparam); + + memset(keyboard_state, 0, 256); + SetKeyboardState(keyboard_state); +} + } // namespace testing } // namespace flutter From 5bc088ff40f4a612726a2de38a61a3a6dd80b632 Mon Sep 17 00:00:00 2001 From: Matej Knopp Date: Tue, 6 Jul 2021 23:00:02 +0200 Subject: [PATCH 4/4] Reformat --- shell/platform/windows/window_win32.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shell/platform/windows/window_win32.cc b/shell/platform/windows/window_win32.cc index c4ac57755dcd5..4449915cde98d 100644 --- a/shell/platform/windows/window_win32.cc +++ b/shell/platform/windows/window_win32.cc @@ -372,10 +372,10 @@ WindowWin32::HandleMessage(UINT const message, // be sent with the character produced at WM_CHAR. Store the produced // keycode (it's not accessible from WM_CHAR) to be used in WM_CHAR. // - // Messages with Control or Win modifiers down are never considered as character - // messages. This allows key combinations such as "CTRL + Digit" to properly - // produce key down events even though `MapVirtualKey` returns a valid character. - // See https://github.com/flutter/flutter/issues/85587. + // Messages with Control or Win modifiers down are never considered as + // character messages. This allows key combinations such as "CTRL + Digit" + // to properly produce key down events even though `MapVirtualKey` returns + // a valid character. See https://github.com/flutter/flutter/issues/85587. unsigned int character = MapVirtualKey(wparam, MAPVK_VK_TO_CHAR); if (character > 0 && is_keydown_message && GetKeyState(VK_CONTROL) == 0 && GetKeyState(VK_LWIN) == 0 && GetKeyState(VK_RWIN) == 0) {