Detecting HiDPI Displays

Hi Everyone,

This probably an easy one and I’m just having a moment. :slight_smile:

Is there a way to detect if you application is running on a machine with a HiDPI display? I thought about using the Canvas ScaleFactor property or ScaleFactorChanged event without luck.

My old 2013 27" iMac doesn’t have a Retina display but I got a 28" HiDPI display for my new Mac mini and I can certainly see that my app is using the hi-res images on my Canvas Buttons.

Would be nice to know though so I could do some programatic changes at some point…

Cheers

TC

Does DesktopDisplay.ScaleFactor get you what you want?

Thanks Tim,

Possibly, on my HiDPI display if gives me a value of 2, so I’m assuming a non HiDPI display would have a value of 0.

I can see that my app is using the 3 x Images on the buttons so this makes sense…

Regards

TC

Using PDFs is much easier than using images in 1x and 2x. But your app isn’t using the 3x images for desktop.

Should be 1

Why do you want to know this, just for curiosity sake or are you planning to draw different graphics for different resolutions?

The Apple recommend way is to use API that Xojo doesn’t expose and to do this for each control.
It is possible to have a window ride multiple displays at which point the window adopts the highest resolution, but each control may not.

However if you stick to using points instead of pixels and standard functionality, the macOS will handle this for you.

This is a scaling factor, so a normal screen would be 1. However do not assume that it will always be 1, 2 or 3. Windows offers intermediate sizes and Apple may also in the future (technically some of their screens are already at intermediate sizes, but they fake with software).

1 Like

Just for curiosity sake really. I like learning new things and seeing what can be done with them. I use image sets for my canvas buttons and they work great on HiDPI displays. Even better now that I replaced the supplied HDMI cable with a Thunderbolt 4 to DisplayPort cable…

TC

As long as it’s simply curiosity, I just wouldn’t recommend altering the contents of your views based upon the Window’s scale factor.

With some declares you can find out the scale factor that is actually applied to that view.

1 Like

I’m going to revive this old topic because I just spend an hour tracking down a “bug” that turned out to be a feature and it led me to this particular thread.

I have two screens on my Mac - a Retina laptop screen, and a conventional external monitor. Some of my rendering code was working fine on the Retina display but producing strangely blurry results on the external monitor.

Turns out I was unwittingly using fractional coordinates to draw a rectangle, draw a picture, etc. On the Retina display, all was well. But on the external monitor, the rectangle was being drawn “in between” two pixels and producing blurry results.

I ended up trimming the fractional parts of the coordinates to make them land on whole pixels, producing good results on both screens, but it really would be best to only do this on the conventional display. And the only way to do that is to know at render time, within the Paint event, what the rendering situation is.

I’ve filed an issue against the documentation to suggest that this situation be mentioned and a fix included:

https://tracker.xojo.com/xojoinc/xojo/-/issues/75870

This is the function to use to determine if s specific view is on a 1x, 2x or 3x screen. Takes a NSSize and returns it converted to be pixel aligned. passing in NSSize( width: 1, height: 1 ), will return how many pixels are used for that size.

IIRC Xojo allows you get the backingStore value for a window, but that is not the correct way to do it, because a customer can configure windows to span across screens, and therefore it should be view specific and not window specific.

Same goes for theming, if you need to know what theme is being used for a control, you should get it from that control, because it is possible not only for windows have a different theme to the application, but also possible for views to have a different to the window and the application.

It’s safer to either let the OS mange the layout for you (List, VStack, Grid, VGrid, etc) or to use integers for control layouts.

This wasn’t a question of control layouts, it was drawing into a graphics context.

I ended up using Graphics.ScaleX, which does appear to properly represent the scaling factor used by the OS and is (probably) specific to the view.

The API I gave you is the recommend API to use to figure out the backing scale of the view, that you’re current drawing the graphics within.

Are you suggesting that it is not behind the values provided by Graphics.ScaleX?

I don’t know what API Xojo is using, I have my suspicions, and I’ve been both right and wrong in the past.

Anywho, if you run into problems, you know which API that Apple recommends you use to figure out the scale of a screen that a view resides on.