c++ - Mac事件点击只是延迟丢弃的事件

标签 c++ macos events quartz-graphics macos-carbon

我正在尝试编写一些在 Mac OSX 10.6 上启用时丢弃所有键盘和鼠标事件的代码。我的代码以 root 用户身份运行。我正在采取的方法是创建一个事件点击,丢弃所有传递给它的事件(启用时)。事件点击回调函数如下所示:

CGEventRef MyTapCallback(CGEventTapProxy proxy,
                         CGEventType type,
                         CGEventRef event,
                         void *refcon)
{
    return CKeyLocker::isEnabled() ? NULL : event;
}

我用来启用和禁用事件点击的代码如下所示:

void CKeyLocker::enable(bool bEnable)
{
    if (bEnable == m_bEnabled)
        return;

    if (bEnable)
    {
        // which events are we interested in?
        CGEventMask evMask = kCGEventMaskForAllEvents;
        CFMachPortRef mp = CGEventTapCreate(kCGHIDEventTap,
                                            kCGHeadInsertEventTap,
                                            kCGEventTapOptionDefault,
                                            evMask,
                                            MyTapCallback,
                                            NULL);

        if (mp)
        {
            qDebug() << "Tap created and active. mp =" << mp;
            m_enabledTap = mp;
            m_bEnabled = true;
        }
    }
    else
    {
        CGEventTapEnable(m_enabledTap, false);
        CFRelease(m_enabledTap);
        m_enabledTap =0;
        m_bEnabled = false;
        qDebug() << "Tap destroyed and inactive";
    }
}

当事件点击处于事件状态时,这种方法非常有效 - 我可以随心所欲地敲击键盘和鼠标,并且没有任何事件通过系统。但是,当点击被禁用时,我在点击处于事件状态时按下的所有键都会出现在当前窗口中。就像事件点击只是延迟事件,而不是破坏它们,这很奇怪,因为 Mac 文档明确指出:

If the event tap is an active filter, your callback function should return one of the following:

The (possibly modified) event that is passed in. This event is passed back to the event system.

A newly-constructed event. After the new event has been passed back to the event system, the new event will be released along with the original event.

NULL if the event passed in is to be deleted.

我返回 NULL,但该事件似乎没有被删除。有什么想法吗?

最佳答案

链接的评论没有我看到的答案,所以我会从我在浏览这些东西时看到的信息中转储一些信息。

首先,我对 CGEventTapCreateForPSN 的运气要好得多。就好像系统给了你一些限制你的水龙头的余地。但是,从这个例子看来,这还不够。

接下来 - 这个/可能/是您所需要的...在您的回电中,您可能希望(并且可能需要)检查以下事件:

switch (type)
{
    case kCGEventTapDisabledByTimeout:
    case kCGEventTapDisabledByUserInput:
    {
        CFMachPortRef *pTap = (CFMachPortRef*)refcon;
        CGEventTapEnable( *pTap, true );
        return NULL;
    }
    default:
        break;
}

不管各种文档做了什么或没说什么,我观察到操作系统感觉像是在“探测”错误的回调;基本上禁用普遍吃事件的事件点击回调。如果你在这些情况下重新注册,操作系统似乎没问题,就好像在说:好的,你似乎知道你在做什么,但我可能会再戳你一下以确保。

关于c++ - Mac事件点击只是延迟丢弃的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2817680/

相关文章:

c++ - 基类在被访问时未初始化

c++ - 从 `const char*' 到 `char*' 的无效转换

objective-c - 应用程序内的 Cocoa 32 位和 64 位二进制文​​件

macos - 列出所有应用程序 - 输出为文本文件

javascript - DIVs点击事件错误触发其他DIVs点击事件

c++ - 如何解释 std::launder 的可达性要求?

c++ - 使用 SWIG 在 Python 中包装 C++ 类

android studio 启动失败 - Java.lang.IllegalArgumentException

c - Windows:使用事件进行共享内存同步

python - Python 的事件框架?