Back to Blog
Guide

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.

Slack Green Team
September 26, 2026
October 7, 2026
6 min read
Share:
mouse jiggler
employee monitoring
it admin
detection

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.

SignalWhere to lookSoftwareUSBMechanical
Jiggler app runningIntune, Jamf, EDR process inventoryYesNoNo
Input marked as injectedLow-level mouse hook on WindowsYesNoNo
Accessibility permissionmacOS Privacy & Security, MDM reportYesNoNo
Mac idle counters disagreeHIDIdleTime vs CGEventSource idle timeYes, testedNot testedNot tested
New or extra mouseDevice Manager, PnP events in DefenderNoYesNo
Tiny moves on a fixed timerMonitoring tool, or the script belowYesYesOften
Mouse moves, keyboard silent for hoursActivTrak, Teramind, Insightful, HubstaffYesYesYes
No output for the hours shown activeTickets, commits, documents, repliesYesYesYes

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).

Always Active

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

Guide

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 Green Team
Guide

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.

Slack Green Team
Guide

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.

Slack Green Team