Steinberg editorhost on 4k monitor is not good

image

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?

The editorhost doesn’t correctly implement the VST3 spec as outlined here: Resize View Call Sequence - VST 3 Developer Portal

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.

When I look at the code in the editor host,
it is doing exactly what is described in the documentation.
Where do you see a difference?

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.

2 Likes

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:

[again.vst3] VSTGUI::VST3Editor::setContentScaleFactor(float) vst3editor.cpp:571
[editorhost.exe] Steinberg::Vst::EditorHost::WindowController::onContentScaleFactorChanged(Steinberg::Vst::EditorHost::IWindow &, float) editorhost.cpp:410
[editorhost.exe] Steinberg::Vst::EditorHost::Window::proc(unsigned int, unsigned long long, long long) window.cpp:204
[editorhost.exe] Steinberg::Vst::EditorHost::Window::WndProc(HWND__ *, unsigned int, unsigned long long, long long) window.cpp:91
[user32.dll] <unknown> 0x00007ff829a58241
[user32.dll] <unknown> 0x00007ff829a57efc
[user32.dll] <unknown> 0x00007ff829a684bc
[ntdll.dll] <unknown> 0x00007ff82b9f3434
[win32u.dll] <unknown> 0x00007ff8295c18d4
[editorhost.exe] Steinberg::Vst::EditorHost::Window::resize(Size) window.cpp:268
[editorhost.exe] Steinberg::Vst::EditorHost::WindowController::resizeView(Steinberg::IPlugView *, Steinberg::ViewRect *) editorhost.cpp:433
[again.vst3] VSTGUI::VST3Editor::requestResize(const VSTGUI::CPoint &) vst3editor.cpp:617
[again.vst3] VSTGUI::VST3Editor::beforeSizeChange(const VSTGUI::CRect &, const VSTGUI::CRect &) vst3editor.cpp:603
[again.vst3] VSTGUI::CFrame::setSize(double, double) cframe.cpp:900
[again.vst3] VSTGUI::CFrame::setZoom(double) cframe.cpp:259
[again.vst3] VSTGUI::VST3Editor::setContentScaleFactor(float) vst3editor.cpp:574
[editorhost.exe] Steinberg::Vst::EditorHost::WindowController::onContentScaleFactorChanged(Steinberg::Vst::EditorHost::IWindow &, float) editorhost.cpp:410
[editorhost.exe] Steinberg::Vst::EditorHost::Window::proc(unsigned int, unsigned long long, long long) window.cpp:204
[editorhost.exe] Steinberg::Vst::EditorHost::Window::WndProc(HWND__ *, unsigned int, unsigned long long, long long) window.cpp:91
[user32.dll] <unknown> 0x00007ff829a58241

... system stack trace omitted
1 Like

Indeed, seems wrong to me too.

Ah, thank you SO much. I wasted so much time trying to figure this out.

for now, I’ve managed to make a workaround whereby I ignore the ‘getSize()’ when resizing the window for the first time.

Thanks for reporting this issue, a fix is now available:

1 Like