I built the JUCE example plugin called ‘AudioPluginExample’ and loaded it into ‘editorhost’, the example plugin host that comes with the Steinberg VST3 SDK.
The plugin Window opens at 25% of the size I expected, it shows only the top-left quarter of the GUI.
I am using a 4k monitor on Windows 10, set at 200% display-scaling.
What’s going wrong here? Who or what is at fault? Who’s house do I cover in toilet paper?
When opening on a hidpi display, the host correctly sends setContentScaleFactor(factor). The JUCE plugin then sends resizeView(size) back to the host, with the new size that is required for the window. At this point, the host is supposed to resize its window and send onSize back to the plugin to let it know that the window size has been updated, but the editorhost app doesn’t seem to do this step. I recommend filing a bug report with Steinberg.
You’re right, I’ve debugged a bit more and it looks like getSize immediately returns the new editor size rather than waiting for the host to call onSize. The editorhost then assumes that the plugin window doesn’t really need resizing because the rect passed to onSize matches the rect returned by getSize.
I’ll push a fix shortly, so that getSize continues to return the old value until onSize is called.
With our fix in place, the editorhost scaling behavior seems a bit broken when dragging the window very slowly between two monitors with different scale factors on Windows 11. The host window size sometimes changes independently of the editor size.
When dragging from a monitor with 100% scaling to a monitor with 150% scaling, the editor gets a call to setContentScaleFactor with a scale of 1.5, and then immediately gets another call with a scale of 1.0.
It looks like, when the plugin calls resizeView on the host, the editorhost calls SetWindowPos via Window::resize. Windows immediately sends WM_DPICHANGED back to the host window, which then calls setContentScaleFactor again on the view. The result is that the host calls setContentScaleFactor twice in the same call stack but with different scaling values. I suspect that the host needs to guard against reentrant DPI calls from the OS somehow.
This can also be reproduced in the again.vst3 example plugin: