AlertWindow and DialogWindow won't scale and center after setGlobalScaleFactor or when JUCE_WIN_PER_MONITOR_DPI_AWARE disabled

AlertWindow and DialogWindow won’t scale and center after setGlobalScaleFactor or when JUCE_WIN_PER_MONITOR_DPI_AWARE disabled.

i’m using juce 6.1.1 on windows.

I created a new project (standalone audio application) to reproduce.

MainComponent constructor

    addAndMakeVisible(m_btn);
    m_btn.setButtonText("OPEN DIALOG");
    m_btn.onClick = [this] {

    juce::DialogWindow::LaunchOptions o;      
    o.content.setOwned(new TestComponent());
    o.content->setSize(460, 300);
    o.dialogTitle = "Dialog test";
    o.dialogBackgroundColour = o.content->getLookAndFeel().findColour(juce::DocumentWindow::backgroundColourId);
    o.escapeKeyTriggersCloseButton = true;
    o.useNativeTitleBar = false;
    o.resizable = false;
    o.componentToCentreAround = this;
    
    o.launchAsync();

};

Result : dialog is centered.

Now in the app constructor i add :
juce::Desktop::getInstance().setGlobalScaleFactor(1.5f);

Result:

Now JUCE_WIN_PER_MONITOR_DPI_AWARE is disabled and setGlobalScaleFactor removed.

Result:

Am i doing something wrong ?

Looks like when JUCE_WIN_PER_MONITOR_DPI_AWARE is disabled ,
Desktop::getInstance().getGlobalScaleFactor() returns the system set scale which in my case is 1.25 (125%).
However AlertWindow and DefaultDialogWindow desktopScale member get set to 1.0f.

Those patches seem to resolve the issue.

juce_AlertWindow.cpp (Line : 39)

AlertWindow::AlertWindow (const String& title,
                          const String& message,
                          MessageBoxIconType iconType,
                          Component* comp)
   : TopLevelWindow (title, true),
     alertIconType (iconType),
     associatedComponent (comp),
#if JUCE_WIN_PER_MONITOR_DPI_AWARE
     desktopScale (comp != nullptr ? Component::getApproximateScaleFactorForComponent (comp) : 1.0f)
#else
    desktopScale (Desktop::getInstance().getGlobalScaleFactor())

#endif
{
    setAlwaysOnTop (juce_areThereAnyAlwaysOnTopWindows());

    accessibleMessageLabel.setColour (Label::textColourId, Colours::transparentBlack);
    addAndMakeVisible (accessibleMessageLabel);

    if (message.isEmpty())
        text = " "; // to force an update if the message is empty

    setMessage (message);

    AlertWindow::lookAndFeelChanged();
    constrainer.setMinimumOnscreenAmounts (0x10000, 0x10000, 0x10000, 0x10000);
}

juce_DialogWindow.cpp (Line : 79)

  DefaultDialogWindow (LaunchOptions& options)
        : DialogWindow (options.dialogTitle, options.dialogBackgroundColour,
                        options.escapeKeyTriggersCloseButton, true,
#if JUCE_WIN_PER_MONITOR_DPI_AWARE
                        options.componentToCentreAround != nullptr
                            ? Component::getApproximateScaleFactorForComponent (options.componentToCentreAround)
                            : 1.0f)
#else
        Desktop::getInstance().getGlobalScaleFactor())
#endif
    {
        setUsingNativeTitleBar (options.useNativeTitleBar);
        setAlwaysOnTop (juce_areThereAnyAlwaysOnTopWindows());

        if (options.content.willDeleteObject())
            setContentOwned (options.content.release(), true);
        else
            setContentNonOwned (options.content.release(), true);

        centreAroundComponent (options.componentToCentreAround, getWidth(), getHeight());
        setResizable (options.resizable, options.useBottomRightCornerResizer);
    }

juce_TopLevelWindow.cpp (Line : 290)

void TopLevelWindow::centreAroundComponent (Component* c, const int width, const int height)
{
    if (c == nullptr)
        c = TopLevelWindow::getActiveTopLevelWindow();

    if (c == nullptr || c->getBounds().isEmpty())
    {
        centreWithSize (width, height);
    }
    else
    {
#if JUCE_WIN_PER_MONITOR_DPI_AWARE
        auto targetCentre = c->localPointToGlobal (c->getLocalBounds().getCentre()) / getDesktopScaleFactor();
#else
        auto targetCentre = c->localPointToGlobal (c->getLocalBounds().getCentre());

#endif
        auto parentArea = c->getParentMonitorArea();

        if (auto* parent = getParentComponent())
        {
            targetCentre = parent->getLocalPoint (nullptr, targetCentre);
            parentArea   = parent->getLocalBounds();
        }

        setBounds (Rectangle<int> (targetCentre.x - width / 2,
                                   targetCentre.y - height / 2,
                                   width, height)
                     .constrainedWithin (parentArea.reduced (12, 12)));
    }
}

Thanks for reporting. I’ve pushed a fix for this to the develop branch here:

while this commit seems to fix standalone exe’s on Windows,
I still experience a similar issue with vst3 and vst2 plugins.

The following is a juce AudioPluginDemo with a new button which toggles the juce desktop scaling factor between 1.0 and 1.5 and another one showing a simple alert. The alertwindow appears to scale somewhat, yet looks still too small to me in both cases?

note this is the latest develop branch of today

I’m running Windows 10 on a macbook pro with retina display. The Windows HDPI desktop scaling factor is set to 200%. And indeed the alert seems to be about half the size we would expect?

PS: PM me if you’d like the code

In a plug-in you’ll need to associate the auxiliarlly desktop window with your editor component since this has a scale factor that has been set by the host, which may not correspond to the desktop scale factor. You can do this via the associatedComponent parameter for AlertWindows.

The problem seem that child windows do not get desktopscale factor. there is a simular thread. here . and the result is Use font and size from DAW in juce popup menus? - #23 by getdunne

I think it is very usefull that all child windows that are create from a parent window have the same desktop scale factor

You can do this via the associatedComponent parameter for AlertWindows.

thanks @ed95, that worked! (could only test now…)

  • associatedComponent parameter did the trick for juce::AlertWindow ctor
  • also, the componentToCentreAround parameter was needed for juce::DialogWindow::showModalDialog()

Hello
is it possible to easy add code, that juce is able to open all child windows of a plugin with the current windows desktop scale factor ?. because currently desktop scale-factor does not get propagated to new juce::DocumentWindow based windows created by a JUCE-based plug-in for example additional preference windows or popup menu windows