Trying to get the real desktop size (in pixels) on macOS and Windows

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
ki
Prole
Posts: 16
Joined: Tue Oct 09, 2012 10:23 am

Trying to get the real desktop size (in pixels) on macOS and Windows

Post by ki »

Hi! I'm trying to get the real desktop size in pixels, independent from any High DPI (Windows) or Retina (macOS) scaling. I need this in order to talk to a third-party library which needs the real desktop dimensions.

Windows:

As slime has said in several threads, Löve on Windows still doesn't support High DPI modes on Windows because SDL doesn't yet support it (groan). The result is that love.window.getDesktopDimensions() returns virtual units on Windows (using Löve 11.3). For example, on a 3840x2160 screen running with 200 % Windows screen scaling, love.window.getDesktopDimensions() returns 1920x1080. The only workaround I've found is to set the Löve executable to be High-DPI-aware in a .bat file:

Code: Select all

setlocal
pushd %~dp0\
set __COMPAT_LAYER=~ HIGHDPIAWARE
love.exe game.love
popd
endlocal
Now the Löve window is not scaled up, and love.window.getDesktopDimensions() returns the size of the desktop in pixels.

macOS:

But I also haven't found a good way to get the real pixel size of the desktop on macOS. On a 3840x2160 screen running in Retina mode, love.window.getDesktopDimensions() always returns 1920x1080 regardless of whether conf.lua -> t.window.highdpi is true or false. I'd like to use this configuration:

Code: Select all

t.window.width = 1200
t.window.height = 700
t.window.highdpi = true
t.window.usedpiscale = false
Because then the window uses pixels at 100% scale, just like with my above workaround on Windows. love.graphics.getPixelDimensions() now gives me the correct pixel size of the window (2400x1400 in this case), but love.window.getDesktopDimensions() still returns 1920x1080.

(Also, it seems like a bug that when using the above configuration, the created window is 2400x1400 pixels large. It should be 1200x700 because t.window.usedpiscale is set to false.)

The only way to get the real desktop size on macOS seems to be using this configuration:

Code: Select all

t.window.highdpi = true
t.window.usedpiscale = true
and then using both love.window.getDesktopDimensions() and love.window.getDPIScale() (which returns 2 on a Retina screen) in order to calculate the desktop pixel size. But this configuration is not what I want because I want the window to be at 100 % pixel scale (t.window.usedpiscale = false) like in Windows.

Suggestion:
  1. Add a love.window.getDesktopPixelDimensions() API. Maybe query a Windows (macOS/other OS) API directly if SDL is still not there yet.
  2. When using the configuration with t.window.usedpiscale = false mentioned above, I think the window size should be 1200x700 pixels, not 2400x1400, on a macOS Retina screen.
(Also, what is the difference between https://love2d.org/wiki/love.window.getDPIScale and https://love2d.org/wiki/love.graphics.getDPIScale ?)
User avatar
AuahDark
Party member
Posts: 107
Joined: Mon Oct 23, 2017 2:34 pm
Location: Indonesia
Contact:

Re: Trying to get the real desktop size (in pixels) on macOS and Windows

Post by AuahDark »

The problem with Windows is the high DPI setting is per-process, not per-window. Every function that query a window (desktop) dimensions is effectively scaled at WinAPI level, not by SDL, hence the problem of supporting it. If you call love.window.getDPIScale in Windows, you'll always get 1 regardless of high DPI setting.

For the macOS problem, you can always love.graphics.scale(1 / love.graphics.getDPIScale) before drawing. Not sure if that's sufficient for you.
Profile. Do you encounter crashes in LÖVE Android and wanna send me logcats? Please hit me up in LÖVE Discord and send the full logcat file!
ki
Prole
Posts: 16
Joined: Tue Oct 09, 2012 10:23 am

Re: Trying to get the real desktop size (in pixels) on macOS and Windows

Post by ki »

AuahDark wrote: Thu Aug 06, 2020 2:01 am For the macOS problem, you can always love.graphics.scale(1 / love.graphics.getDPIScale) before drawing. Not sure if that's sufficient for you.
You mean, to draw at 100 % pixel scale? Yes, but regardless of that I'm still unable to query the macOS desktop dimensions in real pixels.
User avatar
Sasha264
Party member
Posts: 131
Joined: Mon Sep 08, 2014 7:57 am

Re: Trying to get the real desktop size (in pixels) on macOS and Windows

Post by Sasha264 »

HighDPI and Retina is quite a mess, really... But the future is here and we must live with that =) Personally I can not imagine my life without 4k display and 200% ui scaling on windows. And many many games and other programs and frameworks ready for that, it is a bit disappointing that Love2d still does not support this.

