Virtual pinch-to-zoom for any Windows app — no touchscreen required.
TouchpadZoom converts modifier-key + mouse-wheel into native Windows touch-injection pinch gestures, giving you smooth pinch-to-zoom and pan in apps that only support touch input (maps, design tools, image viewers, etc.).
🌐 Website: touchpad.pages.dev
- Pinch-to-Zoom — Hold a modifier chord and scroll to zoom in/out with injected two-finger pinch gestures.
- Click-and-Drag Pan — Hold the modifier chord and left-click-drag to pan with an injected two-finger touch.
- Works Everywhere — Uses the Windows Touch Injection API, so it works in any app that supports touch/pinch gestures.
- Configurable — Adjustable trigger chord, zoom speed, animation steps, direction inversion, and more.
- Click Guard — Suppresses accidental clicks during and shortly after zooming.
- Lightweight — Single Python script with no third-party dependencies (only the Windows API via
ctypes). - Installer Included — Ships with an Inno Setup installer that registers the app to run at startup.
- Windows 8 or later (uses the Touch Injection API)
- Administrator privileges (required by
InitializeTouchInjection) - Python 3.8+ (if running from source)
Download and run ZoomUtility_Installer.exe from the Releases page. The installer:
- Installs the application to your AppData folder.
- Adds a Start Menu shortcut.
- Registers the app to start automatically with Windows.
git clone https://github.com/Domincog/TouchpadZoom.git
cd TouchpadZoom
python zoom.pyNote: Run the terminal/script as Administrator.
Once running, you'll see:
╔══════════════════════════════════════════════╗
║ Virtual Pinch-to-Zoom running ║
║ Hold Ctrl + Alt ║
║ (Wheel is swallowed in that mode) ║
║ Ctrl+C to quit ║
╚══════════════════════════════════════════════╝
| Action | Default Shortcut |
|---|---|
| Zoom in | Ctrl + Alt + Scroll Up |
| Zoom out | Ctrl + Alt + Scroll Down |
| Pan | Ctrl + Alt + Left-click Drag |
| Quit | Ctrl + C |
All options are available as command-line arguments:
python zoom.py [OPTIONS]| Option | Default | Description |
|---|---|---|
--debug |
off | Verbose logging |
--spread |
60 |
Starting half-distance between the two virtual fingers (px) |
--delta |
34 |
Change in spread per wheel tick (px) |
--steps |
10 |
Animation steps per pinch gesture |
--step-sleep |
0.005 |
Sleep between animation steps (seconds) |
--trigger-chord |
ctrl+alt |
Modifier chord (ctrl+alt or ctrl+shift) |
--invert-direction |
off | Invert scroll-to-zoom direction |
--compat-profile |
on |
Diagonal gesture path for broader app compatibility |
--down-hold |
0.012 |
Extra hold after touch-down before animation (seconds) |
--max-gestures-per-sec |
4.0 |
Rate limit for emitted pinch gestures |
--click-guard |
on |
Suppress accidental clicks during zoom |
--click-guard-ms |
180 |
Click suppression cooldown after wheel activity (ms) |
Use Ctrl + Shift as the trigger instead of Ctrl + Alt:
python zoom.py --trigger-chord ctrl+shiftIncrease zoom speed and invert direction:
python zoom.py --delta 50 --invert-directionThis project is licensed under the MIT License.
Made with ❤️ by Dominic