@@ -187,7 +187,7 @@ void KeyboardKeyEmbedderHandler::KeyboardHookImpl(
187
187
const bool is_event_down = action == WM_KEYDOWN || action == WM_SYSKEYDOWN;
188
188
189
189
bool event_key_can_be_repeat = true ;
190
- UpdateLastSeenCritialKey (key, physical_key, sequence_logical_key);
190
+ UpdateLastSeenCriticalKey (key, physical_key, sequence_logical_key);
191
191
// Synchronize the toggled states of critical keys (such as whether CapsLocks
192
192
// is enabled). Toggled states can only be changed upon a down event, so if
193
193
// the recorded toggled state does not match the true state, this function
@@ -197,16 +197,17 @@ void KeyboardKeyEmbedderHandler::KeyboardHookImpl(
197
197
// After this function, all critical keys will have their toggled state
198
198
// updated to the true state, while the critical keys whose toggled state have
199
199
// been changed will be pressed regardless of their true pressed state.
200
- // Updating the pressed state will be done by SynchronizeCritialPressedStates.
201
- SynchronizeCritialToggledStates (key, is_event_down, &event_key_can_be_repeat);
200
+ // Updating the pressed state will be done by SynchronizeCriticalPressedStates.
201
+ SynchronizeCriticalToggledStates (key, is_event_down,
202
+ &event_key_can_be_repeat);
202
203
// Synchronize the pressed states of critical keys (such as whether CapsLocks
203
204
// is pressed).
204
205
//
205
206
// After this function, all critical keys except for the target key will have
206
207
// their toggled state and pressed state matched with their true states. The
207
208
// target key's pressed state will be updated immediately after this.
208
- SynchronizeCritialPressedStates (key, physical_key, is_event_down,
209
- event_key_can_be_repeat);
209
+ SynchronizeCriticalPressedStates (key, physical_key, is_event_down,
210
+ event_key_can_be_repeat);
210
211
211
212
// Reassess the last logical record in case pressingRecords_ was modified
212
213
// by the above synchronization methods.
@@ -317,8 +318,8 @@ void KeyboardKeyEmbedderHandler::KeyboardHookImpl(
317
318
// received despite that GetKeyState says that CapsLock is not pressed. In
318
319
// such case, post-event synchronization will synthesize a CapsLock up event
319
320
// after the main event.
320
- SynchronizeCritialPressedStates (key, physical_key, is_event_down,
321
- event_key_can_be_repeat);
321
+ SynchronizeCriticalPressedStates (key, physical_key, is_event_down,
322
+ event_key_can_be_repeat);
322
323
}
323
324
324
325
void KeyboardKeyEmbedderHandler::KeyboardHook (
@@ -349,7 +350,7 @@ void KeyboardKeyEmbedderHandler::KeyboardHook(
349
350
}
350
351
}
351
352
352
- void KeyboardKeyEmbedderHandler::UpdateLastSeenCritialKey (
353
+ void KeyboardKeyEmbedderHandler::UpdateLastSeenCriticalKey (
353
354
int virtual_key,
354
355
uint64_t physical_key,
355
356
uint64_t logical_key) {
@@ -360,7 +361,7 @@ void KeyboardKeyEmbedderHandler::UpdateLastSeenCritialKey(
360
361
}
361
362
}
362
363
363
- void KeyboardKeyEmbedderHandler::SynchronizeCritialToggledStates (
364
+ void KeyboardKeyEmbedderHandler::SynchronizeCriticalToggledStates (
364
365
int event_virtual_key,
365
366
bool is_event_down,
366
367
bool * event_key_can_be_repeat) {
@@ -415,7 +416,7 @@ void KeyboardKeyEmbedderHandler::SynchronizeCritialToggledStates(
415
416
}
416
417
}
417
418
418
- void KeyboardKeyEmbedderHandler::SynchronizeCritialPressedStates (
419
+ void KeyboardKeyEmbedderHandler::SynchronizeCriticalPressedStates (
419
420
int event_virtual_key,
420
421
int event_physical_key,
421
422
bool is_event_down,
@@ -492,6 +493,72 @@ void KeyboardKeyEmbedderHandler::SynchronizeCritialPressedStates(
492
493
}
493
494
}
494
495
496
+ void KeyboardKeyEmbedderHandler::SyncModifiersIfNeeded (int modifiers_state) {
497
+ // TODO(bleroux): consider exposing these constants in flutter_key_map.g.cc?
498
+ const uint64_t physical_shift_left =
499
+ windowsToPhysicalMap_.at (kScanCodeShiftLeft );
500
+ const uint64_t physical_shift_right =
501
+ windowsToPhysicalMap_.at (kScanCodeShiftRight );
502
+ const uint64_t logical_shift_left =
503
+ windowsToLogicalMap_.at (kKeyCodeShiftLeft );
504
+ const uint64_t physical_control_left =
505
+ windowsToPhysicalMap_.at (kScanCodeControlLeft );
506
+ const uint64_t physical_control_right =
507
+ windowsToPhysicalMap_.at (kScanCodeControlRight );
508
+ const uint64_t logical_control_left =
509
+ windowsToLogicalMap_.at (kKeyCodeControlLeft );
510
+
511
+ bool shift_pressed = (modifiers_state & kShift ) != 0 ;
512
+ SynthesizeIfNeeded (physical_shift_left, physical_shift_right,
513
+ logical_shift_left, shift_pressed);
514
+ bool control_pressed = (modifiers_state & kControl ) != 0 ;
515
+ SynthesizeIfNeeded (physical_control_left, physical_control_right,
516
+ logical_control_left, control_pressed);
517
+ }
518
+
519
+ void KeyboardKeyEmbedderHandler::SynthesizeIfNeeded (uint64_t physical_left,
520
+ uint64_t physical_right,
521
+ uint64_t logical_left,
522
+ bool is_pressed) {
523
+ auto pressing_record_iter_left = pressingRecords_.find (physical_left);
524
+ bool left_pressed = pressing_record_iter_left != pressingRecords_.end ();
525
+ auto pressing_record_iter_right = pressingRecords_.find (physical_right);
526
+ bool right_pressed = pressing_record_iter_right != pressingRecords_.end ();
527
+ bool already_pressed = left_pressed || right_pressed;
528
+ bool synthesize_down = is_pressed && !already_pressed;
529
+ bool synthesize_up = !is_pressed && already_pressed;
530
+
531
+ if (synthesize_down) {
532
+ SendSynthesizeDownEvent (physical_left, logical_left);
533
+ }
534
+
535
+ if (synthesize_up && left_pressed) {
536
+ uint64_t known_logical = pressing_record_iter_left->second ;
537
+ SendSynthesizeUpEvent (physical_left, known_logical);
538
+ }
539
+
540
+ if (synthesize_up && right_pressed) {
541
+ uint64_t known_logical = pressing_record_iter_right->second ;
542
+ SendSynthesizeUpEvent (physical_right, known_logical);
543
+ }
544
+ }
545
+
546
+ void KeyboardKeyEmbedderHandler::SendSynthesizeDownEvent (uint64_t physical,
547
+ uint64_t logical) {
548
+ SendEvent (
549
+ SynthesizeSimpleEvent (kFlutterKeyEventTypeDown , physical, logical, " " ),
550
+ nullptr , nullptr );
551
+ pressingRecords_[physical] = logical;
552
+ };
553
+
554
+ void KeyboardKeyEmbedderHandler::SendSynthesizeUpEvent (uint64_t physical,
555
+ uint64_t logical) {
556
+ SendEvent (
557
+ SynthesizeSimpleEvent (kFlutterKeyEventTypeUp , physical, logical, " " ),
558
+ nullptr , nullptr );
559
+ pressingRecords_.erase (physical);
560
+ };
561
+
495
562
void KeyboardKeyEmbedderHandler::HandleResponse (bool handled, void * user_data) {
496
563
PendingResponse* pending = reinterpret_cast <PendingResponse*>(user_data);
497
564
auto callback = std::move (pending->callback );
@@ -516,8 +583,6 @@ void KeyboardKeyEmbedderHandler::InitCriticalKeys(
516
583
};
517
584
};
518
585
519
- // TODO(dkwingsmt): Consider adding more critical keys here.
520
- // https://github.com/flutter/flutter/issues/76736
521
586
critical_keys_.emplace (VK_LSHIFT,
522
587
createCheckedKey (VK_LSHIFT, false , true , false ));
523
588
critical_keys_.emplace (VK_RSHIFT,
@@ -532,7 +597,6 @@ void KeyboardKeyEmbedderHandler::InitCriticalKeys(
532
597
createCheckedKey (VK_RMENU, true , true , false ));
533
598
critical_keys_.emplace (VK_LWIN, createCheckedKey (VK_LWIN, true , true , false ));
534
599
critical_keys_.emplace (VK_RWIN, createCheckedKey (VK_RWIN, true , true , false ));
535
-
536
600
critical_keys_.emplace (VK_CAPITAL,
537
601
createCheckedKey (VK_CAPITAL, false , true , true ));
538
602
critical_keys_.emplace (VK_SCROLL,
0 commit comments