i3 wm を使うことのメモ (3) カスタマイズ

i3の設定ファイルに書いて、スクリーンロックなど

以前「i3 wm タイル型ウィンドウマネージャを使うことのメモ (1)」で i3 のインストールをやったが、今度はカスタマイズして便利コマンドを付け加えるやつ。

i3 の設定

i3 の設定ファイル

i3 インストール時に作成を了承していれば ~/.config/i3/config というプレーンテキストのファイルが作成されていることだろう。

カスタマイズはこのファイルを書き換えて行う。記述は独自言語のようだけれども、簡単なものなので特にプログラミングの経験を要するものではないだろう。

もしこのファイルがなければ、設定ウィザード i3-config-wizard を実行するといい。これは i3 インストール後の最初の起動で実行されるウィザードと同じものだ。使っているキーボードレイアウトにあわせた設定で ~/.config/i3/config を作成してくれる。なお、すでに ~/.config/i3/config がある場合は実行できない。

また /etc/i3/config にも設定ファイルがあり、こちらは Wizard による調整を含まない(特に $Mod 定義)もののようだが、それを承知ならばこれを使ってもいいだろう。そうでなくとも、参考になる記述が含まれているかも知れない。

なお、i3 の設定ファイルは ~/.i3/config でもいい。

以下、 ~/.config/i3/config あるいは ~/.i3/configi3/config と記す。

dmenu と i3-msg

i3 コマンドには専用コンソールがあるわけではないけれど、コマンドを橋渡しする i3-msg というユーティリティコマンドが用意されている。これを介せばシェルから i3 へコマンドを送れる。

ところで、この実行を端末エミュレータからやってもいいのだが、 dmenu の方が手軽かもしれない。

dmenu は i3 標準指定のアプリなのだが、 i3 パッケージに含まれているわけではないので明示的にインストールする必要がある。

dmenu がインストールされていれば、 $mod+d$modWindows キーに設定されることが多いもよう)を押すと dmenu (dmenu_run) が起動し、スクリーンの最上行に現れる。

例として、カレントウィンドウをフルスクリーン表示に切り替える fullscreen コマンドを利用してみる。

まず $mod+Enter で端末エミュレータをひとつ起動しておいてから、 $mod+d を押して dmenu を起動し、

i3-msg fullscreen

と入力して Enter を押してみる。すると端末のウィンドウがフルスクリーンになるはずだ。もう一度実行するともとに戻る。

この i3-msg は主にシェルスクリプトなど外部から i3 の機能を使うときのためのものだが、設定ファイルに書くことを検討する際、ちょっと試しに実行してみたい場合に便利だろう。

i3 の基本コマンド

