Hi,
I’m developing an application on a Linux system. It runs fine on the Linux development machine, but while porting it to Mac I get some errors. Possibly originating from some bad code design. Let me explain what I do:
I have a bunch of buttons, launching some more or less time consuming tasks. To not lock up the GUI when such a task is in progress, the Component owning those buttons also owns a ThreadPool
and a nested ThreadPoolJob
for all button actions. The buttonClicked
callback then just calls ThreadPool::addJob
and dispatches the acual work to the Thread Pool. This works quite well on my Linux system.
Now there is one Button that invokes a child process which needs to display the console output of that process after it has finished its work to the user, so I acquire a MessageManagerLock
(which in my understanding allows me to safely do some GUI calls from a background thread?), create a Label
, put some text in it, create a DialogWindow
, let it own the Label with the text and then call dialogWindow.launchAsync()
. This works as expected on my Linux system, but locks up the whole GUI on my Mac while not even displaying that dialog window. I can see that some Main Thread Checker: UI API called on a background thread
errors appear on the console. However, I thought GUI calls from a background thread are okay as long as the MessageManagerLock
is acquired - am I wrong in this point?
So, what’s the wrong step here and how should I change my code-design to make it better?
For your information, here are the important parts of the code:
JobStatus runJob() override {
ChildProcess networkSettingsProcess;
// Let the child process do its work and check if it did everything right...
MessageManagerLock mml;
Label *dialogMessage = new Label;
dialogMessage->setColour(Label::ColourIds::backgroundColourId, Colours::darkgrey);
dialogMessage->setText("Network adapter settings were successfully changed. Log messages:\n\n" + networkSettingsProcess.readAllProcessOutput(), NotificationType::dontSendNotification);
dialogMessage->setBounds(0, 0, 500, 500); }
DialogWindow::LaunchOptions dialogWindow;
dialogWindow.dialogTitle = "Network Setup Done";
dialogWindow.content.setOwned(dialogMessage);
dialogWindow.launchAsync();
return jobHasFinished;
};