Ubuntu Weekly Recipe

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

この記事を読むのに必要な時間:およそ 4 分

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

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

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⁠。

※4
気持ち的にはからあげを流したいところでしたが絵文字にからあげはなく,U+1F357をからあげと呼ぶことはポリティカル・コレクトネス的にまずいだろうという判断が働いた結果,寿司になりました。人によってはビールを流すのもいいかもしれません(※未成年の飲酒は法律で禁止されていますが絵文字を使うことは禁止されていません⁠⁠。

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の値で割った剰余で寿司の位置を決めます。といっても単に寿司文字の後ろに剰余の分だけ全角空白を入れているだけです。

※5
本来は幅を取得して環境に応じて自動的に変更する実装が理想です。残念ながらBashを使ってこれを取得する術を思いつかなかったので,ハードコーディングしています。もちろんJavaScriptで拡張機能を作るのであれば,imports.ui.main.panel._leftBox.get_size()などで取得した現在の幅から空き領域を計算できることでしょう。特にトップパネルの左側は,フロントに表示されているアプリケーションによって幅が変わることが多いので,今回のような他のインジケーターのサイズに依存する拡張機能を作るならひと手間必要になります。

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の拡張機能を作成できますね!

著者プロフィール

柴田充也(しばたみつや)

Ubuntu Japanese Team Member株式会社 創夢所属。数年前にLaunchpad上でStellariumの翻訳をしたことがきっかけで,Ubuntuの翻訳にも関わるようになりました。