Somewhere along the way the corporate desktop decided that an idle cursor means an idle human, and every knowledge worker with a managed laptop learned the choreography that follows: the screen lock that fires during a long read, the presence indicator that flips to yellow while you are thinking on paper, the VPN that drops because the machine decided nobody was home, and the whole category of mouse jiggler software exists because that one bad heuristic got baked into a thousand group policies, which is precisely why the tooling that answers it should be held to a higher standard than the average download-site freeware, because a utility whose entire job is to touch your input devices had better be the most boring, most auditable, most honest piece of code on the machine.
Realistic Mouse Jiggler is our entry in that category, a small Rust + egui app for Linux, macOS, and Windows, MIT-licensed, no telemetry, no account, no subscription, and it does exactly one thing: move the cursor in a way that reads as a person at the desk rather than a script on a timer, then get out of the way.
The motion is the product
The naive jiggler teleports the cursor one pixel every thirty seconds, and every endpoint agent and every observant coworker can spot that pattern from across the room, because nothing a human hand does looks like a metronome, so the default mode here is a smooth relative oscillation instead, a four-second sinusoidal sweep with a small vertical wobble layered on top, stepped at thirty-millisecond intervals so the pointer glides instead of jumping, with the whole path computed relative to wherever the cursor already sits so it never yanks the pointer away from something you are actually doing.
On top of that base motion sit two more modes for different tastes, an edge-to-edge traversal that crosses the full virtual desktop width at a fixed twelve hundred pixels per second so a three-monitor span takes proportionally longer instead of teleporting across it, and a random mode that fires bounded horizontal bursts at randomized directions and durations, and the realistic variants of all three add the detail that sells the illusion: micro-breaks.
// Realistic-mode micro-breaks: while moving, pause every 1..20s for 5..15s,
// then always resume. The motion clock freezes during a pause so the path
// continues from exactly where it stopped.
const PAUSE_MOVE_MIN_SEC: f64 = 1.0;
const PAUSE_MOVE_MAX_SEC: f64 = 20.0;
const PAUSE_MIN_SEC: f64 = 5.0;
const PAUSE_MAX_SEC: f64 = 15.0;
That pause scheduler is the whole trick, because a person reading a document does not glide continuously, they drift for a stretch, sit still for five or ten seconds while a paragraph sinks in, then drift again, and the alternation between the one-to-twenty-second moving window and the five-to-fifteen-second hold is what sells it, with the motion clock freezing during a hold so the path resumes from exactly the phase where it stopped rather than snapping to wherever a wall-clock sine would be by now, a small detail that costs a struct and a match statement and buys motion that survives a sideways glance from the next desk over.
One more implementation note worth publishing is the clamping policy, stated plainly in a comment in src/jiggler.rs: the OS clips at screen edges and the user can grab the mouse mid-sweep, so the physical offset can diverge from whatever the app commanded, which means the app clamps what it commands rather than trusting the physical position it reads back, and that “bounded commanded displacement” rule is what keeps a long-running jiggle from slowly walking the cursor into a corner across an afternoon of drift.
Moving the cursor is easy; getting permission is the product
The actual cursor movement runs through enigo, the standard Rust input-simulation crate, and on a clean X11 desktop that would be the end of the story, but the desktop in 2026 is Wayland, and Wayland’s security model treats global input capture and synthetic input as exactly the attack surface they are, so the Linux path reads bindings straight from /dev/input/event* with the user in the input group, and prefers ydotool for cursor movement when it is installed, because ydotool’s uinput-based daemon is the closest thing Wayland has to a blessed path for programmatic input.
macOS wants Accessibility and Input Monitoring permissions granted by hand in System Settings, Windows mostly works out of the box with the caveat that some security tools flag global hooks on sight, and one deliberate design line runs through all three: left click cannot be assigned as a start/stop binding, so the app can never eat the one button you need to reach its own controls, the kind of guardrail you only write down after someone on the team locks themselves out of exactly that.
Tray behavior got the same treatment, with ksni speaking the freedesktop StatusNotifierItem protocol on Linux so KDE Plasma users get a native tray while GNOME users get an honest note that they need an AppIndicator extension, tray-icon covering macOS and Windows, and the KDE/Wayland restore path handled explicitly so minimizing to the tray does not strand the window, because a jiggler you cannot find when your manager walks up is worse than no jiggler at all.
Signing is where these tools usually die
The honest reason this category has a bad reputation is distribution, not motion math, because the average jiggler is an unsigned exe from a site that also wants to install a browser toolbar, so the release pipeline signs everything: Windows artifacts go through Azure Artifact Signing, Microsoft’s hosted signing service now branded Trusted Signing, over OIDC from GitHub Actions with the signature verified in-workflow before the MSI is even built, every release asset gets a detached GPG signature from the VisorCraft Packages key whose public half is committed in the repo, and Arch and CachyOS users get a signed pacman package plus a one-line install script that pulls from the release page.
curl -fsSL https://github.com/visorcraft/realistic-mouse-jiggler/releases/latest/download/install-arch.sh | bash
That pipe into bash earns a skeptical look and it should, so the script is built to survive one: it pins the VisorCraft Packages key fingerprint inline, refuses to continue if the downloaded key does not match it, adds and locally signs the key with pacman-key, then downloads the package and its detached signature and lets pacman verify the pair before a single byte is installed, which means the one-liner is a bootstrap into a verified install rather than a leap of faith, and the fingerprint mismatch path exits loudly instead of quietly installing whatever it found.
None of that is glamorous, and all of it is the difference between a utility you can hand to a colleague and one you have to apologize for, because the machine that runs a jiggler is usually a machine with a security team watching it, and “the signature verifies, the source is public, the package is in pacman format” is the only answer that ends that conversation quickly.
What it deliberately is not
The tradeoff we picked, and would pick again, is scope: there is no scheduler, no calendar integration, no analytics dashboard telling you how awake you looked this week, because the moment a tool like this grows a feature list it grows a business model to match, and the subscription jiggler with a settings sync account is a real product that really exists and we would rather not be it, so what you get is a tray icon, a hotkey, three motion modes, and binaries that verify, a utility that earns its keep the way the good shareware of the nineties did, by doing the one thing correctly and then being quiet about it, and in 2026 that restraint is the feature.
