togo

= ひとりごと to go

zumuya の人による机の上系情報サイト

CGEventTap のタイムアウト

  • Apple
  • 開発

先ほど Frog's Hand 1.0.1 のリリース記事(→ 2019.5.31)を書いた。...短いですね。今月の記事ノルマのためだけに内容のない記事を書くのもあれなので技術的な視点から少しだけ補足説明。

macOS では1CGEventTap という API2 でシステムに発生したイベントを横取り(フック)して別のイベントに置き換える3ことができるのだけど、そういうことをしているアプリケーションが何らかの原因で反応しなくなるとイベントをその先に送信できなくなり、システムがフリーズしたように操作を受け付けなくなってしまう。

そこでその手の API には安全機能がある。決められた時間内に処理が完了しなかった場合、システムはそのアプリケーションにフックさせるのを停止するのだ。

Frog's Hand も CGEventTap を使ってドラッグのマウスドラッグのイベントに対して処理をしているのだけど、普段は問題なく動作していても Mac がスリープしたりすると処理できないのか効果が切れてしまうことがあった。

その対策として定期的に発動するタイマーで CGEventTap が無効になっていないかを確認し、必要であれば有効にする処理を追加したのである。これで解決していればよいのだけれどいかがでしょうか。


  1. ちなみに Windows だったら SetWindowsHookEx() がそれっぽい。 ↩︎

  2. Swift では CGEvent のクラスメソッドっぽく使えるようになってる。CGEvent.tapCreate(tap:place:options:eventsOfInterest:callback:userInfo:) などがそれ。 ↩︎

  3. 置き換える必要がなければ NSEvent.addGlobalMonitorForEvents(matching:handler:) も使えそう。 ↩︎

Share

リンクも共有もお気軽に。記事を書くモチベーションの向上に役立てます。