Help us understand the problem. What is going on with this article?

MacBook のバックライトをオフにするショートカットキーを作る

自分は MacBook を外部ディスプレイに繋ぐときは内蔵ディスプレイは使わないスタイルなので、外部ディスプレイにつないでいる間は内蔵ディスプレイを切っておきたい。(開いた状態で画面を切るのは無理なので、バックライトをオフにしておきたい)

image.png

スリープから復帰するたびに内蔵ディスプレイが明るくなってしまうので、毎回 Touch Bar を触って画面を暗くするのが面倒くさい。ショートカットキーいっぱつでバックライトをオフにできないものかと考えた。

内臓ディスプレイの輝度を操作する方法

ググっていくつか試したもののうまくいかなかった方法。

NVRAM の値をいじる方法

Mac には NVRAM という記憶領域があり、ここに画面輝度の情報が保存されているらしい。

NVRAM (不揮発性ランダムアクセスメモリ) は、Mac がすばやくアクセスできるように所定の設定情報を記憶しておく小容量のメモリです。
NVRAM に記憶される設定情報には、音量、画面解像度、選択されている起動ディスク、時間帯、最近起きたカーネルパニックの情報などが該当します。

Mac で NVRAM または PRAM をリセットする - Apple サポート

NVRAM の値は nvram というコマンドで取得と変更ができるらしいので、これを使えばバックライトが操作できるのではないか。

$ nvram backlight-level

と実行すると、輝度によって違う値が返ってくることがわかる。

輝度が最低 (バックライトオフ) のときの値はどうやら %00%00 らしいので、これを設定してみる。

$ sudo nvram backlight-level='%00%00'

が、画面輝度には反映されない・・・。

どうやら NVRAM の値を書き換えられるだけでハードウェアを操作することはできないらしい。
諦め。

Brightness Down キーを送る方法

Mac の画面輝度を下げる物理キー (Brightness Down) はキーコードが 0x91 なので、これを仮想的に押したことにすれば輝度が下がるのではなかろうか。

$ osascript -l JavaScript -e 'const app = Application("System Events"); app.keyCode(0x91)'

お、少し暗くなった。

(物理キーは1回押せば輝度が1段階下がるので) あとはこれを16回送信すれば輝度最小になるじゃ〜ん!

$ osascript -l JavaScript -e 'const app = Application("System Events"); for (let i = 0; i < 16; i++) { app.keyCode(0x91); }'

と思ったのも束の間、全然うまくいかないんだなこれが。

全然輝度が変わらないことがあったり、中途半端に暗くなったり、思うような挙動をしない。
delay(1.0) を挟んでみたりしてもダメ。

どうやら物理キーを押すのと 0x91 を送信するのとでは何か振る舞いが異なるらしい。
諦め。

最終的に採用した方法

brightness というコマンドを入れた。

brew install brightness で入る。

実装を読むと、C から CoreDisplay の API を呼んでいるようだ。
https://github.com/nriley/brightness/blob/master/brightness.c

最初からそれでよかったのではという気もしなくもないが、できれば何もツールを入れずに実現したかった・・・。

$ brightness 0.0

と実行するだけで画面輝度が最小になるが、これだと接続されているすべてのディスプレイの輝度を下げられてしまうので、内蔵ディスプレイ (built-in) の輝度だけを下げるようにする。

builtin-display-brightness.sh
#!/bin/bash -eu

BUILTIN_DISPLAY_ID=$(brightness -l 2>/dev/null | grep built-in | sed -E 's/^.*ID (0x.+)$/\1/g')
brightness -d $BUILTIN_DISPLAY_ID $1
$ ./builtin-display-brightness.sh 0.0

できた。
便利かよ・・・。

ショートカットキーを割り当てる

Karabiner-Elements の Complex modifications を使って、option + [ で画面輝度が最小になるように設定した。

karabiner.json
{
    "description": "option + [ で内臓ディスプレイのバックライトを消す",
    "manipulators": [
        {
            "from": {
                "key_code": "open_bracket",
                "modifiers": {
                    "mandatory": [
                        "option"
                    ]
                }
            },
            "to": {
                "shell_command": "PATH=$PATH:/usr/local/bin /path/to/builtin-display-brightness.sh 0.0"
            },
            "type": "basic"
        }
    ]
}

注意点としては、Karabiner-Elements の shell_command は /usr/local/bin に PATH が通っていない ので、PATH=$PATH:/usr/local/bin と書いておかないと「brightness コマンドが見当たらない」とエラーになってしまう。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away