5 #include "flutter/fml/logging.h"
7 #include "flutter/shell/platform/embedder/embedder.h"
8 #include "flutter/shell/platform/embedder/test_utils/key_codes.g.h"
15 #include "flutter/shell/platform/windows/testing/engine_modifier.h"
16 #include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
17 #include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
18 #include "flutter/shell/platform/windows/testing/test_keyboard.h"
19 #include "flutter/shell/platform/windows/testing/windows_test.h"
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
23 #include "rapidjson/stringbuffer.h"
24 #include "rapidjson/writer.h"
31 using testing::Invoke;
32 using testing::Return;
33 using namespace ::flutter::testing::keycodes;
40 constexpr SHORT kStateMaskToggled = 0x01;
41 constexpr SHORT kStateMaskPressed = 0x80;
43 constexpr uint64_t kScanCodeBackquote = 0x29;
45 constexpr uint64_t kScanCodeKeyB = 0x30;
46 constexpr uint64_t kScanCodeKeyE = 0x12;
47 constexpr uint64_t kScanCodeKeyF = 0x21;
48 constexpr uint64_t kScanCodeKeyO = 0x18;
49 constexpr uint64_t kScanCodeKeyQ = 0x10;
50 constexpr uint64_t kScanCodeKeyW = 0x11;
51 constexpr uint64_t kScanCodeDigit1 = 0x02;
52 constexpr uint64_t kScanCodeDigit2 = 0x03;
53 constexpr uint64_t kScanCodeDigit6 = 0x07;
56 constexpr uint64_t kScanCodeControl = 0x1d;
57 constexpr uint64_t kScanCodeMetaLeft = 0x5b;
58 constexpr uint64_t kScanCodeMetaRight = 0x5c;
59 constexpr uint64_t kScanCodeAlt = 0x38;
62 constexpr uint64_t kScanCodeBracketLeft = 0x1a;
63 constexpr uint64_t kScanCodeArrowLeft = 0x4b;
64 constexpr uint64_t kScanCodeEnter = 0x1c;
65 constexpr uint64_t kScanCodeBackspace = 0x0e;
67 constexpr uint64_t kVirtualDigit1 = 0x31;
69 constexpr uint64_t kVirtualKeyB = 0x42;
70 constexpr uint64_t kVirtualKeyE = 0x45;
71 constexpr uint64_t kVirtualKeyF = 0x46;
72 constexpr uint64_t kVirtualKeyO = 0x4f;
73 constexpr uint64_t kVirtualKeyQ = 0x51;
74 constexpr uint64_t kVirtualKeyW = 0x57;
76 constexpr
bool kSynthesized =
true;
77 constexpr
bool kNotSynthesized =
false;
79 typedef UINT (*MapVirtualKeyLayout)(UINT uCode, UINT uMapType);
80 typedef std::function<UINT(UINT)> MapVirtualKeyToChar;
82 UINT LayoutDefault(UINT uCode, UINT uMapType) {
83 return MapVirtualKey(uCode, uMapType);
86 UINT LayoutFrench(UINT uCode, UINT uMapType) {
88 case MAPVK_VK_TO_CHAR:
93 return MapVirtualKey(uCode, MAPVK_VK_TO_CHAR);
96 return MapVirtualKey(uCode, uMapType);
100 class TestKeyboardManager :
public KeyboardManager {
102 explicit TestKeyboardManager(WindowDelegate* delegate)
103 : KeyboardManager(delegate) {}
105 bool DuringRedispatch() {
return during_redispatch_; }
108 void RedispatchEvent(std::unique_ptr<PendingEvent> event)
override {
109 FML_DCHECK(!during_redispatch_)
110 <<
"RedispatchEvent called while already redispatching an event";
111 during_redispatch_ =
true;
113 during_redispatch_ =
false;
117 bool during_redispatch_ =
false;
119 FML_DISALLOW_COPY_AND_ASSIGN(TestKeyboardManager);
124 struct KeyStateChange {
136 struct ExpectForgedMessage {
142 struct KeyboardChange {
145 KeyboardChange(Win32Message
message) :
type(kMessage) {
149 KeyboardChange(KeyStateChange change) :
type(kKeyStateChange) {
150 content.key_state_change = change;
153 KeyboardChange(ExpectForgedMessage forged_message)
154 :
type(kExpectForgedMessage) {
155 content.expected_forged_message = forged_message.message;
161 kExpectForgedMessage,
174 state_[virtual_key] = (
pressed ? kStateMaskPressed : 0) |
178 SHORT Get(uint32_t virtual_key) {
return state_[virtual_key]; }
181 std::map<uint32_t, SHORT> state_;
184 class MockKeyboardManagerDelegate :
public KeyboardManager::WindowDelegate,
185 protected MockMessageQueue {
187 MockKeyboardManagerDelegate(WindowBindingHandlerDelegate* view,
188 MapVirtualKeyToChar map_vk_to_char)
189 : view_(view), map_vk_to_char_(std::move(map_vk_to_char)) {
190 keyboard_manager_ = std::make_unique<TestKeyboardManager>(
this);
192 virtual ~MockKeyboardManagerDelegate() {}
201 KeyEventCallback
callback)
override {
207 void OnText(
const std::u16string&
text)
override { view_->OnText(
text); }
209 SHORT GetKeyState(
int virtual_key) {
return key_state_.Get(virtual_key); }
211 void InjectKeyboardChanges(std::vector<KeyboardChange> changes) {
213 for (
const KeyboardChange& change : changes) {
214 switch (change.type) {
215 case KeyboardChange::kMessage:
216 PushBack(&change.content.message);
222 for (
const KeyboardChange& change : changes) {
223 switch (change.type) {
224 case KeyboardChange::kMessage:
227 case KeyboardChange::kExpectForgedMessage:
228 forged_message_expectations_.push_back(ForgedMessageExpectation{
229 .message = change.content.expected_forged_message,
232 case KeyboardChange::kKeyStateChange: {
233 const KeyStateChange& state_change = change.content.key_state_change;
234 if (forged_message_expectations_.empty()) {
235 key_state_.Set(state_change.key, state_change.pressed,
236 state_change.toggled_on);
238 forged_message_expectations_.back()
239 .state_changes_afterwards.push_back(state_change);
244 FML_LOG(FATAL) <<
"Unhandled KeyboardChange type " << change.type;
249 std::list<Win32Message>& RedispatchedMessages() {
250 return redispatched_messages_;
254 BOOL Win32PeekMessage(LPMSG lpMsg,
257 UINT wRemoveMsg)
override {
258 return MockMessageQueue::Win32PeekMessage(lpMsg, wMsgFilterMin,
259 wMsgFilterMax, wRemoveMsg);
262 uint32_t Win32MapVkToChar(uint32_t virtual_key)
override {
263 return map_vk_to_char_(virtual_key);
268 LRESULT Win32SendMessage(UINT
const message,
270 LPARAM
const lparam)
override {
271 return keyboard_manager_->HandleMessage(
message, wparam, lparam)
278 UINT Win32DispatchMessage(UINT Msg, WPARAM wParam, LPARAM lParam)
override {
279 bool handled = keyboard_manager_->HandleMessage(Msg, wParam, lParam);
280 if (keyboard_manager_->DuringRedispatch()) {
281 redispatched_messages_.push_back(Win32Message{
286 EXPECT_FALSE(handled);
288 EXPECT_FALSE(forged_message_expectations_.empty());
289 ForgedMessageExpectation expectation =
290 forged_message_expectations_.front();
291 forged_message_expectations_.pop_front();
292 EXPECT_EQ(expectation.message.message, Msg);
293 EXPECT_EQ(expectation.message.wParam, wParam);
294 EXPECT_EQ(expectation.message.lParam, lParam);
295 if (expectation.message.expected_result != kWmResultDontCheck) {
296 EXPECT_EQ(expectation.message.expected_result,
297 handled ? kWmResultZero : kWmResultDefault);
299 for (
const KeyStateChange& change :
300 expectation.state_changes_afterwards) {
301 key_state_.Set(change.key, change.pressed, change.toggled_on);
308 struct ForgedMessageExpectation {
313 WindowBindingHandlerDelegate* view_;
314 std::unique_ptr<TestKeyboardManager> keyboard_manager_;
315 std::list<ForgedMessageExpectation> forged_message_expectations_;
316 MapVirtualKeyToChar map_vk_to_char_;
317 TestKeystate key_state_;
318 std::list<Win32Message> redispatched_messages_;
320 FML_DISALLOW_COPY_AND_ASSIGN(MockKeyboardManagerDelegate);
327 kKeyCallTextMethodCall,
336 static std::vector<KeyCall> key_calls;
338 void clear_key_calls() {
339 for (KeyCall& key_call : key_calls) {
340 if (key_call.type == KeyCall::kKeyCallOnKey &&
341 key_call.key_event.character !=
nullptr) {
342 delete[] key_call.key_event.character;
349 class TestFlutterWindowsView :
public FlutterWindowsView {
351 TestFlutterWindowsView(std::unique_ptr<WindowBindingHandler> window)
352 : FlutterWindowsView(std::move(window)) {}
354 void OnText(
const std::u16string&
text)
override {
355 key_calls.push_back(KeyCall{
356 .type = KeyCall::kKeyCallOnText,
362 FML_DISALLOW_COPY_AND_ASSIGN(TestFlutterWindowsView);
365 class KeyboardTester {
367 using ResponseHandler =
368 std::function<void(MockKeyResponseController::ResponseCallback)>;
370 explicit KeyboardTester(WindowsTestContext& context)
371 : callback_handler_(RespondValue(false)),
372 map_virtual_key_layout_(LayoutDefault) {
373 std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine(context);
375 engine_ = engine.get();
376 view_ = std::make_unique<TestFlutterWindowsView>(
379 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>());
380 view_->SetEngine(std::move(engine));
381 window_ = std::make_unique<MockKeyboardManagerDelegate>(
382 view_.get(), [
this](UINT virtual_key) -> SHORT {
383 return map_virtual_key_layout_(virtual_key, MAPVK_VK_TO_CHAR);
387 TestFlutterWindowsView& GetView() {
return *view_; }
388 MockKeyboardManagerDelegate& GetWindow() {
return *window_; }
391 void ResetKeyboard() { EngineModifier{engine_}.Restart(); }
394 void Responding(
bool response) { callback_handler_ = RespondValue(response); }
403 MockKeyResponseController::EmbedderCallbackHandler handler) {
404 callback_handler_ = std::move(handler);
407 void SetLayout(MapVirtualKeyLayout layout) {
408 map_virtual_key_layout_ = layout ==
nullptr ? LayoutDefault : layout;
411 void InjectKeyboardChanges(std::vector<KeyboardChange> changes) {
412 FML_DCHECK(window_ !=
nullptr);
413 window_->InjectKeyboardChanges(changes);
417 void InjectPlatformMessage(
const char* channel,
420 rapidjson::Document args_doc;
421 args_doc.Parse(args);
422 FML_DCHECK(!args_doc.HasParseError());
424 rapidjson::Document message_doc(rapidjson::kObjectType);
425 auto& allocator = message_doc.GetAllocator();
426 message_doc.AddMember(
"method", rapidjson::Value(method, allocator),
428 message_doc.AddMember(
"args", args_doc, allocator);
430 rapidjson::StringBuffer buffer;
431 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
432 message_doc.Accept(writer);
434 std::unique_ptr<std::vector<uint8_t>> data =
436 FlutterPlatformMessageResponseHandle response_handle;
437 const FlutterPlatformMessage
message = {
438 sizeof(FlutterPlatformMessage),
444 view_->GetEngine()->HandlePlatformMessage(&
message);
449 size_t RedispatchedMessageCountAndClear() {
450 auto& messages = window_->RedispatchedMessages();
451 size_t count = messages.size();
457 FlutterWindowsEngine* engine_;
458 std::unique_ptr<TestFlutterWindowsView> view_;
459 std::unique_ptr<MockKeyboardManagerDelegate> window_;
460 MockKeyResponseController::EmbedderCallbackHandler callback_handler_;
461 MapVirtualKeyLayout map_virtual_key_layout_;
466 std::unique_ptr<FlutterWindowsEngine> GetTestEngine(
467 WindowsTestContext& context) {
468 FlutterWindowsEngineBuilder builder{context};
470 builder.SetCreateKeyboardHandlerCallbacks(
471 [
this](
int virtual_key) -> SHORT {
474 return window_ ? window_->GetKeyState(virtual_key) : 0;
476 [
this](UINT virtual_key,
bool extended) -> SHORT {
477 return map_virtual_key_layout_(
478 virtual_key,
extended ? MAPVK_VK_TO_VSC_EX : MAPVK_VK_TO_VSC);
481 auto engine = builder.Build();
483 EngineModifier modifier(engine.get());
485 auto key_response_controller =
486 std::make_shared<MockKeyResponseController>();
487 key_response_controller->SetEmbedderResponse(
489 const FlutterKeyEvent* event,
490 MockKeyResponseController::ResponseCallback
callback) {
491 FlutterKeyEvent clone_event = *event;
492 clone_event.character =
event->character ==
nullptr
494 : clone_string(event->character);
495 key_calls.push_back(KeyCall{
496 .type = KeyCall::kKeyCallOnKey,
497 .key_event = clone_event,
501 key_response_controller->SetTextInputResponse(
502 [](std::unique_ptr<rapidjson::Document> document) {
503 rapidjson::StringBuffer buffer;
504 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
505 document->Accept(writer);
506 key_calls.push_back(KeyCall{
507 .type = KeyCall::kKeyCallTextMethodCall,
508 .text_method_call = buffer.GetString(),
511 MockEmbedderApiForKeyboard(modifier, key_response_controller);
518 static MockKeyResponseController::EmbedderCallbackHandler RespondValue(
520 return [value](
const FlutterKeyEvent* event,
521 MockKeyResponseController::ResponseCallback
callback) {
527 FML_DISALLOW_COPY_AND_ASSIGN(KeyboardTester);
530 class KeyboardTest :
public WindowsTest {
532 KeyboardTest() =
default;
533 virtual ~KeyboardTest() =
default;
536 FML_DISALLOW_COPY_AND_ASSIGN(KeyboardTest);
544 #define EXPECT_CALL_IS_EVENT(_key_call, ...) \
545 EXPECT_EQ(_key_call.type, KeyCall::kKeyCallOnKey); \
546 EXPECT_EVENT_EQUALS(_key_call.key_event, __VA_ARGS__);
548 #define EXPECT_CALL_IS_TEXT(_key_call, u16_string) \
549 EXPECT_EQ(_key_call.type, KeyCall::kKeyCallOnText); \
550 EXPECT_EQ(_key_call.text, u16_string);
552 #define EXPECT_CALL_IS_TEXT_METHOD_CALL(_key_call, json_string) \
553 EXPECT_EQ(_key_call.type, KeyCall::kKeyCallTextMethodCall); \
554 EXPECT_STREQ(_key_call.text_method_call.c_str(), json_string);
556 TEST_F(KeyboardTest, LowerCaseAHandled) {
557 KeyboardTester tester{GetContext()};
558 tester.Responding(
true);
563 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
569 EXPECT_EQ(key_calls.size(), 1);
571 kLogicalKeyA,
"a", kNotSynthesized);
573 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
576 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
580 EXPECT_EQ(key_calls.size(), 1);
582 kLogicalKeyA,
"", kNotSynthesized);
584 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
587 TEST_F(KeyboardTest, LowerCaseAUnhandled) {
588 KeyboardTester tester{GetContext()};
589 tester.Responding(
false);
594 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
600 EXPECT_EQ(key_calls.size(), 2);
602 kLogicalKeyA,
"a", kNotSynthesized);
605 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
608 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
612 EXPECT_EQ(key_calls.size(), 1);
614 kLogicalKeyA,
"", kNotSynthesized);
616 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
620 KeyboardTester tester{GetContext()};
621 tester.Responding(
true);
626 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
627 WmKeyDownInfo{VK_LEFT, kScanCodeArrowLeft, kExtended, kWasUp}.Build(
630 EXPECT_EQ(key_calls.size(), 1);
632 kPhysicalArrowLeft, kLogicalArrowLeft,
"",
635 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
638 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
639 WmKeyUpInfo{VK_LEFT, kScanCodeArrowLeft, kExtended}.Build(
642 EXPECT_EQ(key_calls.size(), 1);
644 kLogicalArrowLeft,
"", kNotSynthesized);
646 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
649 TEST_F(KeyboardTest, ArrowLeftUnhandled) {
650 KeyboardTester tester{GetContext()};
651 tester.Responding(
false);
656 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
657 WmKeyDownInfo{VK_LEFT, kScanCodeArrowLeft, kExtended, kWasUp}.Build(
660 EXPECT_EQ(key_calls.size(), 1);
662 kPhysicalArrowLeft, kLogicalArrowLeft,
"",
665 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
668 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
669 WmKeyUpInfo{VK_LEFT, kScanCodeArrowLeft, kExtended}.Build(
672 EXPECT_EQ(key_calls.size(), 1);
674 kLogicalArrowLeft,
"", kNotSynthesized);
676 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
679 TEST_F(KeyboardTest, ShiftLeftUnhandled) {
680 KeyboardTester tester{GetContext()};
681 tester.Responding(
false);
686 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
687 KeyStateChange{VK_LSHIFT,
true,
false},
691 EXPECT_EQ(key_calls.size(), 1);
693 kPhysicalShiftLeft, kLogicalShiftLeft,
"",
696 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
699 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
703 EXPECT_EQ(key_calls.size(), 1);
705 kPhysicalShiftLeft, kLogicalShiftLeft,
"",
708 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
711 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
712 KeyStateChange{VK_LSHIFT,
false,
true},
716 EXPECT_EQ(key_calls.size(), 1);
718 kLogicalShiftLeft,
"", kNotSynthesized);
720 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
723 TEST_F(KeyboardTest, ShiftRightUnhandled) {
724 KeyboardTester tester{GetContext()};
725 tester.Responding(
false);
730 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
731 KeyStateChange{VK_RSHIFT,
true,
false},
735 EXPECT_EQ(key_calls.size(), 1);
737 kPhysicalShiftRight, kLogicalShiftRight,
"",
740 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
743 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
744 KeyStateChange{VK_RSHIFT,
false,
true},
748 EXPECT_EQ(key_calls.size(), 1);
750 kPhysicalShiftRight, kLogicalShiftRight,
"",
753 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
756 TEST_F(KeyboardTest, CtrlLeftUnhandled) {
757 KeyboardTester tester{GetContext()};
758 tester.Responding(
false);
763 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
764 KeyStateChange{VK_LCONTROL,
true,
false},
765 WmKeyDownInfo{VK_CONTROL, kScanCodeControl, kNotExtended, kWasUp}.Build(
768 EXPECT_EQ(key_calls.size(), 1);
770 kPhysicalControlLeft, kLogicalControlLeft,
"",
773 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
776 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
777 KeyStateChange{VK_LCONTROL,
false,
true},
778 WmKeyUpInfo{VK_SHIFT, kScanCodeControl, kNotExtended}.Build(
781 EXPECT_EQ(key_calls.size(), 1);
783 kPhysicalControlLeft, kLogicalControlLeft,
"",
786 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
789 TEST_F(KeyboardTest, CtrlRightUnhandled) {
790 KeyboardTester tester{GetContext()};
791 tester.Responding(
false);
796 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
797 KeyStateChange{VK_RCONTROL,
true,
false},
798 WmKeyDownInfo{VK_CONTROL, kScanCodeControl, kExtended, kWasUp}.Build(
801 EXPECT_EQ(key_calls.size(), 1);
803 kPhysicalControlRight, kLogicalControlRight,
"",
806 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
809 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
810 KeyStateChange{VK_RCONTROL,
false,
true},
811 WmKeyUpInfo{VK_CONTROL, kScanCodeControl, kExtended}.Build(
814 EXPECT_EQ(key_calls.size(), 1);
816 kPhysicalControlRight, kLogicalControlRight,
"",
819 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
823 KeyboardTester tester{GetContext()};
824 tester.Responding(
false);
829 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
830 KeyStateChange{VK_LMENU,
true,
false},
831 WmSysKeyDownInfo{VK_MENU, kScanCodeAlt, kNotExtended, kWasUp}.Build(
834 EXPECT_EQ(key_calls.size(), 1);
836 kLogicalAltLeft,
"", kNotSynthesized);
839 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
842 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
843 KeyStateChange{VK_LMENU,
false,
true},
844 WmSysKeyUpInfo{VK_MENU, kScanCodeAlt, kNotExtended}.Build(
847 EXPECT_EQ(key_calls.size(), 1);
849 kLogicalAltLeft,
"", kNotSynthesized);
852 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
855 TEST_F(KeyboardTest, AltRightUnhandled) {
856 KeyboardTester tester{GetContext()};
857 tester.Responding(
false);
862 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
863 KeyStateChange{VK_RMENU,
true,
false},
864 WmSysKeyDownInfo{VK_MENU, kScanCodeAlt, kExtended, kWasUp}.Build(
867 EXPECT_EQ(key_calls.size(), 1);
869 kPhysicalAltRight, kLogicalAltRight,
"",
873 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
876 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
877 KeyStateChange{VK_RMENU,
false,
true},
878 WmSysKeyUpInfo{VK_MENU, kScanCodeAlt, kExtended}.Build(
881 EXPECT_EQ(key_calls.size(), 1);
883 kLogicalAltRight,
"", kNotSynthesized);
886 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
889 TEST_F(KeyboardTest, MetaLeftUnhandled) {
890 KeyboardTester tester{GetContext()};
891 tester.Responding(
false);
896 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
897 KeyStateChange{VK_LWIN,
true,
false},
898 WmKeyDownInfo{VK_LWIN, kScanCodeMetaLeft, kExtended, kWasUp}.Build(
901 EXPECT_EQ(key_calls.size(), 1);
903 kPhysicalMetaLeft, kLogicalMetaLeft,
"",
906 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
909 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
910 KeyStateChange{VK_LWIN,
false,
true},
911 WmKeyUpInfo{VK_LWIN, kScanCodeMetaLeft, kExtended}.Build(kWmResultZero)});
913 EXPECT_EQ(key_calls.size(), 1);
915 kLogicalMetaLeft,
"", kNotSynthesized);
917 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
920 TEST_F(KeyboardTest, MetaRightUnhandled) {
921 KeyboardTester tester{GetContext()};
922 tester.Responding(
false);
927 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
928 KeyStateChange{VK_RWIN,
true,
false},
929 WmKeyDownInfo{VK_RWIN, kScanCodeMetaRight, kExtended, kWasUp}.Build(
932 EXPECT_EQ(key_calls.size(), 1);
934 kPhysicalMetaRight, kLogicalMetaRight,
"",
937 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
940 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
941 KeyStateChange{VK_RWIN,
false,
true},
942 WmKeyUpInfo{VK_RWIN, kScanCodeMetaRight, kExtended}.Build(
945 EXPECT_EQ(key_calls.size(), 1);
947 kLogicalMetaRight,
"", kNotSynthesized);
949 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
954 KeyboardTester tester{GetContext()};
955 tester.Responding(
true);
958 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
965 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
968 WmCharInfo{
'a',
kScanCodeKeyA, kNotExtended, kWasDown}.Build(
971 EXPECT_EQ(key_calls.size(), 2);
973 kLogicalKeyA,
"a", kNotSynthesized);
975 kLogicalKeyA,
"a", kNotSynthesized);
976 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
982 TEST_F(KeyboardTest, RestartClearsKeyboardState) {
983 KeyboardTester tester{GetContext()};
984 tester.Responding(
true);
987 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
994 tester.ResetKeyboard();
998 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1001 WmCharInfo{
'a',
kScanCodeKeyA, kNotExtended, kWasDown}.Build(
1004 EXPECT_EQ(key_calls.size(), 2);
1006 kLogicalKeyA,
"a", kNotSynthesized);
1008 kLogicalKeyA,
"a", kNotSynthesized);
1009 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
1015 KeyboardTester tester{GetContext()};
1016 tester.Responding(
false);
1021 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1022 KeyStateChange{VK_LSHIFT,
true,
true},
1026 EXPECT_EQ(key_calls.size(), 1);
1028 kPhysicalShiftLeft, kLogicalShiftLeft,
"",
1031 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1034 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1040 EXPECT_EQ(key_calls.size(), 2);
1042 kLogicalKeyA,
"A", kNotSynthesized);
1045 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
1048 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1049 KeyStateChange{VK_LSHIFT,
false,
true},
1053 EXPECT_EQ(key_calls.size(), 1);
1055 kLogicalShiftLeft,
"", kNotSynthesized);
1057 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1060 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1064 EXPECT_EQ(key_calls.size(), 1);
1066 kLogicalKeyA,
"", kNotSynthesized);
1068 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1074 KeyboardTester tester{GetContext()};
1075 tester.Responding(
false);
1080 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1081 KeyStateChange{VK_LCONTROL,
true,
true},
1082 WmKeyDownInfo{VK_CONTROL, kScanCodeControl, kNotExtended, kWasUp}.Build(
1085 EXPECT_EQ(key_calls.size(), 1);
1087 kPhysicalControlLeft, kLogicalControlLeft,
"",
1090 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1093 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1096 WmCharInfo{0x01,
kScanCodeKeyA, kNotExtended, kWasUp}.Build(
1099 EXPECT_EQ(key_calls.size(), 1);
1101 kLogicalKeyA,
"", kNotSynthesized);
1103 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
1106 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1110 EXPECT_EQ(key_calls.size(), 1);
1112 kLogicalKeyA,
"", kNotSynthesized);
1114 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1117 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1118 KeyStateChange{VK_LCONTROL,
false,
true},
1119 WmKeyUpInfo{VK_CONTROL, kScanCodeControl, kNotExtended}.Build(
1122 EXPECT_EQ(key_calls.size(), 1);
1124 kPhysicalControlLeft, kLogicalControlLeft,
"",
1127 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1132 KeyboardTester tester{GetContext()};
1133 tester.Responding(
false);
1138 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1139 KeyStateChange{VK_LCONTROL,
true,
true},
1140 WmKeyDownInfo{VK_CONTROL, kScanCodeControl, kNotExtended, kWasUp}.Build(
1143 EXPECT_EQ(key_calls.size(), 1);
1145 kPhysicalControlLeft, kLogicalControlLeft,
"",
1148 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1151 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1152 WmKeyDownInfo{kVirtualDigit1, kScanCodeDigit1, kNotExtended, kWasUp}
1153 .Build(kWmResultZero)});
1155 EXPECT_EQ(key_calls.size(), 1);
1157 kLogicalDigit1,
"", kNotSynthesized);
1159 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1162 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1163 WmKeyUpInfo{kVirtualDigit1, kScanCodeDigit1, kNotExtended}.Build(
1166 EXPECT_EQ(key_calls.size(), 1);
1168 kLogicalDigit1,
"", kNotSynthesized);
1170 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1173 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1174 KeyStateChange{VK_LCONTROL,
false,
true},
1175 WmKeyUpInfo{VK_CONTROL, kScanCodeControl, kNotExtended}.Build(
1178 EXPECT_EQ(key_calls.size(), 1);
1180 kPhysicalControlLeft, kLogicalControlLeft,
"",
1183 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1189 KeyboardTester tester{GetContext()};
1190 tester.Responding(
false);
1192 tester.SetLayout(LayoutFrench);
1195 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1196 WmKeyDownInfo{kVirtualDigit1, kScanCodeDigit1, kNotExtended, kWasUp}
1197 .Build(kWmResultZero),
1198 WmCharInfo{
'&', kScanCodeDigit1, kNotExtended, kWasUp}.Build(
1201 EXPECT_EQ(key_calls.size(), 2);
1203 kLogicalDigit1,
"&", kNotSynthesized);
1206 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
1209 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1210 WmKeyUpInfo{kVirtualDigit1, kScanCodeDigit1, kNotExtended}.Build(
1213 EXPECT_EQ(key_calls.size(), 1);
1215 kLogicalDigit1,
"", kNotSynthesized);
1217 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1222 KeyboardTester tester{GetContext()};
1223 tester.Responding(
false);
1228 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1229 KeyStateChange{VK_LCONTROL,
true,
true},
1230 WmKeyDownInfo{VK_LCONTROL, kScanCodeControl, kNotExtended, kWasUp}.Build(
1232 KeyStateChange{VK_RMENU,
true,
true},
1233 WmKeyDownInfo{VK_MENU, kScanCodeAlt, kExtended, kWasUp}.Build(
1236 EXPECT_EQ(key_calls.size(), 2);
1238 kPhysicalControlLeft, kLogicalControlLeft,
"",
1241 kPhysicalAltRight, kLogicalAltRight,
"",
1244 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
1247 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1248 WmKeyDownInfo{kVirtualKeyQ, kScanCodeKeyQ, kNotExtended, kWasUp}.Build(
1250 WmCharInfo{
'@', kScanCodeKeyQ, kNotExtended, kWasUp}.Build(
1253 EXPECT_EQ(key_calls.size(), 2);
1255 kLogicalKeyQ,
"@", kNotSynthesized);
1258 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
1261 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1262 WmKeyUpInfo{kVirtualKeyQ, kScanCodeKeyQ, kNotExtended}.Build(
1265 EXPECT_EQ(key_calls.size(), 1);
1267 kLogicalKeyQ,
"", kNotSynthesized);
1269 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1274 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1275 KeyStateChange{VK_LCONTROL,
false,
true},
1276 ExpectForgedMessage{
1277 WmKeyUpInfo{VK_CONTROL, kScanCodeControl, kNotExtended}.Build(
1279 KeyStateChange{VK_RMENU,
false,
true},
1280 WmSysKeyUpInfo{VK_MENU, kScanCodeAlt, kExtended}.Build(
1281 kWmResultDefault)});
1283 EXPECT_EQ(key_calls.size(), 2);
1285 kPhysicalControlLeft, kLogicalControlLeft,
"",
1288 kLogicalAltRight,
"", kNotSynthesized);
1291 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1308 KeyboardTester tester{GetContext()};
1309 tester.Responding(
false);
1315 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1316 KeyStateChange{VK_LCONTROL,
true,
true},
1317 WmKeyDownInfo{VK_CONTROL, kScanCodeControl, kNotExtended, kWasUp}.Build(
1319 KeyStateChange{VK_RMENU,
true,
true},
1320 WmKeyDownInfo{VK_MENU, kScanCodeAlt, kExtended, kWasUp}.Build(
1323 EXPECT_EQ(key_calls.size(), 2);
1325 kPhysicalControlLeft, kLogicalControlLeft,
"",
1328 kPhysicalAltRight, kLogicalAltRight,
"",
1331 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
1336 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1337 KeyStateChange{VK_LCONTROL,
false,
true},
1338 ExpectForgedMessage{
1339 WmKeyUpInfo{VK_CONTROL, kScanCodeControl, kNotExtended}.Build(
1341 KeyStateChange{VK_RMENU,
false,
true},
1342 WmSysKeyUpInfo{VK_MENU, kScanCodeAlt, kExtended}.Build(
1343 kWmResultDefault)});
1344 EXPECT_EQ(key_calls.size(), 2);
1346 kPhysicalControlLeft, kLogicalControlLeft,
"",
1349 kLogicalAltRight,
"", kNotSynthesized);
1352 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1356 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1357 KeyStateChange{VK_LCONTROL,
true,
false},
1358 WmKeyDownInfo{VK_CONTROL, kScanCodeControl, kNotExtended, kWasUp}.Build(
1360 KeyStateChange{VK_RMENU,
true,
true},
1361 WmKeyDownInfo{VK_MENU, kScanCodeAlt, kExtended, kWasUp}.Build(
1364 EXPECT_EQ(key_calls.size(), 2);
1366 kPhysicalControlLeft, kLogicalControlLeft,
"",
1369 kPhysicalAltRight, kLogicalAltRight,
"",
1372 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
1377 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1378 KeyStateChange{VK_LCONTROL,
false,
false},
1379 ExpectForgedMessage{
1380 WmKeyUpInfo{VK_CONTROL, kScanCodeControl, kNotExtended}.Build(
1382 KeyStateChange{VK_RMENU,
false,
false},
1383 WmSysKeyUpInfo{VK_MENU, kScanCodeAlt, kExtended}.Build(
1384 kWmResultDefault)});
1385 EXPECT_EQ(key_calls.size(), 2);
1387 kPhysicalControlLeft, kLogicalControlLeft,
"",
1390 kLogicalAltRight,
"", kNotSynthesized);
1393 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1396 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1397 WmKeyUpInfo{VK_CONTROL, kScanCodeControl, kNotExtended}.Build(
1399 EXPECT_EQ(key_calls.size(), 1);
1403 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
1409 KeyboardTester tester{GetContext()};
1410 tester.Responding(
false);
1412 tester.SetLayout(LayoutFrench);
1415 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1416 WmKeyDownInfo{0xDD, kScanCodeBracketLeft, kNotExtended, kWasUp}.Build(
1418 WmDeadCharInfo{
'^', kScanCodeBracketLeft, kNotExtended, kWasUp}.Build(
1421 EXPECT_EQ(key_calls.size(), 1);
1423 kPhysicalBracketLeft, kLogicalBracketRight,
"^",
1426 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
1429 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1430 WmKeyUpInfo{0xDD, kScanCodeBracketLeft, kNotExtended}.Build(
1433 EXPECT_EQ(key_calls.size(), 1);
1435 kPhysicalBracketLeft, kLogicalBracketRight,
"",
1438 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1441 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1442 WmKeyDownInfo{kVirtualKeyE, kScanCodeKeyE, kNotExtended, kWasUp}.Build(
1444 WmCharInfo{0xEA, kScanCodeKeyE, kNotExtended, kWasUp}.Build(
1447 EXPECT_EQ(key_calls.size(), 2);
1449 kLogicalKeyE,
"ê", kNotSynthesized);
1452 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
1455 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1456 WmKeyUpInfo{kVirtualKeyE, kScanCodeKeyE, kNotExtended}.Build(
1459 EXPECT_EQ(key_calls.size(), 1);
1461 kLogicalKeyE,
"", kNotSynthesized);
1463 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1471 TEST_F(KeyboardTest, DeadKeyWithoutDeadMaskThatCombines) {
1472 KeyboardTester tester{GetContext()};
1473 tester.Responding(
false);
1476 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1477 KeyStateChange{VK_LSHIFT,
true,
true},
1481 EXPECT_EQ(key_calls.size(), 1);
1483 kPhysicalShiftLeft, kLogicalShiftLeft,
"",
1486 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1489 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1490 WmKeyDownInfo{
'6', kScanCodeDigit6, kNotExtended, kWasUp}.Build(
1492 WmDeadCharInfo{
'^', kScanCodeDigit6, kNotExtended, kWasUp}.Build(
1495 EXPECT_EQ(key_calls.size(), 1);
1497 kLogicalDigit6,
"6", kNotSynthesized);
1499 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
1502 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1503 WmKeyUpInfo{
'6', kScanCodeDigit6, kNotExtended}.Build(kWmResultZero)});
1505 EXPECT_EQ(key_calls.size(), 1);
1507 kLogicalDigit6,
"", kNotSynthesized);
1509 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1512 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1513 KeyStateChange{VK_LSHIFT,
false,
true},
1517 EXPECT_EQ(key_calls.size(), 1);
1519 kLogicalShiftLeft,
"", kNotSynthesized);
1521 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1524 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1525 WmKeyDownInfo{kVirtualKeyE, kScanCodeKeyE, kNotExtended, kWasUp}.Build(
1527 WmCharInfo{0xEA, kScanCodeKeyE, kNotExtended, kWasUp}.Build(
1530 EXPECT_EQ(key_calls.size(), 2);
1532 kLogicalKeyE,
"ê", kNotSynthesized);
1535 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
1538 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1539 WmKeyUpInfo{kVirtualKeyE, kScanCodeKeyE, kNotExtended}.Build(
1542 EXPECT_EQ(key_calls.size(), 1);
1544 kLogicalKeyE,
"", kNotSynthesized);
1546 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1551 TEST_F(KeyboardTest, DeadKeyThatDoesNotCombine) {
1552 KeyboardTester tester{GetContext()};
1553 tester.Responding(
false);
1555 tester.SetLayout(LayoutFrench);
1558 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1559 WmKeyDownInfo{0xDD, kScanCodeBracketLeft, kNotExtended, kWasUp}.Build(
1561 WmDeadCharInfo{
'^', kScanCodeBracketLeft, kNotExtended, kWasUp}.Build(
1564 EXPECT_EQ(key_calls.size(), 1);
1566 kPhysicalBracketLeft, kLogicalBracketRight,
"^",
1569 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
1572 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1573 WmKeyUpInfo{0xDD, kScanCodeBracketLeft, kNotExtended}.Build(
1576 EXPECT_EQ(key_calls.size(), 1);
1578 kPhysicalBracketLeft, kLogicalBracketRight,
"",
1581 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1584 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1585 WmKeyDownInfo{kVirtualDigit1, kScanCodeDigit1, kNotExtended, kWasUp}
1586 .Build(kWmResultZero),
1587 WmCharInfo{
'^', kScanCodeDigit1, kNotExtended, kWasUp}.Build(
1589 WmCharInfo{
'&', kScanCodeDigit1, kNotExtended, kWasUp}.Build(
1592 EXPECT_EQ(key_calls.size(), 3);
1594 kLogicalDigit1,
"^", kNotSynthesized);
1603 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
1606 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1607 WmKeyUpInfo{kVirtualDigit1, kScanCodeDigit1, kNotExtended}.Build(
1610 EXPECT_EQ(key_calls.size(), 1);
1612 kLogicalDigit1,
"", kNotSynthesized);
1614 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1620 TEST_F(KeyboardTest, DeadKeyTwiceThenLetter) {
1621 KeyboardTester tester{GetContext()};
1622 tester.Responding(
false);
1627 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1628 WmKeyDownInfo{0xC0, kScanCodeBackquote, kNotExtended, kWasUp}.Build(
1630 WmDeadCharInfo{
'`', kScanCodeBackquote, kNotExtended, kWasUp}.Build(
1633 EXPECT_EQ(key_calls.size(), 1);
1635 kPhysicalBackquote, kLogicalBackquote,
"`",
1638 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
1641 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1642 WmKeyUpInfo{0xC0, kScanCodeBackquote, kNotExtended}.Build(
1645 EXPECT_EQ(key_calls.size(), 1);
1647 kLogicalBackquote,
"", kNotSynthesized);
1649 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1653 std::vector<MockKeyResponseController::ResponseCallback> recorded_callbacks;
1654 tester.LateResponding(
1655 [&recorded_callbacks](
1656 const FlutterKeyEvent* event,
1657 MockKeyResponseController::ResponseCallback
callback) {
1658 recorded_callbacks.push_back(
callback);
1661 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1662 WmKeyDownInfo{0xC0, kScanCodeBackquote, kNotExtended, kWasUp}.Build(
1664 WmCharInfo{
'`', kScanCodeBackquote, kNotExtended, kWasUp, kBeingReleased,
1665 kNoContext, 1,
true}
1666 .Build(kWmResultZero),
1667 WmCharInfo{
'`', kScanCodeBackquote, kNotExtended, kWasUp}.Build(
1670 EXPECT_EQ(recorded_callbacks.size(), 1);
1671 EXPECT_EQ(key_calls.size(), 1);
1673 kPhysicalBackquote, kLogicalBackquote,
"`",
1677 recorded_callbacks.front()(
false);
1678 EXPECT_EQ(key_calls.size(), 2);
1685 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
1687 tester.Responding(
false);
1690 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1691 WmKeyUpInfo{0xC0, kScanCodeBackquote, kNotExtended}.Build(
1694 EXPECT_EQ(key_calls.size(), 1);
1696 kLogicalBackquote,
"", kNotSynthesized);
1698 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1703 KeyboardTester tester{GetContext()};
1704 tester.Responding(
false);
1710 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1711 WmKeyDownInfo{kVirtualKeyW, kScanCodeKeyW, kNotExtended, kWasUp}.Build(
1713 WmCharInfo{0xd800, kScanCodeKeyW, kNotExtended, kWasUp}.Build(
1715 WmCharInfo{0xdf45, kScanCodeKeyW, kNotExtended, kWasUp}.Build(
1718 const char* st = key_calls[0].key_event.character;
1720 EXPECT_EQ(key_calls.size(), 2);
1722 kLogicalKeyW,
"𐍅", kNotSynthesized);
1725 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 3);
1728 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1729 WmKeyUpInfo{kVirtualKeyW, kScanCodeKeyW, kNotExtended}.Build(
1732 EXPECT_EQ(key_calls.size(), 1);
1734 kLogicalKeyW,
"", kNotSynthesized);
1736 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1740 KeyboardTester tester{GetContext()};
1741 tester.Responding(
false);
1744 Win32Message event1 =
1745 WmKeyDownInfo{VK_BACK, kScanCodeBackspace, kNotExtended, kWasUp}.Build(
1747 Win32Message event2 =
1748 WmKeyUpInfo{VK_BACK, kScanCodeBackspace, kNotExtended}.Build(
1752 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1753 KeyStateChange{VK_LSHIFT,
true,
true}, event1});
1754 EXPECT_EQ(key_calls.size(), 2);
1756 kPhysicalShiftLeft, kLogicalShiftLeft,
"", kSynthesized);
1758 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1760 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1761 KeyStateChange{VK_LSHIFT,
false,
true}, event2});
1762 EXPECT_EQ(key_calls.size(), 2);
1764 kLogicalShiftLeft,
"", kSynthesized);
1766 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1769 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1770 KeyStateChange{VK_RSHIFT,
true,
true}, event1});
1771 EXPECT_EQ(key_calls.size(), 2);
1773 kPhysicalShiftRight, kLogicalShiftRight,
"",
1776 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1778 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1779 KeyStateChange{VK_RSHIFT,
false,
true}, event2});
1780 EXPECT_EQ(key_calls.size(), 2);
1782 kPhysicalShiftRight, kLogicalShiftRight,
"",
1785 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1788 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1789 KeyStateChange{VK_LCONTROL,
true,
true}, event1});
1790 EXPECT_EQ(key_calls.size(), 2);
1792 kPhysicalControlLeft, kLogicalControlLeft,
"",
1795 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1797 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1798 KeyStateChange{VK_LCONTROL,
false,
true}, event2});
1799 EXPECT_EQ(key_calls.size(), 2);
1801 kPhysicalControlLeft, kLogicalControlLeft,
"",
1804 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1807 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1808 KeyStateChange{VK_RCONTROL,
true,
true}, event1});
1809 EXPECT_EQ(key_calls.size(), 2);
1811 kPhysicalControlRight, kLogicalControlRight,
"",
1814 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1816 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1817 KeyStateChange{VK_RCONTROL,
false,
true}, event2});
1818 EXPECT_EQ(key_calls.size(), 2);
1820 kPhysicalControlRight, kLogicalControlRight,
"",
1823 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1826 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1827 KeyStateChange{VK_LMENU,
true,
true}, event1});
1828 EXPECT_EQ(key_calls.size(), 2);
1830 kLogicalAltLeft,
"", kSynthesized);
1832 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1834 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1835 KeyStateChange{VK_LMENU,
false,
true}, event2});
1836 EXPECT_EQ(key_calls.size(), 2);
1838 kLogicalAltLeft,
"", kSynthesized);
1840 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1843 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1844 KeyStateChange{VK_RMENU,
true,
true}, event1});
1845 EXPECT_EQ(key_calls.size(), 2);
1847 kPhysicalAltRight, kLogicalAltRight,
"", kSynthesized);
1849 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1851 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1852 KeyStateChange{VK_RMENU,
false,
true}, event2});
1853 EXPECT_EQ(key_calls.size(), 2);
1855 kLogicalAltRight,
"", kSynthesized);
1857 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1860 tester.InjectKeyboardChanges(
1861 std::vector<KeyboardChange>{KeyStateChange{VK_LWIN,
true,
true}, event1});
1862 EXPECT_EQ(key_calls.size(), 2);
1864 kPhysicalMetaLeft, kLogicalMetaLeft,
"", kSynthesized);
1866 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1868 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1869 KeyStateChange{VK_LWIN,
false,
true}, event2});
1870 EXPECT_EQ(key_calls.size(), 2);
1872 kLogicalMetaLeft,
"", kSynthesized);
1874 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1877 tester.InjectKeyboardChanges(
1878 std::vector<KeyboardChange>{KeyStateChange{VK_RWIN,
true,
true}, event1});
1879 EXPECT_EQ(key_calls.size(), 2);
1881 kPhysicalMetaRight, kLogicalMetaRight,
"", kSynthesized);
1883 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1885 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1886 KeyStateChange{VK_RWIN,
false,
true}, event2});
1887 EXPECT_EQ(key_calls.size(), 2);
1889 kLogicalMetaRight,
"", kSynthesized);
1891 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1895 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1896 KeyStateChange{VK_CAPITAL,
false,
true}, event1});
1897 EXPECT_EQ(key_calls.size(), 3);
1899 kPhysicalCapsLock, kLogicalCapsLock,
"", kSynthesized);
1901 kLogicalCapsLock,
"", kSynthesized);
1903 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1905 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1906 KeyStateChange{VK_CAPITAL,
false,
false}, event2});
1907 EXPECT_EQ(key_calls.size(), 3);
1909 kPhysicalCapsLock, kLogicalCapsLock,
"", kSynthesized);
1911 kLogicalCapsLock,
"", kSynthesized);
1913 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1916 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1917 KeyStateChange{VK_SCROLL,
true,
true}, event1});
1918 EXPECT_EQ(key_calls.size(), 2);
1920 kPhysicalScrollLock, kLogicalScrollLock,
"",
1923 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1925 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1926 KeyStateChange{VK_SCROLL,
true,
false}, event2});
1927 EXPECT_EQ(key_calls.size(), 3);
1929 kPhysicalScrollLock, kLogicalScrollLock,
"",
1932 kPhysicalScrollLock, kLogicalScrollLock,
"",
1935 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1938 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1939 KeyStateChange{VK_NUMLOCK,
true,
false}, event1});
1944 EXPECT_EQ(key_calls.size(), 2);
1946 kLogicalNumLock,
"", kSynthesized);
1948 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1950 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1951 KeyStateChange{VK_NUMLOCK,
false,
true}, event2});
1952 EXPECT_EQ(key_calls.size(), 4);
1954 kLogicalNumLock,
"", kSynthesized);
1956 kLogicalNumLock,
"", kSynthesized);
1958 kLogicalNumLock,
"", kSynthesized);
1960 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
1967 TEST_F(KeyboardTest, ImeExtendedEventsAreIgnored) {
1968 KeyboardTester tester{GetContext()};
1969 tester.Responding(
false);
1977 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
1978 KeyStateChange{VK_RCONTROL,
true,
false},
1979 WmKeyDownInfo{VK_PROCESSKEY, kScanCodeControl, kExtended, kWasUp}.Build(
1982 EXPECT_EQ(key_calls.size(), 1);
1986 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
1995 TEST_F(KeyboardTest, UpOnlyImeEventsAreCorrectlyHandled) {
1996 KeyboardTester tester{GetContext()};
1997 tester.Responding(
true);
2002 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
2003 KeyStateChange{VK_LSHIFT,
true,
false},
2006 WmKeyDownInfo{VK_PROCESSKEY, kScanCodeDigit2, kNotExtended, kWasUp}.Build(
2008 KeyStateChange{VK_LSHIFT,
false,
true},
2011 WmKeyUpInfo{
'2', kScanCodeDigit2, kNotExtended, kWasUp}.Build(
2014 EXPECT_EQ(key_calls.size(), 4);
2016 kPhysicalShiftLeft, kLogicalShiftLeft,
"",
2021 kLogicalShiftLeft,
"", kNotSynthesized);
2033 TEST_F(KeyboardTest, SlowFrameworkResponse) {
2034 KeyboardTester tester{GetContext()};
2036 std::vector<MockKeyResponseController::ResponseCallback> recorded_callbacks;
2039 tester.LateResponding(
2040 [&recorded_callbacks](
2041 const FlutterKeyEvent* event,
2042 MockKeyResponseController::ResponseCallback
callback) {
2043 recorded_callbacks.push_back(
callback);
2047 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
2054 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
2057 WmCharInfo{
'a',
kScanCodeKeyA, kNotExtended, kWasDown}.Build(
2060 EXPECT_EQ(key_calls.size(), 1);
2062 kLogicalKeyA,
"a", kNotSynthesized);
2063 EXPECT_EQ(recorded_callbacks.size(), 1);
2064 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
2067 recorded_callbacks.front()(
false);
2069 EXPECT_EQ(key_calls.size(), 3);
2070 EXPECT_EQ(recorded_callbacks.size(), 2);
2073 kLogicalKeyA,
"a", kNotSynthesized);
2074 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
2077 recorded_callbacks.back()(
false);
2079 EXPECT_EQ(key_calls.size(), 4);
2082 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
2096 TEST_F(KeyboardTest, SlowFrameworkResponseForIdenticalEvents) {
2097 KeyboardTester tester{GetContext()};
2098 std::vector<MockKeyResponseController::ResponseCallback> recorded_callbacks;
2101 tester.LateResponding(
2102 [&recorded_callbacks](
2103 const FlutterKeyEvent* event,
2104 MockKeyResponseController::ResponseCallback
callback) {
2105 recorded_callbacks.push_back(
callback);
2109 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
2115 EXPECT_EQ(key_calls.size(), 1);
2117 kLogicalKeyA,
"a", kNotSynthesized);
2119 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
2122 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
2126 EXPECT_EQ(key_calls.size(), 0);
2127 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
2130 EXPECT_EQ(recorded_callbacks.size(), 1);
2131 recorded_callbacks.front()(
false);
2133 EXPECT_EQ(key_calls.size(), 2);
2136 kLogicalKeyA,
"", kNotSynthesized);
2138 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
2141 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
2149 EXPECT_EQ(recorded_callbacks.size(), 2);
2150 EXPECT_EQ(key_calls.size(), 0);
2151 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
2155 recorded_callbacks.back()(
false);
2156 EXPECT_EQ(key_calls.size(), 1);
2158 kLogicalKeyA,
"a", kNotSynthesized);
2160 EXPECT_EQ(recorded_callbacks.size(), 3);
2161 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
2164 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
2168 EXPECT_EQ(key_calls.size(), 0);
2169 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
2173 KeyboardTester tester{GetContext()};
2174 tester.Responding(
false);
2178 tester.InjectPlatformMessage(
2179 "flutter/textinput",
"TextInput.setClient",
2180 R
"|([108, {"inputAction": "TextInputAction.none"}])|");
2183 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
2184 WmKeyDownInfo{VK_RETURN, kScanCodeEnter, kNotExtended, kWasUp}.Build(
2186 WmCharInfo{
'\n', kScanCodeEnter, kNotExtended, kWasUp}.Build(
2189 EXPECT_EQ(key_calls.size(), 2);
2191 kLogicalEnter,
"", kNotSynthesized);
2195 R
"|("method":"TextInputClient.performAction",)|"
2196 R"|("args":[108,"TextInputAction.none"])|"
2199 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
2202 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
2203 WmKeyUpInfo{VK_RETURN, kScanCodeEnter, kNotExtended}.Build(
2206 EXPECT_EQ(key_calls.size(), 1);
2208 kLogicalEnter,
"", kNotSynthesized);
2210 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
2217 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
2223 EXPECT_EQ(key_calls.size(), 2);
2225 kLogicalKeyA,
"a", kNotSynthesized);
2230 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
2234 EXPECT_EQ(key_calls.size(), 1);
2236 kLogicalKeyA,
"", kNotSynthesized);
2240 TEST_F(KeyboardTest, VietnameseTelexAddDiacriticWithFastResponse) {
2250 KeyboardTester tester{GetContext()};
2251 tester.Responding(
false);
2256 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
2262 EXPECT_EQ(key_calls.size(), 2);
2264 kLogicalKeyA,
"a", kNotSynthesized);
2267 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
2270 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
2274 EXPECT_EQ(key_calls.size(), 1);
2276 kLogicalKeyA,
"", kNotSynthesized);
2278 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
2283 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
2284 WmKeyDownInfo{VK_BACK, kScanCodeBackspace, kNotExtended, kWasUp}.Build(
2286 WmCharInfo{0x8, kScanCodeBackspace, kNotExtended, kWasUp}.Build(
2288 WmKeyUpInfo{VK_BACK, kScanCodeBackspace, kNotExtended}.Build(
2290 WmKeyDownInfo{VK_PACKET, 0, kNotExtended, kWasUp}.Build(kWmResultDefault),
2291 WmCharInfo{0xe0 , 0, kNotExtended, kWasUp}.Build(kWmResultZero),
2292 WmKeyUpInfo{VK_PACKET, 0, kNotExtended}.Build(kWmResultDefault)});
2294 EXPECT_EQ(key_calls.size(), 3);
2296 kPhysicalBackspace, kLogicalBackspace,
"",
2299 kLogicalBackspace,
"", kNotSynthesized);
2307 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 3);
2310 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
2311 WmKeyUpInfo{kVirtualKeyF, kScanCodeKeyF, kNotExtended,
2313 .Build(kWmResultZero)});
2315 EXPECT_EQ(key_calls.size(), 1);
2319 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
2323 bool backspace_response) {
2333 KeyboardTester tester{context};
2334 tester.Responding(
false);
2339 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
2345 EXPECT_EQ(key_calls.size(), 2);
2347 kLogicalKeyA,
"a", kNotSynthesized);
2350 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 2);
2353 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
2357 EXPECT_EQ(key_calls.size(), 1);
2359 kLogicalKeyA,
"", kNotSynthesized);
2361 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
2363 std::vector<MockKeyResponseController::ResponseCallback> recorded_callbacks;
2364 tester.LateResponding(
2365 [&recorded_callbacks](
2366 const FlutterKeyEvent* event,
2367 MockKeyResponseController::ResponseCallback
callback) {
2368 recorded_callbacks.push_back(
callback);
2374 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
2375 WmKeyDownInfo{VK_BACK, kScanCodeBackspace, kNotExtended, kWasUp}.Build(
2377 WmCharInfo{0x8, kScanCodeBackspace, kNotExtended, kWasUp}.Build(
2379 WmKeyUpInfo{VK_BACK, kScanCodeBackspace, kNotExtended}.Build(
2381 WmKeyDownInfo{VK_PACKET, 0, kNotExtended, kWasUp}.Build(kWmResultDefault),
2382 WmCharInfo{0xe0 , 0, kNotExtended, kWasUp}.Build(kWmResultZero),
2383 WmKeyUpInfo{VK_PACKET, 0, kNotExtended}.Build(kWmResultDefault)});
2390 EXPECT_EQ(key_calls.size(), 1);
2392 kPhysicalBackspace, kLogicalBackspace,
"",
2395 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
2397 EXPECT_EQ(recorded_callbacks.size(), 1);
2398 recorded_callbacks[0](backspace_response);
2400 EXPECT_EQ(key_calls.size(), 1);
2402 kLogicalBackspace,
"", kNotSynthesized);
2404 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(),
2405 backspace_response ? 0 : 2);
2407 recorded_callbacks[1](
false);
2408 EXPECT_EQ(key_calls.size(), 1);
2411 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
2413 tester.Responding(
false);
2416 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
2417 WmKeyUpInfo{kVirtualKeyF, kScanCodeKeyF, kNotExtended,
2419 .Build(kWmResultZero)});
2421 EXPECT_EQ(key_calls.size(), 1);
2425 EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 0);
2428 TEST_F(KeyboardTest, VietnameseTelexAddDiacriticWithSlowFalseResponse) {
2432 TEST_F(KeyboardTest, VietnameseTelexAddDiacriticWithSlowTrueResponse) {
2439 KeyboardTester tester{GetContext()};
2440 tester.Responding(
false);
2442 tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
2443 WmKeyDownInfo{VK_CAPITAL, 0, kNotExtended}.Build(),
2444 WmKeyUpInfo{VK_CAPITAL, 0, kNotExtended}.Build()});