デスクレットとは
デスクレットはいわゆるCinnamonのデスクトップウィジェットのこと。
時計やカレンダーなどのデスクトップに貼り付けるタイプの小さなアプリケーションです。
デスクレットはCJSというJavascriptベースの言語で書かれており、意外と簡単に作ることが出来ます。
CJS自体はGJSというGnome Shell Extensionsに使われているものがベースです。
シンプルなデスクレットを作ってみよう
デスクレットに最低限必要なファイルは以下の2つのファイルです。
desklet.js
metadata.json
desklet.js
はプログラム本体で、metadata.json
はデスクレットについての情報や設定などが書き込まれています。
また、48×48ピクセルの画像ファイルを用意すると、デスクレットの管理画面にアイコン表示されます。
icon.png
その他に、スタイルシートstylesheet.css
、設定ファイルsettings-schema.json
なども利用できます。
今回はstylesheet.css
を含めた構成で作成したいと思います。
構成ファイルの準備
ホームディレクトリ内のデスクレットのディレクトリに構成ファイルを作成します。
ディレクトリ名はデスクレットの名前@作者名の固有IDで作成します。
今回はmydesklet@urushibara
を使ってみました。適宜書き換えてください。
mkdir -p ~/.local/share/cinnamon/desklets/mydesklet@urushibara
cd ~/.local/share/cinnamon/desklets/mydesklet@urushibara
touch desklet.js metadata.json stylesheet.css
ファイル内容の追加
出来たファイルをエディタで開いて以下の内容を書き込みます。
{
"uuid": "mydesklet@urushibara",
"name": "Hello, world! desklet",
"description": "Displays Hello, World!",
"prevent-decorations": false
}
.my-desklet-label {
font-size: 96px;
}
const Desklet = imports.ui.desklet;
const St = imports.gi.St; //Shell Toolkitのインポート
//デスクレットクラスを定義
class HelloWorld extends Desklet.Desklet {
constructor(metadata, desklet_id) {
super(metadata, desklet_id);
this.window = new St.Bin(); //コンテナの作成
this.text = new St.Label({style_class: "my-desklet-label"}); //cssのクラス名を指定してラベルを初期化
this.text.set_text("Hello world!"); //表示するテキストをセット
this.window.add_actor(this.text); //ラベルをコンテナに追加
this.setHeader(_("Hello world"));
this.setContent(this.window);
}
}
//エントリーポイント
function main(metadata, desklet_id) {
return new HelloWorld(metadata, desklet_id);
}
extend classを使って**ui.desklet.Desklet
**クラスを継承しています。
ここへGtk+ Shell ExtensionのSt(Shell Toolkit)
に含まれている様々なactor
と呼ばれるUIを追加することが出来ます。
(actor
と呼ばれるのはDeskletがClutterを使用している為ですがめんどくさいので省きます><)
今回は使用していませんが、たくさんのactor
を追加したい場合、StBoxLayoutコンテナを使うと配置が楽になります。
ちなみに上記ソースコードはCinnamonのデフォルトの「Clock」のソースコードを参考にしています。みたところECMAscript2015準拠なのかJavascriptというよりもJavaに似た書き方となっています。古いデスクレットのソースコードや公式のサンプルコードを見るとprototype宣言を使ってクラス定義を行っていますが、どちらの書き方でも良いようです。ただしおそらく上記の書き方が今後は主流になるのかなと思います。
デスクレットの起動
メニューから設定→デスクレットを開き、無事に自分のデスクレットがリストに表示されていたら実際に表示させてみましょう。
上のように表示されれば成功です!
もしエラーが発生していたりデスクレットが起動しない場合は、[Super]
+[L]
でMelangeでlogを見ると原因が解るかもしれません。
ファイルを修正したら[ALT]
+[F2]
を押して、r
と入力してEnterでCinnamonをリブートして下さい。
リブートをしないままだとCinnamonにキャッシュされてしまい、ファイルを更新しただけでは再読込してくれません。
イベントハンドラ
今回は使用していませんがui.desklet.DeskletクラスにはCinnamonがデスクレットを追加したり削除したりするときに必要なイベントが用意されています。
on_desklet_clicked() {
//クリックイベント
}
on_desklet_added_to_desktop() {
//デスクトップに追加された時、deskletManagerによって呼び出されます。
}
on_desklet_removed() {
//デスクトップから削除されたときに呼び出されます。
//タイマーや無限ループ処理がある場合、ここで必ず終了処理を行う必要があります。
//※deskletManagerで終了やアンインストールを行って非表示に見えていても
// Cinnamonが終了しない限り非同期なスレッドは破棄されずに残り続けます。
}
右クリック時はDesklet
クラスのプロパティ_menu
がデフォルトでui.PopupMenuのactorを格納しており、標準でポップアップメニューが開きます。
項目を追加したい場合は、this._menu.addAction("text", func)
とやれば項目を追加することが出来ます。
デスクレットの設定画面
ポップアップメニューの[設定]やデスクレット管理画面の[設定]ボタンで表示されるGUIはどのように作成するのか気になると思います。しかし実は最初に必要な構成ファイルのところで書いていたsettings-schema.json
を追加するだけでGUI表示してくれます。
設定項目の型の一覧 - Linux Mint Development Center
しかしながら、deskletManagerはあなたのデスクレットクラスのsettings
プロパティを参照してGUIを作成します。したがって以下のようにコンストラクタ内でsettings
プロパティをnewする必要があります。
const Settings = imports.ui.settings; //インポートを忘れずに
・
・
・
//settingsの初期化
this.settings = new Settings.DeskletSettings(this, this.metadata["uuid"], desklet_id);
この設定内容がこんなふうに表示されます。
設定の反映
普通の設定の取り出し方
let font_size = this.settings.getValue("font-size");
静的な設定を取り出したいときはこの方法でも構いませんが、設定画面から即時に内容を反映させたい場合は、次のようにイベントハンドラをバインドさせます。
this.settings.bind("font-size", "size", this._onSettingsChanged);
おわりに
基本的にアプレットも同じように作成することが出来ます。
設定ファイルの書き出しや読み込みなど、機能的に至れり尽くせりなので、本格的なデスクレットやアプレットも簡単に作れそうですね。
参考サイト
Linux Mint Development Center - Writing applets
Gnome wiki - GnomeShell Development
Cinnamon Javascript Reference Manual - Desklet.Desklet
この記事はこちらのサイトをベースに、最新のLinux Mintの標準デスクレット「clock」のソースを参考に書きました。
Tutorial: Hello, world! Cinnamon desklet - OrangeShark