I'm working on a macOS menubar app that locks any mouse events. What I'm trying to achieve is that after sending mouse events to the CGEventRef based callback, I cannot click anywhere (naturally) but the problem is I cannot quit the loop because of that.
Every time I need to close it, I'm switching to the Xcode app to stop the running app.
This is the main function and the events that I'm sending to the callback function;
void lockTrackpad(void) {
// For keyboard inputs, I add CGEventMaskBit(kCGEventKeyUp)| CGEventMaskBit(kCGEventKeyDown)| CGEventMaskBit(NX_SYSDEFINED)
CGEventMask mask = (
CGEventMaskBit(kCGEventMouseMoved)
| CGEventMaskBit(kCGEventLeftMouseUp)
| CGEventMaskBit(kCGEventLeftMouseDown)
| CGEventMaskBit(kCGEventRightMouseUp)
| CGEventMaskBit(kCGEventRightMouseDown)
| CGEventMaskBit(kCGEventScrollWheel)
);
eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault, mask, CGEventCallback_r, nil);
...
}
And this is the callback function;
CGEventRef CGEventCallback_r(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
CGKeyCode keycode = (CGKeyCode)CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);
printf("Event Tap: %d\n", keycode);
if (keycode == 43) {
printf("quit the application \n");
exit(EXIT_SUCCESS);
}
return nil;
}
What I want is, for example when the loop is running, if press "control U L", I want to run some function to exit the loop. I believe in order to get the keyboard input, I should send the keyboard events as well but I couldn't figure out how to detect my keyboard shortcuts.
- I added the keyboard bits to the mask.
- The app is sandboxed.
I want to do something like this;
CGEventRef CGEventCallback_r(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
CGKeyCode keycode = (CGKeyCode)CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);
// When pressing "control U L", call a function
if (...) {
printf("pressed control U L \n");
doSomething();
}
return nil;
}
CodePudding user response:
I figured out like this;
CGEventRef CGEventCallback_r(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
if (type == kCGEventKeyDown) {
CGKeyCode keyCode = (CGKeyCode)CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);
if (CGEventGetFlags(event) & kCGEventFlagMaskControl) {
// control key is pressed
controlKeyPressed = true;
}
if (keyCode == kVK_ANSI_U) {
// u key is pressed
uKeyPressed = true;
}
if (keyCode == kVK_ANSI_L) {
// l key is pressed
lKeyPressed = true;
}
if (controlKeyPressed && uKeyPressed && lKeyPressed) {
// doSomething();
}
return event;
} else if (type == kCGEventKeyUp) {
CGKeyCode keyCode = (CGKeyCode)CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);
// set the variable to false just like above.
}
if (keycode == 43) {
printf("quit the application \n");
exit(EXIT_SUCCESS);
}
return nil;
}
Also, don't forget to put your variables on a global scope.