Dealing with Display Scaling

Get help with using AutoHotkey and its commands and hotkeys
Posts: 3
Joined: 12 Apr 2017, 22:08
Google: andy.glew

Dealing with Display Scaling

21 Jun 2019, 19:28

Right now I am tweaking some "scroll using trackball" code, but this problem is generic, has occured in many other places.

I frequently use multiple displays with quite different sizes, pixel counts, and display scalings. For example, I am typing this with my Surface Boomk laptop plugged in to 3 external monitos (1 display port, 2 USB). The laptop is set to 200% scaling, my 30" display port monitor is set to 150% scaling, my 2 other monitors are set to 100% scaling/

The basic problem is that, while I would like/expect that
CoordMode,mouse,Screen ; relative to entire desktop
would give me pos == pos2,

in actuality it only does so reliably when all displays have the same 100% scaling. (I assume it also works when all have the same non-100% scaling, but I have not tried that.)

When I have non-uniform scaling, it appears that MouseFGetPos is using 100% scaling, but MouseSetPos is using 200% scaling - possibly the largest scaling used, or that of the primary monitor, or ...

E.g. for the simple code below that actually determines the MouseMove absolute coordinates needed to match a givwen MouseGetPos, example coordinates are

Monitor 4: MouseGetPos (-1174,-370) MouseSetPos (-587,-185) (2x, obviously)
Monitor 2: MouseGetPos (1253,-1753) MouseSetPos (940,-515)
Monitor 1: MouseGetPos == MouseSetPos (933,382)
Monitor 3: MouseGetPost (5644,352) MouseSetPos (2822,176) (again 2x)

You can probably figure out many of the monitor properties from the above. Even more if I provided two sample points per monitor: scaling, monitor UL coordinates and sizes in the entire desktop, etc.

The simple code below determines the MouseMove absolute coordinates needed to match a given MouseGetPos, but

a) it is very slow (which I can fix using standard techniques like gradient descent, with larger step sizes)

b) neither the simple code below which always uses unit steps +/- 1, nor a real gradient descent code, is guaranteed to work. I think that it is possible to construct monitor configuration s where my heuristics for determining which direction to move are invalid. Worse, in reality the function that we are trying to find the fixed point of has large regions that are perfectly flat - it seems that if the MouseMove coordinates map to a region completely outside a monitor, MouseGetPOs is pegged to point on a monitors boundary. I.e. the function is not differentiable.

c) as the mouse cursor moves, it can interfedre with other AHK scripts. E.g. I have an AHK script that looks at mouse position and jumps it across gaps in the display layout that occur because of monitor heterogeneity.

I could fix this by enumerating all monitors, determining which the original MouseGetPos is in, and which the MouseMove-MouseGetPos is in afterwards - and I will do so. But the code is getting complex, so I really want to ask this forum if there is a better way, or if somebody has already done it. Plus, IMHO it is worth reporting this behavior as a bug in AHK's handling of heterogenous monitors. IMHO MouseGetPos;MouseMove;MouseGetPos should always return the same MouseGetPos values.

Q1: is there some setting (other than uniform display scaling) so that
CoordMode,mouse,Screen ; relative to entire desktop
would give me pos == pos2,

i.e. a setting in AHK?

Q2: has anyone already worked out code for something like my Kluge_MouseGetPos below, that will work in all (or at least most reasonable) conditions?

Q3: what are the AHK callable DLLcalls that avoid these scaling issues?

However, if I do that, I might as well use a non-AHK approach for the problem at hand - something like MarbleScroll. That woukld also be a lot more power efficient - instead of a timer polling function, would just hook to the events that are produced when my mouse or trackball are actually moved.

Here's the example code that converges on the MouseGetPos/MouseMOve coordinates.

Code: Select all

	;; AHK bug: multimonitor systems with different scalings in different monitors
	;; seem to not handle display scaling

	;; Kluge_MouseGetPos - since
	;;     MouseGetPos->pos
	;;     MoveMouse<-pos
	;;     MouseGetPos->pos2
	;; does not result in pos2 == pos1,
	;; I am trying to find posAdj such that
	;;     MouseGetPos->pos
	;;     posAdj <- f(pos)
	;;     MoveMouse<-posAdj
	;;     MouseGetPos->pos2
	;; does result in pos2 == pos1,

	;; i.e. I am trying to correct for AHK's broken handling of multiple monitors with different scaling

	CoordMode,tooltip,Screen ; relative to entire desktop
	CoordMode,mouse,Screen ; relative to entire desktop
	MouseGetPos, ox, oy
	ToolTip, Start %ox% %oy%,,,18

	max_tries := 10000
	try_num := 0
	ox_try := ox
	oy_try := oy

	MouseMove (ox_try), (oy_try),0
	MouseGetPos, ox_got, oy_got

		try_num += 1
		MouseMove (ox_try), (oy_try),0
		MouseGetPos, ox_got, oy_got
		ToolTip, Try #%try_num% o: %ox% %oy%  o_try:%ox_try% %oy_try%  o_got: %ox_got% %oy_got%,0,0, 19
		;; TBD: create something that converges faster
		if( ox_got > ox ) {
			ox_try := ox_try - 1
		if( ox_got < ox ) {
			ox_try := ox_try +1
		if( oy_got > oy ) {
			oy_try := oy_try - 1
		if( oy_got < oy ) {
			oy_try := oy_try +1
	} Until ( (try_num >= max_tries) || ((ox_got == ox) && (oy_got == oy)) )
	return {x:(ox_try),y:(oy_try)}
just me
Posts: 6641
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Dealing with Display Scaling

22 Jun 2019, 04:43

MouseMove -> Remarks
The following is an alternate way to move the mouse cursor that may work better in certain multi-monitor configurations:

Code: Select all

DllCall("SetCursorPos", "int", 100, "int", 400)  ; The first number is the X-coordinate and the second is the Y (relative to the screen).

Return to “Ask For Help”

Who is online

Users browsing this forum: Google [Bot], lakozyin, nacken012 and 190 guests