Theme Connector For Snaps classic confinement

GTK snaps that use strict confinement do not inherit the look of custom themes that are not included in the gtk-common-themes snap.

Running sudo snap connect... for every gtk snap is not ideal so I have written a short python script with a GTK GUI that allows you to connect all snaps, which have available plugs to gtk-common-themes:gtk-3-themes , to other custom themes that are also downloaded from the Snap Store, e.g. adapta-gtk-snap, qogir-theme-snap and vimix-gtk-themes-snap. I intend to pack more custom themes as snap packages in the future.

The tricky bit is that the python script runs a few shell commands like:

(get a list of installed snap custom themes)

snap list | grep -E '(theme-snap|themes-snap|adapta-gtk-snap)' | awk '{print $1}'

(check which apps are connected to gtk-common-themes)

snap connections gtk-common-themes | grep gtk-3-themes | awk '{print $2}'

and ultimately when you click on the connect button on the GUI something like:

echo [pass] | sudo -S snap connect [snap_app]:gtk-3-themes [theme_name]:gtk-3-themes

I understand that you are not allowed to use sudo and use other snaps like snap in strict confinement.

So I was wondering whether there is a chance for this app to end up in the store with classic confinement?

URL: https://gitlab.com/gantonayde/theme-connector/-/blob/master/src/theme-connector.py (shell commands are at the top)

@jdstrand, @jamesh

Shouldn’t installed theme snaps automatically connect to any snap using gtk-common-themes? I thought this had a greedy plug declaration?

I didn’t know this is possible, surely it will make things a lot easier when packing custom themes.

How do you make custom themes connect to other snaps using gtk-common-themes?

The docs about the content interface could use some improvement, but this my understanding of what has to happen.

  1. The content identifier specified by the theme snap’s slot must match the content attribute of the consuming snap’s plug. If you don’t specify the content value explicitly, then it will use the name of the plug and slot. So based on what themes the snap provides, this is something like gtk-3-themes or icon-themes etc.
  2. There needs to be a “greedy” plug declaration in the store. This is already in place afaik, @jdstrand should be able to confirm this.
  3. You need to request auto-connection for the theme snap. @jdstrand; is this required for every theme snap?
  4. The theme snap needs to be installed.

When these conditions are met, all snaps using the theme plugs should auto-connect to the theme snap.

A system to automatically install the correct theme snap based on the system theme is still being worked on.

In the snapcraft.yaml of the qogir theme my slots are defined as (content is not explicitly defined so it should be gtk-2-themes and gtk-3-themes in this case?):

slots:
  gtk-2-themes:
     interface: content
     source:
        read:
           - $SNAP/share/gtk2/Qogir
...............
   gtk-3-themes:
      interface: content
      source:
         read:
           - $SNAP/share/themes/Qogir

When I check the connections of the theme snap:

Interface  Plug  Slot                            Notes
content    -     qogir-theme-snap:gtk-2-themes  -
content    -     qogir-theme-snap:gtk-3-themes  -

It also adds the name of the snap qogir-theme-snap:gtk-3-themes. GTK snaps have plugs for gtk-common-themes:gtk-3-themes and do not connect automatically to qogir-theme-snap:gtk-3-themes.

Correct

The prefix of the snap name shouldn’t matter. Snaps of GTK applications simply declare gtk-common-themes as the default provider, not the only provider. If you can manually connect the theme snap to the application snap, then everything should be ok on the theme snap side.

So the only thing left is to request a global auto-connection for the qogir-theme-snap. This is something that the publisher of the snap needs to do. This is an example of such a request: Auto connections of wine-base-stable, wine-base-devel and wine-base-staging

One more example; this is the request the people from the gtk-common-themes snap made: Auto-connection of gtk3-themes, icon-themes, and sound-themes interfaces

I am the publisher of qogir-theme-snap and vimix-gtk-themes-snap. The manual part works fine. So the only thing which I need to do is request auto-connections for both snaps?

