Rofiでクールな軽量ミニマルランチャー

ポップアップウィンドウスイッチャー Rofi

Ubuntu Unity のランチャーはちょっとかっこいいけど、OS起動直後はガリガリ鳴って待たされたり、ちょっとモタっとする。マウスを使わずキーボードだけでいこうとするとイラっとするときがあるものだから、なにかかわりの軽快なヤツはないかなぁと彷徨ってみたら、 Rofi というのをみつけた。

Rofi : A window switcher, run dialog and dmenu replacement

rofi_customized_sample.jpg

Rofi は、シンプルなテキストメニューをそのつど絞り込みながら候補を選択するタイプのインターフェースで、 Unity Dash とか GNOME Do のような絞り込みができる。選択リストは稼働中のウィンドウやパスの通ったコマンドなどで、ウィンドウスイッチャーだけでなくアプリケーションランチャーの側面も併せ持つ。また、スクリプトモードを使うと独自にメニューを作成したりもできる。

rofi_customized_dashboard_2.jpg

そういう、テキストリストを扱う軽量でカスタマイザブルなものだから、ショートカットキーでポップアップさせるとかで軽快操作が手に入るのではなかろうかと私は目論んだ。それで、かように Rofi を使うことと簡便なカスタマイズ方法をメモにした。

試した環境はだいぶ安定してきた Ubuntu 16.04 LTS。

Rofi とは

Rofi はもともと superswitcher にインスパイアされたウィンドウスイッチャーのプロジェクトが名を変え機能を増やし、ということで出来上がってきたもののようだ。現在開発が活発に行われているもよう。

先述の通りウィンドウスイッチャーとも言えるしランチャーとも言えるが、単純なテキストリストから逐次絞り込みインターフェースを生成するものであり、カスタマイズ次第で独自のメニューを生成できるなど用途は広がる。私には percol の X 版のようにも思える(もっとも 公式 には UI Toolkit ではないとあるけれども)。

主な特徴は以下の通り。

  • 組み込み機能
    • ウィンドウスイッチャー
    • アプリケーションランチャー
    • デスクトップアプリケーションランチャー
    • SSHランチャー
    • COMBIモード(複数リストの組み合わせ)
  • 選択履歴の記憶(最近使ったものは上位に表示してくれるなど)
  • スクリプトモードで独自メニューが作成できる
  • dmenu 互換モード
  • キーバインディング、カラースキームなど細かいカスタマイズが可能
  • 絞り込み方には fuzzyマッチ、正規表現マッチ、グロブマッチが指定可能

Rofi はこだわらなければ設定などほとんどせずとも充分便利に働いてくれる。ちょっと物足りないと思うなら細かい指定(カスタマイズ)も可能だ。

Rofi のインストール

最新版とはちょっと仕様が違うかもしれないけれど Ubuntu では apt リポジトリからインストールできる。

sudo apt install rofi

Rofi の使い方

rofi コマンドは基本的に -modi オプションで扱いたいリストを指定し、 -show オプションでデフォルトを指定しつつ起動させる。 -modi にはカンマ区切りで複数を指定でき、切替キー(デフォルトでは Ctrl-Tab )で逐次切り替えられる。

また、特に ウィンドウスイッチャー( window )、アプリケーションランチャー( run )、SSHランチャー( ssh )の3つをそれぞれ使う場合は -modi オプションを省略できるようだ。

ウィンドウスイッチャー

いくつかアプリを起動した後で、端末エミュレータから以下のように Rofi を起動してみる。

rofi -show window

rofi_normal_window.jpg

プロンプトとコンソールスペースの下方に実行中のウィンドウ一覧が表示される。各行は左から、ワークスペース(デスクトップ)名、クラス名、タイトル。

コンソールに文字を打てばそれに従って候補が絞り込まれ、必要ならカーソルを上下に動かし Enter で選択(切り替え)、 ESC で中止してウィンドウを閉じる。

Rofi は文字を入力すると逐次絞り込むインターフェースなので、操作コマンドは Control などモディファイアキーとのコンビネーションが主体となる。デフォルトでは readline ライクなキーバインドだ。ちょっと挙げてみる。(デフォルト詳細は man 参照のこと)

