Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Migrate keyboard_key_handler_unittests to keyboard_win32_unittests #30615

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ std::unique_ptr<FlutterWindowsEngine> GetTestEngine() {
[](FLUTTER_API_SYMBOL(FlutterEngine) engine, bool enabled) {
return kSuccess;
};
MockEmbedderApiForKeyboard(
modifier, [] { return false; },
[](const FlutterKeyEvent* event) { return false; });

MockEmbedderApiForKeyboard(modifier,
std::make_shared<MockKeyResponseController>());

engine->RunWithEntrypoint(nullptr);
return engine;
Expand Down
26 changes: 13 additions & 13 deletions shell/platform/windows/flutter_window_win32_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,10 @@ class TestFlutterWindowsView : public FlutterWindowsView {
public:
TestFlutterWindowsView(std::unique_ptr<WindowBindingHandler> window_binding,
WPARAM virtual_key,
bool is_printable = true,
bool is_syskey = false)
bool is_printable = true)
: FlutterWindowsView(std::move(window_binding)),
virtual_key_(virtual_key),
is_printable_(is_printable),
is_syskey_(is_syskey) {}
is_printable_(is_printable) {}

SpyKeyboardKeyHandler* key_event_handler;
SpyTextInputPlugin* text_input_plugin;
Expand Down Expand Up @@ -269,8 +267,7 @@ class TestFlutterWindowsView : public FlutterWindowsView {
// "SendInput" directly to the window.
const KEYBDINPUT kbdinput = pInputs->ki;
const bool is_key_up = kbdinput.dwFlags & KEYEVENTF_KEYUP;
const UINT message = is_key_up ? (is_syskey_ ? WM_SYSKEYUP : WM_KEYUP)
: (is_syskey_ ? WM_SYSKEYDOWN : WM_KEYDOWN);
const UINT message = is_key_up ? WM_KEYUP : WM_KEYDOWN;

const LPARAM lparam = CreateKeyEventLparam(
kbdinput.wScan, kbdinput.dwFlags & KEYEVENTF_EXTENDEDKEY, is_key_up);
Expand All @@ -295,7 +292,6 @@ class TestFlutterWindowsView : public FlutterWindowsView {
std::vector<Win32Message> pending_responds_;
WPARAM virtual_key_;
bool is_printable_;
bool is_syskey_;
};

// The static value to return as the "handled" value from the framework for key
Expand All @@ -315,9 +311,12 @@ std::unique_ptr<FlutterWindowsEngine> GetTestEngine() {
auto engine = std::make_unique<FlutterWindowsEngine>(project);

EngineModifier modifier(engine.get());
MockEmbedderApiForKeyboard(
modifier, [] { return test_response; },
[](const FlutterKeyEvent* event) { return false; });
auto key_response_controller = std::make_shared<MockKeyResponseController>();
key_response_controller->SetChannelResponse(
[](MockKeyResponseController::ResponseCallback callback) {
callback(test_response);
});
MockEmbedderApiForKeyboard(modifier, key_response_controller);

return engine;
}
Expand Down Expand Up @@ -392,8 +391,7 @@ TEST(FlutterWindowWin32Test, SystemKeyDownPropagation) {
auto window_binding_handler =
std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
TestFlutterWindowsView flutter_windows_view(
std::move(window_binding_handler), virtual_key, false /* is_printable */,
true /* is_syskey */);
std::move(window_binding_handler), virtual_key, false /* is_printable */);
win32window.SetView(&flutter_windows_view);
LPARAM lparam = CreateKeyEventLparam(scan_code, false, false);

Expand All @@ -406,9 +404,11 @@ TEST(FlutterWindowWin32Test, SystemKeyDownPropagation) {
false /* extended */, _))
.Times(2)
.RetiresOnSaturation();
// Syskey events are not redispatched, so TextInputPlugin, which relies on
// them to receive events, no longer works.
EXPECT_CALL(*flutter_windows_view.text_input_plugin,
KeyboardHook(_, _, _, _, _, _))
.Times(1)
.Times(0)
.RetiresOnSaturation();
EXPECT_CALL(*flutter_windows_view.key_event_handler, TextHook(_)).Times(0);
EXPECT_CALL(*flutter_windows_view.text_input_plugin, TextHook(_)).Times(0);
Expand Down
19 changes: 12 additions & 7 deletions shell/platform/windows/flutter_windows_view_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,22 @@ std::unique_ptr<FlutterWindowsEngine> GetTestEngine() {
auto engine = std::make_unique<FlutterWindowsEngine>(project);

EngineModifier modifier(engine.get());
MockEmbedderApiForKeyboard(
modifier,
[] {

auto key_response_controller = std::make_shared<MockKeyResponseController>();
key_response_controller->SetChannelResponse(
[](MockKeyResponseController::ResponseCallback callback) {
key_event_logs.push_back(kKeyEventFromChannel);
return test_response;
},
[](const FlutterKeyEvent* event) {
callback(test_response);
});
key_response_controller->SetEmbedderResponse(
[](const FlutterKeyEvent* event,
MockKeyResponseController::ResponseCallback callback) {
key_event_logs.push_back(kKeyEventFromEmbedder);
return test_response;
callback(test_response);
});

MockEmbedderApiForKeyboard(modifier, key_response_controller);

engine->RunWithEntrypoint(nullptr);
return engine;
}
Expand Down
4 changes: 3 additions & 1 deletion shell/platform/windows/keyboard_key_embedder_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,9 @@ void KeyboardKeyEmbedderHandler::KeyboardHookImpl(
if (eventual_logical_record != 0) {
pressingRecords_[physical_key] = eventual_logical_record;
} else {
pressingRecords_.erase(last_logical_record_iter);
auto record_iter = pressingRecords_.find(physical_key);
assert(record_iter != pressingRecords_.end());
pressingRecords_.erase(record_iter);
}

if (result_logical_key == VK_PROCESSKEY) {
Expand Down
19 changes: 12 additions & 7 deletions shell/platform/windows/keyboard_key_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,9 @@ void KeyboardKeyHandler::DispatchEvent(const PendingEvent& event) {
#else
char32_t character = event.character;

if (event.action == WM_SYSKEYDOWN || event.action == WM_SYSKEYUP) {
return;
}
assert(event.action != WM_SYSKEYDOWN && event.action != WM_SYSKEYUP &&
"Unexpectedly dispatching a SYS event. SYS events can't be dispatched "
"and should have been prevented in earlier code.");

INPUT input_event{
.type = INPUT_KEYBOARD,
Expand Down Expand Up @@ -272,13 +272,18 @@ void KeyboardKeyHandler::ResolvePendingEvent(uint64_t sequence_id,
if (event.unreplied == 0) {
std::unique_ptr<PendingEvent> event_ptr = std::move(*iter);
pending_responds_.erase(iter);
// Don't dispatch handled events or dead key events.
// Don't dispatch handled events, and also ignore dead key events and
// sys events.
//
// Redispatching dead keys events makes Win32 ignore the dead key state
// and redispatches a normal character without combining it with the
// next letter key.
const bool should_redispatch =
!event_ptr->any_handled && !_IsDeadKey(event_ptr->character);
// next letter key. Redispatching sys events is impossible due to
// the limitation of |SendInput|.
const bool is_syskey =
event.action == WM_SYSKEYDOWN || event.action == WM_SYSKEYUP;
const bool should_redispatch = !event_ptr->any_handled &&
!_IsDeadKey(event_ptr->character) &&
!is_syskey;
if (should_redispatch) {
RedispatchEvent(std::move(event_ptr));
}
Expand Down
5 changes: 1 addition & 4 deletions shell/platform/windows/keyboard_manager_win32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,7 @@ bool KeyboardManagerWin32::HandleMessage(UINT const message,
keyCode = ResolveKeyCode(keyCode, extended, scancode);
const bool was_down = lparam & 0x40000000;
bool is_syskey = message == WM_SYSKEYDOWN || message == WM_SYSKEYUP;
const int action = is_keydown_message
? (is_syskey ? WM_SYSKEYDOWN : WM_KEYDOWN)
: (is_syskey ? WM_SYSKEYUP : WM_KEYUP);
if (window_delegate_->OnKey(keyCode, scancode, action, 0, extended,
if (window_delegate_->OnKey(keyCode, scancode, message, 0, extended,
was_down)) {
// For system keys, always pass them to the default WndProc so that keys
// like the ALT-TAB or Kanji switches are processed correctly.
Expand Down
Loading