Hello World!

Following the tradition, let’s first see how the often seen ‘Hello World!’ familiar, minimal, friendly greeting program looks like in G-Golf:

;; Load Gtk
(use-modules (g-golf))
(gi-import "Gtk")

;; When the application is launched..
(define (activate app)
  ;; - Create a new window and a new button
  (let ((window (make <gtk-application-window>
                  #:title "Hello"
                  #:application app))
        (button (make <gtk-button>
                  #:label "Hello, World!")))
    ;; - Which closes the window when clicked
    (connect button
             'clicked
             (lambda (b)
               (close window)))
    (set-child window button)
    (show window)))

;; Create a new application
(let ((app (make <gtk-application>
             #:application-id "org.example.GtkApplication")))
  (connect app 'activate activate)
  ;; Run the application
  (run app 0 '()))

Providing you successfully installed G-Golf, you may run the above code in a Guile REPL (Read Evaluate Print Loop)12, which as described in its comments, starts the application, resulting in opening a (small) window named ‘Hello’, with one button named ‘Hello, World!’, that will close the window when clicked.

hello-world-1

Example 1: Hello World! (1)

Wonderful! But you probably rightfully think that it was a bit slow. This is not because G-Golf nor Guile are slow, but because the Gtk namespace is absolutely huge, and although we only use a few components, we asked to import the all namespace. We will see how to only selectively import the namespace components we need in the next section, but let’s first try the following, (a) close the window and (b) re-evaluate the last expression:

(let ((app (make <gtk-application>
             #:application-id "com.example.GtkApplication")))
  (connect app 'activate activate)
  (run app 0 '()))

Great! Now, the application was launched instantaneously. Since everything it needs was already imported, the time it takes to execute the code is nearly identical to the time it would take to execute the same code from C - if you accurately measure the execution time in both situation, you would see a difference in the results, but small enough that it is safe to declare it imperceptible.

It would be beyond the scope of this introduction to describe the <gtk-application> / g-application-run instance creation and run mechanism in detail, for this, please consult and carefully read their respective entries in the Gtk and Gio reference manuals.

The GNOME team also maintains a wiki called HowDoI, and two pages are dedicated to this subject: HowDoI GtkApplication and HowDoI GtkApplication/CommandLine.

This said, let’s just make a few hopefully usefull comments to newcomers:

  _ Is your application ID valid?

The set of rules that apply and determine if an Application Identifier is valid is fully described in the Gio Reference Manual, here.

In G-Golf, you may check if your application ID is valid by calling g-application-id-is-valid13, for example:

(g-application-id-is-valid "com.example.GtkApplication")
⇒ #t

(g-application-id-is-valid "RedBear")
⇒ #f

If you pass an invalid application ID to a <gtk-application> instance creation, you’ll be noted with a message similar to this:

(process:30818): GLib-GIO-CRITICAL **: 21:58:52.700: g_application_set_application_id: assertion ’application_id == NULL || g_application_id_is_valid (application_id)’ failed

  _ Great, but could we speed things up a little?

Yes we can! In the next section, as promised above, we will walk you through Selective Import, used to reduce the time G-Golf has to spend importing the typelib(s) that your application requires.


Footnotes

(12)

If you haven’t done so, please read the Configuring Guile for G-Golf, Merging Generics and configure your repl as proposed, before to run the example.

(13)

After you at least import either directly (gi-import-by-name "Gio" "Application"), or (gi-import-by-name "Gtk" "Application"), which triggers the appropriate Gio imports, as described in the next section