操作キー 機能 他のキー
Ctrl-n / Ctrl-p 選択カーソルを 下 / 上 へ Down / Up
Ctrl-f / Ctrl-b コンソールカーソルを 右 / 左へ Right / Left
Ctrl-a / Ctrl-e コンソールカーソルを 行頭 / 行尻 へ  
Ctrl-Tab モードの切り替え Shift-Right
Enter 選択 Ctrl-m
Esc キャンセル  

なお、 -dump-xresources オプションで設定内容を全て出力してくれるので、 rofi.kb* で絞れば設定されてあるキーバインディングを確認できる。

rofi -dump-xresources|grep "rofi.kb"

-show window では全ての仮想デスクトップ(ワークスペース)からウィンドウリストをもってきてくれるけれど、別に WindowCD というのがあり、これはカレントデスクトップのみの一覧となる。

rofi -modi windowcd -show windowcd

アプリケーションランチャー

以下のように起動するとアプリケーションランチャーとして利用できる。

rofi -show run

rofi_normal_run.jpg

Enter でアプリを起動するが、 Shift-Enter を使うと端末エミュレータを開いてその上で実行してくれる。コマンドにオプションをつけて実行したいときは Ctrl-Enter を使う。

操作キー 機能 他のキー
Enter 実行 Ctrl-m
Shift-Enter 端末で実行  
Ctrl-Enter コマンドライン実行  
Ctrl-Space コマンドラインへアイテムをコピー  
Esc キャンセル  

Ctrl-Enter の使い方としては、ある程度文字を打って目的のコマンドが出てきたらそれを Ctrl-Space でコンソールにコピーし、オプションを付け加えて Ctrl-Enter とするとスマート。

Shift-Enter では rofi-sensible-terminal がシステムにインストールされてある端末エミュレータを選ぶ(詳細は man rofi-sensible-terminal)が、環境変数 $TERMINAL を設定するか -terminal オプションと共にコマンド名を与えるかすることで意図的な指定も可能。

また、 -show run はパス上の実行ファイルを扱うが、別に DRun (Desktop Run)というのがある。これはデスクトップエントリからリストを生成するもので、 Unity Dash の アプリ Lens みたいな感じになる。

rofi -modi drun -show drun

コマンドの内容が判別しやすいので、DRunの方が扱いやすい場合が多いかも知れない。なお、DRunでも Ctrl-Enter の機能は使える(DRunアイテムにオプション追記して使えるということではないが、自分で正しくコマンドラインを入力すればそれを Ctrl-Enter で実行できる)。

SSHランチャー

SSHランチャーは ~/.ssh/config に記述のある接続先へ接続する端末を起動してくれる。

rofi -show ssh

使われる端末エミュレータは run モードの Shift-Enter と同様のもの。

デフォルトでは端末へ -e オプションで ssh コマンドが渡されるが、 -ssh-client オプションでコマンドを指定することもできる。 sshrc を使いたいんだなどというときでもこれで対応できる。

rofi -show ssh -ssh-client sshrc

COMBI モード

以下のように起動すると、リストの内容がウィンドウスイッチャーとアプリケーションランチャーのコンビネーションになって、 anything みたいなインターフェースになる(それは言い過ぎか)。

rofi -modi combi -show combi

rofi_normal_combi.jpg

COMBIモードのデフォルトコンビネーションは windowrun の組み合わせだが、 -combi-modi オプションで組み合わせを変えることができる。例えば以下のようにするとウィンドウスイッチャー、デスクトップアプリケーションランチャー、SSHランチャーをミックスできる。

rofi -modi combi -show combi -combi-modi window,drun,ssh

Rofi でメニューを作る

Rofi にはウィンドウスイッチャーやアプリケーションランチャーのようなビルトインのモードだけでなしに、ユーザーが独自にメニューを作成することのできる dmenu 互換モードと script モードがある。

dmenu モードはその名の通りテキストメニューアプリの dmenu を模したもので、標準入力からメニューを作って選択内容を出力へ渡す、というシンプルなものだ。ワンライナーでちょちょっとやればメニューを生成できてしまう手軽さがいい。

