Scaling issues with vst3 Plugin Child Windows on Linux/Windows

This commit

and a few related ones before changed scaling behavior in Hi-DPI situations. Things seem fine on Windows, but on Linux with KDE/Wayland I am now seeing problematic behavior for child windows opened by VST3 plugins (PopupMenus / Dialogs / Callouts) and with mouse input in general.

When running a JUCE VST3 plugin inside an X11 host such as Reaper, child-windows appear at incorrect positions and with a different scaling factor than the plugin window itself. Five commits earlier, the behavior was that system scaling factors were essentially ignored, but at least it was consistent and could be worked with.

Now it seems that the main plugin window still opens at 1x pixel scale, while all child windows are scaled by some variant of the system scale factor, and their screen positions are incorrect. This even happens when the system is using legacy scaling mode, where applications should not even be aware of any scaling.

Additionally, when not using legacy system scaling, mouse coordinates appear to switch between scaled and unscaled values during movements.

These changes have completely broken my Linux builds, and I don’t see a practical workaround. Standalone builds work fine.

Is this a known issue, and is there a fix in the works?

I’m testing this with the following setup:

  • Fedora 43
  • KDE Plasma 6.5.5
  • KDE Graphics Platform: Wayland
  • REAPER 7.59
  • Two monitors, one at 100% scaling, and the other at 125%

I’m not sure where you’re setting ‘legacy scaling mode’. In System Settings → Display & Monitor → Display Configuration, I see two options for “Legacy applications (X11)”: “Apply scaling themselves” or “Scaled by the system”.

I tried building the DSPModulePluginDemo VST3 from the develop branch and running it in REAPER. In both X11 scaling modes, combo-box menus open in the correct location and with the correct scale, as do the popup menus when right-clicking on parameters. When “Apply scaling themselves” is enabled, REAPER and its plugin windows are downscaled on the 100% monitor and render with no scaling on the 125% monitor. When “Scaled by the system” is enabled, REAPER + plugins are rendered without scaling on the 100% monitor, and windows are upscaled on the 125% monitor.

Please could you let us know:

  • Which KDE version are you using?
  • Are your graphics drivers up to date? Which version are you using?
  • How are your displays and scaling configured (a screenshot would be helpful)?

Thanks in advance!

Thank you for checking. I built the DSPModulePluginDemo.vst3 myself with today’s JUCE development branch and am still getting the issue.

I am using a very similar setup to you:

Fedora 43, up-to-date
KDE/Plasma 6.5.5, Wayland
Reaper v7.57 (same problem in Ardour 8.12 btw.)


The popup menus appear to be positioned and scaled based on my main display scale (200%).

Here’s my display setup (I used only my main screen for demonstration) :

Maybe the difference is that my main screen is not at 100% scaling?

Before the commits I mentioned, this worked perfectly with the exact same setup.

1 Like

Out of interest, if you carry out the following steps:

  • Log in
  • With REAPER closed, change your screen scale to 100% and hit “apply”
  • Change the scale back to 200% and “apply”
  • Open REAPER

Do you get more reasonable-looking results in that case?

I did see some strange-looking positioning when I change the scale to 200% then logged out and logged back in, so maybe the bug only happens when the scale factor is set during login. I’ll investigate some more.

Ok, I will try that shortly. In the meantime, I tested on machines running Ubuntu 24 LTS and Ubuntu 25 (with Wayland) with fractional scaling and the scaling was correct on those.

I tried changing scales multiple times without success, but then finally realized what is causing the problems:

In an effort to get sharp graphics on my high-dpi display, I used “Legacy Applications (X11) apply scaling by themselves“ in Display preferences and added 150% scaling to both Reaper and Ardour using their settings:
In Reaper it’s an item in ~/.config/reaper.ini called ui_scale=1.5
Ardour has a setting in its Preferences/Size and Scale called GUI and Font scaling I had at 150%.

Both of these lead to the plugin window being enlarged and that seems to be what throws off the JUCE scale and positions of child windows since the mechanism was changed. Before the changes, popup-menus would show up at the position and be scaled to the same scale as the plugin window.

If I revert both apps to 100%, things work as expected but are of course blurry.

If I let Reaper detect the scaling by itself, things now work fine.

But with Ardour, not so much. I have my system set to 200% scale, X11 apps to “scale by themselves”. Ardour opens as a tiny application opening tiny plugin windows, but the popup menus get drawn at 200% scale with the top-left position scaled 2x.

The only way Ardour (8.12) works for me is running in the blurry “scaled by the system“-mode.

I also tried a freshly installed Bitwig Studio. Using X11-apps-“scale by themselves”, the app scales correctly, but plugins open up tiny while the child windows get scaled and popup up in the wrong place.

