Edited at

CinnamonのデスクレットでHello World!

More than 1 year has passed since last update.


デスクレットとは

デスクレットはいわゆる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


ファイル内容の追加

出来たファイルをエディタで開いて以下の内容を書き込みます。


metadata.json

{

"uuid": "mydesklet@urushibara",
"name": "Hello, world! desklet",
"description": "Displays Hello, World!",
"prevent-decorations": false
}


stylesheet.css

.my-desklet-label {

font-size: 96px;
}


desklet.js

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