【问题标题】:macOS: Override Modifier Key with CGEventTapmacOS:使用 CGEventTap 覆盖修饰键
【发布时间】: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 作为点击位置应该确保我的事件点击插入到处理程序列表的头部。我在这里做错了什么还是无法修改这样的事件?

【问题讨论】:

标签: c macos keyboard event-handling macos-carbon


【解决方案1】:

@Willeke 在他们的评论中是正确的。尽管我正确地覆盖了该事件,但我真正需要做的是使用 keydown/keyup 事件来跟踪何时按下了正确的命令键。然后我可以使用该标志来拦截其他按键事件,删除命令修饰符,并使用位运算符插入控制修饰符标志。然而,这里解决这个问题的简单方法来自他们提供的documentation link

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

【讨论】:

    猜你喜欢
    • 2021-01-25
    • 2013-05-10
    • 2013-07-09
    • 1970-01-01
    • 2016-05-12
    • 1970-01-01
    • 1970-01-01
    • 2015-11-27
    • 2020-06-16
    相关资源
    最近更新 更多