Implementation reference · macOS 14 or later
ClickLight
ClickLight is a native AppKit menu bar app for showing clicks during live demos, screen sharing, and UX reviews.
Created and maintained by Aurora Scharff. I contributed a few small pull requests.
Problem
Click feedback for the live moment
Screen-recording tools can add click effects during editing, but that does not help an audience follow an interaction while a demo, screen share, or UX review is happening. ClickLight needs to observe input across applications and draw immediate visual feedback without consuming the click or changing the application underneath it.
ClickLight turns otherwise easy-to-miss mouse actions into clear, colorful animations. Presses expand into glowing rings, releases fade away, secondary clicks use distinct shapes, and drags can become dots or fading laser strokes. Size, duration, intensity, and colors can be adjusted so the feedback remains visible without distracting from the interface underneath.
Implementation scope
From global input to per-display overlays
When ClickLight is enabled, ClickCaptureController starts a listen-only CGEvent tap and an NSEvent global monitor. Both paths translate mouse input into app-specific events posted on the main queue. AppDelegate records accepted clicks and forwards them to OverlayCoordinator, which deduplicates events, selects the display containing the pointer, and renders the configured effect in a transparent window that does not intercept input.
The essential loop
Observe clicks without intercepting them
The primary capture path creates a session-level event tap in listen-only mode. The callback receives matching mouse events while returning them unchanged to the system.
let mask = types.reduce(CGEventMask(0)) { partial, eventType in
partial | (1 << CGEventMask(eventType.rawValue))
}
let userInfo = Unmanaged.passUnretained(self).toOpaque()
guard let tap = CGEvent.tapCreate(
tap: .cgSessionEventTap,
place: .headInsertEventTap,
options: .listenOnly,
eventsOfInterest: mask,
callback: eventTapCallback,
userInfo: userInfo
) else {
return
}
guard let source = CFMachPortCreateRunLoopSource(
kCFAllocatorDefault,
tap,
0
) else {
CFMachPortInvalidate(tap)
return
}
eventTap = tap
runLoopSource = source
CFRunLoopAddSource(CFRunLoopGetMain(), source, .commonModes)
CGEvent.tapEnable(tap: tap, enable: true)Implementation notes
Two capture paths, one overlay coordinator
ClickEventTap installs a session-level, listen-only Core Graphics event tap and an NSEvent global monitor fallback. Both paths normalize input into ClickEvent or KeyboardShortcutEvent values and publish them through NotificationCenter on the main queue.
AppDelegate coordinates permissions, settings, global shortcuts, activity recording, capture state, and update checks. It suppresses events originating inside the settings window and can hide the release highlight associated with the configured screenshot shortcut.
OverlayCoordinator keeps one ClickOverlayWindow per NSScreen, rebuilds them when the display configuration changes, filters disabled event types, and deduplicates reports from the two capture paths.
ClickOverlayWindow is a borderless, transparent, screen-saver-level AppKit window that ignores mouse input. Its view renders the selected press, release, secondary-click, drag, laser, or shortcut feedback without blocking the underlying application.
Requirements and boundaries
Protected input requires explicit permission
ClickLight targets macOS 14 or later. Global click detection depends on Accessibility access, while the optional keyboard shortcut display and screenshot shortcut handling also depend on Input Monitoring. Without those permissions, macOS does not expose the protected input events the corresponding features need.
- macOS 14 or later
- Accessibility permission for global click detection
- Input Monitoring for optional keyboard-based features