2013-08-04 74 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

相關問題