├── README.md ├── archive ├── scroll-2d │ ├── readme.md │ ├── x-button-block.ahk │ └── x-main-2d.ahk ├── v02 │ └── mouse-scroll-v02.ahk └── v03 │ ├── README.md │ ├── mouse-scroll-main.ahk │ ├── mouse-scroll-run.ahk │ └── rbutton-block.ahk ├── img └── wheel.png └── mouse-scroll-v04.ahk /README.md: -------------------------------------------------------------------------------- 1 | # Drag to scroll 🖱️↕ (Autohotkey, Windows) 2 | This Autohotkey app provides system-wide drag-to-scroll feature. It uses mouse movement for scrolling, which turns out to be more efficient and it reduces stress on the operator's hand, compared to the scroll wheel. So if you want better scrolling experience, or maybe your scroll wheel have broken, then this app is for you. 3 | Further, if you use a drawing tablet or a touchpad and the driver/OS does not provide drag scroll, then this app solves it. 4 | 5 | > Note: if this version is not working stable, e.g. the context menu still shows up, you can try older version (v03 in the archive folder) 6 | 7 | ### Installation 8 | Firstly, you need Autohotkey (v1.1.27+) installed on your PC. The easiest option is to download the .exe installer from the offical site: [www.autohotkey.com](https://www.autohotkey.com) 9 | 10 | Once you have installed Autohotkey, “.ahk” files can be run directly in explorer. 11 | 12 | Download the script: 13 | 14 | [mouse-scroll-v04.ahk](mouse-scroll-v04.ahk) 15 | 16 | 17 | ### Run the script 18 | 19 | Run the “mouse-scroll-v04.ahk”. Now hold the right mouse button and move the mouse to scroll. 20 | To close the app, manually close the tray icon. 21 | 22 | If you want the app to start automatically at OS startup, copy-paste the script or a shortcut into the Startup folder (%appdata%\Microsoft\Windows\Start Menu\Programs\Startup). 23 | 24 | ### Setup 25 | **Note**: For smoother scrolling, you may first set the system scroll speed to “1” or “2” in system Mouse Properties: 26 | 27 | 28 | 29 | Customizations are made in the script directly. 30 | Few setup variables are available, see the “User settings” section in the source code. Simply edit the variable in the source code and restart the app (just run it again, it will reload immediately, or click "reload" in the tray icon). 31 | 32 | Settings: 33 | 34 | To use horizontal movement as input (it is better ergonomically and set as default), set the `horiz` variable to “true” or “false”: 35 | > horiz := true 36 | 37 | To swap the scrolling direction, set the `swap` variable to “true” or “false”: 38 | > swap := true 39 | 40 | To set the scroll speed factor, edit the `k` variable: 41 | > k := 6 42 | 43 | 44 | ### Other versions 45 | 46 | 2d scroll (in both directions) 47 | 48 | https://github.com/Mikhail22/drag-scroll--autohotkey/tree/master/archive/scroll-2d#scroll-in-both-directions 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /archive/scroll-2d/readme.md: -------------------------------------------------------------------------------- 1 | # Scroll in both directions 2 | 3 | ### Usage: 4 | 5 | 1. Run x-button-block.ahk 6 | 2. Run x-main-2d.ahk 7 | 8 | -------------------------------------------------------------------------------- /archive/scroll-2d/x-button-block.ahk: -------------------------------------------------------------------------------- 1 | numpaddiv::return 2 | -------------------------------------------------------------------------------- /archive/scroll-2d/x-main-2d.ahk: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | */ 4 | 5 | #SingleInstance force 6 | #NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. 7 | SendMode Input ; Recommended for new scripts due to its superior speed and reliability. 8 | ; SetStoreCapsLockMode, Off 9 | #InstallMouseHook 10 | ; #InstallKeybdHook 11 | running := 1 12 | SetDefaultMouseSpeed, 0 13 | SetMouseDelay, -1 14 | CoordMode, Mouse, Screen 15 | ; === User settings === 16 | swapX := false 17 | swapY := true 18 | ; swap := true ; swap scroll direction 19 | k := 1 ; scroll speed coefficient (higher k means higher speed) 20 | 21 | ; === Internal settings === 22 | scrollsLimit := 10 ; max amount of scroll at once 23 | S := 10 ; unit distance (higher S = lower speed) 24 | 25 | ; ============== 26 | 27 | 28 | 29 | d0X := 0 30 | d0Y := 0 31 | nX := 0 32 | nY := 0 33 | nXabs := 0 34 | nYabs := 0 35 | dSumX := 0 36 | dSumY := 0 37 | mousegetpos, mxFix, myFix 38 | scrollsTotal := 0 39 | dLimit := 50 40 | T := 20 ; scan frequency in MS 41 | TC := 350 ; double click speed MS 42 | ticker := 1000 ; tick counter ms 43 | 44 | loop 45 | { 46 | sleep %T% 47 | pan := getkeystate("rbutton", "P") ; set the key used to scroll 48 | ; pan := getkeystate("numpaddiv", "P") ; set the key used to scroll 49 | trigger := (pan > panPrev) 50 | if (trigger = 1) { 51 | if (ticker < TC) { 52 | send {click right} 53 | } else { 54 | ticker := 0 55 | } 56 | } 57 | ticker := ticker + T 58 | panPrev := pan 59 | mousegetpos mx, my ; get current mouse position 60 | if (pan = 1) { 61 | d0X := k*(mx - mxFix) 62 | d0Y := k*(my - myFix) 63 | ; d0 := k*(mx - mxFix) 64 | dSumX := dSumX + d0X 65 | dSumY := dSumY + d0Y 66 | directionX := (dSumX >= 0) ^ swapX 67 | directionY := (dSumY >= 0) ^ swapY 68 | nX := dSumX // S 69 | nY := dSumY // S 70 | dSumX := dSumX - nX * S ; calculate remainder after division 71 | dSumY := dSumY - nY * S ; calculate remainder after division 72 | 73 | nXabs := abs(nX) 74 | nXabs := min(nXabs, scrollsLimit) 75 | 76 | nYabs := abs(nY) 77 | nYabs := min(nYabs, scrollsLimit) 78 | 79 | if (nXabs > 0) { 80 | if (directionX = 1) 81 | send {wheelleft %nXabs%} 82 | if (directionX = 0) 83 | send {wheelright %nXabs%} 84 | } 85 | if (nYabs > 0) { 86 | if (directionY = 1) 87 | send {wheeldown %nYabs%} 88 | if (directionY = 0) 89 | send {wheelup %nYabs%} 90 | } 91 | 92 | } else { 93 | d0X := 0 94 | d0Y := 0 95 | dSumX := 0 96 | dSumY := 0 97 | } 98 | mousegetpos, mxFix, myFix 99 | } 100 | 101 | 102 | ; +esc:: ExitApp 103 | 104 | 105 | -------------------------------------------------------------------------------- /archive/v02/mouse-scroll-v02.ahk: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Mouse Scroll v.02 4 | by Mikhail V., 2018 5 | tested on Windows 10, AHK 1.1.28 6 | Note: this app uses right mouse button to toggle the scroll, so the rbutton will be blocked 7 | (see rbutton-block.ahk) to prevent the context menu popup. 8 | */ 9 | 10 | #SingleInstance force 11 | #NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. 12 | SendMode Input ; Recommended for new scripts due to its superior speed and reliability. 13 | SetStoreCapsLockMode, Off 14 | ; install mouse hook - it is needed to read the physical state 15 | ; of the mouse button if it is blocked by another thread 16 | #InstallMouseHook 17 | 18 | ; min function 19 | min(a, b) { 20 | if (b < a) { 21 | return b 22 | } 23 | return a 24 | } 25 | 26 | ; scroll function : d = direction, n = amount of scrolls 27 | scroll(d, n) { 28 | if (d = 1) { 29 | send, {wheeldown %n% } 30 | } 31 | if (d = 0) { 32 | send, {wheelup %n%} 33 | } 34 | } 35 | 36 | ; === SETTINGS === 37 | k := 0.6 ; scroll speed coefficient (higher k = more speed) 38 | 39 | swap := true ; swap scroll direction 40 | ; swap := false 41 | movelimit := 15 ; max amount of scroll at once (better leave as is) 42 | ; ============== 43 | 44 | mousegetpos, , Yp ; get mouse Y position 45 | panp := getkeystate("rbutton", "P") ; save key state / set the key used to scroll 46 | dY := 0 47 | totalMoves := 0 48 | 49 | loop 50 | { 51 | sleep 10 52 | pan := getkeystate("rbutton", "P") ; set the key used to scroll 53 | pan_on := (pan > panp) ; check if key state is changed 54 | pan_off := (pan < panp) ; check if key state is changed 55 | panp := pan 56 | ; tooltip %pan% 57 | mousegetpos, , Y ; get current mouse position Y 58 | dY := dY + (k * (Y - Yp)) ; relative mouse movement 59 | Yp := Y ; save Y position 60 | moves := min(floor(abs(dY)), movelimit) ; amount of scroll events per once 61 | direct := (dY >= 0) ^ swap ; get direction 62 | if (moves = movelimit) { 63 | dY := 0 ; dY should always go to zero if movelimit is reached 64 | } else { 65 | dY := dY - (moves * (-1)**(dY < 0)) ; dY remainder should remain for next loop (incase mouse is moving slowly) 66 | } 67 | ; tooltip, %direct% , %dY% 68 | if (pan = true) { 69 | scroll(direct, moves) 70 | totalMoves := totalMoves + moves 71 | } 72 | if (pan_off = true) { 73 | if (totalMoves = 0) { 74 | send {rbutton} 75 | } 76 | totalMoves := 0 77 | } 78 | 79 | } 80 | 81 | ; +esc:: exitapp 82 | -------------------------------------------------------------------------------- /archive/v03/README.md: -------------------------------------------------------------------------------- 1 | # Drag to scroll 🖱️↕ (Autohotkey, Windows) 2 | This Autohotkey app provides system-wide drag-to-scroll feature. It uses mouse vertical movement for scrolling, which turns out to be more efficient and it also significantly reduces stress on the operator's hand compared to the scroll wheel. So if you want better scrolling experience (or maybe your scroll wheel broke) then this app is for you. 3 | Further, if you use a drawing tablet or a touchpad and the driver/OS does not provide drag scroll, then this app solves it. 4 | 5 | ### Installation 6 | Firstly, you need Autohotkey (v1.1.27+) installed on your PC. The easiest option is to download the .exe installer from the offical site: [www.autohotkey.com](https://www.autohotkey.com) 7 | 8 | Once you have installed Autohotkey, “.ahk” files can be run directly in explorer. 9 | 10 | Download and put these 3 files in some local folder together: 11 | 12 | [mouse-scroll-run.ahk](mouse-scroll-run.ahk) 13 | [mouse-scroll-main.ahk](mouse-scroll-main.ahk) 14 | [rbutton-block.ahk](rbutton-block.ahk) 15 | 16 | 17 | ### Run the script 18 | 19 | Run the “mouse-scroll-run.ahk”, it will run other two scripts. Now hold the right mouse button and move the mouse to scroll. 20 | To close the app, manually close tray icons of both scripts. 21 | 22 | If you want the app to start automatically at OS startup, copy-paste the shortcut of the “mouse-scroll-run.ahk” into the Startup folder: 23 | (“%appdata%\Microsoft\Windows\Start Menu\Programs\Startup”). 24 | 25 | ### Setup 26 | **Note**: For smoother scrolling, you may first set the system scroll speed to “1” or “2” in system Mouse Properties: 27 | 28 | 29 | 30 | To customize the scrolling speed you need to edit the main script, “mouse-scroll-main.ahk”. 31 | Few setup variables are available, see “User settings” section in the source code. Simply edit the variable in the source code and restart the app 32 | (just run “mouse-scroll-main.ahk” again, it should reload automatically). 33 | 34 | To set the scroll speed factor, edit the `k` variable: 35 | > k := 6 36 | 37 | To swap the scrolling direction, set the `swap` variable to “true” or “false”: 38 | > swap := true 39 | 40 |
41 | 42 | --- 43 | 44 | ### Files summary 45 | [mouse-scroll-run.ahk](mouse-scroll-run.ahk) - Runs the other two scripts. 46 | [mouse-scroll-main.ahk](mouse-scroll-main.ahk) - Main app 47 | [rbutton-block.ahk](rbutton-block.ahk) - Prevents the right mouse button system-wide 48 | 49 | -------------------------------------------------------------------------------- /archive/v03/mouse-scroll-main.ahk: -------------------------------------------------------------------------------- 1 | /* 2 | Mouse Scroll v03 3 | by Mikhail V., 2020 4 | tested on Windows 10, AHK 1.1.28 5 | 6 | Note: this app uses right mouse button to toggle scrolling, 7 | so the rbutton is blocked to prevent the context menu popup. 8 | (see: rbutton-block.ahk) 9 | */ 10 | 11 | #SingleInstance force 12 | #NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. 13 | SendMode Input ; Recommended for new scripts due to its superior speed and reliability. 14 | SetStoreCapsLockMode, Off 15 | #InstallMouseHook 16 | 17 | ; === User settings === 18 | ; swap := false 19 | swap := true ; swap scroll direction 20 | k := 6 ; scroll speed coefficient (higher k means higher speed) 21 | 22 | ; === Internal settings === 23 | movelimit := 15 ; max amount of scroll at once 24 | S := 20 ; unit distance (higher S = lower speed) 25 | T := 20 ; scan frequency in MS ( 26 | 27 | ; ============== 28 | 29 | mousegetpos, , yp ; get mouse Y position 30 | ; panp := getkeystate("rbutton", "P") ; save key state / set the key used to scroll 31 | dy := 0 32 | dyTotal := 0 33 | movesTotal := 0 34 | 35 | loop 36 | { 37 | sleep %T% 38 | pan := getkeystate("rbutton", "P") ; set the key used to scroll 39 | ; pan_on := (pan > panp) ; check if key state is changed 40 | pan_off := (pan < panp) ; check if key state is changed 41 | panp := pan 42 | mousegetpos, , y ; get current mouse position Y 43 | dy := k * (y - yp) ; relative mouse movement 44 | yp := y ; save y position 45 | dyTotal := dyTotal + dy 46 | moves := dyTotal // S 47 | dyTotal := dyTotal - moves * S ; calculate remainder after division 48 | d := (moves >= 0) ^ swap ; get direction 49 | n := min(abs(moves), movelimit) 50 | ; tooltip, %moves% -- %dy% 51 | 52 | if (pan = true ) { 53 | if (d = 1) 54 | send, {wheeldown %n% } 55 | if (d = 0) 56 | send, {wheelup %n%} 57 | movesTotal := movesTotal + moves 58 | } 59 | if (pan_off = true) { 60 | if (movesTotal = 0) 61 | send {rbutton} 62 | movesTotal := 0 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /archive/v03/mouse-scroll-run.ahk: -------------------------------------------------------------------------------- 1 | 2 | Run, rbutton-block.ahk 3 | Run, mouse-scroll-main.ahk 4 | 5 | exitapp 6 | -------------------------------------------------------------------------------- /archive/v03/rbutton-block.ahk: -------------------------------------------------------------------------------- 1 | ; block the right mouse button 2 | rbutton::return 3 | -------------------------------------------------------------------------------- /img/wheel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mikhail22/drag-scroll--autohotkey/93098527b120559898fe00a3211498f089d45389/img/wheel.png -------------------------------------------------------------------------------- /mouse-scroll-v04.ahk: -------------------------------------------------------------------------------- 1 | /* 2 | Mouse Scroll v04 3 | by Mikhail V., 2021 4 | tested on Windows 10, AHK 1.1.28 5 | */ 6 | 7 | #SingleInstance force 8 | #NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. 9 | SendMode Input ; Recommended for new scripts due to its superior speed and reliability. 10 | 11 | running := 0 12 | 13 | ; === User settings === 14 | swap := false 15 | ; swap := true ; swap scroll direction 16 | 17 | ; horiz := false 18 | horiz := true ; use horizontal movement as input 19 | 20 | k := 2 ; scroll speed coefficient (higher k means higher speed) 21 | 22 | ; === Internal settings === 23 | scrollsLimit := 15 ; max amount of scroll at once 24 | S := 12 ; unit distance (higher S = lower speed) 25 | T := 30 ; scan frequency in MS ( 26 | 27 | ; ============== 28 | 29 | dy := 0 30 | dyTotal := 0 31 | scrollsTotal := 0 32 | 33 | ; #if running 34 | loop 35 | { 36 | sleep %T% 37 | 38 | if (running) { 39 | ; mousegetpos, mx ; get current mouse position 40 | mousegetpos, mx, my ; get current mouse position 41 | if (horiz = 0) { 42 | dy := k * (my - myLast) ; relative mouse movement vertical 43 | myLast := my ; save position 44 | } else { 45 | dy := k * (mx - mxLast) ; relative mouse movement horizontal 46 | mxLast := mx ; save position 47 | } 48 | dyTotal := dyTotal + dy 49 | scrolls := dyTotal // S 50 | dyTotal := dyTotal - scrolls * S ; calculate remainder after division 51 | direction := (scrolls >= 0) ^ swap ; get direction 52 | scrollsN := abs(scrolls) 53 | scrollsTotal := scrollsTotal + scrollsN 54 | n := min(scrollsN, scrollsLimit) 55 | ; tooltip, %scrolls% -- %dy% 56 | if (direction = 1) 57 | send, {wheeldown %n%} 58 | if (direction = 0) 59 | send, {wheelup %n%} 60 | } 61 | } 62 | 63 | rbutton:: 64 | running := 1 65 | dyTotal := 0 66 | mousegetpos, mxLast, myLast 67 | return 68 | 69 | rbutton up:: 70 | running := 0 71 | if (scrollsTotal = 0) 72 | send {rbutton} 73 | scrollsTotal := 0 74 | return 75 | 76 | ; +esc:: ExitApp 77 | --------------------------------------------------------------------------------