Ubuntu Weekly Recipe

第494回GNOME Shellの拡張機能を「シェルスクリプト」作ってみよう

第492回ではGNOME Shellの拡張機能がJavaScriptとCSSで構成されていることを紹介しました。今回は拡張機能を「シェルスクリプト」で作成できるフレームワーク「Argos」を紹介します。

JavaScriptは人類には難しすぎる

GNOME Shellに搭載されている、JavaScriptやCSSを用いてコンパイルすることなくUIをカスタマイズできる機能は非常に便利です。しかしながらJavaScriptはその真の挙動を人類が理解するには難しい言語です[1]⁠。もう少しわかりやすい言語で書けないものでしょうか[2]⁠。

特にGNOME Shellの拡張機能はJavaScriptとCSSだけでなく、Shell ToolkitやTweenerといったあまりドキュメントが充実していないライブラリーも使う必要があるため、余計に難しく感じてしまいます。インジケーターにちょっとしたデータを表示したいだけなのに。

ArgosはそんなJavaScript恐怖症の利用者に向けた、GNOME Shell用インジケーター開発フレームワークです。好みのプログラミング言語を用いて「表示したいものを標準出力に出力する」だけで、任意のデータをインジケーター上に表示できます。対応しているのはインジケーターの拡張だけです。

ArgosはmacOSのメニューバーをカスタマイズするBitBarと完全に互換性があることを謳っています。つまりBitBar向けのスクリプトであれば、UbuntuのGNOME Shell上でもそのまま動くということです。ただし当然のことながら、そのBitBarスクリプトが依存するものは一通りUbuntu上に存在している必要はあります。

まとめるとArgosを使えばシェルスクリプトを使って任意の情報をインジケーターに表示できるということです。

Argosのインストール

ArgosそのものはGNOME Shellの拡張機能です。よってまずはArgosをインストールしましょう。方法はいくつかありますが、拡張機能のページからインストールするか、GitHubからクローンしてコピーするかの2択でしょう。今回は後者を利用します。

$ git clone https://github.com/p-e-w/argos.git
$ mkdir -p ~/.local/share/gnome-shell/extensions/
$ cp -a argos/[email protected]/ ~/.local/share/gnome-shell/extensions/

あとは前回と同様にgnome-shell-extension-prefsを起動して、Argosをオンにします。さらにログインし直すと、拡張機能がロードされて次のような画面がインジケーターに表示されるはずです。

図1 初期状態のArgos
画像
図2 クリックするとドロップダウンメニューが表示される
画像

インジケーターの「Argos」をクリックするとドロップダウンメニューが表示されます。メニューとして備わっているのは次の3つです。

  • Argosのサイトへのリンク
  • インジケーターメニューのスクリプト用ディレクトリ~/.config/argos/へのリンク
  • インジケーターメニューのスクリプトファイル~/.config/argos/argos.shへのリンク

これらはすべて~/.config/argos/argos.shのみで実現しています。

インジケータースクリプトの追加方法

Argosは~/.config/argos/以下のスクリプトを実行し、その標準出力の内容をパースしてインジケーター領域に表示しています。つまり新規にインジケーターに何かを表示したい場合は、スクリプトを~/.config/argos/に追加することになります。

まずは標準でインストールされる、argos.shの中身について見てみましょう[3]⁠。

#!/usr/bin/env bash

URL="github.com/p-e-w/argos"
DIR=$(dirname "$0")

echo "Argos"
echo "---"
echo "$URL | iconName=help-faq-symbolic href='https://$URL'"
echo "$DIR | iconName=folder-symbolic href='file://$DIR'"

非常にシンプルなスクリプトですね。このスクリプトが実行されると以下のような出力が得られます。

Argos
---
github.com/p-e-w/argos | iconName=help-faq-symbolic href='https://github.com/p-e-w/argos'"
/home/shibata/.config/argos | iconName=folder-symbolic href='file:///home/shibata/.config/argos'"

この出力結果がArgos本体に渡されて、インジケーター上のUIとして構築されます。標準出力の結果は次のようなフォーマットであることが期待されています。

インジケーターのタイトル部分(トップパネルに表示される部分)
---
ドロップダウンメニューの項目
ドロップダウンメニューの項目
ドロップダウンメニューの項目
ドロップダウンメニューの項目

各タイトルや項目をカスタマイズしたい場合は、パイプ記号|の後ろにプロパティを設定します。

echo "$URL | iconName=help-faq-symbolic href='https://$URL'"

たとえば上記の例の場合アイコン名がhelp-faq-symbolicになっていますので、/usr/share/icons/Adwaita/scalable/apps/help-faq-symbolic.svgがアイコンとして使われます。さらにhrefプロパティにURIを指定することでクリックしたときにそのアドレスのコンテンツが表示されることになるのです。非常に簡単ですね。

インジケータースクリプトのファイル名

ファイル名にも意味があり、次のようなフォーマットになっています。

NAME.POSITION.INTERVAL.EXTENSION

