核心图形的基本事件处理
Basic event handling with core graphics
我正尝试在 mac os 上处理具有核心图形和核心基础的事件。
我的代码:
#import <CoreGraphics/CoreGraphics.h>
#import <CoreFoundation/CoreFoundation.h>
static int counter = 0;
CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
printf("event 0x%i\n ", counter++);
return event;
}
int main(int argc, const char * argv[]) {
CFRunLoopRef runner = CFRunLoopGetCurrent();
CFMachPortRef mach = CGEventTapCreate(kCGHIDEventTap,kCGTailAppendEventTap , kCGEventTapOptionDefault, kCGEventMaskForAllEvents, myCGEventCallback, NULL);
CFRunLoopSourceRef runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, mach, 0);
CFRunLoopAddSource(runner, runLoopSource, kCFRunLoopCommonModes);
CGEventTapEnable(mach, true);
CFRunLoopRun();
printf("end\n");
}
但它只对触摸板事件有反应。我的程序似乎忽略了键盘事件。我试过更改事件掩码,但没有用。你能给点建议吗?
PS
这是处理事件的良好开端吗?我想制作全屏 OpenGL 游戏
没有像 SFML 或 SDL 这样的库的核心图形。
我正在使用 CGDisplayCapture 和 CGL 来创建 OpeGL 上下文。
要回答您的问题:要通过 CGEventTap
获取键盘事件,必须信任您的应用才能使用辅助功能 API 控制您的计算机。这意味着它必须位于系统偏好设置 -> 安全和隐私 -> 辅助功能下的应用程序列表中。您可以使用函数 AXProcessIsTrustedWithOptions
来请求此权限;您必须是代码签名的,但不是沙盒,并且应该打包为 .app 以便添加到受信任的应用程序列表中。
关于你的第二个问题,如果这是处理游戏事件的好方法……不是,不是。使用 NSEvent
/NSApplication
API 为您的应用程序获取输入。 CGEventTap
是一个更好的选择,当你想要获取整个用户会话或另一个应用程序的事件时,当另一个应用程序最前面时(辅助应用程序通常必须这样做)做一些事情,比如挂钩用户输入来做一些自定义的事情.特别是通过传递 kCGHIDEventTap
您要求在事件进入 window 服务器时将事件传递给您的应用程序……这很容易导致您的应用程序中出现错误,使会话无法使用(例如,不小心丢弃了会话的所有输入)。
我正尝试在 mac os 上处理具有核心图形和核心基础的事件。
我的代码:
#import <CoreGraphics/CoreGraphics.h>
#import <CoreFoundation/CoreFoundation.h>
static int counter = 0;
CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
printf("event 0x%i\n ", counter++);
return event;
}
int main(int argc, const char * argv[]) {
CFRunLoopRef runner = CFRunLoopGetCurrent();
CFMachPortRef mach = CGEventTapCreate(kCGHIDEventTap,kCGTailAppendEventTap , kCGEventTapOptionDefault, kCGEventMaskForAllEvents, myCGEventCallback, NULL);
CFRunLoopSourceRef runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, mach, 0);
CFRunLoopAddSource(runner, runLoopSource, kCFRunLoopCommonModes);
CGEventTapEnable(mach, true);
CFRunLoopRun();
printf("end\n");
}
但它只对触摸板事件有反应。我的程序似乎忽略了键盘事件。我试过更改事件掩码,但没有用。你能给点建议吗?
PS
这是处理事件的良好开端吗?我想制作全屏 OpenGL 游戏 没有像 SFML 或 SDL 这样的库的核心图形。 我正在使用 CGDisplayCapture 和 CGL 来创建 OpeGL 上下文。
要回答您的问题:要通过 CGEventTap
获取键盘事件,必须信任您的应用才能使用辅助功能 API 控制您的计算机。这意味着它必须位于系统偏好设置 -> 安全和隐私 -> 辅助功能下的应用程序列表中。您可以使用函数 AXProcessIsTrustedWithOptions
来请求此权限;您必须是代码签名的,但不是沙盒,并且应该打包为 .app 以便添加到受信任的应用程序列表中。
关于你的第二个问题,如果这是处理游戏事件的好方法……不是,不是。使用 NSEvent
/NSApplication
API 为您的应用程序获取输入。 CGEventTap
是一个更好的选择,当你想要获取整个用户会话或另一个应用程序的事件时,当另一个应用程序最前面时(辅助应用程序通常必须这样做)做一些事情,比如挂钩用户输入来做一些自定义的事情.特别是通过传递 kCGHIDEventTap
您要求在事件进入 window 服务器时将事件传递给您的应用程序……这很容易导致您的应用程序中出现错误,使会话无法使用(例如,不小心丢弃了会话的所有输入)。