C语言 macOS: Override Modifier Key with CGEventTap



我最近在我的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 %llun",
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 tapn");
exit(1);
}
CFRunLoopSourceRef runLoopSource;
if ((runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, tap, 0)) == NULL) {
printf("Failed to create run loop sourcen");
exit(1);
}
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
CGEventTapEnable(tap, true);
CFRunLoopRun();
return 0;
}

现在事件点击正常工作,它确实拦截键盘事件(我可以看到TEST 12 54打印到控制台),但键仍然表现为命令而不是控制。根据CGEventTapCallback的文档,回调可能返回:

一个新建的事件。当新事件被传递回事件系统后,新事件将与原始事件一起发布。

传入kCGHeadInsertEventTap作为tap位置应确保我的事件tap插入在处理程序列表的头部。是我在这里做错了什么,还是只是不可能修改这样的事件?

@Willeke的评论是正确的。虽然我正确地覆盖了事件,但我真正需要做的是使用keydown/keyup事件来跟踪何时按下了正确的命令键。然后,我可以使用该标志来拦截其他按键事件,删除命令修饰符,并使用位操作符插入控制修饰符标志。然而,这个问题的简单解决方案来自他们提供的文档链接:

hidutil property --set '{"UserKeyMapping":[{"HIDKeyboardModifierMappingSrc":0x7000000E7,"HIDKeyboardModifierMappingDst":0x7000000E0}]}'

相关内容

  • 没有找到相关文章

最新更新