2013-08-04 73 views
1

我可以通过我的窗口控制器的keyDown:方法成功对键盘事件作出反应。
执行鼠标拖拽时出现问题:
键盘事件似乎被延迟,只会在鼠标上触发。可可:拖动时不会触发键盘事件(NSEventTrackingRunLoopMode)

要清楚,我的意思是:
•发生在你的窗控制器的KeyDown日志声明:(。上NSSlider为前)方法
•启动您的应用程序,执行一些拖放操作
•当保持拖动,按任意键:没有任何记录到控制台。
•发布拖动:日志出现,耶...

我拖动的控件是一个自定义的NSSlider。
我已经实现了使用'鼠标跟踪循环'方法的拖动机制。 据我所知,拖动时,NSApplication的主运行循环模式正在切换到NSEventTrackingRunLoopMode,从而限制传入事件。

所以,我只是在我的跟踪循环中添加NSKeyDownMask & NSKeyUpMask,并在遇到问题时调用self.nextResponder keyDown/up:方法。 我的问题是解决这个特定的自定义子类。

但可可的原生控件呢?我不能编码异常...

我曾希望NSEvent的“addLocalMonitorForEventsMatchingMask:”方法 ,但唉,说doc:“不会调用嵌套的事件跟踪循环消耗的事件,如控制跟踪,菜单跟踪或窗口拖动“。

因此,是否有一个简单的解决方案来接收键盘事件,而不管应用程序的runloop模式?

+0

我有一个类似的问题,当我使用“鼠标跟踪循环”方法时,定时器似乎不会触发 - 无论我将哪些运行循环模式添加到定时器。当顶级菜单被拉下时,定时器会启动... - 所以在这方面的进展如何? –

回答

2

正如您在NSEventaddGlobalMonitorForEventsMatchingMask:handler:的文档中发现的那样,此限制是有意设计的。

但是,您可以通过使用IOKit框架(特别是IOHID部分)来解决此问题,以接收低级别的设备事件/中断。我最近只需要在鼠标拖动过程中跟踪一些特定的按键。

的基本要点是创建一个IOHID经理IOHIDManagerCreate(),再加入设备的类型(一个或多个)到管理器,它应该“监视器”与IOHIDManagerSetDeviceMatchingMultiple(),经由IOHIDManagerRegisterInputValueCallback()注册到管理器的回调,安排适当的运行 - 与IOHIDManagerScheduleWithRunLoop()联系经理,最后以IOHIDManagerOpen()打开经理。

要在鼠标拖动过程中获取这些低级别事件,请在单独的线程中执行此设置。在为经理安排运行循环时,请使用CFRunLoopGetCurrent()获取当前线程的运行循环,并在IOHIDManagerOpen()之后调用CFRunLoopRun()

This guide from Apple可以帮助您开始,以及this Q&A here on Stack Overflow

+0

我一直在撞墙,试图让IOHIDManager与全屏CGL应用程序一起工作。我没有从所有例子中认识到你必须提供一个运行循环......并且直到我读到你的答案时,我才意识到运行循环可能应该在另一个线程上。非常感谢! – 2016-02-19 04:45:51

相关问题