From 2df4e290fb75e93de2f0d470e518ca880db6f1fe Mon Sep 17 00:00:00 2001 From: Wojtek Mach Date: Tue, 28 Jun 2022 14:55:26 +0200 Subject: [PATCH] wx: Add `WX_MACOS_NON_GUI_APP` We cannot depend on `is_packaged_app()` check because it is not a perfect way of checking if app is bundled. It would return true when the app is bundled with a launcher like this: ```swift import AppKit let task = Process() task.launchPath = "/Users/wojtek/src/otp/bin/erl" task.arguments = ["-noshell", "-eval", "wx:new(), timer:sleep(5000), halt()"] try task.run() task.waitUntilExit() ``` It would return false for this launcher, however: ```swift import AppKit class AppDelegate: NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(_ aNotification: Notification) { let task = Process() task.launchPath = "/Users/wojtek/src/otp/bin/erl" task.arguments = ["-noshell", "-eval", "wx:new(), timer:sleep(5000), halt()"] try! task.run() } } let app = NSApplication.shared let delegate = AppDelegate() app.delegate = delegate app.run() ``` Btw, there has recently been a fix in wx [1] and we'd only be able to take advantage of it when `OSXIsGUIApplication` returns true (and when wx recognizes our app as properly bundled, see [2]). And so I believe to support variety of scenarios, we need precise control. [1] https://github.com/wxWidgets/wxWidgets #22508 [2] https://github.com/erlang/otp #6070 --- lib/wx/c_src/wxe_impl.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp index 440198fa4211..a32e09db0100 100644 --- a/lib/wx/c_src/wxe_impl.cpp +++ b/lib/wx/c_src/wxe_impl.cpp @@ -225,14 +225,16 @@ void WxeApp::MacReopenApp() { send_msg("reopen_app", &empty); } +// See: https://github.com/wxWidgets/wxWidgets/blob/v3.1.5/src/osx/cocoa/utils.mm#L76:L93 bool WxeApp::OSXIsGUIApplication() { - // wx manually activates the application if it's not in the bundle [1]. In particular, it calls - // `[NSApp setActivationPolicy: NSApplicationActivationPolicyRegular]` which prevents the app - // from running in the background and we cannot control it with `LSUIElement` [2]. Their check - // if it's a bundle always returns false for wxErlang. Thus we use our own way of detecting it. - // [1] https://github.com/wxWidgets/wxWidgets/blob/v3.1.5/src/osx/cocoa/utils.mm#L76:L93 - // [2] https://developer.apple.com/documentation/bundleresources/information_property_list/lsuielement - return !is_packaged_app(); + char val_buf[8]; + size_t val_len = 7; + int res = enif_getenv("WX_MACOS_NON_GUI_APP", val_buf, &val_len); + if (res == 0) { + return FALSE; + } else { + return TRUE; + } } #endif