OpenBagTwo's Project Hub
October 23, 2023

Developing for elementary OS the Hard Way

Posted on October 23, 2023  •  5 minutes  • 898 words
Table of contents

I’m a Stan for elementary OS . People say that it’s a macOS clone for Linux, and I’ll loudly tell them that they’re wrong– it’s an OSX clone for Linux, and that is a different thing entirely. But while I love the look and feel of the Pantheon desktop environment, and I was, for a decade and a half, a “.deb or Die” Ubuntu-variant devotee, I ended up switching to Arch (+ Pantheon) on my main workstation about a year ago.

Today I decided I’d like to try designing a GUI app for the first time since undergrad, and while, thanks to Flatpak, I could choose from one of dozens of toolkits, I’m going with Granite because I want this to be an elementary OS application first and foremost.

Obviously, the elementary OS developer guides weren’t written for my particular setup, so this post is serving to document what I did for anyone else who chooses insanity to walk down a similar path.

Of course there’s no elementary-sdk package in the AUR

Though wouldn’t that have been nice!

Of course, elementary-sdk is just a metapackage anyway,

screenshot showing the contents of the elementary-sdk metapackage

and I could just hunt down each metapackage member, but hitting this barrier did make me stop and think: “Wait, why would I install an entire development environment onto my base system?” I wouldn’t do that for a Python project–I’d use a conda environment. So why wouldn’t I do that here?

Solution: Install Distrobox

Honestly, I’m more surprised that I’ve gone this long without using it.

There’s no base elementary OS container, but an Ubuntu 22.04 one should work fine with the added PPAs:

$ distrobox create -n elementary-dev -i ubuntu:22.04
$ distrobox enter elementary-dev
openbagtwo@elementary-dev $ sudo apt update && sudo apt dist-upgrade
openbagtwo@elementary-dev $ sudo apt install software-properties-common
openbagtwo@elementary-dev $ sudo add-apt-repository https://ppa.launchpadcontent.net/elementary-os/stable/ubuntu
openbagtwo@elementary-dev $ sudo apt update
openbagtwo@elementary-dev $ sudo apt install elementary-sdk

And that worked a charm!

Flatpak And Containers Don’t Mix

Following along in the developer guide , the next step was to install the elementary appcenter flatpak.

That failed spectacularly inside of my dev instance with the very unhelpful error:

error: No such file or directory

which took me a minute to track down to a known limitation of Flatpak : running them inside of containers is a little too meta for them.

Solution: Install appcenter on the system

And honestly, having the elementary Flathub repo available on my system is something I want regardless.

$ flatpak remote-add --if-not-exists --system appcenter https://flatpak.elementary.io/repo.flatpakrepo
$ flatpak install -y appcenter io.elementary.Platform io.elementary.Sdk

(I chose the newest available runtimes, which were one point release ahead of the current)

Hello World!

And now, finally, it was time to write my first Vala app .

my first Vala app, with the title changed from the example

Some notes:

For ease of copy-pasting, here’s the commands I used to compile and run my first Vala app:

$ cd /path/to/workspace/vala-project
$ mkdir -p build
$ distrobox enter elementary-dev
openbagtwo@elementary-dev $ valac --pkg gtk4 src/Application.vala -o build/Application
openbagtwo@elementary-dev $ logout
$ ./build/Application

Granite and Meson

So far my application has just been a bog-standard GTK4 app, but the whole point of this exercise was to build something for elementary. Some of the high-level concepts are covered here but at this point I was better served by just copying and modifying meson.build files from a template project .

The big thing was switching over to using GObject-style construction so the top of my program now looks like:

public class EnderChest.Application : Gtk.Application {
    construct {
        application_id = "com.github.openbagtwo.babys-first-vala";
        flags = ApplicationFlags.FLAGS_NONE;
    }
...

I also copied over their startup() method which sets the application styling and registers Ctrl-Q as a keyboard shortcut to quit.

With those changes made and files in place, I hopped back into my distrobox container and ran:

$ cd /path/to/workspace/vala-project
$ distrobox enter elementary-dev
openbagtwo@elementary-dev $ meson build --prefix=/usr
openbagtwo@elementary-dev $ cd build
openbagtwo@elementary-dev $ ninja
openbagtwo@elementary-dev $ logout
$ ./build/src/com.github.openbagtwo.enderchest-gui

which looks the same as before, but now closes with Ctrl-Q.

Playing Around with Granite

Finally, to get a good sense of the widgets at my disposal, I cloned the Granite library itself so I could build and run their granite demo:

$ cd /path/to/workspace/granite
$ distrobox enter elementary-dev
openbagtwo@elementary-dev $ sudo apt install sassc
openbagtwo@elementary-dev $ meson build --preix=/usr
openbagtwo@elementary-dev $ cd build
openbagtwo@elementary-dev $ ninja
openbagtwo@elementary-dev $ logout
$ ./build/demo/granite-7-demo

example of an elementary-style toast notification

So cool! This is going to be so much fun to play around with.

Next Steps

The project I’m working towards is a frontend for EnderChest and GSB , and there’s a lot I don’t know about how to integrate a Python backend with a GUI frontend written in a completely different language (without resorting to just calling the CLI in between). Ahead of me is a fun journey of learning about ABIs and GObject Introspection !

Social Media

Where else you can find me