script モードは指定するスクリプトを、組み込み機能と共にモード選択できるようになる。Rofi 本来の構成上でメニューを実装できる。

dmenuモード

dmenu というのは、もともと dwm という非常にシンプル(最小主義と言われるほどに)なタイル型ウィンドウマネージャに付随していたテキストメニューアプリだ(付属のシェルスクリプトを介して起動するとアプリケーションランチャーとしても使える)。

標準入力から受け取ったテキストでメニューを構成し、ユーザが選択したものを標準出力へ渡すという単純な仕様である。その姿は実行すると画面最上端の一行のみに現れ、キー入力で逐次絞り込みながら選択するというものだ。

これが非常に軽くて扱いやすくて便利なことから、他の様々なウィンドウマネージャでも多く利用されている。

Rofi の dmenu モードはこれを互換的に実装したもので、Rofiのカスタマイザブルなヴィジュアル上でとても簡単にメニューを生成できる。

使い方は簡単で、 -dmenu オプションを付けたところへセパレータとなる改行文字 \n を含んだテキストを、パイプで渡してやればいい。

echo -e "foo\nbar\nbaz" | rofi -dmenu

この例では foobarbaz でメニューを構成し、そこで選んだものを出力に渡してくる( echo-e オプションはバックスラッシュエスケープを有効にするので、改行文字が認識されるようになる)。

dmenuモードでメニューを作る

コマンドメニューとして一番単純なものは、コマンドラインをメニューで選択して返ってきたものをそのまま評価(実行)するというものだろう。

eval "$(echo "gnome-screensaver-command -l|gnome-session-quit --force|systemctl shutdown" | rofi -dmenu -sep "|")"

-sep オプションを使うと区切り文字を指定できる。

rofi_normal_dmenu.jpg

上記は最近の Ubuntu (systemd、gnome)にあわせたメニューで、上からキーボードロック、ログアウト、シャットダウンとなる。

しかし “gnome-ナントカ” とか表示されてもわかりにくいだろうから、もうちょっとメニューっぽくしようとスクリプトファイルにした(メニューもちょっと増やした)。

#!/bin/bash
# rofi_system_dmenu.sh / JennyM 2017 malkalech.com

list=(
  ##  Lock  ##
  "Lock Screen"  "gnome-screensaver-command -l"
  "Logout"       "gnome-session-quit --force"
  ##  Power ##
  "Reboot"       "systemctl reboot"
  "Suspend"      "systemctl suspend"
  "Shutdown"     "systemctl poweroff"
)

if selected="$(for (( i=0; i<=$((${#list[@]}/2-1)); i++ )) { echo "${list[($i+1)*2-2]}"; } | rofi -dmenu -i -format i)"; then
  [[ "$selected" -ge 0 ]] && eval "${list[($selected+1)*2-1]}"
fi

下のほうがごちゃっとしたけど、メニューを書き換えやすいように工夫したつもりなんである。

配列変数 list の値を書き換えればメニューの内容を変更できる。左列(奇数番目配列)が見出し、右列(偶数番目配列)が実際に実行されるコマンドライン。各々クォートで囲むようにする。行数は問わない。

例えば表示されたメニューの “Lock Screen” を選択すると “gnome-screensaver-command -l” というコマンドが実行される。

適当な名前で保存して実行属性つけて実行してみれば以下のように。

rofi_customized_dmenu.jpg

scriptモードで電卓

scriptモードを使うと、ウィンドウスイッチャーやアプリケーションランチャーといった組み込み機能以外の機能を追加できる。

その一例として「電卓モード」を付加してみる。

GTK+版の電卓に Qalculate! という便利で多機能なやつがあるけど、これの CLI版 として Qalc というコマンドライン電卓がある。これが Rofi の scriptモードで利用できる。

まずはとにかく Qalc をインストールする。

sudo apt install qalc

エクスチェンジレートのアップデートが必要になることがあるので、一度 qalc コマンドを実行して問いかけに答えておく。

$ qalc
You need the download exchange rates to be able to convert between different currencies.
You can later get current exchange rates with the "exchange rates" command.
Do you want to fetch exchange rates now from the Internet (default yes)?