I just tried this out on Manjaro KDE/Wayland. If I have the “Legacy applications (X11)“ set to “Apply scaling themselves”, Ardour does not use the system scale, while the plugin (within Ardour) does. In Ardour preferences, you can set the scaling under “Appearance→Size and Scale”. If that is set to the same value as the KDE system scale (215% in my case), everything seems fine. But if the Ardour scaling does not match the KDE setting, I also get weird positioning of the dropdown (which seems to be based on the system scale somehow)

1 Like

With the new knowledge I can get this issue to happen on Ubuntu 25 with Gnome as well. If a host is applying extra scaling to plugin windows, child/sub-windows created by the plugin do not respect it. It seems the conversion from local coordinates and scale to screen coordinates/scale fails in that case.

Today I found this issue also partially exists on Windows under some circumstances.


This is Reaper on Windows 11 on a 150% screen. I disabled application scaling in both Reaper and Windows (Reaper.exe application properties). On the left is my plugin built with JUCE 8.0.9. The popup menu shows at at the correct location and scale. On the right is the DSP demo build with the develop branch and while the position of the popups is correct, the scale is using system scale instead of the plugin window scale.

@reuk, is there any news on this? To me, this is a blocking problem that makes working with the Juce develop branch impossible.

Thanks for your patience - these scaling issues tend to be fairly time-consuming, as they require testing on all supported platforms, and there are a great many use-cases that must be considered. We have a patch in review at the moment that should address the issues you’ve raised. In particular, auxilliary windows that have a ‘target component’ will be fixed to match the scale factor of the target, which should restore the behaviour from the master branch. I’m not sure how long it will take for this branch to be published, but I would expect it to be within days, rather than weeks.

3 Likes

Could we get that behaviour customized? Having plugins scaled down and then having very small to tiny drop-downs is something we would like to avoid.

There’s already a shouldPopupMenuScaleWithTargetComponent() function that can be overridden on the look and feel. Do you need customisation beyond that?

1 Like

No, that should suffice.

We’ve now pushed a series of updates in this area. These two commits are particularly relevant:

Please try updating to the current develop branch and see whether it fixes the issue for you. Please also let us know if you spot any regressions or new problems. Thanks!

1 Like

Thank you very much for the fixes. I see correct scaling and placement of child windows now. The DSPModulePluginDemo works perfectly.

In my own plugin I see a new issue with path (frequency display) drawing. It almost looks like my display component gets wrong values for getWidth() and getHeight() if scaling is applied by the host. However I have to check my code first before blaming Juce and will do so over the weekend.

1 Like

@reuk. Trying to figure out whether my code is at fault for the weird polygon rendering I found a new issue with the latest changes that might be related and happens with the code on the latest develop only. If I build DemoRunner and run it on my 200% scaling fedora/kde machine, I get weird scaling of the individual letters of fonts. It seems to be different for different fonts, but some look really bad (including the ones I want to use). It happens in both system scaling modes, the “Droid Sans” font seems to be affected more than others.

This is with “Apply scaling themselves” (sharp):

And “Scaled by the system” (blurry):

Thank you for your work. I realize this is a very annoying problem to solve due to the number of systems and screen configurations possible and the numerous workarounds/modes/adapters on both Windows and Linux.

I could be wrong, but that might be because of an issue I’ve just spotted regarding font rendering with the software renderer, caused by this commit Font: Remove deprecated functions · juce-framework/JUCE@63aa6f3 · GitHub

Let me know if this patch fixes the issue for you
JUCE-dev-2e3ad0f-Software Renderer: Fix font height regression.patch (1018 Bytes)

1 Like

Hi Anthony. Yes, your patch did fix the weird font rendering!. But I am seeing more issues now. I saw incomplete path rendering previously using the software renderer. I was able to fix that by changing the order in which I add the points to the path - which seems weird.

Additionally, I see a problem with generating paths from fonts. I use juce::GlyphArrangement::createPath() to create paths for letters and this now generates y-flipped paths with huge bounds (20’000s width & height). The y-flip also leads to incorrect winding. This must have changed recently.

I use this code that used to work just fine:

static inline juce::Path pathForString(const juce::String &str, bool bold) {
    juce::Path tp;
    auto f = juce::Font(juce::FontOptions(16.f, bold ? juce::Font::bold : juce::Font::plain));

    juce::GlyphArrangement glyphs;
    glyphs.addLineOfText(f, str, 0.f, 0.f);
    glyphs.createPath(tp);
    return tp;
}

Do you know what/why/when has recently changed in Font rendering?

1 Like