dmenuをいじって使いやすくする
実験レポート風に書こうとして途中で面倒になったので文章の構成が変になったかもしれない。
概要
dmenuはX上で動作するコマンドタイプのランチャである。元々はdwmのために開発されたものだが、他のウィンドウマネージャと合わせて使うことも可能。普通に使うとパスの通っている全てのコマンドが辞書順でメニューに表示されるが、膨大な量になる上、実際にランチャから起動したいものはその中のごく一部である。1そこで、ランチャから起動して使いたいコマンドだけを表示することができないか試したらできてしまった。
dmenuの動作
dmenu単体では完全なランチャとしては動作せず、2つのシェルスクリプトdmenu_runとdmenu_pathの補助により、ランチャとして動作する。
dmenu - 標準入力から行区切りの文字列を入力し、それらを要素とするメニューを表示して、選択されたものを標準出力に出力する
dmenu_run - dmenu_pathによって得られたプログラム一覧を使ってdmenuを起動し、選択されたプログラムの起動を行う
dmenu_path - パスの通っている全てのプログラムを列挙し、行区切りで出力する。出力は~/.dmenu_cacheにキャッシュする
以下にdmenuの動作概念図を示す。
やったこと
おもむろにdmenu_runを眺める。
cat `which dmenu_run`
- やっていることは非常にあっさりしていた。これはいける、と確信を得る。 行番号表示/非表示切替
1 #!/bin/sh 2 exe=`dmenu_path | dmenu ${1+"$@"}` && exec $exe
$@にはdwmから与えられるフォントや色の情報が入っており、dmenuはこれらを引数として受けとることでdwmのバーと同じ見た目を実現する
dmenuは何かが選択されたときに0を返すので&&でつないでいる
今回は自分の使いたいコマンドだけをメニューに出したいので、dmenu_pathは使わない。改行区切りであれば何でもいいので、とりあえず~/.dmenu_listという名前で一覧を書いて保存しておく。
firefox thunderbird libreoffice xlock nitrogen
- 最後に空行があるとメニューに空のエントリが出てしまうので空行は入れない
- それぞれのエントリはそれだけでコマンドとして実行できる(パスが通っている)必要がある
- 今回はやらなかったが、多分この辺は何とでもなる。少し余分にスクリプトを書けば、例えば短い名前とフルパスの表を作っておいてあれこれすることもできるだろう
あとは~/.dmenu_listをdmenuの標準入力に投げ込めば良いので、スクリプトをでっち上げる。ファイルは~/bin/dmenu_personalとした。
行番号表示/非表示切替1 #!/bin/sh 2 exe=$(dmenu < $HOME/.dmenu_list) && exec $exe
ちなみに-lオプションでメニューを複数行表示(行数は-lの後で与える)に、-bで下にメニューを表示するようにできる。これら二つは併用できない。
- とりあえず、単体で問題なく動作することを確認
dmenu_personal
dwmのconfig.hを書き換える
< static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; --- > static const char *dmenucmd[] = { "/home/clear/bin/dmenu_personal", "NULL" };
- フォントや色はdwm側でなく、dmenu_personalの方で引数を与えて設定することにした。変更時再コンパイルする必要がなくなる
- ランチャが使えるようになったのでショートカットキーを大幅削減
dwmをmake、動作確認
- 動いた
まとめ
今回のようなことができたのはひとえにdmenuの設計のおかげ。いい感じに機能を分割してあるおかげで柔軟性が高い。
特に、コンソール上で動作するものはdmenuから起動する意味が無い (1)