├── 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 |
--------------------------------------------------------------------------------