|
31 | 31 | #import "godot_application_delegate.h" |
32 | 32 |
|
33 | 33 | #import "display_server_macos.h" |
| 34 | +#import "key_mapping_macos.h" |
34 | 35 | #import "native_menu_macos.h" |
35 | 36 | #import "os_macos.h" |
36 | 37 |
|
37 | 38 | #import "main/main.h" |
38 | 39 |
|
| 40 | +#import <Carbon/Carbon.h> |
| 41 | + |
39 | 42 | @interface GodotApplicationDelegate () |
40 | 43 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context; |
41 | 44 | - (void)accessibilityDisplayOptionsChange:(NSNotification *)notification; |
@@ -226,10 +229,61 @@ - (void)applicationDidResignActive:(NSNotification *)notification { |
226 | 229 | } |
227 | 230 | } |
228 | 231 |
|
| 232 | +static const CGKeyCode modifiers[8] = { |
| 233 | + kVK_Command, |
| 234 | + kVK_RightCommand, |
| 235 | + kVK_Shift, |
| 236 | + kVK_RightShift, |
| 237 | + kVK_Option, |
| 238 | + kVK_RightOption, |
| 239 | + kVK_Control, |
| 240 | + kVK_RightControl, |
| 241 | +}; |
| 242 | + |
| 243 | +// The list of modifier flags we care about for raising pressed events when the application becomes active. |
| 244 | +constexpr static NSEventModifierFlags FLAGS = NSEventModifierFlagCommand | NSEventModifierFlagShift | NSEventModifierFlagOption | NSEventModifierFlagControl; |
| 245 | + |
229 | 246 | - (void)applicationDidBecomeActive:(NSNotification *)notification { |
230 | 247 | if (os_mac->get_main_loop()) { |
231 | 248 | os_mac->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN); |
232 | 249 | } |
| 250 | + DisplayServerMacOS *ds = Object::cast_to<DisplayServerMacOS>(DisplayServer::get_singleton()); |
| 251 | + if (!ds) { |
| 252 | + return; |
| 253 | + } |
| 254 | + Input *input = Input::get_singleton(); |
| 255 | + if (!input) { |
| 256 | + return; |
| 257 | + } |
| 258 | + |
| 259 | + // Poll the modifier keys and submit pressed events if they are down when the application becomes active. |
| 260 | + int mod = NSEvent.modifierFlags; |
| 261 | + if ((mod & FLAGS) == 0) { |
| 262 | + // No flags we care about. |
| 263 | + return; |
| 264 | + } |
| 265 | + |
| 266 | + DisplayServer::WindowID window_id = ds->get_focused_window(); |
| 267 | + NSEventModifierFlags flags = static_cast<NSEventModifierFlags>(mod); |
| 268 | + |
| 269 | + for (const CGKeyCode key : modifiers) { |
| 270 | + bool is_down = CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, key); |
| 271 | + if (likely(!is_down)) { |
| 272 | + continue; |
| 273 | + } |
| 274 | + Ref<InputEventKey> ke; |
| 275 | + ke.instantiate(); |
| 276 | + |
| 277 | + ke->set_window_id(window_id); |
| 278 | + ke->set_echo(false); |
| 279 | + ke->set_pressed(true); |
| 280 | + ds->get_key_modifier_state(flags, ke); |
| 281 | + ke->set_keycode(KeyMappingMacOS::remap_key(key, mod, false)); |
| 282 | + ke->set_physical_keycode(KeyMappingMacOS::translate_key(key)); |
| 283 | + ke->set_key_label(KeyMappingMacOS::remap_key(key, mod, true)); |
| 284 | + ke->set_location(KeyMappingMacOS::translate_location(key)); |
| 285 | + input->parse_input_event(ke); |
| 286 | + } |
233 | 287 | } |
234 | 288 |
|
235 | 289 | - (void)globalMenuCallback:(id)sender { |
|
0 commit comments