Vala GtkApplication

Vala という言語は C# っぽい文法で C 言語ソースコードを作る言語。
だとしたら GtkApplication はどうなるのだろう。

GtkApplication

Python で G_APPLICATION_HANDLES_OPEN を指定して GtkApplication を作成してもエラーになり Gio.File[] 引数が空配列で渡される現象(バグ?)があり困っていたけど C ソースに展開する Vala でなら使えそうだ。
使いたかったけど今までこんな状況だったので。

G_APPLICATION_HANDLES_OPEN @ C, PyGI, Seed | PaePoi

直感で書いてみても上手くいかなかったのでサンプルコードを探す。

Gtk.Application ? gtk+-3.0
GLib.Application ? gio-2.0

こんなにアッサリ、公式ドキュメントがあるというのはやはり楽だ。
GLib.Application というのもあるけど多分 GApplication のことだろう。

しかしサンプルはコードは protected ではエラーになってしまう。
public に書き換えれば問題なく動いた、override って普通はそうするし。

g_signal_connect ではなく override させるのか。
しかしクラスの概念が無い C 言語で override っていったいどう変換しているのだろう。
-C オプションで展開してみると G_APPLICATION_CLASS に代入する C のサンプルコードと似たようなコードを吐いていた、かなり無駄な関数を辿っているような気がするけど。
結果は connect と同じはずなんだけど Vala では connect だとエラーになる。
交わした約束忘れな…いや何でもない。

//public override void open(File[] files, int n_file, string hint) {
public override void open(File[] files, string hint) {

上のように書きたい所だが配列数は length メソッドで調べろらしい。
C# っぽくしたかったのだろうか、よくワカラン。

とにかく GtkApplication は G_APPLICATION_HANDLES_OPEN 指定で問題なく使えるようだ。
アプリ開発者なら涙がちょちょぎれるくらい嬉しい機能なのに日本語で検索してもウチしか引っかからないって何だよ…
どんだけ嬉しいかサンプルコードを書いてみる。

using Gtk;

public class TestWin : Window {

    private Notebook note;
    private TextView[] view;

    public TestWin ( Gtk.Application app ) {
        this.set_application(app);
        this.set_title("TestWin");
        note = new Notebook();
        this.add ( note );
        this.resize ( 320, 240 );
        this.show_all();
    }
    public void CreateNew () {
        var tab_label = new Label("new.txt");
        var text_view = new TextView();
        view += text_view;
        note.append_page(text_view, tab_label);
        this.show_all();
    }
    public void CreateTab ( File[] files ) {
        foreach ( var file in files ) {
            var tab_label = new Label( file.get_basename () );
            var text_view = new TextView ();
            view += text_view;
            note.append_page(text_view, tab_label);
        }
        this.show_all();
    }
}

public class App : Gtk.Application {

    private TestWin win = null;

    public App () {
        Object (application_id:"apps.test.helloworld", flags:ApplicationFlags.HANDLES_OPEN );
    }
    public override void activate () {
        if ( win == null ) {
            win = new TestWin( this );
        }
        win.CreateNew ();
    }
    public override void open ( File[] files, string hint ) {
        if ( win == null ) {
            win = new TestWin( this );
        }
        win.CreateTab ( files );
    }
}

public class Main {
    public static int main ( string[] args ) {
        Gtk.init ( ref args );
        var app = new App ();
        app.run ( args );
        return 0;
    }
}

vala_gtkapplication.tar.gz

完璧な多重起動防止アプリがこんなにアッサリ作れる。
自力でやるなら DBus 通信処理が必要だがマジでこれだけだ。

libunique なんて便利そうなライブラリも一応あるけど。

LibUnique – GNOME Live!

とにかく GtkApplication を使えば DBus 処理も必要なく別個でライブラリを入れてもらう必要もなく、あの面倒極まりない多重起動防止処理が完結できる。
GtkApplication が管理してくれるので delete-event の処理も必要無い。

と解っていたけど PyGI からでは使えなかったんだよね。
んーやっぱり Vala をメイン言語にするかなと、C は面倒くさいし。