There is no “Linux” Platform (Part 1)

This blog post is based on the talk Jordan Petridis and I gave at LAS 2019 in Barcelona.

In our community there is this idea that “Linux” is the third platform next to Windows and macOS. It’s closely connected to things like the “year of the Linux desktop”, and can be seen in the language around things like Flatpak, which bills itself as “The Future of Apps on Linux” and the Linux App Summit, which is “designed to accelerate the growth of the Linux application ecosystem”.

But what does that actually mean? What does a healthy app ecosystem look like? And why don’t we have one?

I think the core of the problem is actually the layer below that: Before we can have healthy ecosystems, we need healthy platforms to build them on.

What is a Platform?

The word “platform” is often used without a clear definition of what exactly that entails. If we look at other successful platforms there are a ton of different things enabling their success, which are easy to miss when you just look at the surface.

On the developer side you need an operating system developers can use to make apps. You also need a developer SDK and tooling which are integrated with the operating system. You need developer documentation, tutorials, etc. so people can learn how to develop for the platform. And of course once the apps are built there needs to be an app store to submit them to.

Developers can’t make great apps all by themselves, for that you also need designers. Designers need tools to mock up and prototype apps, platform UI patterns for things like layout and navigation, so every app doesn’t have to reinvent the wheel, and a visual design language so designers can make their app fit in with the rest of the system visually. You also need Human Interface Guidelines documenting all of the above, as well as tutorials and other educational resources to help people learn to design for the platform.

On the end user side you need a consumer OS with an integrated app store, where people can get the great apps developers make. The consumer OS can be the same as the developer OS, but doesn’t have to be (e.g. it isn’t for Android or iOS).  You also need a way for people to get help/support when they have problems with their system (whether that’s physical stores, a help website, or just easily google-able Stackoverflow questions).

That’s a lot of different things, but we can group them into four major pieces which are needed in order for something to be a real platform:

  • Operating System
  • Developer Platform
  • Design Language
  • App Store

So if we look at the free software world, where are the platforms?

Linux?

Linux is a kernel, which can be used to build OSes, which can be used to build platforms. Some people (e.g. Google with Android) have done so, but a kernel by itself clearly doesn’t have any the four things outlined above, and therefore is not a platform.

FreeDesktop.org?

What about “Desktop Linux”, which is what people usually mean when they say “Linux”? The problem is that this term doesn’t have a clear definition. You could take it to mean “FreeDesktop.org”, but that also doesn’t come close to being a platform. FreeDesktop is a set of standards that can be used to build platforms (and/or ensure some level of compatibility between different platforms). Endorsement of a single platform or set of technologies goes directly against FreeDesktop’s aims, and as such it should only be thought of as the common building blocks platforms might share.

Ubuntu?

What about distributions? Ubuntu is one of the most popular ones, and unlike others it has its own app store. It still isn’t a platform though, because it doesn’t have the most critical pieces: a developer SDK/technology stack, and a design language.

Other distributions are in a similar but worse position because they don’t have an app store.

GNOME?

GNOME is the most popular desktop stack, and it does have an SDK and design language. However, it only sort of has an app store (because GNOME people work on Flathub), and it doesn’t have an OS. Many distributions ship GNOME, but they are all different in various ways (more on this later), so they don’t provide a unified development target.

Elementary?

Despite being a relatively small project, elementary is attracting third party developers making apps specifically for their platform

Interestingly, the only project which currently has all the pieces is elementary. It has an OS, an SDK, a HIG, and an app store to submit apps to. The OS is largely Ubuntu and the technology stack largely GNOME, but it develops its own desktop and apps on top of that, and does the integration work to make it into a complete consumer product.

This begs the question, why is elementary the only one?

The Means of Distribution

The reasons for this are largely historical. In the early days, free software desktops were a bunch of independently developed components. They were not necessarily designed for each other, or well integrated. This meant in order to have a usable system, someone needed to curate these components and assemble them into an operating system: The first distributions were born.

