首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法使用CGEventTap阻止封装锁

无法使用CGEventTap阻止封装锁
EN

Stack Overflow用户
提问于 2010-05-30 01:16:07
回答 1查看 1.1K关注 0票数 4

我正在使用Quartz CGEventTap,试图全局拦截胶囊锁压力并阻止它们(让它们做一些有用的事情)。我成功地检测到了胶囊锁住的压力,但到目前为止还不能阻止它们。我的代码(源自this stackoverflow answer)类似于:

代码语言:javascript
复制
eventTap = CGEventTapCreate(kCGHIDEventTap,
                            kCGTailAppendEventTap, 
                            kCGEventTapOptionDefault, 
                            eventMask,
                            myCGEventCallback,
                            &oldFlags);

runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);

CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
CGEventTapEnable(eventTap, true);

CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef theEvent, void *refcon)
{
    CGEventFlags *oldFlags = (CGEventFlags *)refcon; 

    switch (type)
    {
        case kCGEventFlagsChanged:
        {
            CGEventFlags newFlags = CGEventGetFlags(theEvent);
            CGEventFlags changedFlags = *oldFlags ^ newFlags; 
            *oldFlags = newFlags;

            if (changedFlags == 65536)
            {
                NSLog(@"Capslock pressed. Let's not return the event");
                return NULL;
            }
            break;
        }
        default:
            break;
    }

    NSLog(@"Different modifier than capslock. Returning the event");
    return theEvent;
}

如果我理解正确的话,返回NULL应该会有效地阻止按键的传播。事实上,它也适用于“正常”的keyup和-down事件。但是,无论如何,胶囊锁都会切换。你知道为什么会这样吗?我是否做了错误的假设?和/或我如何才能以不同的方式来实现我的目标?

谢谢,

雷神

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-06-21 22:26:09

你不能像那样阻止capslock。封装锁定是一种情况,它由键盘驱动程序处理,而不是由Window或单个应用程序处理。按键事件在OS X中的传播方式如下:

键盘驱动程序-> Window Server ->用户会话->活动应用程序

在每个传播级别(用“->”表示),您可以放置一个事件,并阻止和/或修改关键事件。键盘驱动程序和Window Server都是特权组件,另外两个是普通用户级组件。

最早可以捕获键盘事件的时间是事件从驱动程序(内核空间)传播到Window Server (用户空间,但仍具有特权)。然而,如上所述,封装锁状态是在驱动程序内部处理的,因此捕获事件已经太晚了。驱动程序将已经启用键盘上的封装锁定指示灯(如果需要,并且不是由硬件自行执行),并记住封装锁定状态为打开,这对以后所有按键都有影响。

你可以通过编程的方式关闭HID设备的封锁灯(苹果甚至有sample code for that),但这不会关闭封锁灯,它只是关闭了灯。

我所看到的使用事件taps实现的唯一方法是,手动地将每一次带胶囊锁的按键重写为不带胶囊锁的按键(其中没有设置胶囊锁标志,并且所附的字母(如果有的话)是小写的)。此外,为了不让用户感到困惑,您应该关闭胶囊锁灯,如Apple的示例代码所示。

其他选择是:编写自己的键盘驱动程序,它可以控制键盘,而不是苹果的标准驱动程序(没有你想象的那么难,但仍然足够难),或者破解驱动程序(邪恶,但有效)。例如,一些键盘重映射器只覆盖驱动程序的单个方法(驱动程序在OS X中是C++,因此它们是面向对象的对象,您可以在运行时动态覆盖C++方法;不是真正覆盖它们,而是操作方法表)。这两个解决方案的问题是:第一个意味着除非你的驱动程序和苹果的驱动程序一样好,否则一些USB键盘可能无法与你的驱动程序一起工作,而另一些则会,第二个意味着如果你犯了任何错误,系统会用内核恐慌来惩罚这个错误。

我正在寻找一种在Mac上以编程方式切换capslock的方法,到目前为止还没有成功。但我可以向你保证,活动攻击器不是一条可行的道路。

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

https://stackoverflow.com/questions/2935931

复制
相关文章

相似问题

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