I want GtkBuilder+JavaScript

While having coffee with some friends a few weeks ago, I kept coming back to the thought that I need to be able to do small amounts of scripting within GtkBuilder. Especially if I'm going to switch to that from hard coding UIs in C. I figured it would take some hacking to GtkBuilder to do what I wanted. Well, it turns out not. I came to the revelation late last night, in bed, and hacked it up this morning.

First, we create GScriptJs which is a thin wrapper around Gjs. Mostly, just to be able to create an object from within the GtkBuilder file. Then, we create a custom connect func that will look for a given function in the script and attach it to the requested signal. All in all, very few lines of code. I'm pleasantly surprised.

Example GtkBuilder+JavaScript

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <interface>
  3. <object class="GScriptJs" id="script">
  4. <property name="script">
  5. const Gtk = imports.gi.Gtk;
  6.  
  7. function onClicked() {
  8. let w = new Gtk.Window();
  9. w.set_default_size(320, 240);
  10. w.present();
  11. }
  12.  
  13. function onQuit() {
  14. Gtk.main_quit();
  15. }
  16. </property>
  17. </object>
  18. <object class="GtkWindow" id="window">
  19. <signal name="delete-event" handler="onQuit" swapped="no"/>

Example GtkBuilderConnectFunc

  1. static void
  2. connect_func (GtkBuilder *builder,
  3. GObject *object,
  4. const gchar *signal_name,
  5. const gchar *handler_name,
  6. GObject *connect_object,
  7. GConnectFlags flags,
  8. gpointer user_data)
  9. {
  10. const gchar *script_name = user_data;
  11. GScriptJs *script;
  12. GClosure *closure;
  13.  
  14. g_return_if_fail(script_name != NULL);
  15. g_return_if_fail(connect_object == NULL); /* TODO */
  16.  
  17. script = G_SCRIPT_JS(gtk_builder_get_object(builder, script_name));
  18. if (!script) {
  19. g_critical("Cannot locate script %s", script_name);
  20. return;
  21. }
  22.  
  23. closure = g_script_js_get_function(script, handler_name);
  24. if (!closure) {
  25. g_critical("Cannot locate function %s", handler_name);
  26. return;
  27. }
  28.  
  29. g_signal_connect_closure(object, signal_name, closure,
  30. !!(flags & G_CONNECT_AFTER));
  31. }

Get the code at https://github.com/chergert/gtkbuilderscript.

Comments (5)

  1. You might like this

    does not use gtkbuilder, but allows you to build gtk app’s completly in javascript…

    http://www.youtube.com/watch?v=0qJrE2za47U

    Saturday, April 23, 2011 at 9:11 pm #
  2. chergert wrote:

    while that looks pretty neat, i’m not really interested in writing entire apps in javascript. mostly just pushing view related stuff into gtkbuilder+javascript. thanks for the link!

    Saturday, April 23, 2011 at 9:34 pm #
  3. Johan Dahlin wrote:

    Nice hack. It wouldn’t be too much work to add a proper .. in GtkBuilder and extend that mechanism via gtk-modules to get something formal.

    Sunday, April 24, 2011 at 8:41 am #
  4. Johan Dahlin wrote:

    Nice hack. It wouldn’t be too much work to add a proper .. in GtkBuilder and extend that via gtk-modules.

    Sunday, April 24, 2011 at 8:41 am #
  5. Johan Dahlin wrote:

    Ugh, tags are stripped I meant an html-like script tag with a type = text/javascript+gjs or so

    Sunday, April 24, 2011 at 8:42 am #