diff options
Diffstat (limited to 'platform/osx')
-rw-r--r-- | platform/osx/SCsub | 3 | ||||
-rw-r--r-- | platform/osx/crash_handler_osx.h | 1 | ||||
-rw-r--r-- | platform/osx/crash_handler_osx.mm | 1 | ||||
-rw-r--r-- | platform/osx/detect.py | 7 | ||||
-rw-r--r-- | platform/osx/dir_access_osx.h | 1 | ||||
-rw-r--r-- | platform/osx/dir_access_osx.mm | 1 | ||||
-rw-r--r-- | platform/osx/export/export.cpp | 45 | ||||
-rw-r--r-- | platform/osx/export/export.h | 1 | ||||
-rw-r--r-- | platform/osx/godot_main_osx.mm | 12 | ||||
-rw-r--r-- | platform/osx/joypad_osx.cpp | 1 | ||||
-rw-r--r-- | platform/osx/joypad_osx.h | 1 | ||||
-rw-r--r-- | platform/osx/os_osx.h | 27 | ||||
-rw-r--r-- | platform/osx/os_osx.mm | 532 | ||||
-rw-r--r-- | platform/osx/platform_config.h | 1 | ||||
-rw-r--r-- | platform/osx/sem_osx.cpp | 1 | ||||
-rw-r--r-- | platform/osx/sem_osx.h | 1 |
16 files changed, 472 insertions, 164 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/crash_handler_osx.h b/platform/osx/crash_handler_osx.h index 51e0a3ffcb..5d93afb22d 100644 --- a/platform/osx/crash_handler_osx.h +++ b/platform/osx/crash_handler_osx.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef CRASH_HANDLER_OSX_H #define CRASH_HANDLER_OSX_H diff --git a/platform/osx/crash_handler_osx.mm b/platform/osx/crash_handler_osx.mm index c4b5204e1a..d757674a9b 100644 --- a/platform/osx/crash_handler_osx.mm +++ b/platform/osx/crash_handler_osx.mm @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "main/main.h" #include "os_osx.h" #include "project_settings.h" diff --git a/platform/osx/detect.py b/platform/osx/detect.py index 2e686fbee4..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), ] @@ -76,7 +77,7 @@ def configure(env): mpprefix = os.environ.get("MACPORTS_PREFIX", "/opt/local") mpclangver = env["macports_clang"] env["CC"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/clang" - env["LD"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/clang++" + env["LINK"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/clang++" env["CXX"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/clang++" env['AR'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ar" env['RANLIB'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ranlib" @@ -110,7 +111,7 @@ def configure(env): if (env["CXX"] == "clang++"): env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND']) env["CC"] = "clang" - env["LD"] = "clang++" + env["LINK"] = "clang++" ## Dependencies diff --git a/platform/osx/dir_access_osx.h b/platform/osx/dir_access_osx.h index eec3016eaa..e01ff2fe4d 100644 --- a/platform/osx/dir_access_osx.h +++ b/platform/osx/dir_access_osx.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef DIR_ACCESS_OSX_H #define DIR_ACCESS_OSX_H diff --git a/platform/osx/dir_access_osx.mm b/platform/osx/dir_access_osx.mm index a187083dd1..cf66cab060 100644 --- a/platform/osx/dir_access_osx.mm +++ b/platform/osx/dir_access_osx.mm @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "dir_access_osx.h" #if defined(UNIX_ENABLED) || defined(LIBC_FILEIO_ENABLED) diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index 657a899367..c4efa1f0ff 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -359,6 +359,11 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p } if (err == OK) { + print_line("Creating " + tmp_app_path_name + "/Contents/Frameworks"); + err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/Frameworks"); + } + + if (err == OK) { print_line("Creating " + tmp_app_path_name + "/Contents/Resources"); err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/Resources"); } @@ -502,10 +507,23 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p if (use_dmg()) { String pack_path = tmp_app_path_name + "/Contents/Resources/" + pkg_name + ".pck"; - err = save_pack(p_preset, pack_path); + Vector<SharedObject> shared_objects; + Error err = save_pack(p_preset, pack_path, &shared_objects); // see if we can code sign our new package String identity = p_preset->get("codesign/identity"); + + if (err == OK) { + DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + for (int i = 0; i < shared_objects.size(); i++) { + da->copy(shared_objects[i].path, tmp_app_path_name + "/Contents/Frameworks/" + shared_objects[i].path.get_file()); + if (err == OK && identity != "") { + err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Frameworks/" + shared_objects[i].path.get_file()); + } + } + memdelete(da); + } + if (err == OK && identity != "") { ep.step("Code signing bundle", 2); @@ -541,7 +559,9 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p } else { String pack_path = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".pck"); - Error err = save_pack(p_preset, pack_path); + + Vector<SharedObject> shared_objects; + Error err = save_pack(p_preset, pack_path, &shared_objects); if (err == OK) { zipOpenNewFileInZip(dst_pkg_zip, @@ -567,11 +587,32 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p break; zipWriteInFileInZip(dst_pkg_zip, buf, r); } + zipCloseFileInZip(dst_pkg_zip); memdelete(pf); } else { err = ERR_CANT_OPEN; } + + //add shared objects + for (int i = 0; i < shared_objects.size(); i++) { + Vector<uint8_t> file = FileAccess::get_file_as_array(shared_objects[i].path); + ERR_CONTINUE(file.empty()); + + zipOpenNewFileInZip(dst_pkg_zip, + (pkg_name + ".app/Contents/Frameworks/").plus_file(shared_objects[i].path.get_file()).utf8().get_data(), + NULL, + NULL, + 0, + NULL, + 0, + NULL, + Z_DEFLATED, + Z_DEFAULT_COMPRESSION); + + zipWriteInFileInZip(dst_pkg_zip, file.ptr(), file.size()); + zipCloseFileInZip(dst_pkg_zip); + } } } } diff --git a/platform/osx/export/export.h b/platform/osx/export/export.h index ccb96022f9..08294fc33c 100644 --- a/platform/osx/export/export.h +++ b/platform/osx/export/export.h @@ -27,4 +27,5 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + void register_osx_exporter(); diff --git a/platform/osx/godot_main_osx.mm b/platform/osx/godot_main_osx.mm index 156b4c02f2..6ccbaf896b 100644 --- a/platform/osx/godot_main_osx.mm +++ b/platform/osx/godot_main_osx.mm @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "main/main.h" #include "os_osx.h" @@ -81,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/joypad_osx.cpp b/platform/osx/joypad_osx.cpp index bc65aa8149..20ceadca9d 100644 --- a/platform/osx/joypad_osx.cpp +++ b/platform/osx/joypad_osx.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "joypad_osx.h" #include <machine/endian.h> diff --git a/platform/osx/joypad_osx.h b/platform/osx/joypad_osx.h index 78ee4581d5..addbefc5ad 100644 --- a/platform/osx/joypad_osx.h +++ b/platform/osx/joypad_osx.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef JOYPADOSX_H #define JOYPADOSX_H diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index a24bf6c0bc..aa8db8f300 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef OS_OSX_H #define OS_OSX_H @@ -41,6 +42,7 @@ #include "servers/visual/rasterizer.h" #include "servers/visual/visual_server_wrap_mt.h" #include "servers/visual_server.h" +#include <AppKit/NSCursor.h> #include <ApplicationServices/ApplicationServices.h> #undef CursorShape @@ -50,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; @@ -70,6 +83,7 @@ public: CGEventSourceRef eventSource; void process_events(); + void process_key_events(); void *framework; // pthread_key_t current; @@ -86,6 +100,7 @@ public: id context; CursorShape cursor_shape; + NSCursor *cursors[CURSOR_MAX] = { NULL }; MouseMode mouse_mode; String title; @@ -96,6 +111,8 @@ public: Size2 window_size; Rect2 restore_rect; + String open_with_filename; + Point2 im_position; ImeCallback im_callback; void *im_target; @@ -121,7 +138,7 @@ protected: virtual const char *get_video_driver_name(int p_driver) const; virtual void initialize_core(); - virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); + virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); virtual void finalize(); virtual void set_main_loop(MainLoop *p_main_loop); @@ -136,7 +153,10 @@ public: virtual void alert(const String &p_alert, const String &p_title = "ALERT!"); + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false); + virtual void set_cursor_shape(CursorShape p_shape); + virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot); virtual void set_mouse_show(bool p_show); virtual void set_mouse_grab(bool p_grab); @@ -147,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); @@ -201,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; @@ -209,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 0cd02663da..4c459772aa 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "os_osx.h" #include "dir_access_osx.h" @@ -38,6 +39,8 @@ #include "servers/visual/visual_server_raster.h" #include "version_generated.gen.h" +#include <mach-o/dyld.h> + #include <Carbon/Carbon.h> #import <Cocoa/Cocoa.h> #include <IOKit/IOCFPlugIn.h> @@ -48,6 +51,7 @@ #include <os/log.h> #endif +#include <dlfcn.h> #include <fcntl.h> #include <libproc.h> #include <stdio.h> @@ -57,25 +61,40 @@ #include <unistd.h> #if MAC_OS_X_VERSION_MAX_ALLOWED < 101200 +#define NSEventMaskAny NSAnyEventMask +#define NSEventTypeKeyDown NSKeyDown +#define NSEventTypeKeyUp NSKeyUp +#define NSEventModifierFlagShift NSShiftKeyMask +#define NSEventModifierFlagCommand NSCommandKeyMask +#define NSEventModifierFlagControl NSControlKeyMask +#define NSEventModifierFlagOption NSAlternateKeyMask +#define NSWindowStyleMaskTitled NSTitledWindowMask +#define NSWindowStyleMaskResizable NSResizableWindowMask +#define NSWindowStyleMaskMiniaturizable NSMiniaturizableWindowMask +#define NSWindowStyleMaskClosable NSClosableWindowMask #define NSWindowStyleMaskBorderless NSBorderlessWindowMask #endif static NSRect convertRectToBacking(NSRect contentRect) { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) - return [OS_OSX::singleton->window_view convertRectToBacking:contentRect]; - else -#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ - return contentRect; + return [OS_OSX::singleton->window_view convertRectToBacking:contentRect]; } static void get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWithModifiers> state) { - state->set_shift((p_osx_state & NSShiftKeyMask)); - state->set_control((p_osx_state & NSControlKeyMask)); - state->set_alt((p_osx_state & NSAlternateKeyMask)); - state->set_metakey((p_osx_state & NSCommandKeyMask)); + state->set_shift((p_osx_state & NSEventModifierFlagShift)); + state->set_control((p_osx_state & NSEventModifierFlagControl)); + state->set_alt((p_osx_state & NSEventModifierFlagOption)); + 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; @@ -99,11 +118,29 @@ static Vector2 get_mouse_pos(NSEvent *event) { @implementation GodotApplication -// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost -// This works around an AppKit bug, where key up events while holding -// down the command key don't get sent to the key window. - (void)sendEvent:(NSEvent *)event { - if ([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask)) + + // special case handling of command-period, which is traditionally a special + // shortcut in macOS and doesn't arrive at our regular keyDown handler. + if ([event type] == NSEventTypeKeyDown) { + if (([event modifierFlags] & NSEventModifierFlagCommand) && [event keyCode] == 0x2f) { + + Ref<InputEventKey> k; + k.instance(); + + get_key_modifier_state([event modifierFlags], k); + k->set_pressed(true); + k->set_scancode(KEY_PERIOD); + k->set_echo([event isARepeat]); + + OS_OSX::singleton->push_input(k); + } + } + + // From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost + // This works around an AppKit bug, where key up events while holding + // down the command key don't get sent to the key window. + if ([event type] == NSEventTypeKeyUp && ([event modifierFlags] & NSEventModifierFlagCommand)) [[self keyWindow] sendEvent:event]; else [super sendEvent:event]; @@ -116,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); @@ -169,7 +213,6 @@ static Vector2 get_mouse_pos(NSEvent *event) { return NO; } -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - (void)windowDidEnterFullScreen:(NSNotification *)notification { OS_OSX::singleton->zoomed = true; } @@ -177,7 +220,6 @@ static Vector2 get_mouse_pos(NSEvent *event) { - (void)windowDidExitFullScreen:(NSNotification *)notification { OS_OSX::singleton->zoomed = false; } -#endif // MAC_OS_X_VERSION_MAX_ALLOWED - (void)windowDidChangeBackingProperties:(NSNotification *)notification { if (!OS_OSX::singleton) @@ -371,8 +413,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; - (void)cancelComposition { [self unmarkText]; - NSInputManager *currentInputManager = [NSInputManager currentInputManager]; - [currentInputManager markedTextAbandoned:self]; + NSTextInputContext *currentInputContext = [NSTextInputContext currentInputContext]; + [currentInputContext discardMarkedText]; } - (void)insertText:(id)aString { @@ -381,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]]) { @@ -401,8 +436,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; NSCharacterSet *ctrlChars = [NSCharacterSet controlCharacterSet]; NSCharacterSet *wsnlChars = [NSCharacterSet whitespaceAndNewlineCharacterSet]; if ([characters rangeOfCharacterFromSet:ctrlChars].length && [characters rangeOfCharacterFromSet:wsnlChars].length == 0) { - NSInputManager *currentInputManager = [NSInputManager currentInputManager]; - [currentInputManager markedTextAbandoned:self]; + NSTextInputContext *currentInputContext = [NSTextInputContext currentInputContext]; + [currentInputContext discardMarkedText]; [self cancelComposition]; return; } @@ -412,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]; } @@ -488,7 +530,7 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) { } - (void)mouseDown:(NSEvent *)event { - if (([event modifierFlags] & NSControlKeyMask)) { + if (([event modifierFlags] & NSEventModifierFlagControl)) { mouse_down_control = true; _mouseDownEvent(event, BUTTON_RIGHT, BUTTON_MASK_RIGHT, true); } else { @@ -577,8 +619,11 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) { return; if (OS_OSX::singleton->main_loop && OS_OSX::singleton->mouse_mode != OS::MOUSE_MODE_CAPTURED) OS_OSX::singleton->main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER); - if (OS_OSX::singleton->input) + if (OS_OSX::singleton->input) { OS_OSX::singleton->input->set_mouse_in_window(true); + OS_OSX::singleton->cursor_shape = OS::CURSOR_MAX; + OS_OSX::singleton->set_cursor_shape(OS::CURSOR_ARROW); + } } - (void)magnifyWithEvent:(NSEvent *)event { @@ -759,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 & NSCommandKeyMask) { - mod &= ~NSCommandKeyMask; - k->set_pressed(true); - } else { - k->set_pressed(false); - } - } else if (key == 0x38 || key == 0x3c) { - if (mod & NSShiftKeyMask) { - mod &= ~NSShiftKeyMask; - k->set_pressed(true); - } else { - k->set_pressed(false); - } - } else if (key == 0x3a || key == 0x3d) { - if (mod & NSAlternateKeyMask) { - mod &= ~NSAlternateKeyMask; - k->set_pressed(true); - } else { - k->set_pressed(false); - } - } else if (key == 0x3b || key == 0x3e) { - if (mod & NSControlKeyMask) { - mod &= ~NSControlKeyMask; - 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) { @@ -868,20 +920,12 @@ inline void sendPanEvent(double dx, double dy, int modifierFlags) { - (void)scrollWheel:(NSEvent *)event { double deltaX, deltaY; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) { - deltaX = [event scrollingDeltaX]; - deltaY = [event scrollingDeltaY]; + deltaX = [event scrollingDeltaX]; + deltaY = [event scrollingDeltaY]; - if ([event hasPreciseScrollingDeltas]) { - deltaX *= 0.03; - deltaY *= 0.03; - } - } else -#endif // MAC_OS_X_VERSION_MAX_ALLOWED - { - deltaX = [event deltaX]; - deltaY = [event deltaY]; + if ([event hasPreciseScrollingDeltas]) { + deltaX *= 0.03; + deltaY *= 0.03; } if ([event phase] != NSEventPhaseNone || [event momentumPhase] != NSEventPhaseNone) { @@ -919,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; } @@ -955,7 +1023,7 @@ static void displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplay displays_arrangement_dirty = true; } -void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { +Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { /*** OSX INITIALIZATION ***/ /*** OSX INITIALIZATION ***/ @@ -983,7 +1051,7 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au if (p_desired.borderless_window) { styleMask = NSWindowStyleMaskBorderless; } else { - styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | (p_desired.resizable ? NSResizableWindowMask : 0); + styleMask = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | (p_desired.resizable ? NSWindowStyleMaskResizable : 0); } window_object = [[GodotWindow alloc] @@ -992,7 +1060,7 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au backing:NSBackingStoreBuffered defer:NO]; - ERR_FAIL_COND(window_object == nil); + ERR_FAIL_COND_V(window_object == nil, ERR_UNAVAILABLE); window_view = [[GodotContentView alloc] init]; @@ -1008,7 +1076,7 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au window_size.width = p_desired.width * displayScale; window_size.height = p_desired.height * displayScale; - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6 && displayScale > 1.0) { + if (displayScale > 1.0) { [window_view setWantsBestResolutionOpenGLSurface:YES]; //if (current_videomode.resizable) [window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; @@ -1020,8 +1088,7 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au [window_object setAcceptsMouseMovedEvents:YES]; [window_object center]; - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) - [window_object setRestorable:NO]; + [window_object setRestorable:NO]; unsigned int attributeCount = 0; @@ -1079,11 +1146,11 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au #undef ADD_ATTR2 pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; - ERR_FAIL_COND(pixelFormat == nil); + ERR_FAIL_COND_V(pixelFormat == nil, ERR_UNAVAILABLE); context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]; - ERR_FAIL_COND(context == nil); + ERR_FAIL_COND_V(context == nil, ERR_UNAVAILABLE); [context setView:window_view]; @@ -1127,6 +1194,8 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au _ensure_user_data_dir(); restore_rect = Rect2(get_window_position(), get_window_size()); + + return OK; } void OS_OSX::finalize() { @@ -1179,34 +1248,42 @@ public: switch (p_type) { case ERR_WARNING: - os_log_info(OS_LOG_DEFAULT, - "WARNING: %{public}s: %{public}s\nAt: %{public}s:%i.", - p_function, err_details, p_file, p_line); + if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_12) { + os_log_info(OS_LOG_DEFAULT, + "WARNING: %{public}s: %{public}s\nAt: %{public}s:%i.", + p_function, err_details, p_file, p_line); + } logf_error("\E[1;33mWARNING: %s: \E[0m\E[1m%s\n", p_function, err_details); logf_error("\E[0;33m At: %s:%i.\E[0m\n", p_file, p_line); break; case ERR_SCRIPT: - os_log_error(OS_LOG_DEFAULT, - "SCRIPT ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", - p_function, err_details, p_file, p_line); + if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_12) { + os_log_error(OS_LOG_DEFAULT, + "SCRIPT ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", + p_function, err_details, p_file, p_line); + } logf_error("\E[1;35mSCRIPT ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details); logf_error("\E[0;35m At: %s:%i.\E[0m\n", p_file, p_line); break; case ERR_SHADER: - os_log_error(OS_LOG_DEFAULT, - "SHADER ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", - p_function, err_details, p_file, p_line); + if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_12) { + os_log_error(OS_LOG_DEFAULT, + "SHADER ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", + p_function, err_details, p_file, p_line); + } logf_error("\E[1;36mSHADER ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details); logf_error("\E[0;36m At: %s:%i.\E[0m\n", p_file, p_line); break; case ERR_ERROR: default: - os_log_error(OS_LOG_DEFAULT, - "ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", - p_function, err_details, p_file, p_line); + if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_12) { + os_log_error(OS_LOG_DEFAULT, + "ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", + p_function, err_details, p_file, p_line); + } logf_error("\E[1;31mERROR: %s: \E[0m\E[1m%s\n", p_function, err_details); logf_error("\E[0;31m At: %s:%i.\E[0m\n", p_file, p_line); break; @@ -1235,35 +1312,111 @@ void OS_OSX::alert(const String &p_alert, const String &p_title) { [window release]; } +Error OS_OSX::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) { + + String path = p_path; + + if (!FileAccess::exists(path)) { + //this code exists so gdnative can load .dylib files from within the executable path + path = get_executable_path().get_base_dir().plus_file(p_path.get_file()); + } + + if (!FileAccess::exists(path)) { + //this code exists so gdnative can load .dylib files from a standard macOS location + path = get_executable_path().get_base_dir().plus_file("../Frameworks").plus_file(p_path.get_file()); + } + + p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW); + if (!p_library_handle) { + ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + dlerror()); + ERR_FAIL_V(ERR_CANT_OPEN); + } + return OK; +} + void OS_OSX::set_cursor_shape(CursorShape p_shape) { if (cursor_shape == p_shape) return; - switch (p_shape) { - case CURSOR_ARROW: [[NSCursor arrowCursor] set]; break; - case CURSOR_IBEAM: [[NSCursor IBeamCursor] set]; break; - case CURSOR_POINTING_HAND: [[NSCursor pointingHandCursor] set]; break; - case CURSOR_CROSS: [[NSCursor crosshairCursor] set]; break; - case CURSOR_WAIT: [[NSCursor arrowCursor] set]; break; - case CURSOR_BUSY: [[NSCursor arrowCursor] set]; break; - case CURSOR_DRAG: [[NSCursor closedHandCursor] set]; break; - case CURSOR_CAN_DROP: [[NSCursor openHandCursor] set]; break; - case CURSOR_FORBIDDEN: [[NSCursor arrowCursor] set]; break; - case CURSOR_VSIZE: [[NSCursor resizeUpDownCursor] set]; break; - case CURSOR_HSIZE: [[NSCursor resizeLeftRightCursor] set]; break; - case CURSOR_BDIAGSIZE: [[NSCursor arrowCursor] set]; break; - case CURSOR_FDIAGSIZE: [[NSCursor arrowCursor] set]; break; - case CURSOR_MOVE: [[NSCursor arrowCursor] set]; break; - case CURSOR_VSPLIT: [[NSCursor resizeUpDownCursor] set]; break; - case CURSOR_HSPLIT: [[NSCursor resizeLeftRightCursor] set]; break; - case CURSOR_HELP: [[NSCursor arrowCursor] set]; break; - default: {}; + if (cursors[p_shape] != NULL) { + [cursors[p_shape] set]; + } else { + switch (p_shape) { + case CURSOR_ARROW: [[NSCursor arrowCursor] set]; break; + case CURSOR_IBEAM: [[NSCursor IBeamCursor] set]; break; + case CURSOR_POINTING_HAND: [[NSCursor pointingHandCursor] set]; break; + case CURSOR_CROSS: [[NSCursor crosshairCursor] set]; break; + case CURSOR_WAIT: [[NSCursor arrowCursor] set]; break; + case CURSOR_BUSY: [[NSCursor arrowCursor] set]; break; + case CURSOR_DRAG: [[NSCursor closedHandCursor] set]; break; + case CURSOR_CAN_DROP: [[NSCursor openHandCursor] set]; break; + case CURSOR_FORBIDDEN: [[NSCursor arrowCursor] set]; break; + case CURSOR_VSIZE: [[NSCursor resizeUpDownCursor] set]; break; + case CURSOR_HSIZE: [[NSCursor resizeLeftRightCursor] set]; break; + case CURSOR_BDIAGSIZE: [[NSCursor arrowCursor] set]; break; + case CURSOR_FDIAGSIZE: [[NSCursor arrowCursor] set]; break; + case CURSOR_MOVE: [[NSCursor arrowCursor] set]; break; + case CURSOR_VSPLIT: [[NSCursor resizeUpDownCursor] set]; break; + case CURSOR_HSPLIT: [[NSCursor resizeLeftRightCursor] set]; break; + case CURSOR_HELP: [[NSCursor arrowCursor] set]; break; + default: {}; + } } cursor_shape = p_shape; } +void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { + if (p_cursor.is_valid()) { + Ref<Texture> texture = p_cursor; + Ref<Image> image = texture->get_data(); + + int image_size = 32 * 32; + + ERR_FAIL_COND(texture->get_width() != 32 || texture->get_height() != 32); + + NSBitmapImageRep *imgrep = [[[NSBitmapImageRep alloc] + initWithBitmapDataPlanes:NULL + pixelsWide:image->get_width() + pixelsHigh:image->get_height() + bitsPerSample:8 + samplesPerPixel:4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bytesPerRow:image->get_width() * 4 + bitsPerPixel:32] autorelease]; + + ERR_FAIL_COND(imgrep == nil); + uint8_t *pixels = [imgrep bitmapData]; + + int len = image->get_width() * image->get_height(); + PoolVector<uint8_t> data = image->get_data(); + PoolVector<uint8_t>::Read r = data.read(); + + /* Premultiply the alpha channel */ + for (int i = 0; i < len; i++) { + uint8_t alpha = r[i * 4 + 3]; + pixels[i * 4 + 0] = (uint8_t)(((uint16_t)r[i * 4 + 0] * alpha) / 255); + pixels[i * 4 + 1] = (uint8_t)(((uint16_t)r[i * 4 + 1] * alpha) / 255); + pixels[i * 4 + 2] = (uint8_t)(((uint16_t)r[i * 4 + 2] * alpha) / 255); + pixels[i * 4 + 3] = alpha; + } + + NSImage *nsimage = [[[NSImage alloc] initWithSize:NSMakeSize(image->get_width(), image->get_height())] autorelease]; + [nsimage addRepresentation:imgrep]; + + NSCursor *cursor = [[NSCursor alloc] initWithImage:nsimage hotSpot:NSMakePoint(p_hotspot.x, p_hotspot.y)]; + + cursors[p_shape] = cursor; + + if (p_shape == CURSOR_ARROW) { + [cursor set]; + } + } +} + void OS_OSX::set_mouse_show(bool p_show) { } @@ -1665,9 +1818,8 @@ float OS_OSX::_display_scale(id screen) const { if ([screen respondsToSelector:@selector(backingScaleFactor)]) { return fmax(1.0, [screen backingScaleFactor]); } - } else { - return 1.0; } + return 1.0; } Point2 OS_OSX::get_native_window_position() const { @@ -1717,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; @@ -1726,10 +1884,14 @@ void OS_OSX::set_window_size(const Size2 p_size) { CGFloat menuBarHeight = [[[NSApplication sharedApplication] mainMenu] menuBarHeight]; if (menuBarHeight != 0.f) { size.y += menuBarHeight; -#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101104 } else { - size.y += [[NSStatusBar systemStatusBar] thickness]; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200 + if (floor(NSAppKitVersionNumber) < NSAppKitVersionNumber10_12) { +#else + { #endif + size.y += [[NSStatusBar systemStatusBar] thickness]; + } } } @@ -1742,36 +1904,27 @@ void OS_OSX::set_window_size(const Size2 p_size) { void OS_OSX::set_window_fullscreen(bool p_enabled) { if (zoomed != p_enabled) { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 [window_object toggleFullScreen:nil]; -#else - [window_object performZoom:nil]; -#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ } zoomed = p_enabled; }; bool OS_OSX::is_window_fullscreen() const { -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070 - if ([window_object respondsToSelector:@selector(isZoomed)]) - return [window_object isZoomed]; -#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ - return zoomed; }; void OS_OSX::set_window_resizable(bool p_enabled) { if (p_enabled) - [window_object setStyleMask:[window_object styleMask] | NSResizableWindowMask]; + [window_object setStyleMask:[window_object styleMask] | NSWindowStyleMaskResizable]; else - [window_object setStyleMask:[window_object styleMask] & ~NSResizableWindowMask]; + [window_object setStyleMask:[window_object styleMask] & ~NSWindowStyleMaskResizable]; }; bool OS_OSX::is_window_resizable() const { - return [window_object styleMask] & NSResizableWindowMask; + return [window_object styleMask] & NSWindowStyleMaskResizable; }; void OS_OSX::set_window_minimized(bool p_enabled) { @@ -1813,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]; @@ -1826,7 +1993,7 @@ void OS_OSX::set_borderless_window(bool p_borderless) { if (p_borderless) { [window_object setStyleMask:NSWindowStyleMaskBorderless]; } else { - [window_object setStyleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask]; + [window_object setStyleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable]; // Force update of the window styles NSRect frameRect = [window_object frame]; @@ -1950,7 +2117,7 @@ void OS_OSX::process_events() { while (true) { NSEvent *event = [NSApp - nextEventMatchingMask:NSAnyEventMask + nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES]; @@ -1960,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; @@ -2084,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; @@ -2142,7 +2348,7 @@ OS_OSX::OS_OSX() { [apple_menu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; menu_item = [apple_menu addItemWithTitle:NSLocalizedString(@"Hide Others", nil) action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; - [menu_item setKeyEquivalentModifierMask:(NSAlternateKeyMask | NSCommandKeyMask)]; + [menu_item setKeyEquivalentModifierMask:(NSEventModifierFlagOption | NSEventModifierFlagCommand)]; [apple_menu addItemWithTitle:NSLocalizedString(@"Show all", nil) action:@selector(unhideAllApplications:) keyEquivalent:@""]; @@ -2176,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) { diff --git a/platform/osx/platform_config.h b/platform/osx/platform_config.h index a3715e7e4e..1b497cebef 100644 --- a/platform/osx/platform_config.h +++ b/platform/osx/platform_config.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include <alloca.h> #define GLES3_INCLUDE_H "glad/glad.h" diff --git a/platform/osx/sem_osx.cpp b/platform/osx/sem_osx.cpp index 2e7da62e5b..92f749322e 100644 --- a/platform/osx/sem_osx.cpp +++ b/platform/osx/sem_osx.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "sem_osx.h" #include <fcntl.h> diff --git a/platform/osx/sem_osx.h b/platform/osx/sem_osx.h index 0b9bbdfa76..ce31e966b7 100644 --- a/platform/osx/sem_osx.h +++ b/platform/osx/sem_osx.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef SEM_OSX_H #define SEM_OSX_H |