uchan note

プログラミングや電子工作の話題を書きます

【Ubuntu】ラップトップ PC の蓋を閉じてスリープさせる

LAVIE Direct HZ というラップトップ PC に Ubuntu 15.04 を入れて使っている。この PC は 13.3 型もの大きさがあるのに非常に軽く、筆者のお気に入りだ。ただ、残念なことに蓋を閉じてもスリープモードにならない問題があった。

※2017 年 1 月 29 日追記:Ubuntu 16.04 でも動作することを確認しました。

蓋を閉じてもスリープしない

蓋を開閉して dmesg を確認してみると、次のようなメッセージが出ることが確認できた。

f:id:uchan_nos:20200326090049p:plain

蓋を操作するたびに "Unknown key pressed" が記録される。ラップトップの蓋のスイッチが開閉を感知すると、OS に対してあたかもキーボードが打鍵されたかのように信号を送るようになっているらしい。しかしそのキーを OS が知らないために解釈し損ねているというメッセージだ。

Configure unrecognized keys in Linux - Juan Valencia's website には、キーが打たれたときに何が起きるかが詳しく書いてある。簡単に説明すると、キーが打たれるとキーボードから「スキャンコード」が OS に送信され、OS が持つ対応表を元に「キーコード」へ変換される。先のエラーメッセージは、その対応表に登録されていないスキャンコードが送られてきたという意味だ。

蓋の開閉をスリープボタンに対応させる

エラーメッセージにもあるように、OS にそのスキャンコードがどのキーコードに対応させるべきかを教えるコマンドが setkeycodes である。蓋を閉じたときにスリープさせたければ、スキャンコード e02b をスリープボタンと同じキーコードに対応させれば良い。スリープボタンのキーコードは xmodmap コマンドを使って調べる。

$ xmodmap -pke | less

この中から XF86Sleep や XF86WakeUp というキーを探す。見つけたらそのキーコードを覚えておく。筆者の環境ではそれぞれ 150, 151 となっていた。

...
Keycode 150 = XF86Sleep NoSymbol XF86Sleep
Keycode 151 = XF86WakeUp NoSymbol XF86WakeUp
...

これが分かれば、後は setkeycodes コマンドで設定するだけだ。ただし、xmodmap で表示されたキーコードから 8 を引いた値を設定する必要があるようだ。

$ sudo setkeycodes e02b 142
$ sudo setkeycodes e02c 143

うまくいかないときは、試しにアルファベットのキーコードを設定して蓋を開閉してみて、ターミナルに文字が入力されるかを見てみると良いかもしれない。入力された文字を見れば 8 を引くべきかどうかを確認できる。

起動時に自動的に設定する

このままでは、PC を再起動すると設定が初期化されてしまうので、PC を起動するたびに自動的に設定を行うようにしたい。Ubuntu 15.04 では標準で systemd が起動時の処理を担当しているので、それに合わせて設定ファイルを書けば良い。

/etc/systemd/system/set-lid-keys.service

[Unit]
Description=Set Keycodes of LID Keys

[Service]
ExecStart=/bin/sh -c "setkeycodes e02b 142; setkeycodes e02c 143"
Type=oneshot

[Install]
WantedBy=default.target

systemd の一般的な説明は他に譲るとして、上記の設定項目を簡単に説明する。

  • ファイル名:普通のジョブを表す .service という拡張子を付ける。
  • Description:ジョブの説明文。
  • ExecStart:実行させたいプロセスを書く。絶対パスで書かないとダメらしい。
  • Type:oneshot は一度実行してすぐ終わるジョブを表す。
  • WantedBy:default.target は systemd が起動すると必ず実行されるターゲット。他には graphical.target なども有るが、どれが最適かは筆者は知らない。

設定ファイルが準備できたら、システム起動時に読み込まれるように systemctl コマンドで有効化する。

$ sudo systemctl enable set-lid-keys.service

これで設定は完了だ。

さいごに

本投稿とは逆に、蓋を閉じてもスリープさせないようにする設定はよく見かける。例えば systemdで画面を閉じてもスリープに入らないようにする とか。その場合でも、本投稿の手順で蓋のキーを認識させてから、改めて無視するように設定するのが綺麗だろうと思う。