Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wxOSX Cocoa: A problem with starting the application when using UIElement. #23893

Closed
DiCode77 opened this issue Sep 22, 2023 · 11 comments
Closed
Labels
macOS Specific to Cocoa macOS port

Comments

@DiCode77
Copy link

DiCode77 commented Sep 22, 2023

Platform and version information

  • wxWidgets version you use: 3.2.2.1
  • wxWidgets port you use: wxOSX, cocoa.
  • OS and its version: macOS(14.0 (23A344)) Sonoma RC1/2.
  • IDE: Xcode 15.0 (15A240d).

I would like to note in advance that this error does not exist on macOS Ventura or older systems, the problem appears starting with macOS Sonoma.

Description of the problem

The problem is that when I use (UIElement == true), the app only starts on the second try (the UI is rendered).

That is, after the first attempt, only a process is created in the system, but the program does not show signs that it has started.

1

After the second attempt to start the program, the same process starts working, the program interface appears.

2

I want to emphasize that it is not important how you try to launch the program, either with the cursor, or by adding it to the autorun in the system.

With UIElement disabled, the application starts on the first try.

Trying to identify the problem.

I will note right away that if the application is debugged or only launched through the IDE (Xcode), then the problem does not manifest itself, that is, the launch occurs on the first try.

By the method of research, I understood that the problem is that the virtual bool OnInit() method is not called.
That is, for example, the MyApp() constructor works in this class, but the OnInit method does not.

3


That is, we can conclude that when we pass the MyApp class to the macro, after creating the object, the OnInit() method is not called in wxWidgets itself, and this is the problem.

Workaround method

The first option is to call the OnInit() method in the MyApp() constructor, you just need to change the OnInit name, otherwise two application interfaces can be created at once.

4



The second option, this is the classic method, run via int main(), manually create an object of the MyApp class, then call the OnRun function, in this case the program will also start the first time.

Therefore, it is necessary to fix a bug where the OnInit() method is not called by the wxIMPLEMENT_APP macro, if (UIElement == true) is used.


@vadz vadz added the macOS Specific to Cocoa macOS port label Sep 22, 2023
@vadz
Copy link
Contributor

vadz commented Sep 22, 2023

Sorry, I have no idea what is UIElement and how do you set it to true, could you please explain this?

Also, under Mac wxApp::OnInit() is called from OSXOnDidFinishLaunching() which itself is called from [wxNSAppController applicationDidFinishLaunching:] so it looks that either the delegate is not set or its method is not called. Please try debugging what happens in wxApp::DoInitGui().

@DiCode77
Copy link
Author

UIElement's full name is LSUIElement, it should have been mentioned from the beginning, in short this is a parameter that needs to be added to the Config.plist, which is in the program folder, this parameter tells the operating system that this program will run in the background, that is, the icon in the Dock will not be visible, only the shell of the application itself.

More detailed description from Apple

As for the second part of your answer, I will deal with it now.

@vadz
Copy link
Contributor

vadz commented Sep 22, 2023

It would make sense if the applications with LSUIElement set to true didn't call applicationDidFinishLaunching:, although I have no idea why does the behaviour differ between macOS versions. Hopefully there is some other callback we could use in this case?

@DiCode77
Copy link
Author

Just got to the computer, it seems that the problem is in the activateIgnoringOtherApps, Apple says it's already deprecated for macOS 14.0, maybe that's the problem Apple.

@DiCode77
Copy link
Author

DiCode77 commented Sep 25, 2023

I found out that after the [NSApp run] event is generated, the following code is not executed, that is, the application m_onInitResult = OnInit() should be created here, which is not happening, as far as I understand, when we get into the applicationDidFinishLaunching function, we see main action [NSApp stop:nil], then we use [NSApp activateIgnoringOtherApps: YES] to activate the process again, but it doesn't work.

I tried to use another parameter [NSApp active: YES], with it the program started the first time, but I got an error related to events.

Although if you execute m_onInitResult = OnInit() before [NSApp run] is executed, it will work, but in terms of execution sequence there is also a question.

@kamenkitanov
Copy link

I am seeing the same issue on macOS 12.6.6 Monterey and wxWidgets 3.1.4. As @DiCode77 says, the app never returns from [NSApp run] and OnInit is not called.

My workaround currently is to overwrite wxApp::CallOnInit() and activate the app before calling the base implementation:

    virtual bool CallOnInit() override
    {
            [[NSRunningApplication currentApplication] activateWithOptions:
        (NSApplicationActivateAllWindows | NSApplicationActivateIgnoringOtherApps)];
        return wxApp::CallOnInit();
    }

I have tested this also in Sonoma and it seems to resolve the issue.

@vadz
Copy link
Contributor

vadz commented Oct 25, 2023

@csomor Does your "like" above mean that this workaround should be applied?

@csomor
Copy link
Contributor

csomor commented Oct 25, 2023

@csomor Does your "like" above mean that this workaround should be applied?

;-) I have to read a little bit more before I can give the OK, but I appreciate the effort

@csomor
Copy link
Contributor

csomor commented Oct 27, 2023

@DiCode77 @kamenkitanov thanks for your efforts, I've tried to move this into a minimal change PR #24003, could you please test whether this solves the problem for you as well ? Thanks

@DiCode77
Copy link
Author

@csomor Hi, thanks for the fix, ran some tests, with normal launch and auto launch, the app opens properly, it seems to have fixed the problem!

@csomor csomor closed this as completed Oct 27, 2023
@kamenkitanov
Copy link

kamenkitanov commented Oct 27, 2023

Thank you all for quickly applying the fix and for testing/reporting the issue. The fix works for me too, with the caveat I am not on the latest wxWidgets version yet.

vadz pushed a commit that referenced this issue Oct 29, 2023
Change implementation to use Sonoma-supported version of the application
activation call.

See #23893, #24003.

(cherry picked from commit 695ca04)
vadz pushed a commit that referenced this issue Nov 17, 2023
This restores old activation logic for Mac applications, while still
preserving the fix for #23893 from #24003.

Closes #24056.

Closes #24062.
vadz pushed a commit that referenced this issue Nov 17, 2023
This restores old activation logic for Mac applications, while still
preserving the fix for #23893 from #24003.

See #24056, #24062.

(cherry picked from commit 16cca70)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
macOS Specific to Cocoa macOS port
Projects
None yet
Development

No branches or pull requests

4 participants