If I have two identical applications side-by-side on my desktop, is there software that exists that will mimic what I do on the left half on the right? Basically, if my screen is 1000x1000 and a click event happens at 5,5, I would also like it to fire that event at 505,5 (mirrored on the X-axis). I'd like to emulate keyboard and mouse events.
-
have you ever actually used a mirror and figured out how they work? – Baarn Feb 24 '12 at 20:44
-
1Alright, less a mirror and more a duplication. The concept is the same, the math is just different. – qJake Feb 24 '12 at 20:48
-
Which operating system? – iglvzx Feb 24 '12 at 20:59
-
Sorry, Windows 7. – qJake Feb 24 '12 at 20:59
-
2*{In super-hero announcer voice}* This sounds like a job for *Autohotkey*! – Synetech Feb 24 '12 at 21:13
-
@Synetech You read my mind. I'll let you take a crack at it first. – iglvzx Feb 24 '12 at 23:02
-
@iglvzx, you’re kind of putting me in a corner here. I have been meaning to learn AutoHotkey for a long time, but never got around to it yet. `:-P` – Synetech Feb 25 '12 at 20:26
-
1@SpikeX, I threw something together last night that doubles mouse clicks on both halves of the screen, but I’m not sure about your specific requirements. Do you only need single clicks to be doubled or do you need actual dragging (holding the button down and moving the mouse to be doubled on both sides)? I’ve kind of, sort of got that working, but it stutters and is messy. Also, I’m not sure what you mean by keyboard events. Mouse clicks are sent to whatever window happens to be under the cursor at the point, but keys don’t have a screen coordinate associated with them. – Synetech Feb 25 '12 at 20:28
-
I applaud you for the strangeness of your requirements sir. – Bork Blatt Mar 21 '12 at 10:57
-
@Synetech Could you post what you have for the mouse? I guess keyboard "mirroring" is unreasonable, for the reason you stated, but the mouse mirroring would still be useful. :) – qJake Mar 21 '12 at 17:54
-
Warcraft multiboxing :D ?! – Dumbo Mar 25 '12 at 01:03
-
@Bork, what’s strange about it? It reminds me of the spot-the-differences mini-games of HOGs. – Synetech Mar 25 '12 at 03:48
-
@SpikeX, do you have AutoHotkey installed? If not, I can compile the script to a binary if that’s more convenient. – Synetech Mar 25 '12 at 03:49
-
@Synetech Yeah I have it installed. Script would be better (so I can compile it myself). – qJake Mar 26 '12 at 13:00
1 Answers
(Knocking out a preliminary script that did the basic function was about as easy as I thought. It took only a few minutes and worked reasonably well. The problem is that there are lots of little gotchas and edge-cases where something might not work in some specific circumstance or if some other specific expectation exists. I’m still working on an enhanced version of the script that handles double-clicks and dragging, but while there’s plenty of examples and attempts, there are no solid, effective, and concise examples of handling these quite right at this time, so it’s a work in progress.)
In any case, the script below is an older version that I threw together (and cleaned up a bit for public consumption). It does what was asked (and a little more). There’s no real manual; you just run the script and it starts up in the mirroring mode. Mouse-clicks on either side of the screen are duplicated on the other (vertical) half. There are a few hotkeys that can be used to modify the script behavior:
- Alt+Shift+Q turns mirroring on and off
- Ctrl+Shift+Q turns autofire (rapid-repeat) on and off
- Ctrl+Alt+Shift+Q pauses the script so that the mouse behaves normally
- Ctrl+Alt+Shift+Win+Q exits the script
Here is a sample output of the script:

