<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://brokenco.de//feed/by_tag/gtk.xml" rel="self" type="application/atom+xml" /><link href="https://brokenco.de//" rel="alternate" type="text/html" /><updated>2026-08-24T11:29:18+00:00</updated><id>https://brokenco.de//feed/by_tag/gtk.xml</id><title type="html">rtyler</title><subtitle>a moderately technical blog</subtitle><author><name>R. Tyler Croy</name></author><entry><title type="html">Using Glade3 with GtkAda</title><link href="https://brokenco.de//2017/01/07/updated-glade-gtkada-example.html" rel="alternate" type="text/html" title="Using Glade3 with GtkAda" /><published>2017-01-07T00:00:00+00:00</published><updated>2017-01-07T00:00:00+00:00</updated><id>https://brokenco.de//2017/01/07/updated-glade-gtkada-example</id><content type="html" xml:base="https://brokenco.de//2017/01/07/updated-glade-gtkada-example.html"><![CDATA[<p>I have been a hobby hacker for my entire adult life, and a bit before that too.
When your profession is making software, or even making open source software,
the joy from hobby-hacking can diminish or even disappear. One of the things I
learned from <a href="/2015/11/10/choose-happiness.html">burning out</a> was that, if I am
going to continue to enjoy hacking as a personal hobby, I would need to pursue
“frivolous hacking.”</p>

<p><em>Frivolous hacking</em>:</p>

<blockquote>
  <p>Hacking on something for no practical or otherwise useful reason.</p>
</blockquote>

<p>Late last week I was struck with the desire to play around with
<a href="https://libre.adacore.com/tools/gtkada/">GtkAda</a>. Ada has <a href="/2010/12/06/ada-surely-you-jest-mr-pythonman.html">long been a hobby
language</a> for me, but I have
never gotten the desire to make a GUI-based application. For this weekend’s
<em>frivolous hacking</em>, I created <a href="https://github.com/berriedale/arun">arun</a> a
simple Ada Command Runner with GtkAda and <a href="https://glade.gnome.org/">Glade 3</a>.</p>

<p><img src="https://github.com/berriedale/arun/blob/master/screenshot.png?raw=true" alt="Arun" /></p>

<hr />

<p>The primary reason to use Glade, in my opinion, is that it’s 2017 and
hand-coding interface components is beyond tedious. At a high level, Glade
provides a WYSIWYG approach for defining the various interface components a
program requires, exports that as an XML file which can later be loaded by the
program at runtime.</p>

<p><img src="/images/post-images/glade3-gtkada/glade3-arun.png" alt="Glade3 for arun" /></p>

<h3 id="prerequisites">Prerequisites</h3>

<p>My first attempt relied on using the Glade3 and GtkAda packages which exist for
Debian-based systems. Unfortunately <code class="language-plaintext highlighter-rouge">libgtkada2.24.4-dev</code> binds to Gtk+ version
2, rather than Gtk+ version 3, which Glade3 targets.</p>

<p>Instead of native packages, you can also <a href="http://libre.adacore.com">download GtkAda from
AdaCore</a> directly. Opting for this route I was
disappointed to learn that the file named <code class="language-plaintext highlighter-rouge">gtkada-gpl-2016-x86_64-linux-bin.tar.gz</code>
isn’t actually a set of binaries but just a source tarball which must be built
and installed. At first, <a href="https://github.com/AdaCore/gtkada/issues/7#issue-199381675">that didn’t work for me
either</a>! A bug in
that source tarball leaves a user like me with one of two options:</p>

<ol>
  <li>Configure the installation with <code class="language-plaintext highlighter-rouge">./configure --with-GL=no</code></li>
  <li>Grab the latest (<code class="language-plaintext highlighter-rouge">fc8b2f9</code> at this time) from GitHub: <code class="language-plaintext highlighter-rouge">git://github.com/AdaCore/GtkAda.git</code></li>
</ol>

<p>I opted for the latter and within short order (<code class="language-plaintext highlighter-rouge">make -j4</code>!) I had fresh
installation of GtkAda on my system.</p>

<h3 id="writing-an-app">Writing an app</h3>

<p>Fortunately the <a href="http://wiki.ada-dk.org/start">Ada DK wiki</a> has an example I
could start from, which covers the <a href="http://wiki.ada-dk.org/building_gui_with_glade_3">basics of building a GUI with Glade3 in
GtkAda</a>. After cribbing some
Ada code from the wiki page, I found another stumbling block, it wouldn’t
compile.</p>

<p>Turns out some APIs had changed since the page was originally written, but as
luck would have it <a href="https://stackoverflow.com/a/17029228">Stack Overflow had the
answer</a>.</p>

