首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >macOS:用CGEventTap重写修饰符键

macOS:用CGEventTap重写修饰符键
EN

Stack Overflow用户
提问于 2021-09-17 03:08:47
回答 1查看 137关注 0票数 1

因此,我最近在我的macbook键盘上洒了些水,我的左边命令和选项键也不再起作用了。苹果公司希望我把它寄来修理,但我现在没有时间。所以我想我应该重写右边的命令键作为左控制,因为左边的命令键仍然有效。

我根据我发现的键盘记录器要点改编了以下内容:

代码语言:javascript
代码运行次数:0
运行
复制
#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打印到控制台),但键仍然是作为命令而不是控制。根据CGEventTapCallback,回调可能会返回:

一个新建的事件。在将新事件传递回事件系统后,将与原始事件一起释放新事件。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-17 18:58:03

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

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69217301

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档