Move mouse to center of monitor in multi-monitor configuration - CoordMode relative to specific monitor?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
JoeWinograd
Posts: 2213
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Move mouse to center of monitor in multi-monitor configuration - CoordMode relative to specific monitor?

03 Oct 2020, 23:34

Hi Folks,

My goal is to provide a hotkey that moves the mouse to the center of the monitor for each monitor in a multi-monitor config. For example:

Alt+Ctrl+1 ==> move mouse to monitor 1
Alt+Ctrl+2 ==> move mouse to monitor 2
Alt+Ctrl+3 ==> move mouse to monitor 3
Alt+Ctrl+4 ==> move mouse to monitor 4
Alt+Ctrl+5 ==> move mouse to monitor 5
Alt+Ctrl+6 ==> move mouse to monitor 6
Alt+Ctrl+7 ==> move mouse to monitor 7
Alt+Ctrl+8 ==> move mouse to monitor 8
Alt+Ctrl+9 ==> move mouse to monitor 9
Alt+Ctrl+0 ==> move mouse to primary monitor regardless of its number

Here's a script that attempts to do it:

Code: Select all

#Warn,UseUnsetLocal
#NoEnv
#SingleInstance Force
SetBatchLines,-1

HotkeyModifiers:="!^" ; Alt+Ctrl - these are the modifier keys for the number keys (0-9) - change them to whatever you want

NumModifiers:=StrLen(HotkeyModifiers) ; get number of modifier keys
MoveToX:={} ; array for mouse-move X coordinates
MoveToY:={} ; array for mouse-move Y coordinates

CoordMode,Mouse,Screen ; default, but just to be sure
SysGet,NumMons,MonitorCount ; get number of monitors
Hotkey,%HotkeyModifiers%0,MoveMousePrimary,On ; define Modifiers+0 hotkey to move mouse to Primary monitor regardless of its monitor number
Loop,%NumMons% ; process all monitors
{
  MonNum:=A_Index
  SysGet,Coordinates%MonNum%,Monitor,%MonNum% ; get coordinates for this monitor
  Left:=Coordinates%MonNum%Left
  Right:=Coordinates%MonNum%Right
  Top:=Coordinates%MonNum%Top
  Bottom:=Coordinates%MonNum%Bottom
  MoveX:=Floor(0.5*(Right-Left)) ; center
  MoveY:=Floor(0.5*(Bottom-Top)) ; center
  MoveToX[MonNum]:=Left+MoveX ; store mouse-move X coordinate for this monitor
  MoveToY[MonNum]:=Top+MoveY ; store mouse-move Y coordinate for this monitor
  Hotkey,%HotkeyModifiers%%MonNum%,MoveMouseMon,On ; define Modifiers+N hotkey
}
Return

MoveMouseMon:
MonNum:=SubStr(A_ThisHotkey,NumModifiers+1,1) ; monitor number is after the modifiers
X:=MoveToX[MonNum] ; retrieve horizontal mouse-move coordinate
Y:=MoveToY[MonNum] ; retrieve vertical mouse-move coordinate
MouseMove,%X%,%Y% ; move it!
Return

MoveMousePrimary:
SysGet,PrimaryMonNum,MonitorPrimary ; get number of Primary monitor
X:=MoveToX[PrimaryMonNum] ; retrieve horizontal mouse-move coordinate
Y:=MoveToY[PrimaryMonNum] ; retrieve vertical mouse-move coordinate
MouseMove,%X%,%Y% ; move it!
Return
It works well when all the monitors are side-by-side horizontally and not offset from each other very much vertically, but it fails when the monitors are stacked vertically or when offset by large vertical distances. With a picture being worth a thousand words, here's a monitor config where the script works well:

monitor config works.png
monitor config works.png (3.18 KiB) Viewed 3645 times

Here are two monitor configs where it fails:

monitor config fails.png
monitor config fails.png (3.96 KiB) Viewed 3645 times
monitor config also fails.png
monitor config also fails.png (2.94 KiB) Viewed 3645 times

Seems to me that what's needed is a CoordMode option that is relative to a specific monitor number. But, of course, the only CoordMode options are Client, Screen, and Window (the latter being synonymous with Relative, but it's relative to the active window, not to the whole monitor, so not what's needed).

