Paint() not called on Mac but works fine on Windows

I have a window that inherits from AudioProcessorEditor. One of the methods I’ve overiden is this one:

virtual void paint(Graphics & g) override;

Everything works fine on Windows. Application looks good. But when I bring it over to Mac, I can see a few calls to paint() when the application first starts up, correctly drawing the initial state I expect, then paint() doesn’t ever get called again once the application has fully started.

On a secondary worker thread that runs in the background, it periodically (every few seconds) makes these calls:

	auto* editor = getActiveEditor();
	if (editor != nullptr)
	{
		LOG("TEST #1");
		const MessageManagerLock message_manager_lock;
		editor->repaint();
		LOG("TEST #2");
	}

I can see those test messages logged every few seconds, so I know that repaint() is being called. But these calls don’t result in my custom paint() to be called to do the work.

Any idea as to what might prevent paint() from being called on Mac vs Windows?

Mac side is built with AppleClang 11.0.0.11000033
Windows side is built with VisualStudio 2019.

You should not call repaint() from other threads than the main/GUI thread. Didn’t you already get a jassert about that while debugging? Ah nevermind, you do have the MessageManagerLock…But maybe repaint() doesn’t work on Mac even when using that.

Isn’t that what the MessageManagerLock is for? If not, then how should I be doing it?

The more correct approach would be to have a timer or some other mechanism in the editor itself that makes it repaint itself.

This sounds like the wrong advice.

You’re telling me that I should setup a frequent timer to regularly repaint the window, because we cannot call repaint() from another thread after we’ve obtained the MessageManagerLock?

Obviously it’s up to you to figure out some mechanism that prevents excessive unneeded redraws with the timer…It’s a commonly suggested mechanism for this. Using MessageManagerLock is almost never recommended. (And I know from experience using it on Mac Os is particularly problematic, even while it seemed to work OK on Windows.)

Isn’t that what MessageManagerLock is for? So calls like repaint() can be made from other theads? Is this a known issue that it doesn’t work on Mac, or are we barking up the wrong tree?

Other approaches would be to use AsyncUpdater or MessageManager::callAsync, which have their own caveats when used from real time threads.

1 Like

Looking up the documentation for MessageManagerLock, the example in the docs is literally to call repaint() on a component from another thread. I’m thinking there must be something else preventing the repaint from happening only on Mac.