Re: LSUIElement Applications stuck before wxApp::OnInit() until activated (e.g. by re-opening application) (#16156)

106 views
Skip to first unread message

Wojtek Mach

unread,
Jun 8, 2022, 3:54:11 AM6/8/22
to wx-...@googlegroups.com, wxtrac, Author

I can confirm the bug still happens. Here's a way to reproduce it:

build.sh:

#!/bin/sh
set -o pipefail
rm -rf MyApp*

cat << EOF > MyApp.h
#include <wx/wx.h>

class MyApp : public wxApp
{
public:
    virtual bool OnInit();
    virtual void MacOpenURL(const wxString& url);
};

DECLARE_APP(MyApp)
EOF

cat << EOF > MyApp.cpp
#include <wx/wx.h>
#include "MyApp.h"

IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{
  wxPoint pos = wxPoint(50, 50);
  wxFrame* frame = new wxFrame((wxFrame*) NULL, -1, _T("Hello, World!"), pos);
  frame->Show(true);
  SetTopWindow(frame);
  return true;
}

void MyApp::MacOpenURL(const wxString& url)
{
  wxMessageBox(url, _T("MyApp::MacOpenURL"));
}
EOF

mkdir -p MyApp.app/Contents/MacOS

cat << EOF > MyApp.app/Contents/Info.plist
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>CFBundleName</key>
  <string>MyApp</string>
  <key>CFBundleVersion</key>
  <string>1.0.0</string>
  <key>LSUIElement</key>
  <true/>
  <key>CFBundleURLTypes</key>
  <array>
    <dict>
      <key>CFBundleURLName</key>
      <string>MyApp</string>
      <key>CFBundleURLSchemes</key>
      <array>
        <string>myapp</string>
      </array>
    </dict>
  </array>
</dict>
</plist>
EOF

g++ `wx-config --cxxflags` `wx-config --libs` -o MyApp.app/Contents/MacOS/MyApp MyApp.cpp
$ sh build.sh
$ open MyApp.app
$ open myapp://foo
# quit the app
$ open myapp://foo # does nothing (actually hangs but the user doesn't see it)
$ open myapp://foo # opens the app, displays the url popup *twice*

I can confirm the workaround by Stefanus Du Toit worked for me. A fix upstream would be very appreciated. I wouldn't be able to fix it myself but at the very least I could help with testing.


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you authored the thread.Message ID: <wxWidgets/wxWidgets/issues/16156/1149585219@github.com>

VZ

unread,
Jun 8, 2022, 8:15:45 AM6/8/22
to wx-...@googlegroups.com, wxtrac, Author

Can we detect the applications with LSUIElement == true? IF so, I guess we should add it as another check to the code here https://github.com/wxWidgets/wxWidgets/blob/dc4d1b66e4903edfcb66c3b41a36bca8806c98e5/src/osx/cocoa/utils.mm#L84-L101

but I'm completely out of my depth, so I won't dare to change it without @csomor's approval.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you authored the thread.Message ID: <wxWidgets/wxWidgets/issues/16156/1149837664@github.com>

Wojtek Mach

unread,
Jun 8, 2022, 9:35:23 AM6/8/22
to wx-...@googlegroups.com, wxtrac, Author

@vadz I tried triggering that codepath via setting:

bool MyApp::OSXIsGUIApplication() { return TRUE; }

and the bug still occurs.

Triggering that codepath would be undesirable to do so anyway as this line:

[NSApp setActivationPolicy: NSApplicationActivationPolicyRegular];

programatically sets the opposite of LSUIElement=true, it make sure the app is in the Dock. Importantly it takes precedence over LSUIElement setting. For my actual use case (packaging up wxErlang apps) I'm actively making sure this code path is not triggered so that my users can control Dock behaviour via LSUIElement setting.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you authored the thread.Message ID: <wxWidgets/wxWidgets/issues/16156/1149924571@github.com>

VZ

unread,
Jun 8, 2022, 10:45:31 AM6/8/22
to wx-...@googlegroups.com, wxtrac, Author

But Stefanus' workaround was to call [NSApp activateIgnoringOtherApps: YES]... If this doesn't help, then I'm afraid I have no idea what to do here.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you authored the thread.Message ID: <wxWidgets/wxWidgets/issues/16156/1150017694@github.com>

Wojtek Mach

unread,
Jun 8, 2022, 11:18:38 AM6/8/22
to wx-...@googlegroups.com, wxtrac, Author

Sorry for confusion. Just to be clear the workaround was working all along.

But I also see the error in my previous comment. Just setting bool MyApp::OSXIsGUIApplication() { return TRUE; } was not enough because then the other condition, if ( !app.EndsWith(".app") ) failed since my sample app is bundled. So the [NSApp activateIgnoringOtherApps: YES] from that code path was never executed. Sorry about that!


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you authored the thread.Message ID: <wxWidgets/wxWidgets/issues/16156/1150058564@github.com>

VZ

unread,
Jun 8, 2022, 11:46:08 AM6/8/22
to wx-...@googlegroups.com, wxtrac, Author

OK, so the question is how to check for LSUIElement being true, right? Could you please check what does [NSApp activationPolicy] return in this case? I think it should be NSApplicationActivationPolicyAccessory and, if so, we could just call activateIgnoringOtherApps: in this case and hopefully fix the problem.

Alternatively, I think it should be possible to set [NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory] instead of setting LSUIElement in the .plist. So we could also provide a function doing this, e.g. wxApp::OSXSetShowDockIcon() or something like this that would do it and activate the app too.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you authored the thread.Message ID: <wxWidgets/wxWidgets/issues/16156/1150090633@github.com>

Wojtek Mach

unread,
Jun 8, 2022, 3:22:58 PM6/8/22
to wx-...@googlegroups.com, wxtrac, Author

Could you please check what does [NSApp activationPolicy] return in this case?

I can confirm that on LSUIElement=true [NSApp activationPolicy] returns NSApplicationActivationPolicyAccessory. Otherwise, it returns NSApplicationActivationPolicyRegular. Good call!

I wonder if this would be acceptable?

diff --git a/src/osx/cocoa/utils.mm b/src/osx/cocoa/utils.mm
index b2f009fc36..98b0cb8d49 100644
--- a/src/osx/cocoa/utils.mm
+++ b/src/osx/cocoa/utils.mm
@@ -99,6 +99,10 @@ void wxBell()
             [NSApp activateIgnoringOtherApps: YES];
         }
     }