Over the last decades this landscape has changed drastically, however. While GNOME 1 was a set of loosely coupled components, GNOME 2 was already much more cohesive and GNOME 3 is now essentially an integrated product. The shell, core apps, and underlying technologies are all designed with each other in mind, and provide a complete OS experience.

Desktops like GNOME have expanded their scope to cover most of the responsibilities of platforms, and are in effect platforms now, minus the OS part. They have a very clear vision of how the system should work, and app developers target them directly.

The elementary project has taken this development to its logical end point, and made its own vertically integrated OS and app store. This is why it’s the only “real” platform in the free software space at the moment.

GNOME has a relatively vibrant ecosystem of nice third party apps now, despite not being a complete platform (yet). This gives us a glimpse of the potential of this ecosystem.

Distributions, on the other hand, have not really changed since the 90s. They still do integration work on desktop components, package system and applications, set defaults, and make UX decisions. They still operate as if they’re making a product from independent components, even though the actual product work is happening at the desktop layer now.

This disconnect has led to tensions in many areas, which affect both the quality of the system user experience, and the health of the app ecosystem.

What’s interesting about this situation is that desktop developers are now in the same situation app developers have always been in. Unlike desktops, apps have always been complete products. Because of this they have always suffered from the fragmentation and disconnect between developers and users introduced by distribution packaging.

Because of this, app developers and desktop developers now more or less share a common set of grievances with the distribution model, which include:

  • Release schedule: Developers don’t have control over the pace at which people get updates to their software. For apps this can mean people still get old versions of software with issues that were fixed upstream years ago. For desktops it’s even worse, because it means app developers don’t know what version of the platform to target, especially since this can vary wildly (some distributions release every 6 months, others every 2+ years).
  • Packaging errors: Distribution packaging is prone to errors because individual packagers are overloaded (often maintaining dozens or hundreds of packages), and don’t know the software as well as the developers.
  • Overriding upstream decisions: When distributions disagree with upstream decisions, they sometimes keep old version of software, or apply downstream patches that override the author’s intentions. This is very frustrating if you’re an app developer, because users never experience your app as you intended it to be. However, similar to the release schedule issue, it’s even worse when it happens to the core system, because it fragments the platform for app developers.
  • Distro Theming: App developers test with the platform stylesheet and icons, so when distributions change these it can break applications in highly visible ways (invisible widgets, unreadable text, wrong icon metaphors). This is especially bad for third party apps, which get little or no testing from the downstream stylesheet developers. This blog post explains the issue in more detail.

The Wrong Incentives

The reason for a lot of these issues is the incentives on the distribution side. Distributions are shipping software directly to end users, so it’s very tempting to solve any issues they find downstream and just ship them directly. But because the distributions don’t actually develop the software this leads to a number of other problems:

  • Perpetual rebasing: Any change that isn’t upstreamed needs to be rebased on every future version of the upstream software.
  • Incoherent user experience: Downstream solutions to UX problems are often simplistic and don’t fix the entire issue, because they don’t have the development resources for a proper fix. This leads to awkward half-redesigns, which aren’t as polished or thought-through as the original design.
  • Ecosystem fragmentation: Every downstream change adds yet another variable app developers need to test for. The more distributions do it, the worse it gets.

The Endless OS shell is a great example of this. They started out with vanilla GNOME Shell, but then added ever more downstream patches in order to address issues found in in-house usability tests. This means that they end up having to do huge rebases every release, which is a lot of work. At the same time, the issues that prompted the changes do not get fixed upstream (Endless have recently changed their strategy and are working upstream much more now, so hopefully this will get better in the future).

This situation is clearly bad for everyone involved: Distributions spend a ton of resources rebasing their patches forever, app developers don’t have a clear target, and end users get a sub-par experience.

So, what could we do to improve this? We’ll discuss that in Part 2 of this series :)

Restyling apps at scale

tl;dr: If you want to change how an app looks, you need a designer in the loop.

Over the past few months we’ve had a lively debate about “theming” in GNOME, and how it affects our ecosystem. In this discussion I’ve found that there is a divide between people who design and/or develop apps, and people who don’t. I have yet to see an app developer who thinks the current approach to “theming” can work, while many people who aren’t app developers are arguing that it can.

After a few long discussions I started to realize that part of the reason why there’s so little agreement and so much drama around this issue is that we don’t agree what the problem is. Those who don’t work on apps often can’t see the issues with theming and think we want to remove things for no reason, while those who do are very frustrated that the other side doesn’t want to acknowledge how broken everything is.

The basic issue we’re arguing about is whether it’s possible to restyle applications automatically, at scale, without breaking them. In this post I’ll try to explain why I think that it isn’t possible, and why trying to do it is hurting our ecosystem.

There are no themes, just CSS

A fundamental misconception a lot of people have is that GTK 3 supports theming. This is not true, as there is no clearly defined theming API. There are CSS stylesheets, but they were only ever meant to be used by the platform and app developers. The platform stylesheet is called Adwaita (“the only one” in Sanskrit) for a reason.

However, some people (inlcluding major distributions) have been using custom stylesheets as a hacky approximation of “themes” for so long now that nobody even remembers that they are not a real theming API.

An older version of GRadio with Ubuntu’s Ambiance theme

Since CSS is a huge API surface, which is used by both app developers and “theme” developers, it’s very easy for the two to conflict. This leads to apps looking broken unless you manually do QA for every app/theme combination.

“You’re exaggerating, it’s not that bad.”

One of the most frustrating things about the current situation is that to users, it looks like it almost works. For the most part, third-party themes look and work okayish, there are just a few small bugs here and there. A button with too little contrast, an underline clashing with a border, a really large loading spinner. Not that big a deal, you’d think.

However, this view of the situation misses a few really important realities:

  1. App developers are doing a lot of bug fixing to account for “theming”, because people complain to them when their app is broken on certain distros. The current situation essentially forces developers to fix bugs for setups they never intended to support in the first place. They’re not happy about it, but they’re doing it because they don’t want their users to have broken apps.
  2. App developers are trying hard not do anything innovative or visual in their apps, because they know it will break with other stylesheets.
  3. “Theme” developers are fixing a lot of bugs for edge cases in individual apps in their stylesheets. Of course, this is a never-ending task because as soon as a new version of an app is released, something will very likely be broken again.

All of this only kinda sorta works because we have very few apps. If we ever hope to grow our ecosystem past a few dozen apps things have to change, because maintaining a “theme” gets less sustainable with every new app.

There is also the question of what your definition of “broken” is. Some people think that things like these are acceptable:

Date picker in Calendar on Pop OS: There are double arrows left of the month and year labels.
“New Folder” dialog in Nautilus with Ambiance: There’s an invisible “Create” button in the top right.
Gedit on Pop OS: There’s a brown rectangle sticking out of the window at the top, and the widgets at the top of the sidebar look awkward and don’t make sense in this configuration.

I believe this is nowhere near ok. App developers put a lot of effort into making sure their apps look and feel right, fixing bugs, and doing QA. Having distributors change their apps (often in ways that break things) with no QA before users get to experience them is developer-hostile, and would be unacceptable in any other context.

Can you imagine Samsung restyling every third-party app on their phones, without testing them, and when Instagram complains that the text on their buttons is illegible Samsung just shrug and say “Sorry, but branding is very important to us. Why don’t you change your app?”.

“But it’s fine as long as you follow best practices!”

This is a common sentiment among some people. “If only app developers followed best practices, used CSS variables, and derived their colors from theme colors, everything would be fine”, the argument goes. While it’s true that these things are important and make apps more flexible in terms of appearance, this doesn’t come close to solving the entire problem.

If every app only used default GTK controls, in very simple layouts, with no custom widgets or in-app CSS, then best practices would perhaps be enough to prevent apps from breaking. But the reality is that a) this is not the case, and b) we really don’t want it to be the case.

Human Interface Guidelines are just that: guidelines. They have to be implemented manually, they change and evolve over time, and the best apps on any platform push their boundaries in some places and experiment with new patterns (which then sometimes make their way back into the HIG).

