首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在应用程序运行时停止拦截键盘输入- CGEventTap

在应用程序运行时停止拦截键盘输入- CGEventTap
EN

Stack Overflow用户
提问于 2013-02-09 00:39:54
回答 1查看 996关注 0票数 0

使用CGEventTap停止观看键盘事件点击的正确方法是什么?

我正在构建一个简单的背景应用程序,转换特定键的输出。多亏了this excellent post on CGEventTap,我才能启用密钥转换。不幸的是,我似乎无法阻止它,除非杀死应用程序。

当用户切换复选框以打开或关闭该功能时,将调用以下方法。切换会立即发生。关闭可能需要一分钟或更长时间才能生效。我通过日志看到“禁用。停止转换攻丝。”被检测到。但键转换仍在继续。我不明白为什么。

代码语言:javascript
复制
- (void)watchEventTap
{    
        @autoreleasepool
        {
            CFRunLoopSourceRef runLoopSource = NULL;
            CFMachPortRef eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault, CGEventMaskBit(kCGEventKeyUp) | CGEventMaskBit(kCGEventKeyDown) | CGEventMaskBit(NX_SYSDEFINED), myCGEventCallback, NULL);
            runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);

            if (!eventTap)
            {
                NSLog(@"Couldn't create event tap!");
                exit(1);
            }

            if (self.shortcutEnabled) // User default toggled ON
            {
                NSLog(@"Enabled. Convert taps.");
                CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
                CGEventTapEnable(eventTap, true);
                // CFRunLoopRun(); // This blocks rest of app from executing
            }
            else // User default toggled OFF
            {
                NSLog(@"Disabled. Stop converting taps.");
                CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
                CGEventTapEnable(eventTap, false);
                // Clean up the event tap and source after ourselves.
                CFMachPortInvalidate(eventTap);
                CFRunLoopSourceInvalidate(runLoopSource);
                CFRelease(eventTap);
                CFRelease(runLoopSource);
                eventTap = NULL;
                runLoopSource = NULL;
            }
        }
//        exit(0);  // This blocks rest of app from executing
}

谢谢你的建议。我是新开发的Mac应用程序,所以如果我做了一些愚蠢的事情,请原谅我。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-02-11 06:34:28

多亏了一位经验丰富的Mac开发人员,我的问题得到了解决。每次调用该方法时,我都会创建一个新的runLoopsSource。

现在,我已经为tapEvent和runLoop创建了实例变量。只需要一行代码就可以停止eventTap。修改方法如下:

代码语言:javascript
复制
- (void)watchEventTap
{

    @autoreleasepool
    {

        if ( [[NSUserDefaults standardUserDefaults] isEnabledNumLockDV] == YES ) // User default toggled ON
        {
            _runLoopSource = NULL;
             _eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault, CGEventMaskBit(kCGEventKeyUp) | CGEventMaskBit(kCGEventKeyDown) | CGEventMaskBit(NX_SYSDEFINED), myCGEventCallback, NULL);
            _runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, _eventTap, 0);

            if (!_eventTap)
            {
                NSLog(@"Couldn't create event tap!");
                exit(1);
            }

            NSLog(@"Enabled. Convert taps.");
            CFRunLoopAddSource(CFRunLoopGetCurrent(), _runLoopSource, kCFRunLoopCommonModes);
            CGEventTapEnable(_eventTap, true);
        }
        else if ( [[NSUserDefaults standardUserDefaults] isEnabledNumLockDV] == NO ) // User default toggled OFF
        {
            NSLog(@"Disabled. Stop converting taps.");
            CGEventTapEnable(_eventTap, false);
        }

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

https://stackoverflow.com/questions/14777259

复制
相关文章

相似问题

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