I tried calling DialogWindow::showModalDialog from another thread than the message thread on Mac OS X and I hit the
CHECK_MESSAGE_MANAGER_IS_LOCKED assert in Component::addToDesktop.
I have hit this assert before, so I add a MessageManagerLock before calling showModalDialog.
Now I hit the assert jassert(! currentThreadHasLockedMessageManager()) in MessageManager::callFunctionOnMessageThread which is called from Component::runModalLoop.
These two asserts contradict each other, meaning that showModalDialog cannot be called from any other thread than the message thread, even though Component::runModalLoop tries to run it on the messsage thread.
On Windows I hit an assert when setting the title for the window, saying that only the message thread can call this function.
I am unsure whether this issue needs to be fixed or whether an assert checking that the current thread is the message thread just needs to be added to DialogWindow::showModalDialog.
My own work around for this issue is to create a DialogWindow with DialogWindow::LaunchOptions::launchAsync() inside a callFunctionOnMessageThread callback and then just call runModalLoop on this window. Example code below.
I understand you cannot run a modal loop from any other thread than the message thread, but you can trigger it from another thread.
This is at least how I understand the following code.
[code]int Component::runModalLoop()
{
if (! MessageManager::getInstance()->isThisTheMessageThread())
{
// use a callback so this can be called from non-gui threads
return (int) (pointer_sized_int) MessageManager::getInstance()
->callFunctionOnMessageThread (&ComponentHelpers::runModalLoopCallback, this);
}
if (! isCurrentlyModal())
enterModalState (true);
return ModalComponentManager::getInstance()->runEventLoopForCurrentComponent();
}[/code]
What is the point of the callback if its not suppose be called from any other thread than the message thread?
(It’s very old code, and I actually wouldn’t generally recommend using it, TBH, because it could lead to deadlocks if the message thread tries to stop the thread that’s calling runLoop)
Because if you are not using native alert windows, these functions eventually call AlertWindowInfo::invoke which uses callFunctionOnMessageThread and Component::runModalLoop. But you never get any indication that this is a bad idea, as it just works.