Correct, although it might be better to first rename your snaps. I think the store folks might object to the current names. It’s best to avoid using snap in the names because it’s redundant. I don’t think there is a convention yet, so let me propose this:

<name>-[<type>-]themes

The type should not be added when the snap contains multiple types of themes (both gtk-3 and icon themes, for example). The KDE folks currently have to use the gtk-common-themes snap for cursor and icon themes, and they’re not too happy about that name :wink:

So in your case, that would become

  • qogir-themes, and
  • vimix-themes

If you ever add support for Qt themes, you could add them to these snaps, or create a new snap qogir-qt-5-themes.

PS: thanks for your patience in figuring this out. You seem to be the first person actually using this new method :wink:

Note that it’s currently not possible to actually rename a snap. The best method is to unpublish your current snap and create a new one.

I’ve added snap to the name as an indicator that the theme is only for snaps but this does not sound very logical at the moment. I will upload the with the proper names. I understand that once downloaded you can’t delete a snap. By unpublish do you mean closing all channels?

As a side note and because you mentioned qt, is it possible for a snap to make a symbolic link to the home directory during the initial setup, something like:

ln -s $SNAP/share/themes/SomeTheme /home/$user/.local/share/themes/SomeTheme

In other words, can a system-wide theme be installed as a snap package?

PS: Many thanks for the help! I am new to snaps but I really like them.

Closing all channels should do it. You can also unlist your snap in the settings tab on snapcraft.io. More info: Remove snap from store

If I understand you correctly, you want a user to install a system-wide theme by installing a snap? You cannot do this from the snap itself, but this should be possible by the user. We did something similar for the communitheme snap (the initial name of the Yaru theme). The end of this blog explains how it works: https://didrocks.fr/2018/04/10/welcome-to-the-ubuntu-bionic-age-new-wip-ubuntu-theme-as-a-snap/

Basically, you can add the share directory of your snap to XDG_DATA_DIRS and your theme will be available system-wide. If you want to check it out, this is still available on Ubuntu 18.04. Later releases shipped Yaru, so the session which set the XDG_DATA_DIRS was removed. I’m not sure if you can do it without a session file, because GNOME shell needs to pick up the XDG_DATA_DIRS variable and that won’t happen if you set it after GNOME shell starts.

If you’re interested, take a look at these files on Ubuntu 18.04

/snap/communitheme/current/session
/usr/share/wayland-sessions/ubuntu-communitheme-snap-wayland.desktop
/usr/share/xsessions/ubuntu-communitheme-snap.desktop
# + this stuff is added to in gsettings: https://launchpadlibrarian.net/362687782/ubuntu-settings_17.10.19_18.04.diff.gz

Edit: just saw you mentioned Qt. I have no idea if something like this is possible on KDE…

Many thanks for the help once again! I have renamed the snaps.

Regarding auto-connections, do I need to create a new topic for every snap? I plan to upload a few more themes. Probably it would be better to upload as many as I can and then create a single thread

A single thread would be good, indeed.

Automatic theme snap installation is on my todo list. Here are some notes about the design:

The plan there is to have a background user session service packaged as a strict confined snap (both for security, and to limit cross-distro release compatibility problems). It would watch for theme changes, and prompt to install theme snaps as needed.

As for connecting up slots, this will be handled by the greedy connection support as mentioned by @galgalesh. There are a few points to keep in mind though:

  1. the greedy connection feature relies on snap declarations provided by the store to indicate that multiple connection is desired. This would need to be provided by gtk-common-themes and all other snaps providing the slot.
  2. We need some level of review tools support before allowing third parties to publish theme snaps that will auto-connect. For example checking that a GTK 3 theme snap provides nothing but CSS, images, and perhaps a gtk.gresource file.

Having the theme change detection service manually connect plugs/slots is not desirable since (a) it bypasses the autoconnect checks, and (b) it won’t cover apps installed after the theme change.

1 Like