ちょちょっと使ってみる。

> 1/42

  1 / 42 = approx. 0.023809524

> 23 USD to JPY

  23 * dollar = approx. JPY 2595.5248

なかなか便利なのであるが、お題とは違うからこれくらいに。

さて、これを Rofi で使う場合には以下のように -modi オプションでラベルとコマンドを指定してやる。ラベルなんかなんだっていいけど平凡に calc としてみた。

rofi -modi calc:qalc -show calc

rofi_normal_script_qalc.jpg

式を入力して Enter で解が得られ、次の入力待ちになる。

ぶっちゃけ端末でやれることかもしれないんだけど、キーひとつで起動できるようにしておけるんなら、暗算するほど頭が回らないとか、外貨レートがちょっと気になるんだとか、そういうちょっとしたニーズに応える便利さはある。

scriptモードでメニューを作る

dmenu モードのところで作ったメニューを script モード用に作りなおしてみた。

#!/bin/bash
# rofi_system_menu.sh / JennyM 2017 malkalech.com

list=(
  ##  Lock  ##
  "Lock Screen" "gnome-screensaver-command -l"
  "Logout"      "gnome-session-quit --force"
  ##  Power ##
  "Reboot"      "systemctl reboot"
  "Suspend"     "systemctl suspend"
  "Shutdown"    "systemctl poweroff"
)

