How to Detect a Mouse Jiggler: Four Checks, and a Script
How IT teams and monitoring tools detect mouse jigglers: apps, injected input on Windows, a Mac idle-counter test we ran, the USB device log and the movement pattern, with a tested script.
On this page
- 1. Detection signals, and which jiggler each one catches
- 2. Check 1: jiggler apps and scripts
- 3. Check 2: the injected-input flag on Windows
- 4. Check 2 on a Mac: two idle counters that disagree
- 5. Check 3: an extra mouse in the USB device log
- 6. Check 4: the movement pattern
- 7. A detection check in order
- 8. FAQ
To detect a mouse jiggler, check four things in order: the list of running apps, the "injected" flag Windows puts on software mouse input, the USB device log for an extra mouse, and the movement pattern itself. The first three each catch one type of jiggler. The pattern catches all of them: a jiggler moves the pointer a few pixels on a fixed timer, while a person moves it by hundreds of pixels at uneven times and types in between. Monitoring tools such as ActivTrak, Teramind and Insightful look for that pattern, and the script below does the same in 30 lines.
This page is the detection side. The same topic from the employee's side, including what Wells Fargo cited when it fired staff in 2024, is in can a mouse jiggler be detected.
Detection signals, and which jiggler each one catches
There are three kinds of mouse jiggler: software that moves the pointer, a USB dongle that tells the computer it is a mouse, and a mechanical platform that moves a real mouse. Each leaves a different trace.
| Signal | Where to look | Software | USB | Mechanical |
|---|---|---|---|---|
| Jiggler app running | Intune, Jamf, EDR process inventory | Yes | No | No |
| Input marked as injected | Low-level mouse hook on Windows | Yes | No | No |
| Accessibility permission | macOS Privacy & Security, MDM report | Yes | No | No |
| Mac idle counters disagree | HIDIdleTime vs CGEventSource idle time | Yes, tested | Not tested | Not tested |
| New or extra mouse | Device Manager, PnP events in Defender | No | Yes | No |
| Tiny moves on a fixed timer | Monitoring tool, or the script below | Yes | Yes | Often |
| Mouse moves, keyboard silent for hours | ActivTrak, Teramind, Insightful, Hubstaff | Yes | Yes | Yes |
| No output for the hours shown active | Tickets, commits, documents, replies | Yes | Yes | Yes |
Check 1: jiggler apps and scripts
A software jiggler is a running process. Look for Mouse Jiggler (Arkane Systems), Move Mouse, Jiggler and Caffeine, and for AutoHotkey, PowerShell or Python processes that run all day. Endpoint tools list them: Microsoft Intune and Jamf report installed apps, and EDR agents such as Defender for Endpoint keep process history.
On a Mac, any app that moves the pointer needs Accessibility access. The list is in System Settings > Privacy & Security > Accessibility, and MDM tools can report it. The common jiggler apps by platform are in the best mouse jiggler by type, and home-made script versions are in DIY mouse jiggler.
Check 2: the injected-input flag on Windows
Windows marks every mouse event created by software, through SendInput or mouse_event, with the LLMHF_INJECTED flag. A program with a low-level mouse hook can read it. This is how monitoring agents tell software movement from a real mouse:
LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
MSLLHOOKSTRUCT *m = (MSLLHOOKSTRUCT *)lParam;
if (nCode == HC_ACTION && (m->flags & LLMHF_INJECTED)) {
/* this movement came from software, not a physical mouse */
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
The flag catches software jigglers only. A USB jiggler is real hardware, so its input is not marked.
Check 2 on a Mac: two idle counters that disagree
macOS has no LLMHF_INJECTED flag that a script can read, but we found a signal that works like it. A Mac keeps two idle counters. HIDIdleTime in the I/O registry drives display sleep and the screen saver. CGEventSource.secondsSinceLastEventType tells an app how long since the last input event. On October 4, 2026 we ran a minimal Swift software jiggler on macOS 26.5.2 that posts two 1-pixel mouse moves, and read both counters before and after:
before HIDIdleTime 32.3 s CGEventSource idle 67269.7 s
after 2 moves HIDIdleTime 1.1 s CGEventSource idle 67270.8 s
The fake moves reset HIDIdleTime to about a second, so the Mac stays awake. The CGEventSource counter kept counting as if nothing had happened, at about 18.7 hours since anyone touched the real keyboard or mouse. We got the same result on a second run. So on a Mac, a small idle HIDIdleTime next to a large CGEventSource idle time points to a software jiggler. Both counters can be read without admin rights:
ioreg -c IOHIDSystem | awk '/HIDIdleTime/ {print $NF/1000000000; exit}'
import CoreGraphics
print(CGEventSource.secondsSinceLastEventType(.hidSystemState,
eventType: CGEventType(rawValue: ~0)!))
We did not test a USB dongle or a mechanical platform this way. Both produce hardware input, so we would expect both counters to reset together.
Never appear "away" on Slack again
Cloud-based. No downloads. Works 24/7 even when your laptop is off.
Check 3: an extra mouse in the USB device log
A USB jiggler works by acting as a mouse, so the computer records a mouse. List the mice on a Windows PC in PowerShell:
Get-PnpDevice -Class Mouse -PresentOnly | Format-Table FriendlyName, InstanceId
On a Mac:
system_profiler SPUSBDataType
The VID_ part of a Windows InstanceId is the vendor ID. A laptop with a trackpad, a known mouse and a third HID mouse from an unknown vendor is worth a closer look. Home-made jigglers often keep their board name: an Arduino Leonardo reports vendor ID 2341. Sellers of "undetectable" dongles copy the vendor ID of a common mouse brand, which hides the name but not the fact that a device was plugged in.
With Defender for Endpoint, security teams search device connections across the fleet:
DeviceEvents
| where ActionType == "PnpDeviceConnected"
| extend Desc = tostring(parse_json(AdditionalFields).DeviceDescription),
Vendor = tostring(parse_json(AdditionalFields).VendorIds)
| where Desc has "mouse" or Desc has "HID"
| project Timestamp, DeviceName, Desc, Vendor
Companies on CrowdStrike search the same thing in Falcon Device Control events; see can CrowdStrike detect a mouse jiggler.
Check 4: the movement pattern
This is the check that catches every type, including a mechanical platform that moves a real mouse. A jiggler moves the pointer a few pixels at a fixed interval. People move it far, at uneven times, and they type.
This Python script watches the pointer and flags moves of 4 pixels or less that repeat on a steady timer. It needs pip install pyautogui. Run it with the number of minutes to watch, for example python jiggle_watch.py 10.
# jiggle_watch.py: flag tiny pointer moves that repeat on a fixed timer
import statistics
import sys
import time
import pyautogui
minutes = float(sys.argv[1]) if len(sys.argv) > 1 else 10
end = time.time() + minutes * 60
last = pyautogui.position()
bursts = [] # [start_time, pixels_moved]
while time.time() < end:
time.sleep(0.05)
pos = pyautogui.position()
if pos != last:
px = abs(pos.x - last.x) + abs(pos.y - last.y)
if bursts and time.time() - bursts[-1][0] < 1:
bursts[-1][1] += px
else:
bursts.append([time.time(), px])
last = pos
tiny = [t for t, px in bursts if px <= 4] # a person rarely moves 4 px or less
gaps = [b - a for a, b in zip(tiny, tiny[1:])]
print(f"moves: {len(bursts)}, tiny moves: {len(tiny)}")
if len(gaps) >= 4:
mean = statistics.mean(gaps)
spread = statistics.pstdev(gaps) / mean
print(f"tiny moves every {mean:.1f} s, spread {spread:.2f}")
if spread < 0.1:
print("LIKELY JIGGLER: tiny moves on a fixed timer")
We tested it on macOS 26 against a Python jiggler that moved the pointer 1 pixel and back every 5 seconds, while other pointer movement happened on the same machine. Output:
moves: 10, tiny moves: 8
tiny moves every 5.2 s, spread 0.00
LIKELY JIGGLER: tiny moves on a fixed timer
A spread near 0 means the gaps are the same length every time; a person's gaps vary a lot. Jigglers with a "random interval" mode raise the spread, and a mechanical platform that draws a small circle makes larger moves. Commercial tools add the keyboard: hours of pointer movement with no keystrokes, or activity that never pauses for 8 hours, scores as idle or suspicious in ActivTrak and Hubstaff; see can ActivTrak detect a mouse jiggler and can Hubstaff detect a mouse jiggler. Insightful checks each finished shift against a list of known jiggler apps and repetitive input; see can Insightful detect a mouse jiggler.
A detection check in order
- Read the device list for mice you do not recognize.
- Look for jiggler apps and all-day scripts.
- Check the pattern with a monitoring tool or the script above.
- Compare with the work. Hours shown as active with no tickets, commits, documents or replies are the signal that holds up in an HR review. The other checks only show that a device or app was present.
Monitoring employees has legal limits that depend on the country and state, and many require notice. What employers may do is in is it legal for my employer to monitor me.
FAQ
Can IT detect a USB mouse jiggler? On a managed laptop, yes. It shows up as an extra mouse in the device list and in endpoint logs such as Defender's PnpDeviceConnected events.
Can a mechanical mouse jiggler be detected? Not by device logs, because it moves your real mouse. The movement pattern and the missing keyboard input still show.
How does software detect a mouse jiggler? On Windows, it reads the LLMHF_INJECTED flag on mouse events. On a Mac, our test showed the input-event idle counter does not reset for software moves. On any system, it looks for small, regular movements with no other input.
Can Teams or Slack detect a mouse jiggler? Neither app flags jigglers. Teams reads system input, so a jiggler keeps it Available. The Slack desktop app counts keyboard and mouse input anywhere on the computer (Slack desktop 4.52.178 code, checked 7 Oct 2026).
Stop Jiggling Your Mouse.
Join hundreds of remote workers who never worry about their Slack status. Set it up once, stay green forever.
Related Articles
Slack Daily Standup Without a Paid Bot: /remind, Workflow Builder and a Script
We set up a weekday 9:30 standup in a free Slack workspace three ways: a /remind reminder, Workflow Builder, and a short script that posts the questions and collects the thread replies.
Slack Tabs Under a Channel Name: What Each One Is and How to Edit Them
We added, renamed, moved, hid and deleted the tabs under a channel name in Slack web on the Free plan, and compared them with the tabs in a DM.
Leave Multiple Slack Channels at Once: 4 Ways Timed, Plus a Script
Slack has no bulk leave button. We made 12 test channels and left them with the sidebar menu, the channel browser, /leave and a 30-line script, and timed each way.