可可:拖动无键盘事件将触发(NSEventTrackingRunLoopMode)(Cocoa: N

2019-10-18 10:45发布

我能够成功地从我的窗户控制器的KeyDown键盘事件作出反应:方法。
在执行鼠标拖拽的问题出现了:
键盘事件似乎被推迟,将仅在鼠标弹起。

需要明确的是,我的意思是:
•放置日志语句在你的窗控制器的KeyDown:方法
•启动您的应用程序,执行一些拖放操作(在NSSlider为前。)
•同时保持阻力,按任意键:没有登录到控制台。
•释放拖动:日志出现,耶...

我正在拖动控制是一个自定义NSSlider。
我已经实现了使用“鼠标跟踪环”的方法拖动机制。 对于我个人理解,拖动时,的NSApplication的主运行的循环模式切换到NSEventTrackingRunLoopMode,从而限制进入的事件。

所以,我只是简单地添加NSKeyDownMask&NSKeyUpMask在我的跟踪环路和encoutered时,称为self.nextResponder的keyDown /向上:相应的方法。 我的问题是解决了这个特定的自定义子类。

但对于可可的本地控制? 我不能代码例外...

我所希望的NSEvent的“addLocalMonitorForEventsMatchingMask:”方法,但很可惜,说DOC:“不会被要求由嵌套的事件跟踪环路,如控制跟踪,跟踪菜单或窗口中拖动消耗事件”。

那么,是不是有一个简单的解决方案,以接收键盘事件,无论应用程序的runloop模式?

Answer 1:

当你的文档中发现NSEvent类的addGlobalMonitorForEventsMatchingMask:handler: ,这种限制是由设计。

但是,可以通过使用由于IOKit框架(具体地,IOHID部分)接收低电平设备事件/中断解决它。 我不得不期间鼠标拖动跟踪一些特定的按键近日做到这一点。

的基本要点是创建具有IOHID经理IOHIDManagerCreate()然后添加的设备的类型(一个或多个)到管理器,它应该“监视器”与IOHIDManagerSetDeviceMatchingMultiple()经由管理器注册回调IOHIDManagerRegisterInputValueCallback()调度所述适当的运行循环与经理IOHIDManagerScheduleWithRunLoop()最后打开与经理IOHIDManagerOpen()

为了让在鼠标拖动这些低级别的事件,在一个单独的线程执行此设置。 当调度运行循环的管理,使用CFRunLoopGetCurrent()来获得当前线程的运行循环,并调用CFRunLoopRun()IOHIDManagerOpen()

苹果本指南可以帮助您开始,伴随着这个Q&A在这里堆栈溢出 。



文章来源: Cocoa: No keyboard events will fire while dragging (NSEventTrackingRunLoopMode)