diff --git a/shell/platform/windows/window_win32.cc b/shell/platform/windows/window_win32.cc index 7b1e007afc95c..4449915cde98d 100644 --- a/shell/platform/windows/window_win32.cc +++ b/shell/platform/windows/window_win32.cc @@ -371,11 +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. - const unsigned int character = MapVirtualKey(wparam, MAPVK_VK_TO_CHAR); - if (character > 0 && is_keydown_message) { + // + // 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; 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