I looked at all the (Numeric) values of the SysGet options, but nothing there seems to be the ticket.

Anyone have a solution for this? Thanks much, Joe
Rohwedder
Posts: 7750
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Move mouse to center of monitor in multi-monitor configuration - CoordMode relative to specific monitor?

04 Oct 2020, 03:18

Hallo,
sorry, no contribution to the solution!

Code: Select all

MonNum:=SubStr(A_ThisHotkey,NumModifiers+1,1) ; monitor number is after the modifiers
X:=MoveToX[MonNum] ; retrieve horizontal mouse-move coordinate
Y:=MoveToY[MonNum] ; retrieve vertical mouse-move coordinate
MouseMove,%X%,%Y% ; move it!
shortened:

Code: Select all

MonNum:=SubStr(A_ThisHotkey,0) ; monitor number is rightmost
MouseMove,MoveToX[MonNum],MoveToY[MonNum] ; move it!
just me
Posts: 9559
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Move mouse to center of monitor in multi-monitor configuration - CoordMode relative to specific monitor?

04 Oct 2020, 06:04

Hi, which coords do you get for the monitors in the failing examples?
User avatar
JoeWinograd
Posts: 2213
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: Move mouse to center of monitor in multi-monitor configuration - CoordMode relative to specific monitor?

04 Oct 2020, 10:22

Rohwedder wrote:shortened
Hi Rohwedder,
Thanks for the post, but I intentionally do not "shorten" code. I prefer clarity over brevity in my code. Makes it easier for others to understand and maintain my code..easier even for me a year later. :) I do not like to cram as much as possible into a single line. I always use explicit string concatenation with the dot operator. I always use count:=count+1 instead of count+=1. I could go on, but I'm sure that gives you the picture of my coding style. I appreciate your comment, though.
User avatar
JoeWinograd
Posts: 2213
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: Move mouse to center of monitor in multi-monitor configuration - CoordMode relative to specific monitor?

04 Oct 2020, 10:45

just me wrote:which coords do you get
Hi just me,

OK, ran this script on all three configs:

Code: Select all

CoordMode,Mouse,Screen ; coordinates relative to entire desktop
ResultsFile:=A_Temp . "\MonitorCoordinates.txt"
FileDelete,%ResultsFile% ; delete file from previous run
SysGet,NumMons,MonitorCount ; get number of monitors
Loop,%NumMons% ; process all monitors
{
  MonNum:=A_Index
  SysGet,Coordinates%MonNum%,Monitor,%MonNum% ; get coordinates for this monitor
  Left:=Coordinates%MonNum%Left
  Right:=Coordinates%MonNum%Right
  Top:=Coordinates%MonNum%Top
  Bottom:=Coordinates%MonNum%Bottom
  FileAppend,M=%MonNum%`tL=%Left%`tR=%Right%`tT=%Top%`tB=%Bottom%`n,%ResultsFile% ; put coordinates for this monitor into results file
}
SysGet,VirtualWidth,78 ; get width of virtual screen
SysGet,VirtualHeight,79 ; get height of virtual screen
FileAppend,VW=%VirtualWidth%`tVH=%VirtualHeight%,%ResultsFile% ; put virtual screen width and height into results file
Run,%ResultsFile% ; open results file with program that owns TXT file type
MsgBox,4096,Done,Results file is now open
ExitApp
Note that monitor 2 in the screenshots is M=1 in the results file; monitor 3 in the screenshots is M=2 in the results file; monitor 4 in the screenshots is M=3 in the results file (the resolution of M=1 and M=2 is 2560x1440; M=3 is 1920x1080). Results:

works - all horizontal at same vertical level
M=1 L=0 R=2560 T=0 B=1440
M=2 L=-2560 R=0 T=9 B=1449
M=3 L=2560 R=4480 T=226 B=1306
VW=7040 VH=1449

fails - all horizontal but M=2 much lower vertically than the other monitors
M=1 L=0 R=2560 T=0 B=1440
M=2 L=-2560 R=0 T=-1198 B=242
M=3 L=2560 R=4480 T=-981 B=99
VW=7040 VH=2638

fails - M=2 stacked vertically under M=3
M=1 L=0 R=2560 T=0 B=1440
M=2 L=6 R=2566 T=-1440 B=0
M=3 L=2566 R=4486 T=-1217 B=-137
VW=4486 VH=2880

Thanks for your help. Regards, Joe
gregster
Posts: 9103
Joined: 30 Sep 2013, 06:48

Re: Move mouse to center of monitor in multi-monitor configuration - CoordMode relative to specific monitor?

04 Oct 2020, 10:51

Sorry, not much to contribute (I have only two monitors :) ), but just to make sure: Did you try the alternative method to move the mouse, mentioned in the MouseMove Remarks section? I remember that it actually helped some people with 2+ monitors in the past...
https://www.autohotkey.com/docs/commands/MouseMove.htm#Remarks wrote: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).
Not sure, if it can help with this problem...
User avatar
JoeWinograd
Posts: 2213
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: Move mouse to center of monitor in multi-monitor configuration - CoordMode relative to specific monitor?