It sounds very nice to have a snap that watches for theme changes.

Regarding connection slots, if I understand correctly conditions 1) and 2) are needed for making the whole process automated. Is there a practice for this to be done manually at the moment?

I’ve packed 4 custom themes as snaps (hopefully more in the future) and I am wondering if there is a chance for them to be granted auto-connection to gtk-3-themes, gtk-2-themes and icon-themes? My template is the gtk-common-themes snapcraft.yaml, more specifically the Matcha gtk theme part. I am trying to help the author of Matcha with his other themes which are not included in gtk-common-themes. I am happy to include whatever information is needed in the request thread.

For reference, @gantonayde is talking about this request for auto-connecting his themes: Auto-connect custom GTK themes to gtk-3-themes, gtk-2-themes and icon-themes

If I understand it correctly, this is what needs to happen before that request can be granted:

  1. @gantonayde needs to separate each type of theme into a separate snap for gtk, icon and sound themes. Each snap needs to be named according to the convention explained in Automatic theme snap installation notes.

    The theme name will be case folded, reserved characters removed, and prefixed with gtk-theme-, icon-theme-, or sound-theme- to form the snap name. This means we can simply query the store for a particular snap name to determine whether the theme exists.

    I assume gtk-theme will be separated into gtk-3-theme, gtk-2-theme and gtk-4-theme? so gtk-3-theme-qogir would be one of the names?

  2. The review-tools need to be updated.

  3. @gantonayde needs to create a new auto-connection request.

@jamesh, can you confirm this is what needs to happen before the themes from @gantonayde can be granted auto-connection? This is of course separate from the work to automatically install themes. Having the auto-connection working by itself will already be a big improvement for users with custom themes.

1 Like

The usual method of requesting policy exceptions is the “store-requests” category on this forum. I would expect that we do the same for this. It will be a manual process, but you’d only have to go through it once.

(2) is the more difficult part, and would be a prerequisite for allowing third party theme snaps to autoconnect. It’s definitely something we want to get sorted out: we don’t want to be packaging the world’s themes ourselves, and don’t want to have to manually approve each update to third party theme snaps.

@galgalesh, many thanks for the clarifications and the summary. I’m new to this, apologies for not giving the right references.

@jamesh, it makes a lot of sense splitting the icon, gtk and sound themes, especially considering that not all themes have their own icon packs. Would it be possible to confirm that the naming convention which @galgalesh suggested above, i.e. gtk-2-theme-, gtk-3-theme- instead of gtk-theme- is the one needed? It is not a problem to split the themes and upload them separately, I just don’t want to register all possible names for no reason.

The thing which I cannot understand is whether the themes will be considered for auto-connection without the updated review-tools. Should I upload them now or it will be better to wait for the update?

I was planning to just use gtk-theme- as the prefix for snap names, for two reasons:

  1. When there is a matched set of GTK 2 and GTK 3 themes, they’re usually maintained by the same developers, and often released together as a set.
  2. The XSETTINGS protocol exposes a single gtk-theme-name setting, rather than version specific settings.

We’ve got one test snap up on the store for testing: gtk-theme-traditionalhumaized. It doesn’t have the “greedy connection” snap declarations from the store yet, so it doesn’t yet demonstrate the auto connection behaviour we want.

I’d prefer you wait until we have the review tools checks in place. We want to make sure all theme snaps eligible to install are “safe”, and we don’t yet have a complete picture of what that means yet. It will probably include:

  1. Contains the expected content interface slots
  2. Shared content is valid (valid images, valid CSS, etc).
  3. The snap does not provide any apps, daemons, or hooks

The last one is intended to ensure that installing the theme snap doesn’t result in code execution. We don’t want someone to package a popular theme and sneak in a cryptocurrency miner as a background service, for instance.

2 Likes

It is true that this needs more discussion. It is easy enough to verify no apps, daemons, hooks and even executable code, but thinking through what this looks like end to end is definitely needed.