I frequently use multiple displays with quite different sizes, pixel counts, and display scalings. For example, I am typing this with my Surface Book 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
MouseGetPos->pos
MoveMouse<-pos
MouseGetPos->pos2
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
MouseGetPos->pos
MoveMouse<-pos
MouseGetPos->pos2
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
Kluge_MouseGetPos()
{
;; 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
Loop{
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)}
}