Created
September 15, 2013 14:05
-
-
Save be5invis/6571037 to your computer and use it in GitHub Desktop.
DPI-aware FocuslessScroll
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
; Modified by Belleve Invis | |
; In order to support High DPI environment | |
; FocuslessScroll by Scoox | |
; Source: http://www.autohotkey.com/board/topic/6292-send-mouse-scrolls-to-window-under-mouse/?p=398492 | |
; Modifications by Geoff Stokes | |
;Directives | |
#NoEnv | |
#SingleInstance Force | |
#MaxHotkeysPerInterval 150 ;Avoid warning when mouse wheel turned very fast | |
Menu, Tray, Tip, FocuslessScroll by Scoox | |
Menu, Tray, Icon, Shell32.dll, 123 | |
;Autoexecute code | |
IniRead, MinLinesPerNotch, config.ini, FocuslessScroll, linespernotchmin, 1 | |
IniRead, MaxLinesPerNotch, config.ini, FocuslessScroll, linespernotchmax, 3 | |
IniRead, AccelerationThreshold, config.ini, FocuslessScroll, accelerationthreshold, 100 | |
IniRead, AccelerationType, config.ini, FocuslessScroll, accelerationtype, "P" | |
IniRead, StutterThreshold, config.ini, FocuslessScroll, stutterthreshold, 10 | |
IniRead, NaturalScrolling, config.ini, FocuslessScroll, naturalscrolling, true ; Natural Scrolling, like touch devices | |
IniRead, EmulateStandardWScrollLock, config.ini, FocuslessScroll, emulatestandardwithscrolllock, true ; Emulate default Windows scrolling when Scroll Lock is on (3-line, traditional direction) | |
IniRead, TitlebarMinimise, config.ini, FocuslessScroll, titlebarminimise, true | |
;Function definitions | |
;See above for details | |
FocuslessScroll(MinLinesPerNotch, MaxLinesPerNotch, AccelerationThreshold, AccelerationType, StutterThreshold, NaturalScrolling, EmulateStandardWScrollLock, TitlebarMinimise) | |
{ | |
SetBatchLines, -1 ;Run as fast as possible | |
CoordMode, Mouse, Screen ;All coords relative to screen | |
SetMouseDelay, -1 | |
SetKeyDelay, -1 | |
If(%EmulateStandardWScrollLock% == true) AND (GetKeyState("ScrollLock", "T")) | |
{ | |
MinLinesPerNotch := 3 | |
MaxLinesPerNotch := 3 | |
NaturalScrolling := false | |
} | |
;Stutter filter: Prevent stutter caused by cheap mice by ignoring successive WheelUp/WheelDown events that occur to close together. | |
If(A_TimeSincePriorHotkey < StutterThreshold) ;Quickest succession time in ms | |
If(A_PriorHotkey = "WheelUp" Or A_PriorHotkey ="WheelDown") | |
Return | |
VarSetCapacity(pp, 8, 0) | |
DllCall("GetPhysicalCursorPos", ptr, &pp) | |
p_x := NumGet(pp, 0, "uint32") | |
p_y := NumGet(pp, 4, "uint32") | |
ControlClass1 := DllCall("WindowFromPhysicalPoint", "int64", (p_y << 32) | (p_x & 0xFFFFFFFF), "Ptr") ;32-bit and 64-bit support | |
DllCall("PhysicalToLogicalPoint", "uint", ControlClass1, ptr, &pp) | |
m_x := NumGet(pp, 0, "uint32") | |
m_y := NumGet(pp, 4, "uint32") | |
lParam := (m_y << 16) | (m_x & 0x0000FFFF) | |
delta := 120 ;Wheel delta is 120, as defined by MicroSoft | |
If(%NaturalScrolling% == true) ; hack to invert for natural scrolling | |
delta := -delta | |
;Detect WheelDown event | |
If(A_ThisHotkey = "WheelDown" Or A_ThisHotkey = "^WheelDown" Or A_ThisHotkey = "+WheelDown" Or A_ThisHotkey = "*WheelDown") | |
{ | |
delta := -delta ;If scrolling down, invert scroll direction | |
} | |
;Adjust lines per notch according to scrolling speed | |
Lines := LinesPerNotch(MinLinesPerNotch, MaxLinesPerNotch, AccelerationThreshold, AccelerationType) | |
delta := delta * Lines | |
wParam := (delta << 16) | |
;Detect modifer keys held down (only Shift and Control work) | |
If(GetKeyState("Shift","p")) | |
wParam := wParam | 0x4 | |
If(GetKeyState("Ctrl","p")) | |
wParam := wParam | 0x8 | |
SendMessage, 0x20A, wParam, lParam,, ahk_id %ControlClass1% | |
} | |
;All parameters are the same as the parameters of FocuslessScroll() | |
;Return value: Returns the number of lines to be scrolled calculated from the current scroll speed. | |
LinesPerNotch(MinLinesPerNotch, MaxLinesPerNotch, AccelerationThreshold, AccelerationType) | |
{ | |
T := A_TimeSincePriorHotkey | |
;Normal slow scrolling, separationg between scroll events is greater than AccelerationThreshold miliseconds. | |
If((T > AccelerationThreshold) Or (T = -1)) ;T = -1 if this is the first hotkey ever run | |
{ | |
Lines := MinLinesPerNotch | |
} | |
;Fast scrolling, use acceleration | |
Else | |
{ | |
If(AccelerationType = "P") | |
{ | |
;Parabolic scroll speed curve | |
;f(t) = At^2 + Bt + C | |
A := (MaxLinesPerNotch-MinLinesPerNotch)/(AccelerationThreshold**2) | |
B := -2 * (MaxLinesPerNotch - MinLinesPerNotch)/AccelerationThreshold | |
C := MaxLinesPerNotch | |
Lines := Round(A*(T**2) + B*T + C) | |
} | |
Else | |
{ | |
;Linear scroll speed curve | |
;f(t) = Bt + C | |
B := (MinLinesPerNotch-MaxLinesPerNotch)/AccelerationThreshold | |
C := MaxLinesPerNotch | |
Lines := Round(B*T + C) | |
} | |
} | |
Return Lines | |
} | |
;All hotkeys with the same parameters can use the same instance of FocuslessScroll(). No need to have separate calls unless each hotkey requires different parameters (e.g. you want to disable acceleration for Ctrl-WheelUp and Ctrl-WheelDown). If you want a single set of parameters for all scrollwheel actions, you can simply use *WheelUp:: and *WheelDown:: instead. | |
#MaxThreadsPerHotkey 6 ;Adjust to taste. The lower the value, the lesser the momentum problem on certain smooth-scrolling GUI controls (e.g. AHK helpfile main pane, WordPad...), but also the lesser the acceleration feel. The good news is that this setting does no affect most controls, only those that exhibit the momentum problem. Nice. | |
;Scroll with acceleration | |
WheelUp:: | |
WheelDown::FocuslessScroll(MinLinesPerNotch, MaxLinesPerNotch, AccelerationThreshold, AccelerationType, StutterThreshold, NaturalScrolling, EmulateStandardWScrollLock, TitlebarMinimise) | |
;Ctrl-Scroll zoom with no acceleration (MaxLinesPerNotch = MinLinesPerNotch). | |
^WheelUp:: | |
^WheelDown::FocuslessScroll(MinLinesPerNotch, MinLinesPerNotch, AccelerationThreshold, AccelerationType, StutterThreshold, NaturalScrolling, EmulateStandardWScrollLock, TitlebarMinimise) | |
;If you want zoom acceleration, replace above line with this: | |
;FocuslessScroll(MinLinesPerNotch, MaxLinesPerNotch, AccelerationThreshold, AccelerationType, StutterThreshold, NaturalScrolling, EmulateStandardWScrollLock, TitlebarMinimise) | |
#MaxThreadsPerHotkey 1 ;Restore AHK's default value i.e. 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment