Last active
February 1, 2019 15:24
-
-
Save LeoDJ/b2b5a796a312c84eff6635f6fb89afa9 to your computer and use it in GitHub Desktop.
AHK middle mouse scroll everywhere
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; Description: Scroll Explorer on middle mouse button drag | |
; Permalink: https://autohotkey.com/boards/viewtopic.php?t=43715 | |
; Author: aph | |
; Version: 0.4.1 | |
; Modified by: LeoDJ | |
; changelog: | |
; 0.4.1: - fixed Firefox getting stuck | |
; 0.4.0: - implemented much better exponential scrolling behaviour | |
; - tried to handle sticky scrolling better, but sometimes AHK does not see the KeyUp event, even when polled | |
; 0.3.0: - implement other scrolling behaviour, but still not perfect | |
; 0.2.1: - allow scrolling in any application | |
; TODO: | |
; - fix bug when firefox is inactive and is middle-clicked, nothing becomes clickable anymore, until Ctrl-Alt-Del | |
$*MButton:: | |
MouseGetPos, CursorX, CursorY, Window, ClassNN | |
WinGetTitle, Title, ahk_id %Window% | |
WinGetClass, ahk_class, ahk_id %Window% | |
WinGet ahk_exe, ProcessName, ahk_id %Window% | |
WinGet ahk_PID, PID, ahk_id %Window% | |
WinGetText, VisibleText, ahk_id %Window% | |
MouseGetPos, CursorX_ended, CursorY_ended, Window_ended, ClassNN_ended | |
WinGetClass, ahk_class_ended, ahk_id %Window_ended% | |
WinGet ahk_exe_ended, ProcessName, ahk_id %Window_ended% | |
AllowedApp := True or ahk_exe = "explorer.exe" or ahk_exe = "mmc.exe" or ahk_exe = "systempropertiesadvanced.exe" or ahk_exe = "filezilla.exe" or ahk_exe = "7zFM.exe" | |
AllowedText := InStr(VisibleText, "Tree View") or InStr(VisibleText, "FolderView") | |
LimitedApp := ahk_exe = "cmd.exe" | |
DisabledApp := ahk_class_ended = "Shell_TrayWnd" or ahk_class_ended = "WorkerW" or ahk_exe = "firefox.exe" or Title = "3D Viewer" | |
if (AllowedText >= 1) | |
AllowedText = 1 | |
If (DisabledApp) { | |
SendInput, {MButton Down} | |
Return | |
} | |
Else If (!AllowedApp and !LimitedApp and !AllowedText) { | |
SendInput, {MButton Down} | |
Return | |
} | |
Else { | |
If (AllowedApp) { | |
; SendInput, {MButton} | |
} | |
MiddleScroll := 1 | |
SetSystemCursor("SIZEALL") | |
DeadZone = 5 ; How far the middle mouse wheel has to be dragged before scrolling is triggered | |
Sensitivity := 5 ; inverse, higher = less sensitive | |
ExpoBase := 1.1 | |
OrigTimer := 500 ; How quickly the file list scrolls | |
MouseGetPos, X1, Y1, , c, 2 | |
PollInterval := 50 | |
SetTimer, MBScroll, %PollInterval% | |
LastScroll := A_TickCount | |
LastStickyCheck := A_TickCount | |
Timer := 0 | |
ScrollTicks := 0 | |
MBScroll: | |
MouseGetPos, X2, Y2 | |
Distance := Abs(Y2-Y1) | |
If (Distance >= DeadZone) { | |
Timer := OrigTimer / (ExpoBase ** (Distance / Sensitivity - DeadZone)) | |
If (Timer < 0) { | |
Timer := 0 | |
} | |
If (A_TickCount - LastScroll >= Timer) { | |
SendInput, % "{Blind}{Wheel" (Y2 > Y1 ? "Down" : "Up") " " Rounded "}" | |
LastScroll := A_TickCount | |
ScrollTicks++ | |
} | |
; fix sticky scrolling, can't check often, because else GetKeyState gets stuck as well | |
If (A_TickCount - LastStickyCheck >= 50) { | |
LastStickyCheck := A_TickCount | |
If (!GetKeyState("MButton", "P")) { | |
; OutputDebug, "Was stuck, stop scrolling" | |
; SetTimer, MBScroll, off | |
Gosub MBScrollDone | |
Return | |
} | |
} | |
waitTime := Timer < PollInterval ? Timer : PollInterval | |
SetTimer, MBScroll, %waitTime% | |
; debug := GetKeyState("MButton", "P") | |
; OutputDebug, %debug% | |
} | |
Return | |
MBScrollDone: | |
DllCall("SystemParametersInfo", UInt, 0x69, UInt, 3, UInt, 0, UInt, 0) ; Set back to 3 lines scrolled | |
SetTimer, MBScroll, off | |
SetSystemCursor() | |
MiddleScroll := 0 | |
If (ScrollTicks == 0) { | |
SendInput {MButton} | |
} | |
SetSystemCursor(Cursor="") { | |
SystemCursors := "32512IDC_ARROW|32513IDC_IBEAM|32514IDC_WAIT|32515IDC_CROSS|32516IDC_UPARROW|32642IDC_SIZENWSE|32643IDC_SIZENESW|32644IDC_SIZEWE|32645IDC_SIZENS|32646IDC_SIZEALL|32648IDC_NO|32649IDC_HAND|32650IDC_APPSTARTING|32651IDC_HELP" | |
If (Cursor = "") | |
Return DllCall("SystemParametersInfo", "UInt", 0x57, "UInt", 0, "UInt", 0, "UInt", 0) | |
If (StrLen(SystemCursors) = 221) | |
Loop, Parse, SystemCursors, | | |
StringReplace, SystemCursors, SystemCursors, %A_LoopField%, % DllCall("LoadCursor", "UInt", 0, "Int", SubStr(A_LoopField, 1, 5)) A_LoopField | |
If !(Cursor := SubStr(SystemCursors, InStr(SystemCursors "|", "IDC_" Cursor "|") - 5 - p := (StrLen(SystemCursors) - 221) / 14, 5)) | |
MsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, Invalid cursor name! | |
Else | |
Loop, Parse, SystemCursors, | | |
DllCall("SetSystemCursor", "UInt", DllCall("CopyIcon", "UInt", Cursor), "Int", SubStr(A_LoopField, 6, p)) | |
} | |
Return | |
$*MButton Up:: | |
If (DisabledApp or LimitedApp) { | |
SendInput {MButton Up} | |
} | |
Else { | |
Gosub MBScrollDone | |
} | |
Return | |
} | |
Return |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment