Skip to content

Instantly share code, notes, and snippets.

@tanftw
Created January 17, 2026 09:32
Show Gist options
  • Select an option

  • Save tanftw/d2e661f40fdd5adb9f4f5925f23247ba to your computer and use it in GitHub Desktop.

Select an option

Save tanftw/d2e661f40fdd5adb9f4f5925f23247ba to your computer and use it in GitHub Desktop.
Alt + mouse move to scroll

Let users to press alt+mouse move to scroll to the target position, keep the mouse at the current position. Useful for trackball users who want the ability to scroll easily.

How to use: Just run this script, tested with Linux. Didn't check with Windows yet but should works on Windows too. You can add it to the startup application, eg. via .zshrc

#!/usr/bin/env python3
from pynput import keyboard, mouse
# --- CONFIGURATION ---
SENSITIVITY = 10 # Lower = Faster
# ---------------------
m = mouse.Controller()
anchor_pos = None
accumulator = 0
modifier_held = False
def on_key_press(key):
global anchor_pos, accumulator, modifier_held
# Check for either Left Alt or Right Alt
if key in (keyboard.Key.alt, keyboard.Key.alt_l, keyboard.Key.alt_r):
if anchor_pos is None:
anchor_pos = m.position
accumulator = 0
modifier_held = True
def on_key_release(key):
global anchor_pos, modifier_held
if key in (keyboard.Key.alt, keyboard.Key.alt_l, keyboard.Key.alt_r):
anchor_pos = None
modifier_held = False
def on_move(x, y):
global anchor_pos, accumulator, modifier_held
# 1. Safety check
if anchor_pos is None or not modifier_held:
return
# 2. Prevent infinite loop from the cursor reset
if (x, y) == anchor_pos:
return
# 3. Calculate movement
dy = y - anchor_pos[1]
accumulator += dy
# 4. Snap Cursor Back (Lock position)
m.position = anchor_pos
# 5. Scroll Logic
if abs(accumulator) >= SENSITIVITY:
steps = int(accumulator / SENSITIVITY)
# NOTE: We are sending a scroll event WHILE Alt is held.
# Most apps handle this fine, but some might see "Alt+Scroll"
m.scroll(0, -steps)
accumulator -= (steps * SENSITIVITY)
# Start listeners
with keyboard.Listener(on_press=on_key_press, on_release=on_key_release) as k_listener, \
mouse.Listener(on_move=on_move) as m_listener:
k_listener.join()
m_listener.join()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment