Use the system gtk theme

To explain what’s going on quickly. The snap execution environment doesn’t contain any of the themes you may have on your system (stock themes or any locally installed themes). Some snapcraft parts slightly work around that by bundling the same theme many people use on Ubuntu into the snap itself.

Sharing themes from the host into the snap is complex as there are API/ABI issues due to the way themes are made. I’m sure we could try sharing something as an experiment but it’s not guaranteed to work.

1 Like

Honestly, this rather dooms the idea that a snap is a cross-platform way of distributing desktop software. Even if we ignore people who install external themes as being an edge case, simply looking at the idea of Ubuntu with Ambience, Ubuntu with Radiance, and Fedora will mean that my app will look out of place on at least one and probably two out of those three. That’s a terrible experience, I’m afraid; I am extremely loath to distribute my app this way and thus guarantee that it looks wrong on people’s desktops.

2 Likes

As flatpak has the exact same problem the outcome may be some sanity towards how themes are defined. Maybe the ABI won’t be so variable or maybe the CSS declarations won’t change with every minor release number.

1 Like

Yeah, I am loath to make a flatpak for exactly the same reason. Is your thought that the ABI and CSS for themes gets changed to be more stable, and then snappy can provide a way to pick up the system theme because it doesn’t change every go, and then I can make a snap of my app which will inherit the system theme? That could take some time…

I mean we could offer an interface to get access to system themes (user themes are more complex but perhaps could be done as well) but there’s no guarantee that they can be even dlopen’d correctly. No guarantee that those use the same libc.

GTK3 I’ve been told is pure CSS, so ABI should be fine as long as API doesn’t break across releases

It does, constantly, so it’s still an issue. One thing we could do instead is to offer theme snaps that are appropriate for a given base snap or given shared runtime snap, somewhat akin to what flatpak is doing now. Then we could provide one that fits the right theme (via hooks).

I agree with this. We can’t expose the place where themes are kept to the Snaps? I guess I’m not very knowledgeable as to how this works. But it’s actually a big deal for folks I convert to Snaps.

Personally I don’'t mind this anymore. In a world where the CSS of apps open in my browser tab do not match my theme and there are less and less apps which are replaced by these, the eclectic spread of presentation layers feels ok.

Some people use themes for things other than aesthetic preference (not me). For instance, some themes, fonts, and cursors help with accessibility. I think ultimately this needs to be solved. Whether that is through a Free Desktop standard or some other method.

1 Like

The fix for accessing the dark variant theme is addressed in this commit:

https://github.com/snapcore/snapd/commit/464edf17ad673b4521c138354c03a3bfcbeb47c2

1 Like

Is it now possible to use the system theme or is this still not solved?
I’ve packaged the krop tool: https://github.com/gocarlos/krop

Though the app still looks pretty old, is there a way to make it look like the other apps installed on the system?
It uses currently qt4 with python.

1 Like

It is not possible to use system theme yet. At least not in a general way. This will require substantial work to be robust and seamless. On the upside we are working on implementing this:

  • snapd will be able to figure out properties of the system / user it is running on:
  • one such property is the theme the user is operating
  • snapd will be able to automatically download and manage extension snaps such as opengl drivers or themes
  • such extension will be downloaded for each ABI that is needed by the apps on the system in case various base snaps and various different ABIs are in use
  • snapd will automatically use such extension snaps when certain interfaces are in use
3 Likes

Any update on this topic?

Some, there’s ongoing work to generalize the mechanism in which snapd downloads additional snaps (“dependencies” for lack of a better term). With that in place we can extend it to themes. There’s a lot of ongoing work on extending the apparmor rules to allow access to fonds and themes. Some of those are also in the core snap, in the place of placeholder directories for mount points. We haven’t connected the dots yet as we’re working on some key features that will extend our ability to express mount profiles more freely than possible today. Last Friday a small security review were performed and direction and security coordination plan was set in place. This was a long standing desire to decide how to extend those tricky and security-sensitive places in snapd. With that set I’m now working on addressing the key security points (mainly environment scrubbing and child apparmor profiles for snap-update-ns) and my plan is to land those changes after 2.28 is branched off master for release. In 2.29 we should see first concrete elements, such as font sharing and improved ability to shape the mount namespace.

2 Likes

As I already wrote on bugtracker: How about checking what GTK version using .snap and what GTK version using user, then if this versions equal - system specific theme applies to snap?

Yeah, there’s definitely good work coming into the theme support end. I haven’t had enough conversations with the desktop team to feel confident we have a solution to implement in hands, but I’m hoping we can move these conversations forward in the coming days.

So you are saying snap will installed the required theme, by checking the system theme? Nice

but what about qt, to get gnome and qt apps to look same, QGnomePlatform is use, though there isn’t much theme that support QGnomePlatoform but will you support it?

for now there are only one theme, adwaita-qt.

Edited: What if we mount the theme folder (/usr/share/themes and /home/$user/.themes) and For Icons (/usr/share/icons and /home/$USER/.icons)? It can save the one from downloading multiple copies of theme in future.

qt to use gnome theme is done by this guy, adwaita-qt and qgnomeplatform

I’ve been thinking about this a bit. I think we’ve categorically ruled out exposing the system themes directly, since that poses both a backward and forward compatibility problem. So we want some way for a snapped application to access a theme provided by a second snap.

We probably don’t want to model this relationship on the existing interface connection semantics because on multi-user systems different users could potentially have different themes. Rather, we probably want the app to say “I’m interested in gtk-3.20 themes”, and then be given access to all installed gtk-3.20 theme snaps. It’s also worth noting that an app will probably be interested in multiple types of theme resources. A typical GNOME app will want:

  • the GTK theme
  • a matching icon theme
  • a matching mouse cursor theme

So I think we probably want something similar to Flatpak’s extension point idea, which is kind of like our content interface, but in reverse. Something like the following:

  1. application snap A says it is interested in the theme.gtk-3.20 extension point, and wants it exposed at $SNAP/themes

  2. theme snaps B and C say they provide the theme.gtk-3.20 extension point at $SNAP/gtktheme

  3. snap-confine configures A’s mount namespace by doing the equivalent of:

    mount -t tmpfs none /snap/A/current/themes
    mkdir /snap/A/current/gtktheme/B
    mount --bind /snap/B/current/gtktheme /snap/A/current/themes/B
    mkdir /snap/A/current/gtktheme/C
    mount --bind /snap/C/current/gtktheme /snap/A/current/themes/C
    
  4. Whenever new snaps providing the extension point are installed, A’s mount namespace is updated.

We could then rely on something like the desktop-launch script to update $XDG_DATA_DIRS to make themes under these extension point directories discoverable.

In the above example, I’m using the snap package names under the extension point. This would make it difficult to show up with a name like Ambiance, since we don’t allow upper case in package names. It would also be a problem if we wanted separate snaps providing the theme.gtk-2.0 and theme.gtk-3.20 extension points for that theme name.

Flatpak’s solution to this is to make the names of extension points the prefix of the names of the packages that provide that extension, and then use the suffix as the file system path. That guarantees that there isn’t any conflicts by passing the job on to the person managing the repo/store. It’s not clear that is the right option for us with our flat package naming scheme though.

Icon themes will probably add some more complication, since they have the concept of inheritance. For example, the default ubuntu-mono-dark theme says it inherits from Humanity-Dark, Adwaita, and hicolor. Would we expect the snapped version of the theme to be flattened to get rid of the dependencies, or do we need to expose that dependency metadata so that whatever component installs the theme snaps can follow them?

I’m sure there is some more to consider, but hopefully this is enough to start with.

Just a few other points to think about:

  1. detecting the current theme:

    For X apps, this is done via the xsettings protocol, which should work fine via the x11 interface.

    For Wayland apps, GTK uses GSettings/dconf to detect the current theme. This can be accessed using the gsettings interface, but that gives read/write access to all the users’ settings. Ideally this wouldn’t be necessary.

  2. security:

    Some theme formats, like gtk-2.0 may require executable code, which will be running in the application’s security context. So if we do have some kind of extension point API, it might require assertions to allow a snap to provide an extension point.

    Other theme formats like GTK 3 themes and icon themes should be safe though, so I imagine we could have automatic approval of most themes. Possibly in conjunction with some automated sanity checks to make sure the files being exported are of the expected type (e.g. CSS files for GTK themes, image files for icon themes, etc).

  3. developer experience

    Ideally, developers shouldn’t need to include much boiler plate to support standard features. One possible way to do this would be to add plugs and slots (and extension points?) sections to parts in the snapcraft.yaml file. Snapcraft would then copy these to the top level if there is nothing with the same name.

    This way, the desktop-gnome-platform cloud part could ship the boilerplate so all snaps using it pick it up.

2 Likes