読者です 読者をやめる 読者になる 読者になる

LinuxでMacのTotalTerminalもどきを作ってみた

Macには,任意に決めたショートカットキーでターミナルを出したり隠したりできるTotalTerminal(少し前まではVisorという名前だった)というアプリがあります.
TotalTerminal is a system-wide terminal accessible via a hot-key
これがすごく便利で普段Macで使用しています.ちょっとターミナルを出したくなったときにすぐ出すことができて,その中にVimを起動しておいたりするとさらに便利に使えます.
このTotalTerminalが研究室のDebian機でも使いたくなりました.
実はすでにあるのですが,
404 Not Found
これだと

  • ターミナルを隠したときに下のウィンドウにフォーカスが当たらない
  • 別窓でターミナルを実行すると処理の対象がそっちに移ってしまう

といった問題があり,実用に耐えなかったので自作しました.

まず,xdotoolとwmctrlをインストールします.DebianUbuntuならリポジトリにあるので,パッケージマネージャを使って

# apt-get install xdotool

とかすれば入るはずです.
これらはコマンドラインでXの処理(マウスの入力やウィンドウの移動・リサイズなど)を呼び出すツールです.

次に下記のスクリプトを適当なファイル名(例えばTotalTerminalとか)として/usr/local/binあたりに保存し,実行可能権限を付けておきます.

#!/bin/sh

CID_MEMO="${HOME}/.my-visor-cid"
WID_MEMO="${HOME}/.my-visor-wid"
TOTAL_TERMINAL="/usr/bin/gnome-terminal --geometry=212x35+0+0 --title=TotalTerminal --full-screen"

SAVED_WID=`cat $WID_MEMO`
TERM_WID=`xdotool search --class gnome-terminal | grep $SAVED_WID`

if [ -n "${TERM_WID}" ]; then
	# if target terminal exists

	WID=$SAVED_WID

	if [ `xdotool getactivewindow` = "$WID" ]; then
		# if TotalTerminal is active
		xdotool windowunmap $WID
		xdotool windowactivate `cat $CID_MEMO`
	else
		# if TotalTerminal is NOT active
		xdotool getactivewindow > $CID_MEMO
		xdotool windowmap $WID
		xdotool windowactivate $WID
	fi

else
	# if gnome-terminal hasn't been launched

	if ! [ -f "$WID_MEMO" ]; then
		touch $WID_MEMO
	fi

	if ! [ -f "$CID_MEMO" ]; then
		touch $CID_MEMO
	fi

	# clear window id
	echo > $WID
	xdotool getactivewindow > $CID_MEMO

	# start gnome-terminal
	$TOTAL_TERMINAL &
	sleep 1
	WID=`xdotool search --class gnome-terminal | head -1`
	echo $WID > $WID_MEMO
	xdotool windowactivate $WID
fi

あとはこのスクリプトを実行すれば

  • ターミナルが立ち上がっていないときは自動的に立ち上げる
  • ターミナルが表示されているときは隠す
  • ターミナルが表示されていないときは最前面にフルスクリーン表示する

という処理を行います.
ウィンドウIDで対象のターミナルを管理するので,別窓で新たにターミナルを開いても期待通り動作します.
初実行時にすでにターミナルが立ち上がっているときは動作がおかしくなりますので,PC起動時に実行するプログラムのリストに上記スクリプトを入れておくことをおすすめします.

また,MacのTotalTerminalのようにショートカットキーに関連付けておくと非常に便利です.僕の場合はウィンドウデコレータにcompizを使っているので,CompizConfigSettingManager ( ccsm )を用いてAlt+Enterが押されると上記のスクリプトが実行されるように設定しています.

なお,初回起動時にターミナルを最初から隠したい場合は一番最後のfiの手前にxdotool windowunmap $WIDなどと書いておけば良いです.あと,ターミナルがフルスクリーンで表示されるのが嫌な場合は,最初あたりにある--full-screenオプションの指定を削除し,代わりに適切なサイズを指定することにより改善できます.また,gnome-terminal以外のターミナルを用いている場合は変数$TOTAL_TERMINALの中身を適宜書き換えてください.

ちなみに,ターミナルを出す直前のフォーカスが当たっているウィンドウと対象とするターミナルのウィンドウIDをファイルで管理しているので,homeに隠しファイルが増えるのが嫌な場合はパスを適宜書き換えてください.
ここは後で時間があれば環境変数を使ってやる方法に書き換えるかもしれません.

これでターミナルを使いたいと思ったときにはショートカットキーでいつでも呼び出せる環境が整いました.

※10/21にバグ修正
※12/22にwmctrlが不要になるように改善