HiDPI, DPIAwareness, VST et al

I’m sorry for opening another thread on this lovely subject.

In general things works well for us,
But for one specific case I need to get the correct scale and this fails under Nuendo 13 and REAPER 7, Standalone works just fine.

When things go wrong?
With multiple displays. I have a laptop with 2.8K display and 200% scaling. and an 1080k at 100% scaling.

The strange thing is that only when running as VST3, I get the wrong scale for the secondary display… It seems to be sticking with the main display DPI.

The Desktop::findDisplays functions kick at first creation or when dis/connecting another monitor

Anyone got a hint about this?

Just a hunch, but maybe it’s grabbing the DPI of the display the host is on? Does the scaling change if you also move the host window to the other display?

Thanks for the idea.
I’m afraid the DPI is the same.
Also, the juce::Displays are being calculated only once on creation or when physically attaching/detaching displays.

The following is working on my system (windows 11, Reaper 7.11, Juce 7.0.11, VST3), switching between a 200% and a 100% display:

juce::Desktop::getInstance().getDisplays().getDisplayForRect(component->getScreenBounds())->scale

Are you using one display or two?

Two displays, one with 200% scaling, the other with 100% scaling.

Did you check the value of your JUCE_WIN_PER_MONITOR_DPI_AWARE constant?

Thanks, this is enabled by default on Projucer…

The problem from what I’m seeing is a mixed-bag which I’m not sure what’s the right approach. In order to properly grab DPI, there’s GetDpiForMonitor it’s not being used if loadDPIAwarenessFunctions() is not set, and that’s never the case for non-Apps…

static void setDPIAwareness()
{
....
    if (! JUCEApplicationBase::isStandaloneApp())
        return;

Interesting tidbit, getCursorSizeForPeerFunction explicitly calls it.
I suspect for the Displays query it should be used if valid since Displays are per “Desktop” and agnostic to the host…

The following is working on my system (windows 11, Reaper 7.11, Juce 7.0.11, VST3), switching between a 200% and a 100% display:

REAPER has multiple settings for how it behaves about DPIs. did you change it at some point?

What settings exactly?
I could not find anything related to DPI glancing over the different preference tabs.

REAPER has:

With:

Anyway, I think the juce::Desktop approach can result incorrect dpi / scale values. Not sure why my device is different. It’s a laptop with Intel Arc graphics and Intel Core Ultra 125H.

For my specific need of some MouseEvent scaling got wrong, this was useful:

    auto scale = juce::Component::getApproximateScaleFactorForComponent (component);

Looks like I have the same settings as yours in all relevant areas.

getApproximateScaleFactorForComponent should return the AffineTransform scale and miss the display one.

Here are two methods I use to get the final scale from either the component or the graphics context:

// logic barrowed from ComponentAnimator
float getFinalScale(juce::Component* component) {
	return
		(float)juce::Desktop::getInstance().getDisplays().getDisplayForRect(component->getScreenBounds())->scale
		*
		juce::Component::getApproximateScaleFactorForComponent(component)
	;
}
// same result:
float getFinalScale(juce::Graphics& g) {
	return g.getInternalContext().getPhysicalPixelScaleFactor();
}

Also worth mentioning: in the Direct2D branch getPhysicalPixelScaleFactor ignores the AffineTransfrom part for some reason, contrary to all other renderers I tried on both PC and Mac. @matt mentioned its behavior could change in JUCE8.