In the JUCE Demo, in the Thread Demo, there are these little balls flying around. When I stop moving the mouse over the JUCE window, after a few seconds the balls stop moving, like the whole thing is not being repainted. When I move the mouse again, they continue moving, but not from the same position anymore, so they moved in background, but where not repainted.
right, I’ll check that one out…
it’s also the same in the OpenGL demo. 2 seconds after not moving the mouse, the 3d cube stops turning.
I just made a bet with myself that this is again your Thread-based Timer Code not working, exactly as on OS X, when plugins freezed. There really might be a flaw in it when CPU usage goes up.
Any updates on this?
I’m having the exact same bug.
I also did some printf debugging and realized my 30ms timer is running as a 3s timer or so.
But if I move the mouse around, my timerCallback gets called much more often.
There must be a lock somewhere which gets released on X events or something.
Okay, well, I fixed this problem. It works for me, my timer+repaint() based animations are now smooth on X
By debugging I realized that the X client messages sent by juce_postMessageToSystemQueue() in juce_linux_Messaging.cpp were very slowly received by juce_dispatchNextMessageOnSystemQueue().
I got a lot of timeouts in InternalTimerThread::run(), unless I moved the mouse on the window, as previously said.
Googl’ing about x client messages, I found that the same X display handle shouldn’t be used in different threads.
So, to fix this, I reopen the display in juce_postMessageToSystemQueue():
— build/linux/platform_specific_code/juce_linux_Messaging.cpp (revision 690)
+++ build/linux/platform_specific_code/juce_linux_Messaging.cpp (working copy)
@@ -61,6 +61,7 @@
static Atom specialId;
static Atom broadcastId;
static Atom specialCallbackId;
+static String _displayName;
// This is referenced from WindowDriver.cpp
@@ -198,11 +199,11 @@
sigaction (SIGSYS, &saction, NULL);
- String displayName (getenv (“DISPLAY”));
- if (displayName.isEmpty())
displayName = T(":0.0");
- _displayName = getenv (“DISPLAY”);
- if (_displayName.isEmpty())
_displayName = T(":0.0");
- display = XOpenDisplay (displayName);
display = XOpenDisplay (_displayName);
if (display == 0)
@@ -264,6 +265,9 @@
// Need to reopen display, because the display handle doesn’t play well
// across threads:
Display * display = XOpenDisplay (_displayName);
clientMsg.display = display;
clientMsg.window = juce_messageWindowHandle;
@@ -282,6 +286,8 @@
XFlush (display); // This is necessary to ensure the event is delivered
Good bug-spotting there, but it seems a bit inefficient to keep reopening it - perhaps a thread-local variable might be the best way to access it, then it’d only need to be opened once per thread?
Agreed, I thought about this, but didn’t have enough time for it. Anyway the main idea is in my small patch.
i’m getting the same problem here. if i don’t move the mouse over my juce window for some seconds, the apps starts “thinking” and i get a wait cursor.
anyway your patch doesn’t work here. i get:
In my case, the wait cursor only appeared with Juce release 1.46. Using svn r690, the animations were blocking too, but there was no wait cursor.
So I suspect you are using Juce 1.46. My patch is for Juce svn r690, not for 1.46. Here’s a clean version for download:
oh yeah sorry, it happens with a project i’m actually doing that had an old version of the amalgamated version of juce i forgot to update.
i’ll apply the patches again and see what happens.
This is also related to my OpenGL context threading shenanigans, and probably some problems I encounter when debugging and using printf on Linux.
For the OpenGL, I make a display connection and use that. I didn’t realize other, non graphics stuff was using the display connection, but I guess the messaging is? That’s interesting.
So, should every Linux thread actually have an X connection?