diff --git a/shell/platform/windows/flutter_windows_engine.cc b/shell/platform/windows/flutter_windows_engine.cc index a5766c16577cd..c3eebe9fda533 100644 --- a/shell/platform/windows/flutter_windows_engine.cc +++ b/shell/platform/windows/flutter_windows_engine.cc @@ -544,7 +544,11 @@ void FlutterWindowsEngine::SendKeyEvent(const FlutterKeyEvent& event, FlutterKeyEventCallback callback, void* user_data) { if (engine_) { - embedder_api_.SendKeyEvent(engine_, &event, callback, user_data); + if (canSendKeyboardEvents_) { + embedder_api_.SendKeyEvent(engine_, &event, callback, user_data); + } else { + callback(false, user_data); + } } } @@ -656,6 +660,8 @@ void FlutterWindowsEngine::InitializeKeyboard() { FML_LOG(ERROR) << "Cannot initialize keyboard on Windows headless mode."; } + canSendKeyboardEvents_ = false; + auto internal_plugin_messenger = internal_plugin_registrar_->messenger(); KeyboardKeyEmbedderHandler::GetKeyStateHandler get_key_state = GetKeyState; KeyboardKeyEmbedderHandler::MapVirtualKeyToScanCode map_vk_to_scan = @@ -682,8 +688,8 @@ FlutterWindowsEngine::CreateKeyboardKeyHandler( return SendKeyEvent(event, callback, user_data); }, get_key_state, map_vk_to_scan)); - keyboard_key_handler->AddDelegate( - std::make_unique(messenger)); + keyboard_key_handler->AddDelegate(std::make_unique( + messenger, [this]() { return canSendKeyboardEvents_; })); keyboard_key_handler->InitKeyboardChannel(); return keyboard_key_handler; } @@ -851,6 +857,8 @@ void FlutterWindowsEngine::OnChannelUpdate(std::string name, bool listening) { lifecycle_manager_->BeginProcessingExit(); } else if (name == "flutter/lifecycle" && listening) { lifecycle_manager_->BeginProcessingLifecycle(); + } else if (name == "flutter/keydata" && listening) { + canSendKeyboardEvents_ = true; } } diff --git a/shell/platform/windows/flutter_windows_engine.h b/shell/platform/windows/flutter_windows_engine.h index 3914978f9fc1d..eb48a08ddba5b 100644 --- a/shell/platform/windows/flutter_windows_engine.h +++ b/shell/platform/windows/flutter_windows_engine.h @@ -383,6 +383,9 @@ class FlutterWindowsEngine { // Handlers for keyboard events from Windows. std::unique_ptr keyboard_key_handler_; + // Wether the framework is ready to receive keyboard events. + bool canSendKeyboardEvents_ = false; + // Handlers for text events from Windows. std::unique_ptr text_input_plugin_; diff --git a/shell/platform/windows/keyboard_key_channel_handler.cc b/shell/platform/windows/keyboard_key_channel_handler.cc index eaa1a7696b6f3..ecbadeca5d197 100644 --- a/shell/platform/windows/keyboard_key_channel_handler.cc +++ b/shell/platform/windows/keyboard_key_channel_handler.cc @@ -100,12 +100,14 @@ int GetModsForKeyState() { } // namespace KeyboardKeyChannelHandler::KeyboardKeyChannelHandler( - flutter::BinaryMessenger* messenger) + flutter::BinaryMessenger* messenger, + CanSendHandler can_send) : channel_( std::make_unique>( messenger, kChannelName, - &flutter::JsonMessageCodec::GetInstance())) {} + &flutter::JsonMessageCodec::GetInstance())), + can_send_(can_send) {} KeyboardKeyChannelHandler::~KeyboardKeyChannelHandler() = default; @@ -154,13 +156,19 @@ void KeyboardKeyChannelHandler::KeyboardHook( callback(false); return; } - channel_->Send(event, [callback = std::move(callback)](const uint8_t* reply, - size_t reply_size) { - auto decoded = flutter::JsonMessageCodec::GetInstance().DecodeMessage( - reply, reply_size); - bool handled = decoded ? (*decoded)[kHandledKey].GetBool() : false; - callback(handled); - }); + + if (can_send_()) { + channel_->Send(event, [callback = std::move(callback)](const uint8_t* reply, + size_t reply_size) { + auto decoded = flutter::JsonMessageCodec::GetInstance().DecodeMessage( + reply, reply_size); + bool handled = decoded ? (*decoded)[kHandledKey].GetBool() : false; + callback(handled); + }); + } else { + // std::cerr << " >>>>>> CAN NOT SEND >>>>>> \n"; + callback(false); + } } } // namespace flutter diff --git a/shell/platform/windows/keyboard_key_channel_handler.h b/shell/platform/windows/keyboard_key_channel_handler.h index 7a5d96f73ac17..418b169c1aa1c 100644 --- a/shell/platform/windows/keyboard_key_channel_handler.h +++ b/shell/platform/windows/keyboard_key_channel_handler.h @@ -24,9 +24,12 @@ namespace flutter { class KeyboardKeyChannelHandler : public KeyboardKeyHandler::KeyboardKeyHandlerDelegate { public: + using CanSendHandler = std::function; + // Create a |KeyboardKeyChannelHandler| by specifying the messenger // through which the events are sent. - explicit KeyboardKeyChannelHandler(flutter::BinaryMessenger* messenger); + explicit KeyboardKeyChannelHandler(flutter::BinaryMessenger* messenger, + CanSendHandler can_send); ~KeyboardKeyChannelHandler(); @@ -47,6 +50,9 @@ class KeyboardKeyChannelHandler // The Flutter system channel for key event messages. std::unique_ptr> channel_; + // A callback which returns a bool indicating if key events can be sent. + CanSendHandler can_send_; + FML_DISALLOW_COPY_AND_ASSIGN(KeyboardKeyChannelHandler); }; diff --git a/shell/platform/windows/keyboard_key_channel_handler_unittests.cc b/shell/platform/windows/keyboard_key_channel_handler_unittests.cc index 0fd63eccb0d52..5bbd06f4610e6 100644 --- a/shell/platform/windows/keyboard_key_channel_handler_unittests.cc +++ b/shell/platform/windows/keyboard_key_channel_handler_unittests.cc @@ -51,7 +51,7 @@ TEST(KeyboardKeyChannelHandlerTest, KeyboardHookHandling) { } }); - KeyboardKeyChannelHandler handler(&messenger); + KeyboardKeyChannelHandler handler(&messenger, []() { return true; }); bool last_handled = false; handler.KeyboardHook( @@ -106,7 +106,7 @@ TEST(KeyboardKeyChannelHandlerTest, ExtendedKeysAreSentToRedispatch) { } }); - KeyboardKeyChannelHandler handler(&messenger); + KeyboardKeyChannelHandler handler(&messenger, []() { return true; }); bool last_handled = true; // Extended key flag is passed to redispatched events if set. @@ -140,7 +140,8 @@ TEST(KeyboardKeyChannelHandlerTest, DeadKeysDoNotCrash) { return true; }); - KeyboardKeyChannelHandler handler(&messenger); + KeyboardKeyChannelHandler handler(&messenger, []() { return true; }); + // Extended key flag is passed to redispatched events if set. handler.KeyboardHook(0xDD, 0x1a, WM_KEYDOWN, 0x8000005E, false, false, [](bool handled) {}); @@ -164,7 +165,8 @@ TEST(KeyboardKeyChannelHandlerTest, EmptyResponsesDoNotCrash) { return true; }); - KeyboardKeyChannelHandler handler(&messenger); + KeyboardKeyChannelHandler handler(&messenger, []() { return true; }); + handler.KeyboardHook(64, kUnhandledScanCode, WM_KEYDOWN, L'b', false, false, [](bool handled) {});