for (( i=1; i<=$((${#list[@]}/2)); i++ )); do
  [[ -z "$@" ]] && echo "${i}. ${list[$i*2-2]}" && continue
  [[ "$@" == "${i}. ${list[$i*2-2]}" ]] && command="${list[$i*2-1]}" && break
done
eval "${command:-:}"

メニュー項目をユニークに扱うのに、 dmenu モードでは要素番号を得るオプションが使えた。けれど script モードでは難しくていい方法が思いつかず、見出しの頭に数字を打って識別させるようにしてしまった。

これを ~/bin/rofi_system_menu.sh などとして保存し、実行属性をつけてやる。

chmod +x ~/bin/rofi_system_menu.sh

そして Qalc の時と同じように指定して Rofi を起動すると、メニューが出来上がる。

rofi -modi system:rofi_system_menu.sh -show system

Ubuntu は ~/bin を作成するとパスが通るようになっていると思うが、パスが通っていない場合は system:$HOME/bin/rofi_system_menu.sh というようにフルパス指定してやる。

Rofi でダッシュボードみたいなやつをつくってみる

ダッシュボードっていうか、ようするにメニューとランチャーとスイッチャーを簡単にまとめたようなやつ。カラースキームやキーバインディングズも気にしつつやってみる。

モード切り替えとサイドバー

さて、上でやったスクリプトモードと他のモードを同時に指定してみたいが、ここで -sidebar-mode というオプションを使ってみる。これは切り替えられるモードのインジケータをウィンドウの下端に表示してくれる。切り替えモードが多いときは何が使えるのか見えた方がありがたいかと思う。

rofi -modi combi,system:rofi_system_menu.sh,calc:qalc,run,ssh -combi-modi window,drun -show combi -sidebar-mode

rofi_customized_script.jpg

上記では、切り替え可能モードは COMBI、システムメニュー(上でやった ~/bin/rofi_system_menu.sh )、電卓(Qalc)、アプリケーションランチャー(Run)、SSHランチャーで、 COMBIモードはウィンドウスイッチャーとデスクトップアプリケーションランチャーの組み合わせ、としている。

デスクトップアプリケーションランチャー(DRun)は使い勝手がいいけれど、パスをトレースしてくれるアプリケーションランチャー(Run)の方が都合がいいこともある。例えば自前のスクリプトをパスの通った ~/bin とかに入れておくだけだと DRun で扱えないけど、 Run なら選択対象にできるわけだ。そういうことで Run を付け加えてある。

荒削りなんだけど、これで大抵の操作ができるものになったかと思う。

設定を起動スクリプトにする

先ほどの一行を元に、設定に手を入れて整えていく。

Rofi の設定は ~/.Xresources (または ~/.Xdefaults)に書いてリソース設定するか、あるいは ~/.config/rofi/config にリソース設定書式で書くという方法があるけれど、起動オプションで一気に指定してもいい。それでここでは起動オプションを簡単なスクリプトファイルにまとめるようにした。

#!/bin/bash
# rofi_launch.sh / JennyM 2016 malkalech.com

alpha="cc"   # opacity (00〜FF)

options=(
  -modi            "combi,system:rofi_system_menu.sh,calc:qalc,run,ssh"
  -combi-modi      "window,drun"
  -show            "combi"
  -font            "Ubuntu 28"
  -width           "100"
  -padding         "80"
  -lines           "8"
  -fixed-num-lines
  -hide-scrollbar
  -sidebar-mode

  ##  key bindings  ##
  -kb-cancel        "Escape,Control+g,Control+bracketleft,Control+c"
  -kb-mode-next     "Shift+Right,Control+i,Control+Tab"
  -kb-mode-previous "Shift+Left,Control+Shift+i"

  #### color scheme
  -color-enabled   "true"
  ## window         bg                   border               separator
  -color-window    "argb:${alpha}040404, argb:${alpha}040404, argb:${alpha}458588"
  ## text & cursor  bg             fg                   bg (alt)       bg (highlight)       fg (highlight)
  -color-normal    "argb:00000000, argb:${alpha}458588, argb:00000000, argb:${alpha}076678, argb:${alpha}83a598"
  -color-active    "argb:00000000, argb:${alpha}689d6a, argb:00000000, argb:${alpha}427b58, argb:${alpha}8ec07c"
  -color-urgent    "argb:00000000, argb:${alpha}b16286, argb:00000000, argb:${alpha}8f3f71, argb:${alpha}d3869b"
)

rofi "$@" "${options[@]}"

オプションの概要を以下に示す。

  • -modi : 切り替え可能モード、複数指定可。モード切替キーを押す毎に指定の順で切り替わる。指定可能なものは以下の通り。
    • window : ウィンドウスイッチャー
    • windowcd : ウィンドウスイッチャー(カレントワークスペースのウィンドウみ)
    • run : アプリケーションランチャー
    • drun : デスクトップアプリケーションランチャー
    • ssh : SSHランチャー。 .ssh/config に記述のあるssh接続先一覧
    • combi : COMBIモード。 -combi-modi オプションで設定したモード
    • scriptモード。<ラベル>:<コマンド> というように指定する。
  • -combi-modi : COMBIモードで一緒くたに表示させるモードを指定する。
  • -show : 最初に表示するモード。例えば -show run とすると最初にアプリランチャーを表示する。
  • -font : フォントはとりあえずディストロにあわせて Ubuntu を指定しているのだけれど、色々と試してみるべきかと。細身なプロポーショナル書体を大きめのポイントで指定するとかっこいいだろうし、あえてモノスペース系っていうのもクール(親指)。
  • -width : ウィンドウの幅。数字が、100以下は左右幅のパーセンテージ、100超はピクセル数、0未満(マイナス)の場合はキャラクター桁数を示す。
  • -padding : ウィンドウ内のマージンピクセル数。
  • -lines : プロンプトを除いた表示行数。
  • -fixed-num-lines : 表示行数をモード問わず固定する。ピョコピョコしなくていい。
  • -hide-scrollbar : スクロールバーを表示しない。
  • -sidebar-mode : モードインジケータを表示する。
  • -kb* : キーバインディング。Emacsライクに C-g でもキャンセルできるとありがたい。ついでなので Vimライクに C-[C-c にも。またモード切り替えを C-i にもあてた。 C-I で逆順。
  • -color* : カラースキーム。 ここ にいくつかテーマがあるうえ Theme generator というのもあるので参考に。ここでは gruvbox のパレットから適当に(青っぽく)選んだ。なお、透過率の指定は -opacity オプションがなくなった(?)ようなので、 ARGB値でカラーごと指定する(上記スクリプトでは変数 $alpha の値で不透明度を設定している)。

ほかにも細かく色々な指定が可能だ。 man rofiROFI 1 rofi )を参照されたし。

このスクリプトを ~/bin/rofi_launch.sh に保存して実行属性をつけて、実行してみる。

chmod +x ~/bin/rofi_launch.sh
rofi_launch.sh

rofi_customized_dashboard_1.jpg

C-i でモードを切り替え。

rofi_customized_dashboard_2.jpg

オプションを優先してとるようにしてあるので例えば、

rofi_launch.sh -show run

とすれば最初にアプリケーションランチャー(Run)を表示してくれる。

ショートカットキーを設ける

Ubuntu 16.04 のリポジトリで供されている Rofi バージョン 0.15 にはデーモンモードが存在し、常駐してショートカットキーを受け付けるのだが、その後のバージョンでデーモンモードは廃止された。理由があってのことのようだからここではそれを使わず、デスクトップ環境の機能を使うようにしたい。

無印 Ubuntu は [システム設定] からキーボード・ショートカットの設定が可能。

右上のまあるいスイッチから [システム設定] – [キーボード] – [ショートカット] とたどって、左の一覧から [独自のショートカット] を選んで [+] で追加。名前: Rofi 、 コマンド: ~/bin/rofi_launch.sh と設定。

rofi_shortcutkeydialog.jpg

次に、表の右列の [無効] をクリックして登録したいショートカットキーを押す。

押しやすいキーに設ければより素早くポップアップできるであろう。ちなみに私はちょうどあいている C-; でRofiがポップアップするように設定してみた。

これで、設定したショートカットキーを押すと Rofi のウィンドウがポップアップする。

その他

Ubuntu 16.04 (Xenial Xerus) の APTリポジトリには Rofi のバージョン 0.15.11 が登録されてあるが、その後に何度かのバージョンアップが行われ、現在( [2017-05-15 Mon] )のステーブルは 1.3.1 となっている。Ubuntu に限って言えば 16.10 Yakkety には 1.2 が、 17.04 Zesty には 1.3 が登録されてあるもよう。

ここでは現在の最新 LTS である 16.04 Xenial に合わせて Rofi 0.15.11 を取り上げてある。プリリリースのような番号だけれど、きちんと機能して十分な活躍を果たしてくれる。

けれど、やはりその後のリリースでは仕様を違えるところもあり、そのひとつにデーモンモードの廃止がある。デーモンモードは常駐してショートカットキーを受け付けたり高速起動することを狙ったもののようであった。

廃止の理由としては、デーモンが増えることのメモリ運用に与える影響を踏まえ、グローバル・キーバインディングはウィンドウマネージャ(あるいはデスクトップ環境)寄りの仕事であり、もしやるにしてもそれ専門のデーモンに任せるべきであろうこと、そして Rofi は常駐せずとも充分高速に起動することなどが挙げられていたようだ。

ひとつのことをうまくやるもの達の組み合わせをこそ、快挙をもたらす仕様たらしめんとする。しからば、上のことは歓迎できるかと思う。

メジャーなデスクトップ環境はみな便利で、キーボード・ショートカットを追加する手だてだって用意されていることが多い。まずはそういうのを利用するべきなんであろう。あるいは xbindkeys などに任せるということだろう。AutoKey というのもあったがどうなっているだろうか。

ところで、現在開発が進められている Version 1.4 ではテーマをCSSライクな書式で設定できるようになるらしい。CSSとなればより細かい制御が可能になるし、装飾要素も一気に増えることだろう。これは楽しみ。

Sources and Revisions

Sources

Revisions

  • [2016-07-20 Wed] スクリプトファイル名に拡張子
  • [2017-04-21 Fri] スクリプト改訂(透明化指定方法や色あい変更)
  • [2017-05-05 Fri] 加筆、スクリプト改訂と追加
  • [2017-05-08 Mon] スクリプト改訂
  • [2017-05-19 Fri] 結びを追記、スクリプト改訂

コメント

  1. […] dmenuはi3標準指定のメニューソフト。rofi は便利なウィンドウスイッチャーでdmenuのかわりとしても使える。comptonはウィンドウの透過と影を生成する(タイリングでも透過は必要と思うときに)。lxappearanceは軽量のテーマスイッチャー。 […]

  2. […] 参考サイト – Arch Wiki (Rofi) – Rofiでクールな軽量ミニマルランチャー – […]