Skip to content

Commit 7d46f0f

Browse files
committed
Merge pull request godotengine#106365 from stuartcarnie/sgc_macos_modifier_state_focus
macOS: Send initial modifier keys as input events
2 parents fdde7c3 + 9a631d1 commit 7d46f0f

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

platform/macos/godot_application_delegate.mm

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,14 @@
3131
#import "godot_application_delegate.h"
3232

3333
#import "display_server_macos.h"
34+
#import "key_mapping_macos.h"
3435
#import "native_menu_macos.h"
3536
#import "os_macos.h"
3637

3738
#import "main/main.h"
3839

40+
#import <Carbon/Carbon.h>
41+
3942
@interface GodotApplicationDelegate ()
4043
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
4144
- (void)accessibilityDisplayOptionsChange:(NSNotification *)notification;
@@ -226,10 +229,61 @@ - (void)applicationDidResignActive:(NSNotification *)notification {
226229
}
227230
}
228231

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+
229246
- (void)applicationDidBecomeActive:(NSNotification *)notification {
230247
if (os_mac->get_main_loop()) {
231248
os_mac->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN);
232249
}
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+
}
233287
}
234288

235289
- (void)globalMenuCallback:(id)sender {

0 commit comments

Comments
 (0)