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

Commit a23522d

Browse files
committed
Impl & test
Remove unused Better doc
1 parent f16e757 commit a23522d

3 files changed

Lines changed: 35 additions & 7 deletions

File tree

shell/platform/windows/keyboard_key_embedder_handler.cc

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ void KeyboardKeyEmbedderHandler::KeyboardHookImpl(
186186

187187
const bool is_event_down = action == WM_KEYDOWN || action == WM_SYSKEYDOWN;
188188

189+
bool event_key_can_be_repeat = true;
189190
UpdateLastSeenCritialKey(key, physical_key, sequence_logical_key);
190191
// Synchronize the toggled states of critical keys (such as whether CapsLocks
191192
// is enabled). Toggled states can only be changed upon a down event, so if
@@ -197,14 +198,14 @@ void KeyboardKeyEmbedderHandler::KeyboardHookImpl(
197198
// updated to the true state, while the critical keys whose toggled state have
198199
// been changed will be pressed regardless of their true pressed state.
199200
// Updating the pressed state will be done by SynchronizeCritialPressedStates.
200-
SynchronizeCritialToggledStates(key, is_event_down);
201+
SynchronizeCritialToggledStates(key, is_event_down, &event_key_can_be_repeat);
201202
// Synchronize the pressed states of critical keys (such as whether CapsLocks
202203
// is pressed).
203204
//
204205
// After this function, all critical keys except for the target key will have
205206
// their toggled state and pressed state matched with their true states. The
206207
// target key's pressed state will be updated immediately after this.
207-
SynchronizeCritialPressedStates(key, physical_key, is_event_down);
208+
SynchronizeCritialPressedStates(key, physical_key, is_event_down, event_key_can_be_repeat);
208209

209210
// The resulting event's `type`.
210211
FlutterKeyEventType type;
@@ -340,7 +341,8 @@ void KeyboardKeyEmbedderHandler::UpdateLastSeenCritialKey(
340341

341342
void KeyboardKeyEmbedderHandler::SynchronizeCritialToggledStates(
342343
int event_virtual_key,
343-
bool is_event_down) {
344+
bool is_event_down,
345+
bool* event_key_can_be_repeat) {
344346
// NowState ----------------> PreEventState --------------> TrueState
345347
// Synchronization Event
346348
for (auto& kv : critical_keys_) {
@@ -385,6 +387,7 @@ void KeyboardKeyEmbedderHandler::SynchronizeCritialToggledStates(
385387
key_info.physical_key,
386388
key_info.logical_key, empty_character),
387389
nullptr, nullptr);
390+
*event_key_can_be_repeat = false;
388391
}
389392
key_info.toggled_on = true_toggled;
390393
}
@@ -394,7 +397,8 @@ void KeyboardKeyEmbedderHandler::SynchronizeCritialToggledStates(
394397
void KeyboardKeyEmbedderHandler::SynchronizeCritialPressedStates(
395398
int event_virtual_key,
396399
int event_physical_key,
397-
bool is_event_down) {
400+
bool is_event_down,
401+
bool event_key_can_be_repeat) {
398402
// During an incoming event, there might be a synthesized Flutter event for
399403
// each key of each pressing goal, followed by an eventual main Flutter
400404
// event.
@@ -424,8 +428,18 @@ void KeyboardKeyEmbedderHandler::SynchronizeCritialPressedStates(
424428
if (is_event_down) {
425429
// For down events, this key is the event key if they have the same
426430
// virtual key, because virtual key represents "functionality."
431+
//
432+
// In that case, normally Flutter should synthesize nothing since the
433+
// resulting event can adapt to the current state by flexing between a
434+
// down and a repeat event. However, in certain cases (when Flutter has
435+
// just synchronized the key's toggling state) the event must not be a
436+
// repeat event.
427437
if (virtual_key == event_virtual_key) {
428-
pre_event_pressed = false;
438+
if (event_key_can_be_repeat) {
439+
continue;
440+
} else {
441+
pre_event_pressed = false;
442+
}
429443
}
430444
} else {
431445
// For up events, this key is the event key if they have the same

shell/platform/windows/keyboard_key_embedder_handler.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,14 @@ class KeyboardKeyEmbedderHandler
115115
// Check each key's state from |get_key_state_| and synthesize events
116116
// if their toggling states have been desynchronized.
117117
void SynchronizeCritialToggledStates(int event_virtual_key,
118-
bool is_event_down);
118+
bool is_event_down,
119+
bool* event_key_can_be_repeat);
119120
// Check each key's state from |get_key_state_| and synthesize events
120121
// if their pressing states have been desynchronized.
121122
void SynchronizeCritialPressedStates(int event_virtual_key,
122123
int event_physical_key,
123-
bool is_event_down);
124+
bool is_event_down,
125+
bool event_key_can_be_repeat);
124126

125127
// Wraps perform_send_event_ with state tracking. Use this instead of
126128
// |perform_send_event_| to send events to the framework.

shell/platform/windows/keyboard_win32_unittests.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,18 @@ TEST(KeyboardTest, ShiftLeftUnhandled) {
697697
clear_key_calls();
698698
EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
699699

700+
// Hold ShiftLeft
701+
tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
702+
WmKeyDownInfo{VK_SHIFT, kScanCodeShiftLeft, kNotExtended, kWasDown}.Build(
703+
kWmResultZero)});
704+
705+
EXPECT_EQ(key_calls.size(), 1);
706+
EXPECT_CALL_IS_EVENT(key_calls[0], kFlutterKeyEventTypeRepeat,
707+
kPhysicalShiftLeft, kLogicalShiftLeft, "",
708+
kNotSynthesized);
709+
clear_key_calls();
710+
EXPECT_EQ(tester.RedispatchedMessageCountAndClear(), 1);
711+
700712
// Release ShiftLeft
701713
tester.InjectKeyboardChanges(std::vector<KeyboardChange>{
702714
KeyStateChange{VK_LSHIFT, false, true},

0 commit comments

Comments
 (0)