以下はi3のコマンドの一部。ほかにもいっぱいあるけれど(i3: i3 User’s Guide #_list_of_commands)、よく使うものを定義系とアクション系に分けてみた。

定義

set 変数定義
font フォント定義
bindsym / bindcode キー定義
mode モード定義
for_window ウィンドウスタイルの定義
assign ウィンドウの所属ワークスペース定義

アクション

exec コマンド実行
focus ウィンドウにフォーカス
layout ウィンドウのレイアウト
kill ウィンドウを閉じる
move ウィンドウを任意のワークスペースへ動かす
workspace ワークスペースを切り替える

exec コマンドと startup-notification

アプリの起動(プログラムの実行)は exec コマンドで行う。試しに i3-msg exec firefox と実行してみれば、Firefox が起動するはずだ。例えば i3 起動時( OS 起動後)に Firefox も自動的に起動してほしければ i3/config のどこかへ exec firefox とだけ記述しておけばいい。

この exec コマンドは startup-notification に対応している。

startup-notification というのは、起動最中のアプリの状態をマウスカーソルで知らせる仕組みで、 時計あるいは砂時計のカーソルと言えばわかりやすいだろうか。

これはアプリ側の対応が必要なものなのだが、未対応なアプリも少なくないらしい。そこで i3 では startup-notification に対応していないアプリであっても、60秒間は時計を表示するようにしている。

つまり、 exec コマンドを使うとたいていは時計カーソルが表示されるということである。

しかし、起動完了後も長々とカーソル時計(あるいはグルグルまわるやつかもしれない)が表示されこともあり、意味がわからずちょっとした混乱状態となることも多い。このように時計が必要ない場合もあるだろうということで、 --no-startup-id というオプションが用意されている。これで起動すればカーソルが時計に変わることはない。

使用の目安として、GUIアプリの実行を設定するならばとりあえず exec だけで試してみて、時計がながながと表示されてイヤだなとなれば --no-startup-id を付け足してやるという風にすればいいと思う。端末エミュレータそのものや TUI なんかは起動が早いから、端から --no-startup-id でいいかもしれない。

exec --no-startup-id urxvt -e alsamixer

bindsym / bindcode

キーバインディングは、キーシンボルを使って設定するなら bindsym 、キーコードなら bindcode で行う。多くの場合 bindsym でいいと思うのだが、キーボードレイアウトを時々変更するということがあるならば bindcode を使うのがいいかもしれない。

例えばデフォルトで設定されている dmenu 起動キーの設定は次の通りだ。

bindsym $mod+d exec dmenu_run

お察しの通り $mod+dexec dmenu_run を割り当てるということだ。

ちなみに、この設定でマウスカーソルをdmenuの範囲にのせると時計にかわるかと思う。

ショートカットキー設定例

・ Alt+F2 で dmenu

他のWMでは Alt+F2 に起動メニュー(ランチャ)が仕込んであったりすることがあるが、それを dmenu で設定してみる。以下を i3/config の最後でいいから付け加える。

bindsym $altl+F2 exec --no-startup-id i3-dmenu-desktop

書いて保存したら Shift+$mod+r で i3 を再起動。 Alt+F2 を押すと dmenu が表示されるかと思う。 --no-startup-id を指定したので、マウスカーソルを dmenu の上にのせても時計に変わらないはずだ。

$mod+d には dmenu_run が仕掛けられているが、ここでは i3-dmenu-desktop というのを設定した。見かけは一緒だけれども表示される候補はデスクトップエントリから選ばれているので、この方が扱いやすい場合もある。

・ スクリーンロック

ちょっとトイレに行くときなど、スクリーンロックできないとうまくない。だってそれは、いちいちログアウトなんてやってられないから。だからスクリーンロックするショートカットキーを設けたい。

前の「i3 wm タイル型ウィンドウマネージャを使う」では DM (デスクトップマネージャ)として LightDM をインストールした。 LightDM には dm-tool という便利な CLI ツールがあって、スクリーンロックもこれでかけられる。

bindsym Control+Mod1+l exec dm-tool lock

Control+Alt+l を押せばロックされて LightDM の画面に切り替わる。トイレから帰ったらパスワードで元の画面に戻って来られる。

端末エミュレータ

rxvt-unicode で省メモリと高速起動

i3 では端末エミュレータを複数起動するような使い方が多いことだろう。そこで urxvt (rxvt-unicode) をデーモンモードで利用すれば多少のメモリ節約になるし、起動もはやい。

やり方は、 urxvt のデーモン(urxvtd)を常駐させておき、以降はクライアント(urxvtc)を使うようにする(詳細は「urxvt こと rxvt-unicode を使うことのメモ」)。

さて、デフォルトの i3/config では端末起動キー $mod+Enteri3-sensible-terminal というシェルスクリプトの起動が設定されている。

bindsym $mod+Return exec i3-sensible-terminal

i3-sensible-terminal はインストールされている端末エミュレータの中からある優先順位に則ってひとつを実行する(環境変数 TERMINAL が定義されていれば最優先)。しかし選択候補に urxvtc / urxvtd 連携の定義はないし、複雑な条件選択には向かないようだ。ここでは i3-sensible-terminal を使わず、コマンドラインを定義する。

また Ubuntu なんかで Control+Alt+t を押すと端末エミュレータが起動するが、それも真似てみる。

set $exec_terminal exec --no-startup-id "urxvtc || { [ $? -eq 2 ] && urxvtd -q -o -f && urxvtc; }"
bindsym $mod+Return $exec_terminal
bindsym Control+Mod1+t $exec_terminal

上記では変数( $exec_terminal )にコマンド内容を set したものを bindsym で利用するようにしてみた。複数のキーに設定することだし、こうしておくと見通しもいい。

i3-sensible-terminal は環境変数 TERMINAL を最優先するが、引数やパイプの付与は考慮していないもよう。

TUI アプリを urxvtc で起動する

ranger ファイルマネージャ とか、あるいは cmus ミュージックプレイヤー などの TUI アプリは、わざわざ端末でコマンドを打って起動したりせず、コマンドキー一発で起動して欲しい。

先程の i3/config への1行記述だと、以下のようになるだろう。

set $exec_filemanager exec --no-startup-id "urxvtc -e ranger || { [ $? -eq 2 ] && urxvtd -q -o -f && urxvtc -e ranger; }"

これでもいいが、オプションが混んでくると長いことになって記述ミスでイライラしてしまう。そこで、 urxvtc / urxvtd の起動をシェルスクリプトファイルに分けておく。

以下は、「urxvt こと rxvt-unicode を使うことのメモ」に記してあったシェルスクリプトをちょっと改造した。

#!/bin/bash
#
# ~/bin/run_urxvt_tui / JennyM 2017 malkalech.com

options=(
  -vb          # visualBell:  on:-vb  off:+vb
  +sb          # scrollBar:  on:-sb  off:+sb
  +bc          # cursorBlink:  on:-bc  off:+bc
  +uc          # cursorUnderline:  on:-uc  off:+uc
  -fade    40  # fading
  -sl    2000  # saveLines

  "$@"
)

urxvtc "${options[@]}" || { [ "$?" -eq 2 ] && urxvtd -q -o -f && urxvtc "${options[@]}"; }

これを ~/bin/run_urxvt_tui に保存し実行属性をつけておく。特に TUI 向けの起動オプションを書いてある。ほかにもあるなら配列 options に書き加えておくといい( "$@" より上に )。

そうしておいて、 i3/config で以下のような変数を定義して、

set $exec_filemanager exec --no-startup-id ~/bin/run_urxvt_tui -e ranger
set $exec_musicplayer exec --no-startup-id ~/bin/run_urxvt_tui -e cmus

あとは先の例のように bindsym (または bindcode ) でキーバインドを定義すればいい。

壁紙の設定

i3 も壁紙の設定は可能だ。かといって、メジャーディストロのデスクトップのように壁紙チェンジャーがセットアップされているわけではないので、いま少し手間をかける必要がある。

GNOME 版なんかだと常駐して壁紙を勝手に切り替えるような高機能な壁紙アプリがたくさんあるようだが、ここではホントにもう壁紙をセットするだけのことを挙げる。

feh で壁紙を設定する

feh は非常に軽量な画像ビューアだが、壁紙設定機能も持ち、豊富なオプションを使ったコマンドラインからの操作も可能となっている。 i3 の壁紙設定はこの feh を使って行うのがポピュラーなようだ。使い方は流石の ArchWiki 日本語版( Feh – ArchWiki (ja) )が詳しく判りやすい。ここでは壁紙設定のみをザックリと記す。

feh -Zr ~/Pictures と実行すると ~/Pictures 下の画像をビューアで順次表示する( -r は再帰的探索)。

カーソルキー / で 前/次 の画像を表示、 / でズームイン/アウト。 q で終了。

そして壁紙にしたい画像で m あるいはマウス右クリックで表示されるメニューから FileBackgroundSet Scaled などとすれば、壁紙に設定される。

また、コマンドライン で壁紙を設定するには feh --bg-fill ~/Pictures/image.jpg などとすればいい。オプション --bg-xxx を指定することでバックグラウンドへの表示を指定(つまり壁紙設定)するとともに、表示方法を指定する。表示方法は以下の通り。

--bg-fill 画面幅まで拡大/縮小し、はみ出た分は切り捨てる
--bg-max 画面いっぱいに、はみ出ないよう表示する
--bg-scale 画面いっぱいに画像を表示(アスペクト比を無視)
--bg-center 等倍表示
--bg-tile タイリング(リピート表示)

feh は、壁紙設定をする度にそれを再現する ~/.fehbg というシェルスクリプトファイルを自動作成してくれる(実行属性もつけてくれる)。だから i3/config へ以下の1行を書いておけば、 i3 起動時に壁紙が適用されるという寸法だ。

exec --no-startup-id ~/.fehbg

nitrogen で壁紙を設定する

nitrogen は GUI で画像サムネイルを見ながら壁紙を設定する専用アプリ。常駐するような機能は持たず壁紙をセットするだけのことなのだが、軽くて直感的で妙に判りやすい(と思う)。

nitrogen を実行し、ウィンドウ右下の Preferences ボタンで設定ダイアログを開いて Add ボタンで壁紙に使いたいファイルがあるディレクトリを指定すると、サムネイルが表示されるようになるからそこから選んで、 Apply 。ディレクトリは複数指定できる。

あるいは、 nitrogen ~/Picures のように実行すれば最初から ~/Picures 以下(再帰的探索)の画像をサムネイル表示してくれる(設定内容へディレクトリの追加はしない)。

feh と同じように、壁紙を設定するとその情報が保存される( ~/.config/nitrogen 下に保存)。 i3 を再起動したときに --restore オプション付きで nitrogen を実行すれば、やはり、前回使っていた同じ壁紙が表示される。だから i3/config へは以下の1行をかいておけばいい。

exec --no-startup-id nitrogen --restore

i3 では nitrogen のウィンドウは通常アプリの扱いを受けるので、スプリット表示でない場合には画面いっぱいに表示されて、ちょっと使い難い。壁紙を設定したらすぐに C-q して閉じるようなものだから、ならばフローティングウィンドウにしておくのがいいかもしれない。以下の1行を i3/config に追加しておけば、常にフローティングウィンドウで表示されるようになる。

for_window [instance="nitrogen" class="Nitrogen"] floating enable

なお、フローティングウィンドウへの切り替え(トグル)キーはデフォルトで Shift+$mod+Space だ。

壁紙をランダムに選ぶ

feh には複数ソースの中からランダムに画像を選ぶ --randomize オプションがあるが、探索するディレクトリ名を引数にした場合に画像以外も指定することになり、エラーとなって画像が切り替わらないことがある。これは、ディレクトリでなく拡張子をワイルドカード指定するようにすれば避けられる。

$ feh --bg-fill --randomize ~/Pictures/Wallpapers/*.jpg 

しかし、そうすると指定ディレクトリ以下を再帰的に探索させたい時に --recursive オプションが指定できない。

そこで、 find で抽出した中からランダムに選んで feh に渡すようにしてみる。以下は ~/Pictures 下を再帰的に探索した中から、ランダムに壁紙を設定する(bash, zsh)。

$ feh --bg-fill "$(find -L ~/Pictures \( -name *.jpg -or -name *.jpeg -or -name *.png -or -name *.gif \) | sort -R | head -n 1)"

nitrogen も引数を与えればコマンドラインから壁紙設定できるので、以下のようにすれば同様になる。

$ nitrogen --set-zoom-fill --save "$(find -L ~/Pictures \( -name *.jpg -or -name *.jpeg -or -name *.png -or -name *.gif \) | sort -R | head -n 1)"

もっとも、 nitrogen にも --random というオプションがある。 nitrogen --set-zoom-fill --random ~/Picures などと指定する。

Revisions

  • [2017-03-25 Sat] Fix: スクリーンロックのソースコード( $altlMod1
  • [2017-10-10 Tue] 追記