diff --git a/shell/platform/windows/flutter_windows_view_unittests.cc b/shell/platform/windows/flutter_windows_view_unittests.cc index 259b82baef983..d0e975d303047 100644 --- a/shell/platform/windows/flutter_windows_view_unittests.cc +++ b/shell/platform/windows/flutter_windows_view_unittests.cc @@ -116,38 +116,6 @@ TEST(FlutterWindowsViewTest, KeySequence) { key_event_logs.clear(); } -TEST(FlutterWindowsViewTest, RestartClearsKeyboardState) { - std::unique_ptr engine = GetTestEngine(); - - auto window_binding_handler = - std::make_unique<::testing::NiceMock>(); - FlutterWindowsView view(std::move(window_binding_handler)); - view.SetEngine(std::move(engine)); - - test_response = false; - - // Receives a KeyA down. Events are dispatched and decided unhandled. Now the - // keyboard key handler is waiting for the redispatched event. - view.OnKey(kVirtualKeyA, kScanCodeKeyA, WM_KEYDOWN, 'a', false, false, - [](bool handled) {}); - EXPECT_EQ(key_event_logs.size(), 2); - EXPECT_EQ(key_event_logs[0], kKeyEventFromEmbedder); - EXPECT_EQ(key_event_logs[1], kKeyEventFromChannel); - key_event_logs.clear(); - - // Resets state so that the keyboard key handler is no longer waiting. - view.OnPreEngineRestart(); - - // Receives another KeyA down. If the state had not been cleared, this event - // will be considered the redispatched event and ignored. - view.OnKey(kVirtualKeyA, kScanCodeKeyA, WM_KEYDOWN, 'a', false, false, - [](bool handled) {}); - EXPECT_EQ(key_event_logs.size(), 2); - EXPECT_EQ(key_event_logs[0], kKeyEventFromEmbedder); - EXPECT_EQ(key_event_logs[1], kKeyEventFromChannel); - key_event_logs.clear(); -} - TEST(FlutterWindowsViewTest, EnableSemantics) { std::unique_ptr engine = GetTestEngine(); EngineModifier modifier(engine.get()); diff --git a/shell/platform/windows/keyboard_unittests.cc b/shell/platform/windows/keyboard_unittests.cc index 351b56be39f2a..62f7b21bb8d45 100644 --- a/shell/platform/windows/keyboard_unittests.cc +++ b/shell/platform/windows/keyboard_unittests.cc @@ -953,6 +953,66 @@ TEST_F(KeyboardTest, MetaRightUnhandled) { EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1); } +// Press and hold A. This should generate a repeat event. +TEST_F(KeyboardTest, RepeatA) { + KeyboardTester tester{GetContext()}; + tester.Responding(true); + + // Press A + tester.InjectKeyboardChanges(std::vector{ + WmKeyDownInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended, kWasUp}.Build( + kWmResultZero), + WmCharInfo{'a', kScanCodeKeyA, kNotExtended, kWasUp}.Build( + kWmResultZero)}); + + // Hold A + tester.InjectKeyboardChanges(std::vector{ + WmKeyDownInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended, kWasDown}.Build( + kWmResultZero), + WmCharInfo{'a', kScanCodeKeyA, kNotExtended, kWasDown}.Build( + kWmResultZero)}); + + EXPECT_EQ(key_calls.size(), 2); + EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalKeyA, + kLogicalKeyA, "a", kNotSynthesized); + EXPECT_CALL_IS_EVENT(key_calls[1], kFlutterKeyEventTypeRepeat, kPhysicalKeyA, + kLogicalKeyA, "a", kNotSynthesized); + EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0); +} + +// Press A, hot restart the engine, and hold A. +// This should reset the keyboard's state and generate +// two separate key down events. +TEST_F(KeyboardTest, RestartClearsKeyboardState) { + KeyboardTester tester{GetContext()}; + tester.Responding(true); + + // Press A + tester.InjectKeyboardChanges(std::vector{ + WmKeyDownInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended, kWasUp}.Build( + kWmResultZero), + WmCharInfo{'a', kScanCodeKeyA, kNotExtended, kWasUp}.Build( + kWmResultZero)}); + + // Send the "hot restart" signal. This should reset the keyboard's state. + tester.GetView().OnPreEngineRestart(); + + // Hold A. Notice the message declares the key is already down, however, the + // the keyboard does not send a repeat event as its state was reset. + tester.InjectKeyboardChanges(std::vector{ + WmKeyDownInfo{kVirtualKeyA, kScanCodeKeyA, kNotExtended, kWasDown}.Build( + kWmResultZero), + WmCharInfo{'a', kScanCodeKeyA, kNotExtended, kWasDown}.Build( + kWmResultZero)}); + + EXPECT_EQ(key_calls.size(), 2); + EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeDown, kPhysicalKeyA, + kLogicalKeyA, "a", kNotSynthesized); + EXPECT_CALL_IS_EVENT(key_calls[1], kFlutterKeyEventTypeDown, kPhysicalKeyA, + kLogicalKeyA, "a", kNotSynthesized); + EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0); +} + // Press Shift-A. This is special because Win32 gives 'A' as character for the // KeyA press. TEST_F(KeyboardTest, ShiftLeftKeyA) {