Unwanted image stretching on 4k monitor (JUCE 6 and 7 - Windows)


I found strange image stretching when displaying image inside modal DialogWindow (using drawImage* methods inside paint() method). Right after image has been displayed, it gets stretch-down automatically for a few pixels. After that, all other components are slightly realigned as well.

This is happening only on hi resolution (4k), with active scaling. I’ve experienced issue also when displaying image in main component, but it’s not so obvious like it is with dialog window.

Here’s the video showing this misbehaviour: first example is using Projucer 7, 2nd example is showing my test program. In both cases, you can see unwanted image down-stretching right after modal window has been opened.

EDIT: further investigation shows, that delaying image painting a bit (200 ms) fixes stretching, but this is obviously not an acceptable solution.

Any ideas?

I found the code which is causing the stretching. It’s happening in ComponentPeer::handlePaint() method.

if (peerBounds.getWidth() != componentBounds.getWidth() || peerBounds.getHeight() != componentBounds.getHeight())
        // Tweak the scaling so that the component's integer size exactly aligns with the peer's scaled size
        g.addTransform (AffineTransform::scale ((float) peerBounds.getWidth() / (float) componentBounds.getWidth(),
                                                (float) peerBounds.getHeight() / (float) componentBounds.getHeight()));

Somehow, when showing DialogWindow, peer bounds are 4 pixels larger than component bounds. Not sure where this difference came from … maybe it’s border thickness ??

Can any of the devs take a quick look at this this? It’ can be easily reproduced by opening Projucer “About” window on hi-res monitor with scaling active. I don’t think this stretching can be considered as normal. @reuk @ed95

Any help would be greatly appreciated!

Polite bump :slight_smile:


I have two 4K monitors, both with different scaling values on each monitor and I don’t see any delay within Projucer.

I will try my laptop when I get a chance.

1 Like

It’s not delay, but slight de-scaling of the dialog contents (for example contents of Projucer “About” dialog).

I am using 4k monitor with 3840x2160 resolution - tried with 150% and 200% scaling.

In my video above it’s visible how Juce logo shrinks a bit when dialog is displayed. Not happening here when scaling is disabled.

I have absolutely no idea why this is happening. It’s interesting that this is happening only when window is TopLevelWindow, ResizableWindow, DocumentWindow and similar. It’s NOT happening when i am using raw component to mimic window (using the same content as with document).

If anyone else can replicate this issue or maybe has any idea what could going on, please let me know.

Thx for help!

Sorry, by delay I mean, I wasn’t able to catch the scaling happening due to it happening so quickly on my machine.

It’s normal for components to change their scaling when it detects a change (going from monitor to monitor for example).

Are you testing in Release mode?

1 Like

Sure, usually they are scaled correctly, but this one, hm, i dunno, it looks like dialog is first displayed and then it’s contents are immediately shrinked.

I did an experiment where i displayed dialog with 200 ms delay (using timer) and shrinking dissapeared !?!

I tried both debug and release modes.

I think Projucer example is sometimes a bit difficult to notice. But if you’ll create your own example, you’ll notice it and it will become extremely annoying, especially when dialog contains a lot components.

Unless something else is going on, this is common; the component starts with default scaling and then rescales itself to match the monitor. It could also be exacerbated by something to do with it being a child window.

A delayed launch would mask the scaling delay too.

Can you replicate this behaviour by dragging the window across monitors with different scaling parameters?

No, i don’t notice it when dragging window.

In my example, scaling transformation (correction) takes place because peer dimensions are 4 pixels larger than its component dimensions . I tried to debug JUCE code (ComponentPeer::handlePaint()) - see the code in one of my previous replies). I would say that both peer and component are already scaled, but slight difference appears. Sometimes there are also cases (on the exact same dialog), when dimensions match and then no scaling is applied.

Note that this is happening, when dialog is initially showing.

I will have to see if I can replicate this but so far its not happening on any of my machines.

How are you instantiating the child windows?

Can i send you my example VS project? It’s very basic.

My example is using juce::DialogWindow::LaunchOptions for child window. Child window uses content component, which displays bitmap.

If the image is being redrawn at a different size, I would expect the About box’s repaint function to be called a few times. If I stick a breakpoint in the repaint function, then presumably I should see the background image being painted at the incorrect size after hitting the breakpoint once, and then drawn at the correct size after hitting it again (or several more times).

Instead, I see the image drawn correctly after the very first paint:

trimmed.zip (1.4 MB)

What happens if you put a breakpoint in the same place? Is the paint function being triggered more times on your system?

1 Like

FWIW the g.addTransform (... line of ComponentPeer::handlePaint isn’t hit for me when I open the Projucer’s “About…” window. I’ve tried with 150% and 200% scaling. I’m testing on Windows 10 21H2.

Without being able to reproduce the issue I don’t think we’ll be able to make much progress. Is there anything potentially unusual about your computer (multiple attached displays with different scaling factors) or OS install (are you using the latest version of Windows 10, or an older version?) or your build of the Projucer (are you building with Visual Studio or something more unusual like MinGW, changing the preprocessor definitions etc.)?

Edit: it might also be interesting to know which Windows SDK version you’re using to build the Projucer. I don’t think that should have an effect, but it’s another data point.

1 Like

Thx for your effort! I did most of the debugging with my test program. I’ll now repeat that with Projucer as well.

Ops interesting … paint() method is triggered 3 (!) times … we are on something!

Using freshly cloned JUCE 7.0.2 repository with VS 2019 and SDK 10.0.18362.0.

Running Win10 - i don’t do updates often, a bit paranoid, computer is running pretty smoothly with tons of software (music production, sw development). Windows update is the last thing i would do :slight_smile:

My displays config is following:

primary: DELL touch screen (HD 1920 x 1080, no scaling)
secondary: BENQ (4K 3840 x 2160, 200% scaling)

What is special is, that because of space limitations, my 2nd monitor is on the left and 1st monitor on the right.

Issue is present only on 4K monitor! For test, I’ve tried also to reverse the order of monitors with the same results. Interesting thing is also that number of paint() calls is decreasing when i set scaling on 4K monitor to lower value, 150%, for example.

I tried to make a video, but having some issues when capturing 4k screen :frowning:

Please could you let me know which Windows 10 version you’re running?



I think we’ve reproduced most parts of your set-up, but there are two that we haven’t tried out here:

  • I’ve been testing with VS2022 and SDK 10.0.22621.0. I don’t think the VS version should have any effect, and the SDK version is unlikely to, but you could try installing a newer SDK (you can do this alongside your existing SDK) and check whether a build of the Projucer using the new SDK still exhibits the problem.
  • I’ve been testing on the latest Windows 10 and Windows 11 releases, but we can’t easily test your OS version because it reached end-of-life in December 2021. The scaling behaviour may have changed between OS versions. If you’re reluctant to update your OS you could test out a newer version of Windows in a virtual machine instead.

Perfect … big thanks, i’ll give it a try with the latest SDK and then Windows VM as well. Let’s see…