Mac
MacOSX
Swift

Swift を用いて MacOS のキーボード無効化する方法

最初に

この記事は MacOS を Swift を用いてキーボードを無効化する方法について記載します。
記載時の環境は以下の通りです。

対象 バージョン
Swift 4.2.1
MacOS 10.13.6

Demo

Mac の画面右上にカーソルを持っていくとキーボードの (有効|無効) が切り替わります。
有効であれば入力することができ、無効であれば入力することが出来ません。

Dec-22-2018 17-54-56.gif

ソースコード解説

アクセシビリティの設定

キーボードやマウスのイベント等、コンピュータの制御に関する処理をトラッキングする場合、
アクセシビリティの設定が必要となります。
以下のコードで判定し、もしアクセシビリティの設定を行っていない場合は許可ダイアログを出すようにします。

let options = NSDictionary(
    object: kCFBooleanTrue,
    forKey: kAXTrustedCheckOptionPrompt.takeUnretainedValue() as NSString
) as CFDictionary

AXIsProcessTrustedWithOptions(options)

アクセシビリティの許可を促すダイアログ
スクリーンショット 2018-12-22 15.24.37.png

キーボードを無効化する処理

次にキーボードを無効化する処理について説明します。

CGEvent.tapCreate(
    tap: .cgSessionEventTap,
    place: .headInsertEventTap,
    options: .defaultTap,
    eventsOfInterest: CGEventMask((1 << CGEventType.keyDown.rawValue) | (1 << CGEventType.flagsChanged.rawValue)),
    callback: { (proxy: CGEventTapProxy, type: CGEventType, event: CGEvent, refcon: UnsafeMutableRawPointer?) -> Unmanaged<CGEvent>? in
        if [.keyDown, .flagsChanged].contains(type) {
            let keyCode: Int64 = 99999 // this keycode does not exist.
            event.setIntegerValueField(.keyboardEventKeycode, value: keyCode)
        }
        return Unmanaged.passRetained(event)
    },
    userInfo: UnsafeMutableRawPointer(Unmanaged.passRetained(self).toOpaque())
)

eventesOfInterst にトラッキングする EventMask を指定することにより、コールバックでイベントを取得することが出来ます。

上記のコードでは keyDownflagsChangedEventMask を指定し、
コールバックで存在しないキーコードに上書きすることにより、キーボードを無効化しています。
flagsChanges は、⌘キーShiftキーを指しています。

その他、キーボードを有効化に戻したり、マウスのトラッキング処理も含めたソースコードを Gist に載せてますので、
ご興味ある方はぜひ見てください。
https://gist.github.com/bpyamasinn/b2b255403d09c55f9e799456565bc616

開発経緯

自宅勤務中で集中してる時に、キーボードの上に乗ってくる猫を退かせるのに抵抗感がありました。

申し訳ないな...と思いつつキーボードから退かせた後、
寂しげな後ろ姿を見ると心が痛んだので、キーボードを切り替える技術を検証しました。

最後に

これで猫が乗ってきても、何も問題ありません。
猫が甘えてくる時は撫でてあげましょう :relaxed:
きっと、満足した頃には自分からキーボードから退いてくれます。

もちろん、キーボードは入力出来ない状態のため、メールや Slack 等の連絡を確認したり、
仕様書の確認等に時間をあてましょう。


以下、おまけ

我が家の猫がキーボードの上で温まってる時の写真

スクリーンショット 2018-12-22 14.58.00.png

この子を退かせることなんて出来ない... :thinking:

ボタン式でキーボード切り替え

画面右上にボタンを用意し、そのボタンをクリックするとキーボードの状態を切り替える方法を最初に試しました。
しかし、ボタンを押す頃には猫が乗ってきてしまっていたので、もう少し早くロックできる方法を探りました。

カメラ式でキーボード切り替え

Mac Book 内蔵カメラを用いて、猫を監視しキーボードの状態を切り替える方法を試しました。
猫の判定はある程度出来たものの、ずっとカメラを起動すると Mac の電池消費スピードが著しく上がってしまったためボツに...

結果、カーソルを右上に持っていってロックする方法が最適という結果に至りました。
何か他に良い方法あったらご提案頂けると嬉しいです :pray: