Developing With The Flatpak CLI

Flatpak is a very powerful tool for development, and is well-integrated into GNOME Builder. This is what I’d recommend for most developers. But what if you use a plain text editor? Barring Visual Studio Code, there aren’t many extensions for common text editors to use flatpak. This tutorial will go over how to use flatpak to build and test your apps with only the command line.

Building & Testing Your App

First, you’ll need to have flatpak installed and a flatpak manifest. You’ll also need the right runtime and SDK installed. Then, you’ll need to set up the environment to build your application. Navigate to your project directory from the terminal. Once there run the following command:

# $MODULE_NAME is the name of your application's flatpak module
$ flatpak-builder --repo=repo --build-only --stop-at=$MODULE_NAME --force-clean flatpak_app $APP_ID.json

This will fetch all the dependencies declared in the flatpak manifest and build each one, stopping with your app. Then, you need to use flatpak build to run the build commands for your application.

First you configure the buildsystem:

# $CONFIG_OPTS should match the `config-opts` for the module in your flatpak manifest
$ flatpak build --filesystem=host flatpak_app meson _build --prefix=/app $CONFIG_OPTS

Then run the build & install command:

# $BUILD_OPTS should match the build-options in the flatpak manifest.
# `append-path` turns into `--env=PATH=$PATH:$APPEND_PATH`
$ flatpak build --filesystem=host $BUILD_OPTS flatpak_app ninja -C _build install

After that, you can also use flatpak build to test the application:

# $FINISH_ARGS would be the `finish-args` from your flatpak manifest
$ flatpak build --filesystem=host $FINISH_ARGS flatpak_app $APP_EXECUTABLE_NAME

Creating Dist Tarballs

One of the responsibilities an app maintainer has is creating tarballs of their applications for distribution. This can be challenging, as the maintainer needs to build using an environment that has all dependencies – including versions of dependencies that aren’t yet released.

Flatpak allows for developers to do this in a simple way. If you haven’t run the
command above to fetch and build your dependencies, do so now.
Also run the configuration step. Now you should be ready to run the dist command:

$ flatpak build --filesystem=host flatpak_app ninja -C _build dist

Now you should have a release tarball ready in _build/meson-dist.

Notes

While this method works for development, it’s a bit clumsy. I highly recommend using GNOME Builder or Visual Studio Code with the flatpak extension. These tools handle the clumsiness for you, allowing you to focus entirely on development. However, if you find yourself wanting to develop using flatpak and don’t want to use either of the above options, this is the way to do so.

Glade Not Recommended

If you are starting out with GTK development, you may have heard of a tool called Glade. Glade is a UI designer application for GTK projects, that allows you to create, modify, and preview UI files before writing code. In that sense, Glade is a very useful tool for GTK apps.

With that said, I must implore that you do not use Glade.

Why? Glade was built for it’s own format, before the advent of
GtkBuilder. It does not know certain properties, does not know
of certain features, and does not know modern GTK practices.

Instead of ignoring what it does not know, it aggressively “corrects” it. Glade will re-write your UI files to its whims,
including but not limited to:

  • Removing property bindings
  • Removing unknown properties
  • Adding child properties to GtkBox children everywhere
    • These are gone in GTK 4, which adds extra work to the porting process
  • Adding explicit GtkViewports that cause a double-border
  • Forcing minimum width and height on GtkListBoxRows
  • Re-arranging objects within the UI file
  • Changing the format of all properties in an edited UI file

This makes Glade harmful in different ways. Your UI files will be bloated, due to Glade adding placeholders, child properties,
and extra widgets where they aren’t needed. When you make a
contribution to an app, you may be asked to re-do it by hand
because Glade made unnecessary changes. When porting to GTK 4 you
will need to do more work, as Glade doesn’t know to avoid
deprecated widgets, properties, and child properties.

All of these elements combine to make Glade more harmful than helpful. So please, do not use Glade. If you are working with UI
files write them by hand. An editor with code folding and syntax
highlighting can be very helpful. If you need to mock something
up, you can try sketching on a piece of paper or using our
mockup resources. Whatever you choose, don’t use Glade.

New Release: Color Picker v2.4.0

Gcolor3 is now “Color Picker”! With the rename comes a new maintiner, a new icon, lots of new improvements, and many translation updates.

Release Notes

  • Color Picker now works on Wayland!
  • The typography and iconography of Color Picker has changed to be consistent and more in line with the GNOME HIG.
  • The use of deprecated GTK APIs has been dropped, which will make porting to GTK4 a smooth process.
  • Multiple other under-the-hood improvements

What is a Platform?

Often when looking for apps on Linux, one might search for something “cross-platform”. What does that mean? Typically it refers to running on more than one operating system, e.g. Windows, macOS, and GNU/Linux. But, what are developers really targeting when they target GNU/Linux, since there’s such diverse ecosystem of environments with their own behaviors? Is there really a “Linux Desktop” platform at all?

The Prerequisites

When developing an app for one platform, there are certain elements you can assume are there and able to be relied on. This can be low-level things like the standard library, or user-facing things like the system tray. On Windows you can expect the Windows API or Win32, and on macOS you can expect Cocoa. With GNU/Linux, the only constants are the GNU userspace and the Linux kernel. You can’t assume systemd, GLib, Qt, or any of the other common elements will be there for every system.

What about freedesktop? Even then, not every desktop follows all of the specifications within freedesktop, such as the Secrets API or the system tray. So making assumptions based on targeting freedesktop as a platform will not work out.

To be a true platform, the ability to rely on elements being stable for all users is a must. By this definition, the “Linux Desktop” itself is not a platform, as it does not meet the criteria.

Making Platforms Out of “The Linux Desktop”

It is possible to build fully realized platforms on top of GNU/Linux. The best example of this is elementary OS. Developers targeting elementary OS know that different elements like Granite will be present for all users of elementary OS. They also know elements that won’t be there, such as custom themes or a system tray. Thus, they can make decisions and integrate things with platform specifics in mind. This ability leads to polished, well-integrated apps on the AppCenter and developers need not fear a distro breaking their app.

To get a healthy app development community for GNOME, we need to be able to have the same guarantees. Unfortunately, we don’t have that. Because GNOME is not shipped by upstream, downstreams take the base of GNOME we target and remove or change core elements. This can be the system stylesheet or something even more functional, like Tracker (our file indexer). By doing this, the versions of GNOME that reach users break the functionality or UX in our apps. Nobody can target GNOME if every instance of it can be massively different from another. Just as no one can truly target the “Linux Desktop” due to the differences in each environment.

How do we solve this, then? To start, the community idea of the “Linux Desktop” as a platform needs to be moved past. Once it’s understood that each desktop is target that developers aim for, it will be easier for users to find what apps work best for their environment. That said, we need to have apps for them to find. Improving the development experience for various platforms will help developers in making well-integrated apps. Making sure they can safely make assumptions is fundamental, and I hope that we get there.

Developing GNOME: The Basics

I’ve been working in the GNOME community for a little under a year and a half now. During my time contributing to the project, I’ve seen a lot of misunderstandings from the community about how we work. So, I’ve decided to write a multi-part series on how development on GNOME works.

This first post will cover the basics. In future I’ll explain our tooling, how apps are created, and how changes happen across the ecosystem.

The Release Cycle

At the center of GNOME development is the release cycle. Every 6 months we put out a major release, with patch releases in-between. Major releases typically happen in September and March, and are named after the city of the most recent conference. GNOME 3.30 was named after the city we held GUADEC in, and 3.32 is named after where GNOME.Asia took place.

At different intervals in the cycle we have freeze periods, after which no changes can be made to certain parts of the code. Core apps, such as Web, Files, and Settings all strictly follow the release cycle and freezes. Apps outside of the core set like Polari, Builder, and Fractal can follow their own schedules or versioning schemes, but tend to put out releases alongside the GNOME core.

The freeze deadlines often determine what contributions make it into a release. For example, if a UI change is submitted after the UI freeze, maintainers need to seek approval from the Design and Release teams before the change can be merged. Freezes are staggered, and come in the following order:

  • UI, Feature, and API/ABI Freezes
  • String Freeze
  • Hard Code Freeze

The hard code freeze ends once the major release for the cycle is out. If you want to apply a change that violates the other freezes, you need to create a branch for the latest stable release. So, if I need to merge a UI change after the 3.32 release is out, I need to first create a gnome-3-32 branch before I accept the change onto master. This branch will then be used to cherry-pick changes for the 3.32.X releases.

How Apps Are Maintained

Each project within GNOME has its own developers. The Music developers aren’t necessarily the same people working on the Shell, and the Shell developers generally aren’t the same people working on GTK. While many developers work across the ecosystem on different projects, there is no one team of developers. This is why “GNOME decided such and such” is often inaccurate.

The maintainers of a project have full say over what contributions are or are not accepted. While certain things can be proposed, maintainers have the right to reject proposals. This is, for example, is why Terminal did not have a HeaderBar until 3.32 and doesn’t enable it by default. Nobody is forced to do anything, but often developers and designers will agree on a direction for an app, or the ecosystem at large.

Contrary to popular belief, most maintainers are not paid by Red Hat although some core components like Files and GNOME Shell do have Red Hat employees employed to work on them. Other companies such as Canonical, Purism, and Endless employ developers to work on the parts of the stack that matter to them. That said, most contributors are not on company time even if they are employed by the likes of Red Hat. And of course those that are employed to work on GNOME still aren’t paid for all of their work on GNOME. Most of our work is done on our own time, as limited by the rest of our lives.

It’s also worth noting that GNOME is built with a wide range of technologies; while GTK is written exclusively in C, Music is a Python project and Calculator is implemented with Vala. The Python developers working on Music are great with Python and GStreamer, but they aren’t going to be much help fixing a rounding error in Calculator as a general rule, and as volunteers it wouldn’t be fair to expect them to be, either.

tl;dr: GNOME is a community of individuals each with their own motivations and vision for their own part of the project doing their best to build a great platform for users.