diff options
Diffstat (limited to 'platform/osx')
-rw-r--r-- | platform/osx/SCsub | 3 | ||||
-rw-r--r-- | platform/osx/detect.py | 3 | ||||
-rw-r--r-- | platform/osx/godot_main_osx.mm | 11 | ||||
-rw-r--r-- | platform/osx/os_osx.h | 19 | ||||
-rw-r--r-- | platform/osx/os_osx.mm | 246 |
5 files changed, 216 insertions, 66 deletions
diff --git a/platform/osx/SCsub b/platform/osx/SCsub index 029e3d808c..5efe2d0b22 100644 --- a/platform/osx/SCsub +++ b/platform/osx/SCsub @@ -10,6 +10,7 @@ def make_debug(target, source, env): os.system(mpprefix + '/libexec/llvm-' + mpclangver + '/bin/llvm-dsymutil %s -o %s.dSYM' % (target[0], target[0])) else: os.system('dsymutil %s -o %s.dSYM' % (target[0], target[0])) + os.system('strip -u -r %s' % (target[0])) files = [ 'crash_handler_osx.mm', @@ -23,6 +24,6 @@ files = [ prog = env.add_program('#bin/godot', files) -if env["debug_symbols"] == "full" or env["debug_symbols"] == "yes": +if (env["debug_symbols"] == "full" or env["debug_symbols"] == "yes") and env["separate_debug_symbols"]: env.AddPostAction(prog, make_debug) diff --git a/platform/osx/detect.py b/platform/osx/detect.py index bb601abd40..5f33100e42 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -19,11 +19,12 @@ def can_build(): def get_opts(): - from SCons.Variables import EnumVariable + from SCons.Variables import BoolVariable, EnumVariable return [ ('osxcross_sdk', 'OSXCross SDK version', 'darwin14'), EnumVariable('debug_symbols', 'Add debug symbols to release version', 'yes', ('yes', 'no', 'full')), + BoolVariable('separate_debug_symbols', 'Create a separate file with the debug symbols', False), ] diff --git a/platform/osx/godot_main_osx.mm b/platform/osx/godot_main_osx.mm index 9d1a5566c9..6ccbaf896b 100644 --- a/platform/osx/godot_main_osx.mm +++ b/platform/osx/godot_main_osx.mm @@ -82,8 +82,17 @@ int main(int argc, char **argv) { #endif OS_OSX os; + Error err; + + if (os.open_with_filename != "") { + char *argv_c = (char *)malloc(os.open_with_filename.utf8().size()); + memcpy(argv_c, os.open_with_filename.utf8().get_data(), os.open_with_filename.utf8().size()); + err = Main::setup(argv[0], 1, &argv_c); + free(argv_c); + } else { + err = Main::setup(argv[0], argc - first_arg, &argv[first_arg]); + } - Error err = Main::setup(argv[0], argc - first_arg, &argv[first_arg]); if (err != OK) return 255; diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 3648d41604..aa8db8f300 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -52,6 +52,17 @@ class OS_OSX : public OS_Unix { public: + struct KeyEvent { + unsigned int osx_state; + bool pressed; + bool echo; + uint32_t scancode; + uint32_t unicode; + }; + + Vector<KeyEvent> key_event_buffer; + int key_event_pos; + bool force_quit; // rasterizer seems to no longer be given to visual server, its using GLES3 directly? //Rasterizer *rasterizer; @@ -72,6 +83,7 @@ public: CGEventSourceRef eventSource; void process_events(); + void process_key_events(); void *framework; // pthread_key_t current; @@ -99,6 +111,8 @@ public: Size2 window_size; Rect2 restore_rect; + String open_with_filename; + Point2 im_position; ImeCallback im_callback; void *im_target; @@ -153,6 +167,7 @@ public: virtual void set_window_title(const String &p_title); virtual Size2 get_window_size() const; + virtual Size2 get_real_window_size() const; virtual void set_icon(const Ref<Image> &p_icon); @@ -207,6 +222,8 @@ public: virtual bool is_window_minimized() const; virtual void set_window_maximized(bool p_enabled); virtual bool is_window_maximized() const; + virtual void set_window_always_on_top(bool p_enabled); + virtual bool is_window_always_on_top() const; virtual void request_attention(); virtual String get_joy_guid(int p_device) const; @@ -215,6 +232,8 @@ public: virtual void set_ime_position(const Point2 &p_pos); virtual void set_ime_intermediate_text_callback(ImeCallback p_callback, void *p_inp); + virtual String get_unique_id() const; + virtual OS::PowerState get_power_state(); virtual int get_power_seconds_left(); virtual int get_power_percent_left(); 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) { |