A menu-bar app that turns one hand and the built-in webcam into the mouse — pinch to click, hold to drag, glide to scroll, moving the real system cursor anywhere on the Mac.
A webcam and one hand instead of a mouse. A Python vision engine tracks your hand with MediaPipe Hand Landmarker and turns pinch and finger poses into real clicks, drags and scrolls — moving the actual macOS cursor through Quartz CGEvents, so it works in every application rather than only inside one window.
Two surfaces sit on the same engine: a menu-bar Mac app, and a browser SDK built for kiosk screens where nobody wants to touch the glass.
A whole gesture vocabularyPinch and release to click, pinch and hold to drag, two fingers to scroll with momentum, thumb-to-middle for right-click, three-finger swipe to change Spaces, thumbs-up to start Dictation. A closed fist is a deliberate no-op, so folding your hand never fires a click.
The real system cursorQuartz CGEvent injection rather than a drawn overlay — it moves the same cursor every app already listens to, which is also why macOS makes you grant Accessibility first.
Precision AssistMagnetic snapping to genuinely clickable elements, read live from the Accessibility tree, so hand jitter doesn't cost you a small button.
Self-contained .appEmbedded CPython — no system Python or venv at runtime. The installer signs and notarizes with a Developer ID, so there's no Gatekeeper warning on first launch.
Browser SDKA drop-in ES module that renders a smoothed cursor on any page and dispatches genuine pointer events, so existing web UI responds without knowing a hand is driving.
Kiosk deploymentsystemd units for a Compute Module 5, a GStreamer relay that lets several consumers share one camera, and raised-hand arbitration to decide whose hand is driving when a crowd is standing in front of the screen.
Tuned against recorded traces rather than by feel: the arbitration work cut hand-to-hand flip-flopping from 17.9 to 4.1 switches per minute, and a One Euro filter holds the cursor steady without the lag a plain moving average would add.
Stack — Python · MediaPipe Hand Landmarker · Quartz CGEvents · PyObjC + rumps · WebSocket · JS ES module · systemd on CM5