addGlobalMonitorForEventsMatchingMask不起作用 [英] addGlobalMonitorForEventsMatchingMask not working

查看:417
本文介绍了addGlobalMonitorForEventsMatchingMask不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在获取启用了辅助功能的应用程序(在开发案例中为XCode)来捕获全局keyDown事件时遇到了麻烦.我已经看到了很多类似下面的代码示例,但是在10.9.4上对我来说这不起作用.

I am having trouble with getting an assistive-enabled application (XCode in the development case) to capture global keyDown events. I've seen lots of code examples like the below, but this doesn't work for me on 10.9.4.

#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>

// 10.9+ only, see this url for compatibility:
// http://stackoverflow.com/questions/17693408/enable-access-for-assistive-devices-programmatically-on-10-9
BOOL checkAccessibility()
{
  NSDictionary* opts = @{(__bridge id)kAXTrustedCheckOptionPrompt: @YES};
  return AXIsProcessTrustedWithOptions((__bridge CFDictionaryRef)opts);
}

int main(int argc, const char * argv[])
{
  @autoreleasepool {
    if (checkAccessibility()) {
        NSLog(@"Accessibility Enabled");
    }
    else {
        NSLog(@"Accessibility Disabled");
    }

    NSLog(@"registering keydown mask");
    [NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask
                                           handler:^(NSEvent *event){
                                               NSLog(@"keydown: %@", event.characters);

                                           }];

      NSLog(@"entering run loop.");
      [[NSRunLoop currentRunLoop] run];
    }
    return 0;
}

收到的输出是:

2014-08-25 17:26:36.054 test[64725:303] Accessibility Enabled
2014-08-25 17:26:36.055 test[64725:303] registering keydown mask
2014-08-25 17:26:36.067 test[64725:303] entering run loop.

在这里,无论我按下哪个键或按下哪个应用程序具有焦点,都不会发生其他日志记录.

Once here, no other logging occurs, regardless of which keys I hit or what application has focus when I hit them.

FWIW,我正在尝试编写辅助应用程序,而不是键盘记录器或其他有害的东西.我看过这个问题的其他实例,但它们似乎处理以下问题:1)应用程序未启用辅助功能;或者2)未接收到某些需要CGEvents接收的特殊"命令键.我没有看到任何键,甚至没有看到简单的键(在我输入这篇文章的过程中一直在运行,并且没有记录任何内容). TIA!

FWIW, I'm trying to write an assistive application, not a key-logger or other evil thing. I've looked at the other instances of this question, but they seem to deal with either 1) the application not being assistive-enabled or 2) not receiving certain 'special' command keys that one would need CGEvents to receive. I am not seeing any keys, even simple ones (it's been running through my typing of this post and nothing was logged). TIA!

推荐答案

因此,多亏了Ken Thomases提出的上述问题,我才能够找到解决方法.关键的细节是我正在使用命令行应用程序模板(我不需要UI,因此我试图将事情减至最少).对我来说是新闻,但事后看来很明显,仅创建运行循环并不会创建事件循环.为了在命令行应用程序中复制事件循环的创建,必须使用典型可可应用程序的更多胆量.首先,您必须具有一个实现NSApplicationDelegate协议的类,该委托将是应用程序代码所在的位置,而main方法仅需执行以下操作:

So, thanks to Ken Thomases' question above, I was able to work out how to do this. The key detail is that I am using a command line application template (I don't have any need for a UI, so I was trying to keep things minimal). News to me, but obvious in hindsight, just creating a run loop doesn't create an event loop. In order to replicate the creation of an event loop within a command line application, more of the guts of a typical cocoa application have to be brought into play. First, you have to have a class implementing the NSApplicationDelegate protocol, and that delegate will be where the application code lives, leaving the main method to simply do the following:

#import <Foundation/Foundation.h>
#include "AppDelegate.h"

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        AppDelegate *delegate = [[AppDelegate alloc] init];

        NSApplication * application = [NSApplication sharedApplication];
        [application setDelegate:delegate];
        [NSApp run];
    }
}

这是一个无笔尖,无菜单栏的应用程序,就像通​​常的命令行应用程序模板一样,但是由于有[NSApp run]调用,它确实具有真正的事件循环.然后将我以前在上面的main方法中拥有的应用程序代码移到应用程序委托中:

This is a nib-less, menubar-less application, just like the usual command line application template, but it does have a true event loop, due to the [NSApp run] call. Then the application code that I used to have in my main method above moved into the app delegate:

#import "AppDelegate.h"

@implementation AppDelegate

// 10.9+ only, see this url for compatibility:
// http://stackoverflow.com/questions/17693408/enable-access-for-assistive-devices-programmatically-on-10-9
BOOL checkAccessibility()
{
    NSDictionary* opts = @{(__bridge id)kAXTrustedCheckOptionPrompt: @YES};
    return AXIsProcessTrustedWithOptions((__bridge CFDictionaryRef)opts);
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    if (checkAccessibility()) {
        NSLog(@"Accessibility Enabled");
    }
    else {
        NSLog(@"Accessibility Disabled");
    }

    NSLog(@"registering keydown mask");
    [NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask
                                           handler:^(NSEvent *event){
                                               NSLog(@"keydown: %@", event.characters);

                                           }];
}

@end

为了完整起见和将来的读者,头文件看起来像这样:

And just for completeness sake and future readers, the header file looks like this:

#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>

@interface AppDelegate : NSObject <NSApplicationDelegate>

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification;

@end

这篇关于addGlobalMonitorForEventsMatchingMask不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