Detecting a retina display

I’m using this method to determine if my app is running on a retina display.

  Declare Function BackingScaleFactor Lib "AppKit" Selector "backingScaleFactor" (target As WindowPtr) As Double
  Return BackingScaleFactor(w)

If the returned value is > 1 it’s retina.

But I’m finding that on a new 5K iMac running El Capitan the value returned is always 1. Is there a problem with the Declare?

What is w ?

The window the control is in.

Never mind. I found the complete working code here

#If TargetCocoa Then If System.IsFunctionAvailable("BackingScaleFactor", "AppKit") Then Declare Function BackingScaleFactor Lib "AppKit" Selector "backingScaleFactor" (Target As WindowPtr) As Double Return BackingScaleFactor( w ) End If #Endif Return 1

Unfortunately, I confirm it does not “see” Retina on my MacBook either under EC.

Have you tried wrapping the app with AppWrapper or setting the plist as required?

I’m running this in the debugger, so no plist.

you have to Retinalize this App first like Carlo said…

Err… that may be the problem.

Build step for retina:

Dim App As String = CurrentBuildLocation + "/""" + CurrentBuildAppName + ".app""" Call DoShellCommand("/usr/bin/defaults write " + App + "/Contents/Info ""NSHighResolutionCapable"" YES")

I applied the Retina key to Plist, sandboxed, no difference. The method still reports 1.

Apparently, El Capitan (Captain Hook ?) broke BackingScaleFactor.

@Thomas Jakobs and @Tim Parnell. So you’re saying you can’t use this function to detect retina when running in the debugger?

Jonathan, you need to use the script I pasted here in a build step for Mac to see retina while debugging.

El Capitan Hook may have broken something with retina, but without that script it won’t display retina even on working systems.

Sorry, I’m confused. There is no build step since I’m running in the debugger, not building. Or are you saying that code will fire anyway even when running?

For lack of a better way of explaining, download the HTML Edit demo project and see how the retina build step is set up. It applies even to debug builds. You might even be able to drag it out of the demo project into your own.

Just be sure to place it after the Build step because the app has to exist first :slight_smile:

Thanks a lot. I’ll download it.

Edit: Got it and it works like a charm. Thanks again.

[quote=245512:@Jonathan Ashwell]Thanks a lot. I’ll download it.

Edit: Got it and it works like a charm. Thanks again.[/quote]

Jonathan, the addition of the NSHighResolutionCapable key to your app’s Info.plist does not help with detecting a Retina display. I tested BackingScaleFactor still reports 1. I do not think that can be the answer to your original question.

No, it does for me. I checked in the debugger and and now it does detect the retina display and returns a value of 2. I don’t know why it’s not for you. You created a Retina script after your Build script?

Does not work here. The key is present in Info.plist (verified with XCode) but still, I get 1.

Well. Soon Xojo will support Retina. With some luck it will be more reliable.

I’m not sure why you need to detect Retina but if it’s for images in a Canvas, then this little trick works great for me.
Let’s say you want to draw a 512512 Image in a Canvas. Then I make sure the actual ‘MyImage’ is 10241024. (So just make sure the images you Draw are twice the size)

Then draw it like this in the Canvas:

  g.DrawPicture(MyImage, 0, 0, MyImage.Width \\ 2, MyImage.Height \\ 2, 0, 0, MyImage.Width, MyImage.Height)

This always works. Even if I drag the App halfway to my second (non-retina) screen, things stays perfect.
Maybe it helps.

You need to know because for the best results the image you draw should be appropriate for the screen you’re drawing on. So you draw the 1x image on a normal display, the 2x image (drawn into the same area) on the retina display. See Apple’s High Resolution Guidelines for OS X

I understand that.
What I’m saying is that if it’s for drawing images on a Canvas, try it like I described above. It can save a ton of hassle.
If you do it that way, you never have to check if it’s retina/pick the right Image. It just always works. On both retina and non-retina screens.

It also works if you have 2 screens (1 retina and 1 non-retina) and drag things around.