CGEventTap のタイムアウト

MacDev

先ほど 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:) も使えそう。 ↩︎

Frog's Hand 1.0.1 

Products

修飾キーを押しながらのドラッグでスクロールできるアプリケーション、Frog's Hand のバージョン 1.0.1 をリリース。起動し続けていると効果がなくなることがある問題を修正しました。

ダウンロードは Documents から。

© 2005-2019 zumuya