Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scaling Factor detection on Windows 10 #95

Open
aglitchman opened this issue Mar 11, 2019 · 8 comments
Open

Scaling Factor detection on Windows 10 #95

aglitchman opened this issue Mar 11, 2019 · 8 comments
Labels

Comments

@aglitchman
Copy link

I have a 24' 3840x2160 monitor that I use with Windows 10 at a scale of 200%. So virtually it's 1920x1080 with PPI, like Apple Retina.

DefOS failed to determine the correct scaling_factor (must be 2):

DEBUG:SCRIPT: Found 1 displays:
DEBUG:SCRIPT: 
{ --[[000000001CBDA340]]
  bounds = { --[[000000001CBDA3E0]]
    y = 0,
    x = 0,
    height = 2160,
    width = 3840
  },
  name = "Generic PnP Monitor",
  mode = { --[[000000001CBDA410]]
    reflect_y = false,
    width = 3840,
    scaling_factor = 1,
    refresh_rate = 60,
    reflect_x = false,
    orientation = 0,
    height = 2160,
    bits_per_pixel = 32
  },
  id = "\\.\DISPLAY1"
}

Seems that on Windows 10 you should to use this API to determine the correct scaling_factor:
https://docs.microsoft.com/en-us/windows/desktop/api/shellscalingapi/nf-shellscalingapi-getscalefactorformonitor
https://docs.microsoft.com/en-us/windows/desktop/api/shtypes/ne-shtypes-device_scale_factor

Also, width/height in bounds or mode should be half the size, right?

@dapetcu21
Copy link
Collaborator

dapetcu21 commented Mar 11, 2019

From what I know there are two ways to scale a display on Windows, which compound with each other. One which controls the actual size of the display on the desktop canvas (which DefOS tracks) and one which controls the size of UI elements for windows on a particular screen (shell scaling).

The values that bounds returns are returned in such a way that you can plug them back into defos.set_window_size to move your window around the desktop canvas. They also match the window size values that Defold sets your window to when HiDPI is disabled. I intend on sticking with that behaviour and keeping it consistent across platforms.

I'm not that sure about the value in mode, though. I could include the shell scaling factor, but then mode.width / mode.scaling_factor won't equal bounds.width anymore. Alternatively, we could add another ui_scaling_factor value in the mode table, which won't break this behaviour, but might be a little confusing.

@aglitchman
Copy link
Author

I just found out that scaling_factor becomes equal to 1 when High Dpi is enabled in game.project.
If hidpi is off, scaling_factor is detected correctly, so the issue can be closed.
Is it a bug or a feature?

@dapetcu21
Copy link
Collaborator

@aglitchman Does mode.width / mode.scaling_factor equal bounds.width? Can I see the full table?

@aglitchman
Copy link
Author

I recently upgraded my monitor to 27 inches, so scaling_factor is now 1.5 (150%).

pprint(defos.get_current_display_id())
pprint(defos.get_displays())

High Dpi is off

DEBUG:SCRIPT: \\.\DISPLAY1
DEBUG:SCRIPT: 
{ --[[000000003ED84720]]
  1 = { --[[000000003ED84750]]
    bounds = { --[[000000003ED84810]]
      y = 0,
      x = 0,
      height = 1440,
      width = 2560
    },
    name = "BenQ PD2700U",
    mode = { --[[000000003ED84840]]
      reflect_y = false,
      width = 3840,
      scaling_factor = 1.5,
      refresh_rate = 60,
      reflect_x = false,
      orientation = 0,
      height = 2160,
      bits_per_pixel = 32
    },
    id = "\\.\DISPLAY1"
  },
  \\.\DISPLAY1 = { --[[000000003ED84750]]
    bounds = { --[[000000003ED84810]]
      y = 0,
      x = 0,
      height = 1440,
      width = 2560
    },
    name = "BenQ PD2700U",
    mode = { --[[000000003ED84840]]
      reflect_y = false,
      width = 3840,
      scaling_factor = 1.5,
      refresh_rate = 60,
      reflect_x = false,
      orientation = 0,
      height = 2160,
      bits_per_pixel = 32
    },
    id = "\\.\DISPLAY1"
  }
}

High Dpi is on

DEBUG:SCRIPT: \\.\DISPLAY1
DEBUG:SCRIPT: 
{ --[[0000000030374720]]
  1 = { --[[0000000030374750]]
    bounds = { --[[0000000030374810]]
      y = 0,
      x = 0,
      height = 2160,
      width = 3840
    },
    name = "BenQ PD2700U",
    mode = { --[[0000000030374840]]
      reflect_y = false,
      width = 3840,
      scaling_factor = 1,
      refresh_rate = 60,
      reflect_x = false,
      orientation = 0,
      height = 2160,
      bits_per_pixel = 32
    },
    id = "\\.\DISPLAY1"
  },
  \\.\DISPLAY1 = { --[[0000000030374750]]
    bounds = { --[[0000000030374810]]
      y = 0,
      x = 0,
      height = 2160,
      width = 3840
    },
    name = "BenQ PD2700U",
    mode = { --[[0000000030374840]]
      reflect_y = false,
      width = 3840,
      scaling_factor = 1,
      refresh_rate = 60,
      reflect_x = false,
      orientation = 0,
      height = 2160,
      bits_per_pixel = 32
    },
    id = "\\.\DISPLAY1"
  }
}

@dapetcu21
Copy link
Collaborator

Yeah. This is the intended behaviour. Window coordinates map 1:1 to the display pixels, so scaling_factor is 1. As I said above, we maybe should add a ui_scaling_factor property that would report the shell scaling factor independently from this.

@aglitchman
Copy link
Author

I use DefOS on Windows to scale the window down to the desktop height after starting and move the window to the center of the screen. Very useful in the development process.

When high dpi is off, my code works fine. When high dpi is on, it works incorrectly because the real height of the taskbar and the window borders are unknown because of incorrect scaling_factor.

Adding ui_scaling_factor will help me a lot.

@dapetcu21
Copy link
Collaborator

dapetcu21 commented Apr 19, 2019

For the window borders, you can query them. defos.get_window_size() returns the window bounds including window borders and defos.get_view_size() returns the bounds of just the rendering surface (excluding window borders). The setters work the same.

@aglitchman
Copy link
Author

For the window borders, you can query them.

Yeah, that's what I do. But without ui_scaling_factor it is impossible to calculate the height of the taskbar.

@britzl britzl added the windows label Jan 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants