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