You did a great job to figure out how to workaround that on both (!) win and mac. I wonder how it differs on linux, btw... And exactly about your question: I tried to set t.window.usedpiscale = false, or = true, does not matter for me on windows, regardless of that love.window.getDesktopDimensions() returns 3840x2160 when love runs in "high-dpi" mode, and 1920x1080 when love runs in "low-dpi" mode.

To setup "high-dpi" mode permanently I use that .bat file:

Code: Select all

REG ADD "HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" /V "D:\<path_to_my_love>\love.exe" /T REG_SZ /D ~HIGHDPIAWARE /F
So, as far as I understand you can:
  • set "high-dpi" mode for love.exe on windows
  • set t.window.highdpi = true t.window.usedpiscale = true
  • call love.window.getDesktopDimensions(), multiply it by love.window.getDPIScale()
...and result will be real desktop dimensions on both os.
But it seems that you are aware of that method. So I can not figure out, what is the problem with that? (except that it looks not so cool and clean)
But this configuration is not what I want because I want the window to be at 100 % pixel scale (t.window.usedpiscale = false) like in Windows.
I read that several times, and did not completely understand... So you want to know real desktop dimensions, but that is not all you want? You want something about window size?
ki
Prole
Posts: 16
Joined: Tue Oct 09, 2012 10:23 am

Re: Trying to get the real desktop size (in pixels) on macOS and Windows

Post by ki »

Sasha264 wrote: Sat Aug 22, 2020 10:14 pm To setup "high-dpi" mode permanently I use that .bat file:

Code: Select all

REG ADD "HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" /V "D:\<path_to_my_love>\love.exe" /T REG_SZ /D ~HIGHDPIAWARE /F
Yes, that's also possible. This creates a Windows registry entry on the user's computer. When deploying the application to end users, you need to ship this .bat file too and have them execute this at least once before executing the .exe file. And if the path to the executable changes, they'd need to do it again. Personally, I'd rather not create such a registry entry, so I use my .bat file above which needs to be executed every time to start the application.
Sasha264 wrote: Sat Aug 22, 2020 10:14 pm ...and result will be real desktop dimensions on both os.
But it seems that you are aware of that method. So I can not figure out, what is the problem with that?
I don't want to ship any .bat file, and I don't want to require my users to execute .bat files. It's a poor workaround.
Sasha264 wrote: Sat Aug 22, 2020 10:14 pm
The only way to get the real desktop size on macOS seems to be using this configuration:

Code: Select all

t.window.highdpi = true
t.window.usedpiscale = true
and then using both love.window.getDesktopDimensions() and love.window.getDPIScale() (which returns 2 on a Retina screen) in order to calculate the desktop pixel size. But this configuration is not what I want because I want the window to be at 100 % pixel scale (t.window.usedpiscale = false) like in Windows.
I read that several times, and did not completely understand... So you want to know real desktop dimensions, but that is not all you want? You want something about window size?
Yes, I want to know the real desktop dimensions, but I also want the Löve APIs to use the same DPI scaling behaviour on macOS and Windows. Either both of my applications on macOS and Windows should always use a DPI scale of 1 regardless of the UI-scaling of the OS desktop, or both applications on macOS and Windows should correctly handle 200%-scaled desktop resolutions, which means that the applications dynamically use a DPI scale of 1 on a 100%-scaled desktop resolution and a DPI scale of 2 on a 200%-scaled desktop resolution.

However, using the "high-DPI" .bat file workaround on Windows (the only way to receive the real desktop dimensions) results in a DPI scale of 1 in the Windows application running on a 200%-scaled desktop, and using the above configuration on macOS (the only way to calculate the real desktop dimensions on macOS) results in a DPI scale of 2 in the macOS application also running on a 200%-scaled desktop.

As a result, my graphics code can't use the same size values for both Windows and macOS applications. For example, a rectangle created with love.graphics.rectangle('line', 0, 0, 10, 10) is twice as large in the macOS application (20x20 pixels, roughly 5 mm on my monitor) than in the Windows application (10x10 pixels, roughly 2.5 mm on my monitor).
User avatar
Xii
Party member
Posts: 137
Joined: Thu Aug 13, 2020 9:09 pm
Contact:

Re: Trying to get the real desktop size (in pixels) on macOS and Windows

Post by Xii »

ki wrote: Tue Aug 25, 2020 3:30 pm I don't want to ship any .bat file, and I don't want to require my users to execute .bat files. It's a poor workaround.
Since a .bat file is just a list of Windows shell commands, can't you use os.execute(command) to do it from Lua code? (you'll have to check that love.system.getOS() == "Windows")
ki
Prole
Posts: 16
Joined: Tue Oct 09, 2012 10:23 am

Re: Trying to get the real desktop size (in pixels) on macOS and Windows

Post by ki »

In other cases, that would be possible. But executing a shell command from Löve means that the command is executed after the Löve application has already started and is running. In this case, the command (which tells Windows to run the following executables as high-DPI) needs to be run before starting the Löve application.
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 210 guests