IMKit捕获NSKeyup事件 [英] IMKit to catch NSKeyup event

查看:324
本文介绍了IMKit捕获NSKeyup事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为一个实验,我试图实现以下:




  • 让空格键作为修饰键 - 其中按住空格键和打字键打印不同的字母。释放空格键会将状态恢复正常,只需按下它就像一个正常的空格键。



keydown和keyup事件,但在 handleEvent:client: /IMKServerInput_Additions/Reference/IMKServerInput.htmlAddions/Reference/IMKServerInput.html#//apple_ref/doc/uid/TP40006161-CH3-SW4rel =nofollow> IMKServerInput协议似乎只捕获键向下和鼠标事件。



没有太多的可可经验,我尝试了一些没有成功的方法:





我得出结论,IMKit只能的被动接收事件。
因为它不是一个应用程序,没有 keyUp:方法覆盖 - AFAIK,IMKit不继承 NSResponder class。



不幸的是,可可太宽泛了,对于像我这样的新手来说,

解决方案

我试过全部可能的替代方案一个一个,并最终通过创建一个全局EventTap
CGEventTap



代码基本上看起来像这样:

  //创建事件点击。 
CGEventMask eventMask =((1 CFMachPortRef eventTap = CGEventTapCreate(kCGSessionEventTap,
kCGHeadInsertEventTap,
0,
eventMask,
myCGEventCallback,
NULL);

if(!eventTap){
NSLog(@无法创建事件tap \\\
);
return NO;
} else {
//创建一个运行循环源。
runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault,eventTap,0);
//添加到当前运行循环。
CFRunLoopAddSource(CFRunLoopGetCurrent(),runLoopSource,kCFRunLoopCommonModes);
//启用事件点击。
CGEventTapEnable(eventTap,true);
return YES;
}

其中 myCGEventCallback



同时这里是我发现的一些:




  • 根据键输入消息序列文档中,应用程序仅将链接事件传递到输入法工具包,之后尝试链中的其他堆处理程序。你不能让 IMKServerInput 'catch'NSKeyUp事件。只需向 recognizedEvents:添加 NSKeyUpMask 就不起作用。

  • addLocalMonitorForEventsMatchingMask:handler: CGEventTapCreateForPSN 不会捕获事件。我想这是因为虽然输入法可能作为一个单独的进程运行,事件本身是从应用程序,像TextEdit,并移交给输入`方法。

  • <$

  • 创建一个全局EventTap需要运行具有sudo权限的进程 - 复制一个新的硬件设备和制作驱动程序。输入方法 / Library /输入方法不使用sudo权限运行,或将应用程序注册到辅助功能控件。这是在系统偏好→安全&隐私权&rarr隐私标签→辅助功能,在小牛。


As an experiment, I am trying to achieve the following:

  • Let spacebar work as a modifier key - like the Shift key - where holding the spacebar key down and typing keys print different letters. Releasing the spacebar would set the state back to normal, and just pressing it behaves like a normal space key.

I was thinking of handling the keydown and keyup event, but apparently handleEvent:client: in IMKServerInput Protocol seems to only catch key down and mouse events.

Without much experience with cocoa, I’ve tried some methods with no success:

I reached to a conclusion that IMKit is only capable of passively receiving events. Since it is not an application, there is no keyUp: method to override - AFAIK, IMKit does not inherit NSResponder class.

Unfortunately cocoa is way too broad and has much less (or overflowed with non-helping) documentations for a novice like me to dive in.

Can anyone help me to the right direction?

解决方案

I tried all possible alternatives one by one, and eventually achieved it by creating a global EventTap with CGEventTap.

The code basically looks like this:

// Create an event tap.
CGEventMask eventMask = ((1 << kCGEventKeyDown) | (1 << kCGEventKeyUp));
CFMachPortRef eventTap = CGEventTapCreate(kCGSessionEventTap,
                            kCGHeadInsertEventTap,
                            0,
                            eventMask,
                            myCGEventCallback,
                            NULL);

if (!eventTap) {
    NSLog(@"failed to create event tap\n");
    return NO;
} else {
    // Create a run loop source.
    runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
    // Add to the current run loop.
    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
    // Enable the event tap.
    CGEventTapEnable(eventTap, true);
    return YES;
}

where myCGEventCallback handles the global states.

Meanwhile here are some of what I've found out:

  • According to The Key-Input Message Sequence document, the application only passes the keydown event to the Input Method Kit, after trying other bunch of handlers in the chain. You cannot let IMKServerInput 'catch' the NSKeyUp event. Just adding an NSKeyUpMask to recognizedEvents: would not work.
  • addLocalMonitorForEventsMatchingMask:handler: and CGEventTapCreateForPSN would not catch the event. I suppose this is because though an Input Method may run as a separate process, the event itself is fired from the application, like TextEdit, and handed over to the Input `Method.
  • IOHIDManager: is for adding new hardware devices and making drivers.
  • Creating a global EventTap requires either running the process with sudo privilege -- copying the Input Method to /Library/Input Methods does not run with sudo privilege --, or registering the application to the Accessibility control. That's in System Preferences → Security & Privacy → Privacy tab → Accessibility, in Mavericks.

这篇关于IMKit捕获NSKeyup事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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