<p>Without going into too much detail on how to use GtkAda,
<a href="https://github.com/berriedale/arun/commit/35b17986d4adb45ed91f8ecfc94f37f846f5a59e#diff-84ad0731ead1a1baefde1c6df1194789">this
version</a>
of the <code class="language-plaintext highlighter-rouge">Arun.Main</code> procedure demonstrates a basic version of loading and
starting a Glade3-based GtkAda app:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Gtk.Main.Init;
Gtk_New (Builder);

-- Load `arun.glade` which contains the interface definition
Return_Code := Add_From_File (Builder  =&gt; Builder,
                              Filename =&gt; "arun.glade",
                              Error    =&gt; Error'Access);

if Error /= null then
   Put_Line ("Error : " &amp; Get_Message (Error));
   Error_Free (Error);
   return;
end if;

-- Register a signal handler for when
-- the "Main_Quit" signal is fired
Register_Handler (Builder      =&gt; Builder,
                  Handler_Name =&gt; "Main_Quit",
                  Handler      =&gt; Arun.Handlers.Quit'Access);

Do_Connect (Builder);

-- Get the Gtk_Widget object from the Gtkada.Builder API
-- for our commandWindow so it will be shown.
Gtk.Widget.Show_All (
    Gtk_Widget (Gtkada.Builder.Get_Object (Builder, "commandWindow")));

Gtk.Main.Main;
Unref (Builder);
</code></pre></div></div>

<p>With the <code class="language-plaintext highlighter-rouge">arun</code> binary compiled, I decided to try it out:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>obj % ./arun
Starting arun
Error : Failed to open file 'arun.glade': No such file or directory
obj %
</code></pre></div></div>

<p>As one might expect, there is a downside to loading files at executable
runtime.</p>

<p>Another <a href="http://stackoverflow.com/a/28876764">Stack Overflow answer</a> introduced me
to the <code class="language-plaintext highlighter-rouge">glib-compile-resources</code> executable, which provides the solution
for loading the <code class="language-plaintext highlighter-rouge">.glade</code> file at runtime in a more portable way. Instead of
referring to a <code class="language-plaintext highlighter-rouge">.glade</code> file, <code class="language-plaintext highlighter-rouge">glib-compile-resources</code> creates a C file which
can be compiled and linked into the application. Of course, this adds some more
build-time complexity, as <code class="language-plaintext highlighter-rouge">glib-compile-resources</code> needs to be called, the C
file needs to be compiled, and then the object file must be linked into the
resulting binary.</p>

<p>With the Makefile put together, instead of <code class="language-plaintext highlighter-rouge">Add_From_File</code> the application uses
<code class="language-plaintext highlighter-rouge">Add_From_Resource</code> as is demonstrated in <a href="https://github.com/berriedale/arun/commit/5bf248399355582af49e83e59199fcb985210137">this commit</a>.
With a resource the binary can then be distributed without the <code class="language-plaintext highlighter-rouge">.glade</code> file:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>obj % ./arun
Starting arun
Searching for x
Searching for xeye
Searching for xeyes
Looking for an executable in /home/tyler/.rvm/gems/ruby-2.1.5/bin
Looking for an executable in /home/tyler/.rvm/gems/ruby-2.1.5@global/bin
Looking for an executable in /home/tyler/.rvm/rubies/ruby-2.1.5/bin
Looking for an executable in /home/tyler/bin
Looking for an executable in /home/tyler/scratch/bin
Looking for an executable in /home/tyler/.rvm/bin
Looking for an executable in /home/tyler/scratch/node_modules/.bin
Looking for an executable in /home/tyler/scratch/ada/gnat-gpl-2016-x86_64-linux-bin/bin
Looking for an executable in /home/tyler/scratch/ada/spark-gpl-2016-x86_64-linux-bin/bin
Looking for an executable in /home/tyler/bin
Looking for an executable in /usr/local/bin
Looking for an executable in /usr/bin
Found executable at /usr/bin/xeyes
Should Execute: xeyes
Spawning /usr/bin/xeyes
obj %
</code></pre></div></div>

<p>Suffice it to say, using GtkAda isn’t <em>difficult</em> per se, it’s only difficult
to use when there are toolchain specific idiosyncrasies that are hard to
Google. Aside from that challenge, I far prefer writing GtkAda rather than
“pure” Gtk+ with C or C++.</p>

<p>Of course I don’t expect anybody else to find my code useful, nor do I have
lofty ambitions about it, thereby meeting my “frivolous hacking” requirement!</p>]]></content><author><name>R. Tyler Croy</name></author><category term="ada" /><category term="gtk" /><category term="glade" /><category term="gtkada" /><summary type="html"><![CDATA[I have been a hobby hacker for my entire adult life, and a bit before that too. When your profession is making software, or even making open source software, the joy from hobby-hacking can diminish or even disappear. One of the things I learned from burning out was that, if I am going to continue to enjoy hacking as a personal hobby, I would need to pursue “frivolous hacking.”]]></summary></entry></feed>