Search code examples
jsonuser-interfacevalaclutter

Vala - Clutter Json UI - How to connect UI Signals?


I'm trying to use JSON based UI files with Clutter. And I want to connect a signal from UI file to a Vala code.

I have tried something like this, it loads the UI but not connects the signal.

How can I connect the signals from UI file? Thanks!


Here is my main.vala:

using Clutter;


class UIDemo {

    public UIDemo()
    {
        var ui_json = new Script();
        ui_json.load_from_file("ui.json");
        ui_json.connect_signals(this);

        Stage stage = (Stage)ui_json.get_object("main-stage");

        stage.show();
    }

    protected void onActivated()
    {
        stdout.printf("ACTIVATED");
    }

}

void main(string[] args)
{
    Clutter.init(ref args);

    var app = new UIDemo();

    Clutter.main();
}

Here is the ui.json:

{
    "id": "main-stage",
    "type": "ClutterStage",
    "color": "white",
    "width": 800,
    "height": 600,
    "title": "Script demo",
    "children": [{
        "id": "hello-label",
        "type": "ClutterText",
        "x": 400,
        "y": 300,
        "text": "Hello, world!",
        "color": "black",
        "font-name": "Sans 48px"
    }],
    "signals": [
    {
        "name": "destroy",
        "handler": "clutter_main_quit"
    },
    {
        "name": "activate",
        "handler": "onActivated"
    }]
}

Solution

  • There are two things to get this working:

    1. match the handler name in the ClutterScript to the name generated by Vala
    2. export the handler name to the dynamic symbols table of the binary file

    There is a third thing, the example doesn't print on stdout while the program is running, but stderr does.

    In ui.json I changed:

        {
            "name": "activate",
            "handler": "onActivated"
        }
    

    to

        {
            "name": "activate",
            "handler": "ui_demo_onActivated"
        }
    

    The name in C generated by Vala includes the class name. It can also be found by looking at the C code. Use the --ccode switch with valac to generate the C file.

    This symbol also needs to appear in the dynamic symbol table of the binary. The GNOME documentation for writing ClutterScript handler functions advises -export-dynamic should be passed to the linker. This is done by the C compiler and this switch can be passed to the C compiler from valac using -X -export-dynamic:

    valac --pkg clutter-1.0 -X -export-dynamic main.vala
    

    You can read the dynamic symbols available in the binary. For a platform that generates ELF binaries, such as Linux, use readelf --dyn-syms main, where main is the name of the binary generated. ui_demo_onActivated will be in that list.