InputPulse is a lightweight macOS menu bar utility that shows how many keyboard presses and mouse clicks you have made today. It lives entirely in the status bar and never displays any windows.
- Counts global key-down and mouse-down events across the system
- Updates the menu bar title in real time (format
K:<keys> M:<clicks>) - Menu shows per-device totals and the day anchor
- Manual "Reset Today" action plus automatic reset at midnight
- Optional toggles to hide keyboard or mouse counts from the menu bar while continuing to track both in the background
- Status bar refresh rate is selectable (real-time, 1s, 2s, 5s) so you can throttle the top-level numbers if desired
- One-click “Launch at Login” toggle that writes a user LaunchAgent so InputPulse starts automatically after you sign in
- Rolling history submenu that lists previous 15+ days of totals plus dual line charts (keyboard vs mouse) with hover tooltips. The textual history list scrolls vertically so you can review every day.
- Gracefully handles missing Accessibility privileges with a clear hint
- Make sure Xcode command-line tools are installed (
xcode-select --install). - From the repository root run the script that matches your machine (or run
./build.shto auto-detect):- Apple silicon (arm64):
./build-arm64.sh
- Intel (x86_64):
./build-x86_64.sh
.app. - Apple silicon (arm64):
- Launch the freshly built app:
open build/InputPulse.app
- The first launch will trigger macOS privacy prompts. Approve the request and add InputPulse to System Settings → Privacy & Security → Accessibility so it can listen to global input events.
If you are only running InputPulse on your own machine and do not have access to a paid Apple Developer certificate, you can self-sign the bundle. macOS will still label the app as coming from an "unidentified developer" (Gatekeeper warnings remain) and you will need to right-click → Open the first time, but keeping a consistent self-signed identity reduces how often Accessibility permission gets revoked between rebuilds.
- Build the app for your architecture (for example
./build-arm64.sh). - Run
./self-sign.sh(orCERT_NAME="Custom Name" ./self-sign.sh build/InputPulse.app). The script will:- Create a self-signed "code signing" certificate in your login keychain if one does not already exist.
- Grant
codesignaccess to the private key whenKEYCHAIN_PASSWORDis provided. - Re-sign
build/InputPulse.appwith that identity and verify the bundle.
- Clear the quarantine bit if you downloaded the repo from the internet:
xattr -d com.apple.quarantine build/InputPulse.app. - Launch the app via Finder by using Open (or right-click → Open) so Gatekeeper records that you trust this binary.
Environment variables you can tweak when running the script:
CERT_NAME— Friendly name for the self-signed identity. Re-use the same name when re-running so the script keeps using the existing certificate.KEYCHAIN_PATH— Override the keychain file; defaults to your login keychain.KEYCHAIN_PASSWORD— Password for the target keychain. Supplying it lets the script automatically grantcodesignaccess to the imported private key (otherwise macOS may prompt when signing).
Limitations: self-signed binaries are still blocked by Gatekeeper on machines that have not run the explicit Open action, notarization is not possible, and other users must repeat these steps on their own Macs. For wider distribution you will still need an Apple Developer ID certificate and notarization.
ActivityMonitorinstalls aCGEventtap at the session level to hear key-down and mouse-down events. macOS requires Accessibility permission for this.- Daily totals are persisted in
UserDefaults, and up to 14 previous days are archived automatically for the history submenu. Resets (manual or at midnight) only affect the current day. StatusMenuControllerupdates the status bar title and menu contents whenever the counts change.build.shcompiles the Swift sources withswiftc, creates a minimal.appbundle, and drops it inbuild/InputPulse.app.
- If the menu title shows
Grant Access, open System Settings → Privacy & Security → Accessibility and enable InputPulse. You may need to quit and relaunch the app afterward. - Event taps occasionally get disabled by the system (for example, after waking from sleep). The app automatically attempts to re-enable the tap; if it fails, quit and relaunch.