04 Oct 2020, 11:54

gregster wrote:I have only two monitors
Hi gregster,
Even with only two monitors you can see the problem. Stack them vertically...or just move one of them down much lower than the other...the script will fail.
DllCall("SetCursorPos", "int", 100, "int", 400) ; The first number is the X-coordinate and the second is the Y (relative to the screen).
I was wondering if there's a DLL that might help, but I don't see how that one would do it, since it still appears to move the cursor relative to the whole screen. Is there a DLL call like that one, where you can specify the X and Y coords, but where you can also specify a monitor name or number, such that the "SetCursorPos" would be relative to that monitor name/number? Thanks, Joe
User avatar
JoeWinograd
Posts: 2213
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: Move mouse to center of monitor in multi-monitor configuration - CoordMode relative to specific monitor?

04 Oct 2020, 20:39

Hi gregster,

Update on my last post. I replaced both occurrences of this:

MouseMove,%X%,%Y%

With this:

DllCall("SetCursorPos","int",X,"int",Y)

Unfortunately, same result. But thanks for the idea...was worth a try. Regards, Joe
User avatar
Nextron
Posts: 1391
Joined: 01 Oct 2013, 08:23
Location: Netherlands OS: Win10 AHK: Unicode x32

Re: Move mouse to center of monitor in multi-monitor configuration - CoordMode relative to specific monitor?

05 Oct 2020, 13:29

JoeWinograd wrote:
03 Oct 2020, 23:34
but it fails when the monitors are stacked vertically or when offset by large vertical distances.
How does it fail? Does the cursor not move at all or does it move to a wrong place, like the corner of a screen?
User avatar
JoeWinograd
Posts: 2213
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: Move mouse to center of monitor in multi-monitor configuration - CoordMode relative to specific monitor?

05 Oct 2020, 14:31

Nextron wrote:How does it fail?
Hi Nextron,

The monitor numbers are confusing because of the way Windows assigns them (and Display 1 is disconnected). Here's a summary based on the three screenshots in my initial post:

Display 2 (Primary) M=1 Alt+Ctrl+1 (and Alt+Ctrl+0)
Display 3 (Extended) M=2 Alt+Ctrl+2
Display 4 (Extended) M=3 Alt+Ctrl+3

Here's how the script fails: In the case where Display 2 is to the right of Display 3 but far below it vertically (the second screenshot in my initial post), the Alt+Ctrl+2 hotkey moves the mouse to the left edge of Display 2 (in the middle vertically), where it stops, i.e., never moves to Display 3 (same behavior when trying to move the mouse there manually...it won't go beyond the left edge of Display 2). Likewise, the Alt+Ctrl+3 hotkey moves the mouse to the right edge of Display 2 (in the middle vertically), where it stops, i.e., never moves to Display 4 (same behavior when trying to move the mouse there manually...it won't go beyond the right edge of Display 2).

In the case where Display 2 is stacked under Display 3 vertically (the third screenshot in my initial post), the failing behavior is the same as described in the above paragraph.

Btw, in both of those cases, Alt+Ctrl+1 (same as Alt+Ctrl+0) works fine, i.e., moves the mouse to the center of Display 2.

Thanks, Joe

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: ntepa and 124 guests