🐰

F6キーでMacやディスプレイを一発スリープさせたかった

2024/04/24に公開1

要求

Macをスリープさせる方法にはいくつかありますが、できればそれをワンタップで行いたいと思っていました。

私はデスクトップMacを使っているので、ラップトップのMacBookシリーズのように蓋を閉める方法をとれません。ソフトウェアではmacOS標準で Option–Command–Eject(EjectまたはTouch IDキー)でスリープさせる方法があります。しかしこれはキーの組み合わせが少し複雑で、もう少し手軽さが欲しいと思いました。また、システムは起きたままディスプレイのみスリープさせる方法も別で欲しかったのです。

https://support.apple.com/ja-jp/guide/mac-help/mh10330/mac

  • Macで二つのことを実現したい
    • システムスリープを手軽に行える
    • ディスプレイスリープを手軽に行える
  • スリープさせたいときに即時に実行できる
  • マウスを使いたくない
  • コマンド入力など複雑な操作が伴わない
  • Siriや音声入力に頼らない

Karabiner-ElementsでF6キーにスリープを割り当てる

なぜF6キーなのかというと、AppleのMagic KeyboardにはF6キーに月のシンボル(🌙)が刻印されていて、macOSでは「おやすみモード(Do Not Disturb)」を切り替える専用キーになっています。私はおやすみモードをほとんど使わないし、使う場合もGUIで操作するのでここに別のアクションを割り当てても不都合がありませんでした。また、通常のFキーとしての機能はFn(または地球儀キー🌐)を組み合わせれば良いので、そちらの不都合もありません。月のシンボルがスリープっぽいというのも都合がよかったです。

https://support.apple.com/ja-jp/102439

Karabiner-Elementsを使うと複雑なキーのリマップを行えるので、これ用のComplex Modificationsを独自に作ってみました。

以下のパスに空のJSONファイルを作って定義を追記していきます。定義の有効化方法などKarabiner-Elements自体の使い方の説明は省きます。

~/.config/karabiner/assets/complex_modifications/F-keys.json

単体F6でディスプレイをスリープ

F6キーを単体で押した際にディスプレイをスリープできるようにします。

Complex ModificationsのfromにF6を指示し、toでControl-Shift-Ejectにリマップします。Control-Shift-EjectはディスプレイスリープのためのmacOSのキーボードショートカットです。

{
    "description": "F6 ▸ Sleep display",
    "manipulators": [
        {
            "from": {
                "key_code": "f6"
            },
            "to": [
                {
                    "consumer_key_code": "eject",
                    "modifiers": [
                        "control",
                        "shift"
                    ]
                }
            ],
            "type": "basic"
        }
    ]
}

Shift-F6でシステムをスリープ

F6キーをワンタップでシステムが寝てしまうのは流石に危ないという理由で、私はShift-F6でそれを行えるようにしました。そこで前回の定義のfrommodifiersをぶら下げてshiftを追加すれば良いと思って試したのですが、これはうまくいきませんでした。なぜなら、toによるリマップではキーを押下した瞬間にスリープコマンドが実行されるので、そのままキーから指を離した時のイベントにMacが反応してすぐに起き上がってしまうのです。(めちゃくちゃ素早くターンと押してもダメでした。)

そこで、コマンドをKey up的なイベントで実行するか、もしくは遅延実行で対処できないかと考え、結果以下の方法に落ち着きました。これはtoの代わりにto_delayed_actionを使ってコマンドを遅延実行します。ゆっくりとキーを押すと流石にうまくいきませんが、二つのキーをタップする程度の時差なら問題ありませんでした。

リマップする内容はOption-Command-Ejectで、冒頭で紹介したmacOSに標準で備わるキーボードショートカットです。

{
    "description": "shift + F6 ▸ Sleep Mac",
    "manipulators": [
        {
            "from": {
                "key_code": "f6",
                "modifiers": {
                    "mandatory": [
                        "shift"
                    ]
                }
            },
            "to_delayed_action": {
                "to_if_invoked": [
                    {
                        "consumer_key_code": "eject",
                        "modifiers": [
                            "option",
                            "command"
                        ]
                    }
                ]
            },
            "type": "basic"
        }
    ]
}

余談:Do Not Disturbキーへの対応

Karabiner-Elementsでは技術的な理由からDo Not Disturbキーを直接参照することができないようです。本件には直接関係ありませんが、もしDo Not Disturbを別のキーにリマップして引き続き使用したい場合にはmacOSのシステム設定内にあるキーボードショートカット環境設定との併用が無難なようです。

参考資料:
https://github.com/pqrs-org/Karabiner-Elements/issues/2516

Discussion

tana00tana00

M1Pro w/ Karabiner-Element14.13.0の当方の環境ではopt + cmd + ejectでは一瞬SleepするがすぐにWakeUpしてしまう。残念。

$sw_vers
ProductName:            macOS
ProductVersion:         14.4.1
BuildVersion:           23E224

代わりにKarabiner-Elementで次のKey Eventを送るとSleepしてくれた。同時にScreen Lockが掛かるが今は目を瞑っている。
Lock Key on Magic Keyboard w/o Touch ID
また、software_function(iokit_power_management_sleep_system)を送る事でSystem Sleepさせる事が出来る事が次のLinkで紹介されてます。
iokit_power_management_sleep_system | Karabiner-Elements
これもやってみると確かにSleepしてくれるのだがWakeUp後にKarabiner-MultiTouchExtensionが多重起動されてしまいました。厄介なので止めてしまいました。