diff options
Diffstat (limited to 'platform/osx/os_osx.mm')
-rw-r--r-- | platform/osx/os_osx.mm | 246 |
1 files changed, 183 insertions, 63 deletions
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 939f75859c..4c459772aa 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -88,6 +88,15 @@ static void get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWithM state->set_metakey((p_osx_state & NSEventModifierFlagCommand)); } +static void push_to_key_event_buffer(const OS_OSX::KeyEvent &p_event) { + + Vector<OS_OSX::KeyEvent> &buffer = OS_OSX::singleton->key_event_buffer; + if (OS_OSX::singleton->key_event_pos >= buffer.size()) { + buffer.resize(1 + OS_OSX::singleton->key_event_pos); + } + buffer[OS_OSX::singleton->key_event_pos++] = p_event; +} + static int mouse_x = 0; static int mouse_y = 0; static int prev_mouse_x = 0; @@ -144,6 +153,13 @@ static Vector2 get_mouse_pos(NSEvent *event) { @implementation GodotApplicationDelegate +- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename { + // Note: called before main loop init! + char *utfs = strdup([filename UTF8String]); + OS_OSX::singleton->open_with_filename.parse_utf8(utfs); + return YES; +} + - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { if (OS_OSX::singleton->get_main_loop()) OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST); @@ -407,13 +423,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; - (void)insertText:(id)aString replacementRange:(NSRange)replacementRange { NSEvent *event = [NSApp currentEvent]; - Ref<InputEventKey> k; - k.instance(); - - get_key_modifier_state([event modifierFlags], k); - k->set_pressed(true); - k->set_echo(false); - k->set_scancode(0); NSString *characters; if ([aString isKindOfClass:[NSAttributedString class]]) { @@ -438,8 +447,15 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; if ((codepoint & 0xFF00) == 0xF700) continue; - k->set_unicode(codepoint); - OS_OSX::singleton->push_input(k); + OS_OSX::KeyEvent ke; + + ke.osx_state = [event modifierFlags]; + ke.pressed = true; + ke.echo = false; + ke.scancode = 0; + ke.unicode = codepoint; + + push_to_key_event_buffer(ke); } [self cancelComposition]; } @@ -788,80 +804,87 @@ static int translateKey(unsigned int key) { - (void)keyDown:(NSEvent *)event { - Ref<InputEventKey> k; - k.instance(); - - get_key_modifier_state([event modifierFlags], k); - k->set_pressed(true); - k->set_scancode(latin_keyboard_keycode_convert(translateKey([event keyCode]))); - k->set_echo([event isARepeat]); + //disable raw input in IME mode + if (!imeMode) { + OS_OSX::KeyEvent ke; - NSString *characters = [event characters]; - NSUInteger i, length = [characters length]; + ke.osx_state = [event modifierFlags]; + ke.pressed = true; + ke.echo = [event isARepeat]; + ke.scancode = latin_keyboard_keycode_convert(translateKey([event keyCode])); + ke.unicode = 0; - //disable raw input in IME mode - if (!imeMode) - OS_OSX::singleton->push_input(k); + push_to_key_event_buffer(ke); + } if ((OS_OSX::singleton->im_position.x != 0) && (OS_OSX::singleton->im_position.y != 0)) [self interpretKeyEvents:[NSArray arrayWithObject:event]]; } - (void)flagsChanged:(NSEvent *)event { - Ref<InputEventKey> k; - k.instance(); - int key = [event keyCode]; - int mod = [event modifierFlags]; + if (!imeMode) { + OS_OSX::KeyEvent ke; - if (key == 0x36 || key == 0x37) { - if (mod & NSEventModifierFlagCommand) { - mod &= ~NSEventModifierFlagCommand; - k->set_pressed(true); - } else { - k->set_pressed(false); - } - } else if (key == 0x38 || key == 0x3c) { - if (mod & NSEventModifierFlagShift) { - mod &= ~NSEventModifierFlagShift; - k->set_pressed(true); - } else { - k->set_pressed(false); - } - } else if (key == 0x3a || key == 0x3d) { - if (mod & NSEventModifierFlagOption) { - mod &= ~NSEventModifierFlagOption; - k->set_pressed(true); - } else { - k->set_pressed(false); - } - } else if (key == 0x3b || key == 0x3e) { - if (mod & NSEventModifierFlagControl) { - mod &= ~NSEventModifierFlagControl; - k->set_pressed(true); + ke.echo = false; + + int key = [event keyCode]; + int mod = [event modifierFlags]; + + if (key == 0x36 || key == 0x37) { + if (mod & NSEventModifierFlagCommand) { + mod &= ~NSEventModifierFlagCommand; + ke.pressed = true; + } else { + ke.pressed = false; + } + } else if (key == 0x38 || key == 0x3c) { + if (mod & NSEventModifierFlagShift) { + mod &= ~NSEventModifierFlagShift; + ke.pressed = true; + } else { + ke.pressed = false; + } + } else if (key == 0x3a || key == 0x3d) { + if (mod & NSEventModifierFlagOption) { + mod &= ~NSEventModifierFlagOption; + ke.pressed = true; + } else { + ke.pressed = false; + } + } else if (key == 0x3b || key == 0x3e) { + if (mod & NSEventModifierFlagControl) { + mod &= ~NSEventModifierFlagControl; + ke.pressed = true; + } else { + ke.pressed = false; + } } else { - k->set_pressed(false); + return; } - } else { - return; - } - get_key_modifier_state(mod, k); - k->set_scancode(latin_keyboard_keycode_convert(translateKey(key))); + ke.osx_state = mod; + ke.scancode = latin_keyboard_keycode_convert(translateKey(key)); + ke.unicode = 0; - OS_OSX::singleton->push_input(k); + push_to_key_event_buffer(ke); + } } - (void)keyUp:(NSEvent *)event { - Ref<InputEventKey> k; - k.instance(); + if (!imeMode) { + + OS_OSX::KeyEvent ke; - get_key_modifier_state([event modifierFlags], k); - k->set_pressed(false); - k->set_scancode(latin_keyboard_keycode_convert(translateKey([event keyCode]))); + ke.osx_state = [event modifierFlags]; + ke.pressed = false; + ke.echo = false; + ke.scancode = latin_keyboard_keycode_convert(translateKey([event keyCode])); + ke.unicode = 0; - OS_OSX::singleton->push_input(k); + push_to_key_event_buffer(ke); + } } inline void sendScrollEvent(int button, double factor, int modifierFlags) { @@ -940,6 +963,30 @@ void OS_OSX::set_ime_intermediate_text_callback(ImeCallback p_callback, void *p_ } } +String OS_OSX::get_unique_id() const { + + static String serial_number; + + if (serial_number.empty()) { + io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice")); + CFStringRef serialNumberAsCFString = NULL; + if (platformExpert) { + serialNumberAsCFString = (CFStringRef)IORegistryEntryCreateCFProperty(platformExpert, CFSTR(kIOPlatformSerialNumberKey), kCFAllocatorDefault, 0); + IOObjectRelease(platformExpert); + } + + NSString *serialNumberAsNSString = nil; + if (serialNumberAsCFString) { + serialNumberAsNSString = [NSString stringWithString:(NSString *)serialNumberAsCFString]; + CFRelease(serialNumberAsCFString); + } + + serial_number = [serialNumberAsNSString UTF8String]; + } + + return serial_number; +} + void OS_OSX::set_ime_position(const Point2 &p_pos) { im_position = p_pos; } @@ -1822,6 +1869,12 @@ Size2 OS_OSX::get_window_size() const { return window_size; }; +Size2 OS_OSX::get_real_window_size() const { + + NSRect frame = [window_object frame]; + return Size2(frame.size.width, frame.size.height); +} + void OS_OSX::set_window_size(const Size2 p_size) { Size2 size = p_size; @@ -1913,6 +1966,20 @@ void OS_OSX::move_window_to_foreground() { [window_object orderFrontRegardless]; } +void OS_OSX::set_window_always_on_top(bool p_enabled) { + if (is_window_always_on_top() == p_enabled) + return; + + if (p_enabled) + [window_object setLevel:NSFloatingWindowLevel]; + else + [window_object setLevel:NSNormalWindowLevel]; +} + +bool OS_OSX::is_window_always_on_top() const { + return [window_object level] == NSFloatingWindowLevel; +} + void OS_OSX::request_attention() { [NSApp requestUserAttention:NSCriticalRequest]; @@ -2060,11 +2127,49 @@ void OS_OSX::process_events() { [NSApp sendEvent:event]; } + process_key_events(); [autoreleasePool drain]; autoreleasePool = [[NSAutoreleasePool alloc] init]; } +void OS_OSX::process_key_events() { + + Ref<InputEventKey> k; + for (int i = 0; i < key_event_pos; i++) { + + KeyEvent &ke = key_event_buffer[i]; + + if ((i == 0 && ke.scancode == 0) || (i > 0 && key_event_buffer[i - 1].scancode == 0)) { + k.instance(); + + get_key_modifier_state(ke.osx_state, k); + k->set_pressed(ke.pressed); + k->set_echo(ke.echo); + k->set_scancode(0); + k->set_unicode(ke.unicode); + + push_input(k); + } + if (ke.scancode != 0) { + k.instance(); + + get_key_modifier_state(ke.osx_state, k); + k->set_pressed(ke.pressed); + k->set_echo(ke.echo); + k->set_scancode(ke.scancode); + + if (i + 1 < key_event_pos && key_event_buffer[i + 1].scancode == 0) { + k->set_unicode(key_event_buffer[i + 1].unicode); + } + + push_input(k); + } + } + + key_event_pos = 0; +} + void OS_OSX::push_input(const Ref<InputEvent> &p_event) { Ref<InputEvent> ev = p_event; @@ -2184,6 +2289,7 @@ OS_OSX *OS_OSX::singleton = NULL; OS_OSX::OS_OSX() { + key_event_pos = 0; mouse_mode = OS::MOUSE_MODE_VISIBLE; main_loop = NULL; singleton = this; @@ -2276,6 +2382,20 @@ OS_OSX::OS_OSX() { Vector<Logger *> loggers; loggers.push_back(memnew(OSXTerminalLogger)); _set_logger(memnew(CompositeLogger(loggers))); + + //process application:openFile: event + while (true) { + NSEvent *event = [NSApp + nextEventMatchingMask:NSEventMaskAny + untilDate:[NSDate distantPast] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + + if (event == nil) + break; + + [NSApp sendEvent:event]; + } } bool OS_OSX::_check_internal_feature_support(const String &p_feature) { |