diff options
Diffstat (limited to 'platform/osx')
| -rw-r--r-- | platform/osx/crash_handler_osx.mm | 7 | ||||
| -rw-r--r-- | platform/osx/detect.py | 18 | ||||
| -rw-r--r-- | platform/osx/export/export.cpp | 43 | ||||
| -rw-r--r-- | platform/osx/os_osx.h | 5 | ||||
| -rw-r--r-- | platform/osx/os_osx.mm | 177 |
5 files changed, 183 insertions, 67 deletions
diff --git a/platform/osx/crash_handler_osx.mm b/platform/osx/crash_handler_osx.mm index ed8a955ae5..e19fdf1b9f 100644 --- a/platform/osx/crash_handler_osx.mm +++ b/platform/osx/crash_handler_osx.mm @@ -77,7 +77,12 @@ static void handle_crash(int sig) { void *bt_buffer[256]; size_t size = backtrace(bt_buffer, 256); String _execpath = OS::get_singleton()->get_executable_path(); - String msg = GLOBAL_GET("debug/settings/crash_handler/message"); + + String msg; + const ProjectSettings *proj_settings = ProjectSettings::get_singleton(); + if (proj_settings) { + msg = proj_settings->get("debug/settings/crash_handler/message"); + } // Dump the backtrace to stderr with a message to the user fprintf(stderr, "%s: Program crashed with signal %d\n", __FUNCTION__, sig); diff --git a/platform/osx/detect.py b/platform/osx/detect.py index 36a753e683..4c88f91d13 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -53,16 +53,18 @@ def configure(env): elif (env["target"] == "release_debug"): if (env["optimize"] == "speed"): #optimize for speed (default) - env.Prepend(CCFLAGS=['-O2', '-DDEBUG_ENABLED']) + env.Prepend(CCFLAGS=['-O2']) else: #optimize for size - env.Prepend(CCFLAGS=['-Os', '-DDEBUG_ENABLED']) + env.Prepend(CCFLAGS=['-Os']) + env.Prepend(CPPFLAGS=['-DDEBUG_ENABLED']) if (env["debug_symbols"] == "yes"): env.Prepend(CCFLAGS=['-g1']) if (env["debug_symbols"] == "full"): env.Prepend(CCFLAGS=['-g2']) elif (env["target"] == "debug"): - env.Prepend(CCFLAGS=['-g3', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Prepend(CCFLAGS=['-g3']) + env.Prepend(CPPFLAGS=['-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) ## Architecture @@ -88,10 +90,10 @@ def configure(env): env['AR'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ar" env['RANLIB'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ranlib" env['AS'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-as" - env.Append(CCFLAGS=['-D__MACPORTS__']) #hack to fix libvpx MM256_BROADCASTSI128_SI256 define + env.Append(CPPFLAGS=['-D__MACPORTS__']) #hack to fix libvpx MM256_BROADCASTSI128_SI256 define detect_darwin_sdk_path('osx', env) - env.Append(CPPFLAGS=['-isysroot', '$MACOS_SDK_PATH']) + env.Append(CCFLAGS=['-isysroot', '$MACOS_SDK_PATH']) env.Append(LINKFLAGS=['-isysroot', '$MACOS_SDK_PATH']) else: # osxcross build @@ -110,7 +112,7 @@ def configure(env): env['AR'] = basecmd + "ar" env['RANLIB'] = basecmd + "ranlib" env['AS'] = basecmd + "as" - env.Append(CCFLAGS=['-D__MACPORTS__']) #hack to fix libvpx MM256_BROADCASTSI128_SI256 define + env.Append(CPPFLAGS=['-D__MACPORTS__']) #hack to fix libvpx MM256_BROADCASTSI128_SI256 define if (env["CXX"] == "clang++"): env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND']) @@ -124,10 +126,10 @@ def configure(env): ## Flags - env.Append(CPPPATH=['#platform/osx']) + env.Prepend(CPPPATH=['#platform/osx']) env.Append(CPPFLAGS=['-DOSX_ENABLED', '-DUNIX_ENABLED', '-DGLES_ENABLED', '-DAPPLE_STYLE_KEYS', '-DCOREAUDIO_ENABLED', '-DCOREMIDI_ENABLED']) env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-framework', 'CoreMIDI', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback', '-framework', 'CoreVideo']) env.Append(LIBS=['pthread']) - env.Append(CPPFLAGS=['-mmacosx-version-min=10.9']) + env.Append(CCFLAGS=['-mmacosx-version-min=10.9']) env.Append(LINKFLAGS=['-mmacosx-version-min=10.9']) diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index 5e94bc457b..9dabbb12fc 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -121,7 +121,7 @@ void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/info"), "Made with Godot Engine")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.png"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.png,*.icns"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/identifier", PROPERTY_HINT_PLACEHOLDER_TEXT, "com.example.game"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/signature"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/short_version"), "1.0")); @@ -409,7 +409,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p String src_pkg_name; - EditorProgress ep("export", "Exporting for OSX", 3); + EditorProgress ep("export", "Exporting for OSX", 3, true); if (p_debug) src_pkg_name = p_preset->get("custom_package/debug"); @@ -432,7 +432,9 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p FileAccess *src_f = NULL; zlib_filefunc_def io = zipio_create_io_from_file(&src_f); - ep.step("Creating app", 0); + if (ep.step("Creating app", 0)) { + return ERR_SKIP; + } unzFile src_pkg_zip = unzOpen2(src_pkg_name.utf8().get_data(), &io); if (!src_pkg_zip) { @@ -441,7 +443,6 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p return ERR_FILE_NOT_FOUND; } - ERR_FAIL_COND_V(!src_pkg_zip, ERR_CANT_OPEN); int ret = unzGoToFirstFile(src_pkg_zip); String binary_to_use = "godot_osx_" + String(p_debug ? "debug" : "release") + ".64"; @@ -543,11 +544,21 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p iconpath = ProjectSettings::get_singleton()->get("application/config/icon"); if (iconpath != "") { - Ref<Image> icon; - icon.instance(); - icon->load(iconpath); - if (!icon->empty()) { - _make_icon(icon, data); + if (iconpath.get_extension() == "icns") { + FileAccess *icon = FileAccess::open(iconpath, FileAccess::READ); + if (icon) { + data.resize(icon->get_len()); + icon->get_buffer(&data.write[0], icon->get_len()); + icon->close(); + memdelete(icon); + } + } else { + Ref<Image> icon; + icon.instance(); + icon->load(iconpath); + if (!icon->empty()) { + _make_icon(icon, data); + } } } //bleh? @@ -568,7 +579,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p f->close(); if (is_execute) { // Chmod with 0755 if the file is executable - f->_chmod(file, 0755); + FileAccess::set_unix_permissions(file, 0755); } memdelete(f); } else { @@ -617,7 +628,9 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p } if (err == OK) { - ep.step("Making PKG", 1); + if (ep.step("Making PKG", 1)) { + return ERR_SKIP; + } if (export_format == "dmg") { String pack_path = tmp_app_path_name + "/Contents/Resources/" + pkg_name + ".pck"; @@ -639,7 +652,9 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p } if (err == OK && identity != "") { - ep.step("Code signing bundle", 2); + if (ep.step("Code signing bundle", 2)) { + return ERR_SKIP; + } // the order in which we code sign is important, this is a bit of a shame or we could do this in our loop that extracts the files from our ZIP @@ -664,7 +679,9 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p // and finally create a DMG if (err == OK) { - ep.step("Making DMG", 3); + if (ep.step("Making DMG", 3)) { + return ERR_SKIP; + } err = _create_dmg(p_path, pkg_name, tmp_app_path_name); } diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index dfe7b27bd0..eed230ba89 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -60,6 +60,7 @@ public: unsigned int osx_state; bool pressed; bool echo; + bool raw; uint32_t scancode; uint32_t unicode; }; @@ -165,13 +166,14 @@ public: void wm_minimized(bool p_minimized); - virtual String get_name(); + virtual String get_name() const; 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 CursorShape get_cursor_shape() const; 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); @@ -185,6 +187,7 @@ public: virtual Size2 get_window_size() const; virtual Size2 get_real_window_size() const; + virtual void set_native_icon(const String &p_filename); virtual void set_icon(const Ref<Image> &p_icon); virtual MainLoop *get_main_loop() const; diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 4bbe30a7d1..567d24de3e 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -337,6 +337,11 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt } - (void)windowDidMove:(NSNotification *)notification { + + if (OS_OSX::singleton->get_main_loop()) { + OS_OSX::singleton->input->release_pressed_events(); + } + /* [window->nsgl.context update]; @@ -387,7 +392,7 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt @interface GodotContentView : NSView <NSTextInputClient> { NSTrackingArea *trackingArea; NSMutableAttributedString *markedText; - bool imeMode; + bool imeInputEventInProgress; } - (void)cancelComposition; - (BOOL)wantsUpdateLayer; @@ -413,7 +418,7 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt - (id)init { self = [super init]; trackingArea = nil; - imeMode = false; + imeInputEventInProgress = false; [self updateTrackingAreas]; [self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]]; markedText = [[NSMutableAttributedString alloc] init]; @@ -447,7 +452,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; [markedText initWithString:aString]; } if (OS_OSX::singleton->im_active) { - imeMode = true; + imeInputEventInProgress = true; OS_OSX::singleton->im_text.parse_utf8([[markedText mutableString] UTF8String]); OS_OSX::singleton->im_selection = Point2(selectedRange.location, selectedRange.length); @@ -462,7 +467,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; } - (void)unmarkText { - imeMode = false; + imeInputEventInProgress = false; [[markedText mutableString] setString:@""]; if (OS_OSX::singleton->im_active) { OS_OSX::singleton->im_text = String(); @@ -535,6 +540,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; ke.osx_state = [event modifierFlags]; ke.pressed = true; ke.echo = false; + ke.raw = false; // IME input event ke.scancode = 0; ke.unicode = codepoint; @@ -712,8 +718,6 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) { 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_EXIT); - if (OS_OSX::singleton->input) - OS_OSX::singleton->input->set_mouse_in_window(false); } - (void)mouseEntered:(NSEvent *)event { @@ -721,8 +725,6 @@ 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) - OS_OSX::singleton->input->set_mouse_in_window(true); OS::CursorShape p_shape = OS_OSX::singleton->cursor_shape; OS_OSX::singleton->cursor_shape = OS::CURSOR_MAX; @@ -969,10 +971,10 @@ static const _KeyCodeMap _keycodes[55] = { { 'i', KEY_I }, { 'o', KEY_O }, { 'p', KEY_P }, - { '[', KEY_BRACERIGHT }, - { ']', KEY_BRACELEFT }, - { '{', KEY_BRACERIGHT }, - { '}', KEY_BRACELEFT }, + { '[', KEY_BRACELEFT }, + { ']', KEY_BRACERIGHT }, + { '{', KEY_BRACELEFT }, + { '}', KEY_BRACERIGHT }, { 'a', KEY_A }, { 's', KEY_S }, { 'd', KEY_D }, @@ -1044,29 +1046,52 @@ static int remapKey(unsigned int key) { - (void)keyDown:(NSEvent *)event { - //disable raw input in IME mode - if (!imeMode) { - OS_OSX::KeyEvent ke; + // Ignore all input if IME input is in progress + if (!imeInputEventInProgress) { + NSString *characters = [event characters]; + NSUInteger length = [characters length]; - ke.osx_state = [event modifierFlags]; - ke.pressed = true; - ke.echo = [event isARepeat]; - ke.scancode = remapKey([event keyCode]); - ke.unicode = 0; + if (!OS_OSX::singleton->im_active && length > 0 && keycode_has_unicode(remapKey([event keyCode]))) { + // Fallback unicode character handler used if IME is not active + for (NSUInteger i = 0; i < length; i++) { + OS_OSX::KeyEvent ke; - push_to_key_event_buffer(ke); + ke.osx_state = [event modifierFlags]; + ke.pressed = true; + ke.echo = [event isARepeat]; + ke.scancode = remapKey([event keyCode]); + ke.raw = true; + ke.unicode = [characters characterAtIndex:i]; + + push_to_key_event_buffer(ke); + } + } else { + OS_OSX::KeyEvent ke; + + ke.osx_state = [event modifierFlags]; + ke.pressed = true; + ke.echo = [event isARepeat]; + ke.scancode = remapKey([event keyCode]); + ke.raw = false; + ke.unicode = 0; + + push_to_key_event_buffer(ke); + } } - if (OS_OSX::singleton->im_active == true) + // Pass events to IME handler + if (OS_OSX::singleton->im_active) [self interpretKeyEvents:[NSArray arrayWithObject:event]]; } - (void)flagsChanged:(NSEvent *)event { - if (!imeMode) { + // Ignore all input if IME input is in progress + if (!imeInputEventInProgress) { OS_OSX::KeyEvent ke; ke.echo = false; + ke.raw = true; int key = [event keyCode]; int mod = [event modifierFlags]; @@ -1113,17 +1138,37 @@ static int remapKey(unsigned int key) { - (void)keyUp:(NSEvent *)event { - if (!imeMode) { + // Ignore all input if IME input is in progress + if (!imeInputEventInProgress) { + NSString *characters = [event characters]; + NSUInteger length = [characters length]; - OS_OSX::KeyEvent ke; + // Fallback unicode character handler used if IME is not active + if (!OS_OSX::singleton->im_active && length > 0 && keycode_has_unicode(remapKey([event keyCode]))) { + for (NSUInteger i = 0; i < length; i++) { + OS_OSX::KeyEvent ke; - ke.osx_state = [event modifierFlags]; - ke.pressed = false; - ke.echo = false; - ke.scancode = remapKey([event keyCode]); - ke.unicode = 0; + ke.osx_state = [event modifierFlags]; + ke.pressed = false; + ke.echo = [event isARepeat]; + ke.scancode = remapKey([event keyCode]); + ke.raw = true; + ke.unicode = [characters characterAtIndex:i]; - push_to_key_event_buffer(ke); + push_to_key_event_buffer(ke); + } + } else { + OS_OSX::KeyEvent ke; + + ke.osx_state = [event modifierFlags]; + ke.pressed = false; + ke.echo = [event isARepeat]; + ke.scancode = remapKey([event keyCode]); + ke.raw = true; + ke.unicode = 0; + + push_to_key_event_buffer(ke); + } } } @@ -1550,7 +1595,7 @@ void OS_OSX::delete_main_loop() { main_loop = NULL; } -String OS_OSX::get_name() { +String OS_OSX::get_name() const { return "OSX"; } @@ -1696,6 +1741,11 @@ void OS_OSX::set_cursor_shape(CursorShape p_shape) { cursor_shape = p_shape; } +OS::CursorShape OS_OSX::get_cursor_shape() const { + + return cursor_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; @@ -1852,6 +1902,31 @@ void OS_OSX::set_window_title(const String &p_title) { [window_object setTitle:[NSString stringWithUTF8String:p_title.utf8().get_data()]]; } +void OS_OSX::set_native_icon(const String &p_filename) { + + FileAccess *f = FileAccess::open(p_filename, FileAccess::READ); + ERR_FAIL_COND(!f); + + Vector<uint8_t> data; + uint32_t len = f->get_len(); + data.resize(len); + f->get_buffer((uint8_t *)&data.write[0], len); + memdelete(f); + + NSData *icon_data = [[[NSData alloc] initWithBytes:&data.write[0] length:len] autorelease]; + if (!icon_data) { + ERR_EXPLAIN("Error reading icon data"); + ERR_FAIL(); + } + NSImage *icon = [[[NSImage alloc] initWithData:icon_data] autorelease]; + if (!icon) { + ERR_EXPLAIN("Error loading icon"); + ERR_FAIL(); + } + + [NSApp setApplicationIconImage:icon]; +} + void OS_OSX::set_icon(const Ref<Image> &p_icon) { Ref<Image> img = p_icon; @@ -2581,30 +2656,44 @@ void OS_OSX::process_key_events() { const KeyEvent &ke = key_event_buffer[i]; - if ((i == 0 && ke.scancode == 0) || (i > 0 && key_event_buffer[i - 1].scancode == 0)) { + if (ke.raw) { + // Non IME input - no composite characters, pass events as is 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_scancode(ke.scancode); k->set_unicode(ke.unicode); push_input(k); - } - if (ke.scancode != 0) { - k.instance(); + } else { + // IME input + 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(ke.scancode); + 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); - 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); } + if (ke.scancode != 0) { + k.instance(); - push_input(k); + 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); + } } } |