NAMEはスクリプト名です。NAMEの先頭が.(ピリオド⁠⁠」だった場合、そのスクリプトは無視されます。

POSITIONはインジケーターを表示するトップパネル上の位置です。l(左⁠c(中央⁠r(右⁠⁠」のいずれかひとつを選択できます。Ubuntu 17.10の標準のテーマだと、⁠アクティビティ」と表示されている部分が左に、曜日と時刻が表示されている部分が中央に、各種ステータスアイコンが並んでいる部分が右に該当します。10rのように各文字の手前に数字を置くことで、同じ位置を示すもの同士の表示順を指定できます。省略した場合は、右に置きます。

INTERVALはスクリプトの実行周期です。数字とs(秒⁠m(分⁠h(時⁠d(日⁠⁠」のいずれかの組み合わせです。ArgosはINTERVALで指定された周期ごとにスクリプトを再実行するため、定期的に情報を取得するタイプのインジケーターは、INTERVALをファイル名に入れる必要があります。省略されると再実行されません。

EXTENSIONはスクリプトの拡張子です。拡張子の付け方に制約はありませんが、設定しておかないとPOSISIONやINTERVALを正しく処理できませんので注意してください。

以下にいくつかの例をあげましょう。

  • foo.sh:起動時に一度だけ実行され、トップパネルの右端に表示
  • foo.c.sh:起動時に一度だけ実行され、トップパネルの中央に表示
  • foo.1s.sh:1秒ごとに実行され、トップパネルの右端に表示
  • foo.10l.10m.sh:10分ごとに実行され、トップパネルの左端に表示9l11lがあればその間に表示される)
  • foo.2r..sh:起動時に一度だけ実行され、トップパネルの右端に表示1r3rがあればその間に表示される)

POSITIONのみを省略することやPOSIITONとINTERVALの両方を省略することは可能です。INTERVALのみ省略したい場合は最後の例のようにピリオドを並べる必要があります。

トップパネルを流れる🍣

せっかくなので寿司をトップパネルに流してみましょう[4]⁠。

Unicode上に絵文字がマップされているため、インジケーター上に絵文字を表示することは簡単です。最近のUbuntuには絵文字フォントも最初からインストールされており、追加でパッケージをインストールする必要もありません。ただし17.10では、カラー絵文字には未対応なので流すとなるとモノクロの寿司になります。

残念ながらトップパネル上の任意の位置にインジケーターを置くことはできません。左・中央・右というカテゴリーの違いはあるものの、いずれも「詰めて」表示されます。そこで泥臭いですが、空白文字を左右に挿入することで位置調整を行うことにしましょう。

具体的なコードは以下のとおりです。これを~/.config/argos/sushi.r.1s.shとして保存します。また実行権限もつけておいてください。

#!/usr/bin/env bash

WIDTH=27
PAD="$(($(date +%s)%$WIDTH))"
echo -n ":sushi:"
if [ "$PAD" != "0" ]; then
    printf ' %.0s' `eval echo {1..$PAD}`
fi
echo " | trim=false"

ポイントは4つです。

  • インジケーターの最大幅の指定
  • 時刻を利用した寿司の位置の指定
  • trim=falseによる空白文字の扱い
  • emojilibを利用した「🍣」の表示

まずインジケーターの最大幅をWIDTHで設定しています。要するにトップパネル右側の空き領域分の全角文字幅だと考えてください。当然環境によって異なります[5]⁠。さらにdateコマンドで現在の時刻を秒単位で取得し、WIDTHの値で割った剰余で寿司の位置を決めます。といっても単に寿司文字の後ろに剰余の分だけ全角空白を入れているだけです。

Argosのインジケーターのラベルは、そのままだと前後の空白をトリミングしてしまいます。よってプロパティにtrim=falseを設定してトリミングを無効化しています。

さらにArgosはemojilibを取り込んでいます。よって「:label:」で絵文字を指定可能です。もちろんシェルスクリプト内部に直接絵文字を書いてしまってもかまいません。ちなみにPango Markupによる文字の装飾(太字化や色付けなど)も可能です。

Argosは基本的に行頭・行末の空白は無視します。しかしながらプロパティにtrim=falseを設定することでこの挙動を回避できます。

図3 デスクトップを流れる寿司
画像

デスクトップにもシェル芸を

ここまで紹介したように、Argosは標準出力に適切な文字列を出力するスクリプトを用意することでインジケーター領域をカスタマイズできるツールです。

macOSのBitBarとも互換性が確保されているため、たとえばTwitterのツイートをPythonを使って表示したりRSSによる更新通知をPHPでリストアップしたりGitHubのステータスをJavaScriptで取得するようなBitBar用スクリプトをそのまま利用できます。

もちろんすべてシェルスクリプトだけで構築することも可能でしょう。つまり読者の皆様のほとばしるシェル愛をGNOME Shellに全力でぶつけられるわけです。ちなみにArgosのインターフェースは標準出力なので、シェル以外でも問題ありません。たとえばArgosとNode.jsと組み合わせたらJavaScriptでもGNOME Shellの拡張機能を作成できますね!

おすすめ記事

記事・ニュース一覧