This kind of experimentation means that it’s impossible to “theme” apps automatically. Visual design and interaction design are very closely linked, so if you want to change the style, you need a designer to actually think about what a widget should look like.

For example: How should the Pop theme know what a “flat” variant of the new Nautilus path bar should look like? It’s impossible to do this automatically, because it’s a new pattern.

The new path bar in Nautilus
The new path bar in Nautilus with the Pop OS theme (completely broken)

This is not a rare situation, even among core GNOME apps. Many of the apps I’ve personally worked on have their own equivalent of the Nautilus path bar. And that’s the way it should be. Apps have different needs that sometimes require custom solutions, and this experimentation is good for the ecosystem. However, it also means that automatic restyling is impossible.

“But what about Adwaita Dark and High Contrast?”

The point that the dark and high contrast variants of Adwaita can be seen as GTK 3 kinda sorta supporting themes is technically accurate, but misguided. Adwaita variants may technically just be different stylesheets, but this is just an implementation detail. There are very clear differences between them and third-party “themes”.

  1. They are very very close to Adwaita code-wise, and therefore much less likely to break.
  2. There’s a finite number of them, and they are part of the platform. This makes them a tangible target for developers to test for and support, which is completely different from third-party “themes” which just apply random CSS to every app without any QA.
  3. They are part of the same design language, so they require very little extra work to adapt to from a design point of view. If you follow the best practices mentioned above, often no work at all.
GNOME Builder with Adwaita Dark

“But what about consistency? I want all my apps to look the same!”

“Consistency” is a word you hear a lot in debates about theming, but it seems to mean different things to different people.

To some, consistency effectively means “everything should use the same colors”. This is relatively easy to achieve for some apps, even across toolkits, if you simply provide a “theme” for each toolkit.
However, this “consistency” is very shallow. Just because a Qt app uses the Adwaita colors it doesn’t automatically fit in with the GNOME platform. UI patterns are much more important, and they can’t be changed with theming. There is no magic that can redesign menu bar apps with header bars.

No matter how hard you theme these, they will never look native on GNOME

Real consistency can only happen by design, and requires the app developer to build it into the app at every step. If you want all your apps to look the same, only use apps built for your platform’s HIG. “Fixing” apps after the fact with theming isn’t really making your system more consistent, but it’s hurting app developers a great deal.

Of course, even the very shallow “everything uses the same colors” consistency is impossible to enforce across all apps and toolkits. Apps like Blender, Telegram, or Steam don’t respond to system theming at all, and even Firefox and Chromium only do so in a very limited fashion.

“But users *want* themes!”

“Users” want a lot of things, but just because you want something impossible that doesn’t make it possible. In this case, it’s important to be aware of the costs of giving complete visual freedom to “themes”, both in individual app developer effort, and chilling effects on the ecosystem. If given a choice between customization and more, better apps, I’m confident the majority of people would prefer the latter.

Would it be nice if there were a way to be able to restyle every app to make them look like Material Design, or macOS, or Windows 95, and have them all look as if they were built for that style? Absolutely! I would love that! However, as I’ve tried to explain in this blog post, this is simply not realistic.

So, what can we do?

As the recent discussions have shown, talking about solutions before we agree what the problem is isn’t very productive, so for now I’m mostly interested in making sure we’re all aware of the problem and its various facets. There are several different stakeholders with different perspectives on this issue, and making progress will mean making some hard choices. At this year’s GUADEC we had a Theming & Ecosystem BoF where we talked about a number of potential directions, and I hope we can move forward on that path.

No matter what we come up with though, I think it’s crucial that we start taking the needs of app developers seriously. Developers are the lifeblood of any platform, and we’ve been treating them very poorly. If we want to grow our ecosystem and actually compete with other major platforms, we need to fix that.

Note: The examples in this post have been chosen because the themes in question ship with major distributions, so app developers tend to get complaints about them. It’s not my intention to single them out, this problem applies to all third-party themes equally.