Mirror.ahk
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Mirror.ahk mirrors mouse clicks on one half of the screen to the other half
; http://superuser.com/questions/393738/
;
; (cl) 2012- Synetech inc., Alec Soroudi
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Hotkeys:
; Alt+Shift+Q to toggle mirroring
; Ctrl+Shift+Q to toggle autofire
; Ctrl+Alt+Shift+Q to completely pause the script (mouse behaves normally)
; Ctrl+Alt+Shift+Win+Q to quit
;
; Defaults to single-click, mirrored
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#SingleInstance force
CoordMode, Mouse, Screen
SetDefaultMouseSpeed, 0
SetMouseDelay, -1
SendMode Play ;Try modes Event, Input, or Play
;Variables
SysGet, MonitorWorkArea, MonitorWorkArea, %A_Index%
Half := (MonitorWorkAreaRight - MonitorWorkAreaLeft) >> 1
Mirror := 1
Autofire := 0
;Main function
Dupe(action, var) {
;Calculate other half
MouseGetPos, x,y
Global Half
if (x<Half) {
Left := (Half + x)
}
else {
Left := (x - Half)
}
Global Mirror
if (action=0) { ;Mouse
if (var=0) { ;Left-click
if Mirror
Click %Left% %y% Left
Click %x% %y% Left
}
else if (var=1) { ;Right-click
Click %Left% %y% Right
Click %x% %y% Right
}
else if (var=2) { ;Middle-click
Click %Left% %y% Middle
Click %x% %y% Middle
}
else if (var=3) { ;Button4-click
Click %Left% %y% X1
Click %x% %y% X1
}
else if (var=4) { ;Button5-click
Click %Left% %y% X2
Click %x% %y% X2
}
}
; else if (action=1) { ;Keyboard - do what???
; }
}
;Hotkeys
!+q:: ;Pause mirroring with Alt+Shift+Q
Mirror := !Mirror
; MsgBox Mirror: %Mirror%
return
^+q:: ;Toggle autofire with Ctrl+Shift+Q
Autofire := !Autofire
; MsgBox Autofire: %Autofire%
return
^!+q:: ;Pause script with Ctrl+Alt+Shift+Q
Suspend
; if (A_IsSuspended = 1)
; MsgBox Hotkeys suspended
; else
; MsgBox Hotkeys resumed
return
^!+#q:: ;Quit with Ctrl+Alt+Shift+Win+Q
; MsgBox Quitting
ExitApp
return
+#q:: ;Reload/restart script with Shift+Win+Q
; MsgBox Reloading
Reload
return
;Handlers
*$LButton::
Loop {
; if (Mirror)
Dupe(0, 0)
GetKeyState, State, LButton, P
if (!Autofire || State = "U")
Break
}
return
*$RButton::
Loop {
if (Mirror)
Dupe(0, 1)
GetKeyState, State, RButton, P
if (!Autofire || State = "U")
Break
}
return
*$MButton::
Loop {
if (Mirror)
Dupe(0, 2)
GetKeyState, State, MButton, P
if (!Autofire || State = "U")
Break
}
return
*$XButton1::
Loop {
if (Mirror)
Dupe(0, 3)
GetKeyState, State, XButton1, P
if (!Autofire || State = "U")
Break
}
return
*$XButton2::
Loop {
if (Mirror)
Dupe(0, 4)
GetKeyState, State, XButton2, P
if (!Autofire || State = "U")
Break
}
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- 68,243
- 36
- 223
- 356
-
-
1With auto-fire on, it keeps drawing dots while you hold the mouse-button down. With it off, you have to click the mouse-button for each dot. – Synetech Jan 22 '18 at 16:31
-
1how do I get it to work I tried it out but it wont not click – Kewin Björk Nielsen Mar 26 '19 at 08:47
-
4Tried this on Windows 10, too - no click events are fired anymore while the script is running. Any ideas, what to change in the script? – DivineTraube Apr 25 '19 at 16:31
-
**Drag and drop does not work, and will never work without emulating "multi-touch gestures".** I mean, above emulates "mouse" jumping to other side and clicking there as well, but because said jumping counts as dragging, same *hack/trick* is not possible for dragging. – Top-Master May 17 '23 at 05:52