I have a component that is setAlwaysOnTop(true) and fairly regularly it moves itself.
If I get the cpu usage high (just moving the mouse over other components really fast so they need to repait a lot is enough) then the moving component fails to erase itself as it moves. (Or more likely, the components underneath are not getting their repaint message)
Nasty. I expect that it’s not the cpu that’s the factor, but rather that there are lots of separate areas being told to repaint at the same time.
One quick idea, looking at the mac code, is that it might be a floating point rounding error. The HIView repainting is all done in floating point co-ords, and a quick way to test it would be to increase the area in juce_mac_Windowing.cpp, line 710, just by adding a pixel, e.g.
r.origin.x = x - 1;
r.origin.y = y - 1;
r.size.width = w + 2;
r.size.height = h + 2;
If that sorts it out, then we can try some more elegant rounding on the numbers.
Hmm. That’s bad news because it’s Apple code that manages the paint region. They might have a bug, or maybe some limit on the number of rectangles before it starts ignoring them? I guess the only way to find out would be to make it reproducable, but that’s not easy.
Hmm. Yes, resizing a component from within a paint() would call repaint() indirectly. Seems like the mac must be clearing the dirty region list at the end of the paint callback, and losing any new regions that were added.
I think it might actually be better to say that repaint() is ok in a paint() callback, and to fix the mac implementation so that it works. I’m not on my mac at the moment, but how about this little change to the order in the mac ComponentPeer:
[code] if (context.reduceClipRegion (regionsNeedingRepaint))
{
regionsNeedingRepaint.clear();
if (! peer->getComponent()->isOpaque())
{
for (RectangleList::Iterator i (*context.getRawClipRegion()); i.next();)
{
const Rectangle& r = i.getRectangle();
image->clear (r.getX(), r.getY(), r.getWidth(), r.getHeight());
}
}
regionsNeedingRepaint.clear();
peer->clearMaskedRegion();
peer->handlePaint (context);
}
else
{
regionsNeedingRepaint.clear();
}