Skip to content

Instantly share code, notes, and snippets.

@webuniverseio
Last active February 21, 2022 02:44
Show Gist options
  • Save webuniverseio/2b0dcac475bfd4be68f4308e5a5584cb to your computer and use it in GitHub Desktop.
Save webuniverseio/2b0dcac475bfd4be68f4308e5a5584cb to your computer and use it in GitHub Desktop.
Windows Mouse Keys replacement using AutoHotKey

Video walk through is here (shows the concepts and how to get started): https://youtu.be/dYjXPDM2xPQ

Mousekeys are activate when NumLock is deactivated.

  • Numpad1-4,6-9: Move mouse
  • Ctrl + Movement Keys: Fast move
  • Numpad5: Left Click (click multiple times for double, triple click)
  • Win + Numpad5: Right Click
  • Numpad0: Hold Left MButton, release with Numpad5
  • ScrollLock: Toggle scroll mode, then use arrows to scroll up/down/left/right
#SingleInstance Force
varSlowStep := 10
varFastStep := 75
pressingUp := False
pressingDown := False
pressingLeft := False
pressingRight := False
lastHorizontal := 0
lastVertical := 0
;jump to center
NumpadDel::DllCall("SetCursorPos", "int", A_ScreenWidth / 2, "int", A_ScreenHeight / 2)
;right click
#NumpadClear::Click, Right
;ctrl click
^NumpadClear::Send ^{Click}
;scroll
varInScrollMode :=false
ScrollLock::
varInScrollMode := !varInScrollMode
;set state on so it is obvious that now page will be scrolling
if (varInScrollMode)
SetScrollLockState, On
else
SetScrollLockState, Off
return
Up::
if (varInScrollMode)
Click, WU
else
Send {Up}
return
Down::
if (varInScrollMode)
Click, WD
else
Send {Down}
return
Left::
if (varInScrollMode)
Click, WL
else
Send {Left}
return
Right::
if (varInScrollMode)
Click, WR
else
Send {Right}
return
;hold action
varIsHolding := false
NumpadIns::
varIsHolding := true
Send {Click, Down}
return
;normal click or release hold
NumpadClear::
if (varIsHolding) {
Send {Click, Up} ;release
varIsHolding := false
}
else
Send {Click} ;normal click
return
;modified version of https://github.com/uahnbu/mousekeys/blob/f7640c3ac648761246604685b628defd22be0e19/mouse.ahk#L1
;press down regular
^NumpadUp::
NumpadUp::PressUp()
^NumpadDown::
NumpadDown::PressDown()
^NumpadLeft::
NumpadLeft::PressLeft()
^NumpadRight::
NumpadRight::PressRight()
;release regular
^NumpadUp UP::
NumpadUp UP::ReleaseUp()
^NumpadDown UP::
NumpadDown UP::ReleaseDown()
^NumpadLeft UP::
NumpadLeft UP::ReleaseLeft()
^NumpadRight UP::
NumpadRight UP::ReleaseRight()
;press down diagonal
^NumpadHome::
NumpadHome::PressUp() PressLeft()
^NumpadEnd::
NumpadEnd::PressDown() PressLeft()
^NumpadPgUp::
NumpadPgUp::PressUp() PressRight()
^NumpadPgDn::
NumpadPgDn::PressDown() PressRight()
;release diagonal
^NumpadHome UP::
NumpadHome UP::ReleaseUp() ReleaseLeft()
^NumpadEnd UP::
NumpadEnd UP::ReleaseDown() ReleaseLeft()
^NumpadPgUp UP::
NumpadPgUp UP::ReleaseUp() ReleaseRight()
^NumpadPgDn UP::
NumpadPgDn UP::ReleaseDown() ReleaseRight()
return
;functions to continuously run move functions while keys are pressed
PressUp() {
global
if (lastVertical = -1)
return
offDirection := ["Left", "", "Right"][lastHorizontal + 2]
if (pressingDown || lastHorizontal != 0)
SetTimer % "Move" . ["", "Down"][pressingDown + 1] . offDirection, Delete
SetTimer % "MoveUp" . offDirection, 1
lastVertical := -1, pressingUp := True
}
PressDown() {
global
if (lastVertical = 1)
return
offDirection := ["Left", "", "Right"][lastHorizontal + 2]
if (pressingUp || lastHorizontal != 0)
SetTimer % "Move" . ["", "Up"][pressingUp + 1] . offDirection, Delete
SetTimer % "MoveDown" . offDirection, 1
lastVertical := 1, pressingDown := True
}
PressLeft() {
global
if (lastHorizontal = -1)
return
offDirection := ["Up", "", "Down"][lastVertical + 2]
if (pressingRight || lastVertical != 0)
SetTimer % "Move" . offDirection . ["", "Right"][pressingRight + 1], Delete
SetTimer % "Move" . offDirection . "Left", 1
lastHorizontal := -1, pressingLeft := True
}
PressRight() {
global
if (lastHorizontal = 1)
return
offDirection := ["Up", "", "Down"][lastVertical + 2]
if (pressingLeft || lastVertical != 0)
SetTimer % "Move" . offDirection . ["", "Left"][pressingLeft + 1], Delete
SetTimer % "Move" . offDirection . "Right", 1
lastHorizontal := 1, pressingRight := True
}
ReleaseUp() {
global
lastVertical := pressingDown, pressingUp := False
offDirection := ["Left", "", "Right"][lastHorizontal + 2]
SetTimer % "MoveUp" . offDirection, Delete
if (pressingDown || lastHorizontal != 0)
SetTimer % "Move" . ["", "Down"][pressingDown + 1] . offDirection, 1
}
ReleaseDown() {
global
lastVertical := -pressingUp, pressingDown := False
offDirection := ["Left", "", "Right"][lastHorizontal + 2]
SetTimer % "MoveDown" . offDirection, Delete
if (pressingUp || lastHorizontal != 0)
SetTimer % "Move" . ["", "Up"][pressingUp + 1] . offDirection, 1
}
ReleaseLeft() {
global
lastHorizontal := pressingRight, pressingLeft := False
offDirection := ["Up", "", "Down"][lastVertical + 2]
SetTimer % "Move" . offDirection . "Left", Delete
if (pressingRight || lastVertical != 0)
SetTimer % "Move" . offDirection . ["", "Right"][pressingRight + 1], 1
}
ReleaseRight() {
global
lastHorizontal := -pressingLeft, pressingRight := False
offDirection := ["Up", "", "Down"][lastVertical + 2]
SetTimer % "Move" . offDirection . "Right", Delete
if (pressingLeft || lastVertical != 0)
SetTimer % "Move" . offDirection . ["", "Left"][pressingLeft + 1], 1
}
MoveLeft() {
step := GetStep()
MouseMove -step, 0, 0, R
}
MoveRight() {
step := GetStep()
MouseMove step, 0, 0, R
}
MoveUp() {
step := GetStep()
MouseMove 0, -step, 0, R
}
MoveDown() {
step := GetStep()
MouseMove 0, step, 0, R
}
MoveUpLeft() {
step := GetStep()
MouseMove -step, -step, 0, R
}
MoveUpRight() {
step := GetStep()
MouseMove step, -step, 0, R
}
MoveDownLeft() {
step := GetStep()
MouseMove -step, step, 0, R
}
MoveDownRight() {
step := GetStep()
MouseMove step, step, 0, R
}
GetStep() {
global
return GetKeyState("Ctrl", "P") ? varFastStep : varSlowStep
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment