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

Respect scale factor on recent Windows versions #52

Closed
wants to merge 3 commits into from

Conversation

dscho
Copy link
Contributor

@dscho dscho commented Feb 15, 2021

On my laptop, the scale factor is 200% (scale-unaware applications will think that my 3240x2160 display is a 1620x1080 one). One of those scale-unaware applications is node.exe. A screen.capture(path) would therefore capture only the upper-left quadrant of my screen, and nut.js would therefore be unable to screen.find() anything outside that area.

This PR fixes that by scaling the captured screen, also pretending that there is no scale factor involved.

This fixes nut-tree/nut.js#183.

... at least using MSVC 2019.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Due to an off-by-one, the full width or height would have been rejected,
even as the block below would fall back to said full width and height.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Recent Windows versions allow to change the "Scale" factor of the
display. This is particularly useful on high DPI devices, where
displaying windows in the regular pixel size would make it _really_ hard
to read (think: 3240x2160 resolution on a regular laptop, where the
Scale factor would default to 200%).

To maintain compatibility with scale-unaware software, this is an opt-in
feature, where applications have to specify via their manifest that they
are aware of it. Otherwise, Windows will pretend that the resolution is
actually lower.

However, this leads to a problem where calling `screen.capture()`
_thinks_ that the resolution on above-mentioned laptop is actually
1620x1080, yet when capturing a 1620X1080 rectangle at 0x0, it only
captures the upper left quadrant!

Let's capture the full screen and downsize it using the current Scale
factor.

Note: an alternative would be to report the high resolution as desktop
size. However, this is incompatible with `screen.highlight()` and
`mouse.move()` which are unaware of the scale factor. The easier
direction, therefore, seems to be the chosen one: just downscale the
high-resolution screen capture and continue to work in the scale-unaware
mode.

Note, too: yet _another_ alternative would be to change the manifest.
But I think that would not work because it would be `node.exe` whose
manifest would have to change, this Node module's `.dll` cannot change
the application's behavior.

For now, we do not bother trying to fall back to using
`GetScaleFactorForDevice()` on Windows 8 (`GetScaleFactorForMonitor()`
is only available in Windows 8.1 and newer).

To allow _running_ on Windows 8 (or older), we only try to load that
function at runtime rather than linking to it (because the `.dll` would
otherwise not even load on Windows 8).

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
dscho added a commit to dscho/nut.js that referenced this pull request Feb 15, 2021
When capturing a screen region in a recent Windows version on a high-DPI
device, the captured image can have a much higher resolution than
scale-unaware applications such as `node.exe` might think (compare also
nut-tree/libnut-core#52).

For convenience, let's support scaling the "needle" image that `nut.js`
is told to find.

For example, on my laptop, where the scale factor is 200%, I would
capture a rectangular region, save it as a `.png` file, then tell
`nut.js` to find it thusly:

	await screen.find('needle.png', 10000, { scaleNeedle: true })

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
@dscho
Copy link
Contributor Author

dscho commented Feb 15, 2021

The CI failure seems to be a time-out downloading Node, not a bug in my code:

info TOOL Using Unix Makefiles generator.
info DIST Downloading distribution files.
http DIST 	- https://nodejs.org/dist/v12.20.1/SHASUMS256.txt
http DIST 	- https://nodejs.org/dist/v12.20.1/node-v12.20.1-headers.tar.gz
ERR! OMG read ECONNRESET
ERR! OMG read ECONNRESET
npm ERR! code ELIFECYCLE

@s1hofmann s1hofmann self-requested a review March 4, 2021 22:35
Copy link
Member

@s1hofmann s1hofmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dscho 👋

Please refer to nut-tree/nut.js#211 (review) regarding the overall review

@s1hofmann s1hofmann added the enhancement New feature or request label Mar 9, 2021
@s1hofmann
Copy link
Member

Closing this in favor of #59

@s1hofmann s1hofmann closed this Mar 14, 2021
@dscho dscho deleted the respect-scale-factor-on-win10 branch March 14, 2021 12:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Wrong coordinates when windows 10 scale is higher than 100%
2 participants