【发布时间】:2021-11-11 23:17:23
【问题描述】:
所以我最近在我的 macbook pro 键盘上洒了一些水,我的左侧命令和选项键不再起作用。苹果想让我把它寄去维修,我现在没有时间。所以我想我会覆盖右命令键作为左控制键,因为左命令键仍然有效。
我根据我发现的键盘记录器要点改编了以下内容:
#include <stdio.h>
#import <Carbon/Carbon.h>
#import <ApplicationServices/ApplicationServices.h>
CGEventRef loggerCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void* context)
{
if (type == kCGEventFlagsChanged && CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode) == 54 /* right cmd key */) {
printf(
"TEST: %d %llu\n",
type,
CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode)
);
CGKeyCode virtualKey = 0x3B; // kVK_Control (left control);
CGEventRef override = CGEventCreateCopy(event);
CGEventSetIntegerValueField(override, kCGKeyboardEventKeycode, virtualKey);
return override;
}
return event;
}
int main(int argc, const char * argv[])
{
CFMachPortRef tap;
if ((tap = CGEventTapCreate(kCGHIDEventTap,
kCGHeadInsertEventTap,
0, kCGEventMaskForAllEvents,
loggerCallback, NULL)) == NULL) {
printf("Failed ot create event tap\n");
exit(1);
}
CFRunLoopSourceRef runLoopSource;
if ((runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, tap, 0)) == NULL) {
printf("Failed to create run loop source\n");
exit(1);
}
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
CGEventTapEnable(tap, true);
CFRunLoopRun();
return 0;
}
现在事件点击工作正常,它确实拦截了键盘事件(我可以看到TEST 12 54 打印到控制台),但该键仍然表现为命令而不是控制。根据documentation for CGEventTapCallback,回调可能会返回:
一个新建的事件。新事件传回事件系统后,新事件将与原事件一起释放。
传入kCGHeadInsertEventTap 作为点击位置应该确保我的事件点击插入到处理程序列表的头部。我在这里做错了什么还是无法修改这样的事件?
【问题讨论】:
-
修饰键触发修饰标志,参见
CGEventFlags。也许重新映射键会起作用,请参阅Technical Note TN2450 Remapping Keys in macOS 10.12 Sierra
标签: c macos keyboard event-handling macos-carbon