JUCE 7 has introduced the consolidation of repaint calls on Windows to synchronize them with the screen refresh (Git commit 05a42424f980).
The associated monitor for a
HWND is determined with
MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL). The monitor for a component which is added to the desktop with a position outside of any screen will therefore be NULL and will not get attached to a
VSyncThread immediately. When the component is moved, a call to
handlePositionChanged() will appear after a
WM_WINDOWPOSCHANGED was received and will update the associated monitor.This works well in most standard situations.
However, hosted plugin editors in JUCE are embedded into several layers of native windows. Additionally, in our use case we have further surrounding native desktop windows to allow scrolling of hosted plugin editors.
Those child windows will never receive a
WM_WINDOWPOSCHANGED because their position relative to the parent does not change. Therefore, they will never get attached to a
VSyncThread even if they are moved into a screen area and will never get repainted.
For a quick fix I would propose to change the behaviour of
MONITOR_DEFAULTTONULL to one of the other options:
But I am still unsure if the overall approach works correctly for nested native windows in general and if it might be a better fix to make sure all child windows get re-attached to a
VSyncThread when their parent component’s monitor has changed. For example move a hosted plugin in the AudioPluginHost Demo between two screens on Windows and you can see in the debugger that the associated monitor will never get updated.