There are techniques for Linux and Windows, but is there a way to count mouse and keyboard events in Mac OS X? I'm interested in doing statistical analysis of my daily activity.
5 Answers
Based on the inspiration provided by MrDaniel, I decided to program a simple little counter.
The source code for this, minus the UI defined as xib
; uses Foundation and AppKit frameworks (full sources and Xcode project on GitHub):
DBAppDelegate.h
//
// DBAppDelegate.h
// CocoaActivityCounter
//
// Created by Daniel Beck on 29.07.2012.
// Copyright (c) 2012 Daniel Beck. All rights reserved.
//
#import <Cocoa/Cocoa.h>
static id monitorLeftMouseDown;
static id monitorRightMouseDown;
static id monitorKeyDown;
@interface DBAppDelegate : NSObject <NSApplicationDelegate>
@property (assign) IBOutlet NSWindow *window;
@property (strong) IBOutlet NSTextView *logView;
@property (weak) IBOutlet NSToolbarItem *toolbarStartButton;
@property (weak) IBOutlet NSToolbarItem *toolbarStopButton;
@property (weak) IBOutlet NSToolbarItem *toolbarClearButton;
@property (weak) IBOutlet NSTextField *keyPressCounterLabel;
@property (weak) IBOutlet NSTextField *leftMouseCounterLabel;
@property (weak) IBOutlet NSTextField *rightMouseCounterLabel;
@property (readwrite) NSDateFormatter *logDateFormatter;
@property (readwrite) NSNumber *keyPressCounter;
@property (readwrite) NSNumber *leftMouseCounter;
@property (readwrite) NSNumber *rightMouseCounter;
@property (readwrite) BOOL loggingEnabled;
- (IBAction)stopButtonPressed:(id)sender;
- (IBAction)startButtonPressed:(id)sender;
- (IBAction)clearButtonPressed:(id)sender;
- (void)logMessageToLogView:(NSString*)message;
- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem;
@end
DBAppDelegate.m
//
// DBAppDelegate.m
// CocoaActivityCounter
//
// Created by Daniel Beck on 29.07.2012.
// Copyright (c) 2012 Daniel Beck. All rights reserved.
//
#import "DBAppDelegate.h"
#import <AppKit/NSEvent.h>
@implementation DBAppDelegate
@synthesize logView;
@synthesize toolbarStartButton;
@synthesize toolbarStopButton;
@synthesize keyPressCounterLabel;
@synthesize leftMouseCounterLabel;
@synthesize rightMouseCounterLabel;
@synthesize toolbarClearButton;
@synthesize loggingEnabled;
@synthesize keyPressCounter;
@synthesize leftMouseCounter;
@synthesize rightMouseCounter;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
self.loggingEnabled = NO;
self.logDateFormatter = [[NSDateFormatter alloc] init];
[self.logDateFormatter setTimeStyle:NSDateFormatterMediumStyle];
self.keyPressCounter = [NSNumber numberWithInt:0];
self.leftMouseCounter = [NSNumber numberWithInt:0];
self.rightMouseCounter = [NSNumber numberWithInt:0];
}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication {
return YES;
}
-(void)logMessageToLogView:(NSString*)message {
[logView setString: [[logView string] stringByAppendingFormat:@"%@: %@\n", [self.logDateFormatter stringFromDate:[NSDate date]], message]];
}
- (IBAction)stopButtonPressed:(id)sender {
if (!self.loggingEnabled) {
return;
}
self.loggingEnabled = false;
[NSEvent removeMonitor:monitorLeftMouseDown];
[NSEvent removeMonitor:monitorRightMouseDown];
[NSEvent removeMonitor:monitorKeyDown];
}
- (IBAction)startButtonPressed:(id)sender {
if (self.loggingEnabled) {
return;
}
self.loggingEnabled = true;
monitorLeftMouseDown = [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask handler:^(NSEvent *evt) {
[self logMessageToLogView:[NSString stringWithFormat:@"Left mouse down!"]];
self.leftMouseCounter = [NSNumber numberWithInt:(1 + [self.leftMouseCounter intValue])];
}];
monitorRightMouseDown = [NSEvent addGlobalMonitorForEventsMatchingMask:NSRightMouseDownMask handler:^(NSEvent *evt) {
[self logMessageToLogView:@"Right mouse down!"];
self.rightMouseCounter = [NSNumber numberWithInt:(1 + [self.rightMouseCounter intValue])];
}];
monitorKeyDown = [NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask handler:^(NSEvent *evt) {
[self logMessageToLogView:[NSString stringWithFormat:@"Key down: %@ (key code %d)", [evt characters], [evt keyCode]]];
self.keyPressCounter = [NSNumber numberWithInt:(1 + [self.keyPressCounter intValue])];
}];
}
- (IBAction)clearButtonPressed:(id)sender {
self.keyPressCounter = [NSNumber numberWithInt:0];
self.leftMouseCounter = [NSNumber numberWithInt:0];
self.rightMouseCounter = [NSNumber numberWithInt:0];
[self.logView setString:@""];
}
- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem {
if ([theItem isEqualTo:toolbarStartButton]) {
return !self.loggingEnabled;
}
if ([theItem isEqualTo:toolbarStopButton]) {
return self.loggingEnabled;
}
if ([theItem isEqualTo:toolbarClearButton]) {
return !self.loggingEnabled;
}
return YES;
}
@end
Icons used in the toolbar are from Tango Desktop Project.
-
1
-
1Works nice for mouse but doesn't capture key presses in 10.10 :(– MeckiCommented Apr 15, 2015 at 9:38
-
@Mecki I added that to the repo description a while back when I noticed. Unfortunately I have no idea why, possibly related to per-app access restrictions to universal access API, and the binary being unsigned. Or they even killed this off entirely.– Daniel Beck ♦Commented Apr 15, 2015 at 13:38
-
On Mac OS X 10.9.5, it works well for mouse but doesn't capture key presses too. Have you figured out the reason, Mecki? Thanks. Commented Jul 8, 2015 at 3:00
-
@JiakuanW I got a PR a while back in the GitHub repository that claims to resolve this problem (untested).– Daniel Beck ♦Commented Jul 8, 2015 at 11:11
Typingstats displays a total number of keystrokes and various other metrics. It doesn't count pointing device clicks though.
-
Have you tried it yourself? Does it change the keyboard layout based upon what you really have or is it always US?– Daniel Beck ♦Commented Jul 29, 2012 at 20:42
-
App Store app, not available in Canada and possibly elsewhere.– JustinCommented Apr 13, 2017 at 14:44
A click and button press counter program is possible via writing a Cocoa Objective-C program that can receive and count mouse and keyboard click events.
The class to take a look at is NSEvent specifically the addGlobalMonitorForEventsMatchingMask:handler: class method should prove to be very helpful. Since it offers to monitor events such as:
NSLeftMouseUp
NSRightMouseUp
NSOtherMouseUp
NSLeftMouseDown
NSRightMouseDown
NSOtherMouseDown
NSKeyDown
-
3Please try to answer in a way that actually brings the user closer to his goal. Just telling him to learn programming doesn't. You could, for example, provide relevant code snippets or function calls, the gist of an actual solution. While still not useful to everyone, it could be used as foundation by others to provide a working solution.– Daniel Beck ♦Commented Jul 27, 2012 at 18:09
-
Good call Daniel Beck looks like I was taking the wrong approach when suggesting using the "Accessibility Programming Guidelines for Cocoa", after further reading I was pointed to NSEvent class, which seems like it will do the job...– MrDanielCommented Jul 27, 2012 at 20:17
There is also open source OctoMouse utility, it can be installed on macos with Homebrew brew install octomouse
.