I have a really basic little command line app that grabs the mouse coordinates the next time the mouse is clicked.
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
CGFloat displayScale = 1.0f;
if ([[NSScreen mainScreen] respondsToSelector:@selector(backingScaleFactor)])
{
displayScale = [NSScreen mainScreen].backingScaleFactor;
}
CGPoint loc = CGEventGetLocation(event);
CFRelease(event);
printf("%dx%d\n", (int)roundf(loc.x * displayScale), (int)roundf(loc.y * displayScale) );
exit(0);
return event;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
CFMachPortRef eventTap;
CGEventMask eventMask;
CFRunLoopSourceRef runLoopSource;
eventMask = 1 << kCGEventLeftMouseDown;
eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap,
1, eventMask, myCGEventCallback, @"mydata");
runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource,
kCFRunLoopCommonModes);
CGEventTapEnable(eventTap, true);
CFRunLoopRun();
}
return 0;
}
I'm building it with cmake with the following file:
cmake_minimum_required(VERSION 3.0.0)
project (location)
set(CMAKE_C_FLAGS "-arch x86_64 -mmacosx-version-min=10.12 -std=gnu11 -fobjc-arc -fmodules")
This all worked fine until the upgrade to Mojave.
A bit of poking around shows this is down to the latest set of security updates and some hints (except CGEventTapCreate()
is not returning null) about settings some values in Info.plist
to allow the app to use the accessibility API. But I'm struggling to work out where to put it as I just have a single .m file with the code.
Edit
- This needs to run as a none root user (company policy)
- if the only way to get it to ask for permission then it can be extended to be a "GUI" app with a minimal UI
This app is just to grab the upper left hand corner of a region of the screen to feed to a second app that streams that area of screen to a second device. The code for the streamer is common across Win/Linux/MacOS so trying to keep the screen coordinate collection totally separate