+
+    if ( [NSApp activationPolicy] == NSApplicationActivationPolicyAccessory ) {
+        [NSApp activateIgnoringOtherApps: YES];
+    }
 }

 - (void)application:(NSApplication *)sender openFiles:(NSArray *)fileNames

that is, after the if ( !wxApp::sm_isEmbedded && wxTheApp && wxTheApp->OSXIsGUIApplication() ) block?


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you authored the thread.Message ID: <wxWidgets/wxWidgets/issues/16156/1150306910@github.com>

VZ

unread,
Jun 9, 2022, 2:26:15 PM6/9/22
to wx-...@googlegroups.com, wxtrac, Author

Could you please check the linked PR above works for you? TIA!


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you authored the thread.Message ID: <wxWidgets/wxWidgets/issues/16156/1151460235@github.com>

Wojtek Mach

unread,
Jun 9, 2022, 5:13:23 PM6/9/22
to wx-...@googlegroups.com, wxtrac, Author

Thank you for the patch! It looks good to me and it works well in the attached sample app.

Unfortunately it won't work for wxErlang which is ultimately what I am after. Perhaps it is not even problem with Erlang per se but rather me not knowing how to properly packaged it up into an .app bundle. Please feel free to ignore what follows.

In a nutshell I have this bundle:

MyApp.app/
  Contents/
    Info.plist
    MacOS/
      MyApp # bash script or a compiled executable that starts Resources/erlang/bin/erl
    Resources/
      erlang/
        bin/
        lib/
        ...   

It works well however my running program cannot determine it is in fact in a bundle, CFBundle/NSBundle APIs report the bundle path to /path/to/MyApp/Contents/Resources/erlang/bin (where the executable is located) as opposed to /path/to/MyApp, none of the bundle keys are set, etc. Interestingly, if I set LSUIElement=true in the Info.plist, even though the runtime reports the wrong bundle, [NSApp activationPolicy] correctly reports accessory.

Because of this bundle limitation, this condition in cocoa/utils.mm: if ( !app.EndsWith(".app") ) will evaluate to true which is definitely not what I want, I don't want [NSApp setActivationPolicy: NSApplicationActivationPolicyRegular]; to be executed as it will overwrite the LSUIElement=true setting. In fact I added code to wxErlang so that when we determine we're in a bundle (not using CFBundle/NSBundle but other heuristic), we have OSXIsGUIApplication() return false so that that code path is not triggered. In hindsight that was probably a mistake and instead we need to find a proper fix.

In any case, definitely more research/work to be done in Erlang/wxErlang, nothing for you to worry about. Again, thank you for the patch!


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you authored the thread.Message ID: <wxWidgets/wxWidgets/issues/16156/1151630140@github.com>

VZ

unread,
Jun 10, 2022, 12:19:09 PM6/10/22
to wx-...@googlegroups.com, wxtrac, Author

Closed #16156 as completed via 84de9c0.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you authored the thread.Message ID: <wxWidgets/wxWidgets/issue/16156/issue_event/6787278110@github.com>

Reply all
Reply to author
Forward
0 new messages