Smoothy is a Rust + Tauri desktop app for Linux that adds smooth, inertial mouse-wheel scrolling (Mac-like feel) with runtime tuning.
It captures wheel input from real devices, processes it with a smoothing/acceleration engine, and re-emits optimized wheel events through a virtual uinput device.
- Smooth wheel animation with easing (
easeOutCubic/linear) - Exponential acceleration ramp for rapid scrolling
- Backlog handling and sub-step precision output
- Vertical + optional horizontal wheel support
- Runtime controls from GUI (no restart required)
- Profile-based tuning (
custom,normal,aggressive,precision) - Diagnostics panel (permissions, device visibility, velocity graph)
- Exit behavior control:
ask,exit, orminimize
Smoothy uses a split pipeline inside one app:
-
Input Reader (evdev)
- Reads wheel events from
/dev/input/event* - Supports both standard and hi-res wheel axes
- Reads wheel events from
-
Physics Engine (Rust)
- Converts wheel steps to virtual distance (
step_size_px,pulse_scale) - Applies acceleration combo scaling for burst input
- Releases queued impulses over time with easing
- Converts virtual distance to hi-res + discrete wheel events
- Converts wheel steps to virtual distance (
-
Virtual Emitter (uinput)
- Emits smoothed wheel events through
/dev/uinput
- Emits smoothed wheel events through
-
Tauri GUI (React + TypeScript)
- Updates physics config at runtime through commands
- Displays service state, permissions, and velocity diagnostics
- Linux desktop environment
- Node.js + npm
- Rust toolchain (
cargo,rustc) - Tauri Linux build dependencies (WebKit/GTK packages for your distro)
If Linux GUI dependencies are missing,
cargo check/ Tauri build steps will fail.
git clone <your-repo-url>
cd smoothy
npm installSmoothy needs read access to /dev/input/event* and write access to /dev/uinput.
Run:
sudo bash resources/install-linux-permissions.shThen log out and log back in so your input group membership is applied.
Included resources:
resources/99-smoothy.rulesresources/install-linux-permissions.shresources/smoothy.service
npm run tauri devnpm run tauri:build- Open the app and go to Home.
- Start the service from the app menu.
- Tune behavior via profile or numeric parameters.
- Use Settings to:
- inspect diagnostics
- view velocity graph
- configure close-button behavior (
ask/exit/minimize)
If the service cannot start, check Settings > Diagnostic first (input readability + uinput availability).
You can run Smoothy in daemon mode with --daemon.
Use the provided systemd user template:
- Copy
resources/smoothy.serviceto~/.config/systemd/user/smoothy.service - Update
ExecStart=to your installed Smoothy binary path - Enable and start:
systemctl --user daemon-reload
systemctl --user enable --now smoothy.serviceBuild .deb and .AppImage bundles:
npm run package:linuxAlternative direct command:
npm run tauri:bundle:linuxNotes:
- AppImage flow uses
NO_STRIP=1to avoid linuxdeploy strip issues on some RELR-enabled systems. - Output directory:
src-tauri/target/release/bundle/
- Better onboarding for Linux permissions and startup checks
- Per-device profile assignment and automatic device mapping
- Safer profile import/export and sharing
- System tray controls and richer background behavior
- Improved diagnostics (event counters, latency indicators, error hints)
- More preset calibration for different wheel hardware
- Optional advanced tuning assistant (guided recommendations)
- Better desktop integration across distros/compositors
- Stability/performance hardening for broader hardware coverage
- Backend: Rust, Tokio, evdev, uinput
- Desktop shell: Tauri v2
- Frontend: React + TypeScript + Tailwind + Radix UI primitives
If Smoothy helps your workflow, you can support development here: