HumbleUI/JWM

macOS: Work around for -XstartOnMainThread

mworzala opened this issue · 3 comments

JavaFX appears to use performSelectorOnMainThread to start the app, perhaps it is worth doing something similar. Should also be easier to work with native image, as apparently the option does not work (though I have not tested personally)

Eg

App.init(() -> {
    Window window = App.makeWindow();
    // ...

    App.start();
});

Interesting! That would be a huge usability improvement. Can you check if it works? We have this

JWM/macos/cc/App.mm

Lines 85 to 97 in def339b

extern "C" JNIEXPORT void JNICALL Java_io_github_humbleui_jwm_App__1nRunOnUIThread
(JNIEnv* env, jclass cls, jobject callback) {
JavaVM* javaVM;
env->GetJavaVM(&javaVM);
auto callbackRef = env->NewGlobalRef(callback);
dispatch_async(dispatch_get_main_queue(), ^{
JNIEnv* env2;
if (javaVM->GetEnv(reinterpret_cast<void**>(&env2), JNI_VERSION_1_8) == JNI_OK) {
jwm::classes::Runnable::run(env2, callbackRef);
env2->DeleteGlobalRef(callbackRef);
}
});
}
but as far as I remember it didn’t worked without -XstartOnFirstThread for some reason anyway

but as far as I remember it didn’t worked without -XstartOnFirstThread for some reason anyway

As far as I could tell at a glance, this requires [NSApp run] to have been called for the inner part to be executed.

I do seem to have a version working locally without -XstartOnFirstThread, although the API will need to change. There needs to be some runnable to do user init. It could be what I posted above, but I am not sure there is any reason to separate App#init and App#start, eg something like

App.init(() -> {
    Window window = App.makeWindow();

    // ...
}); // blocks for app runtime

Let me know what you think regarding API while I clean up my local version.

(I am not convinced I can explain how performSelectorOnMainThread works, but it does seem to work. Perhaps someone with more experience can comment after seeing it)

The design you proposed is nice. So init will do what now init + start do combined, right? And init will block, in the hope you could do rest of your logic inside event handlers, right?