Proposal: allow snaps to specify their exact desktop file ID


#1

As part of the effort by the Ubuntu desktop team to migrate another application to a strict confinement snap, we are running up against problems with the way snapd names desktop files for applications. In particular, it is a problem for handling desktop notifications in gnome-shell.

This isn’t the first time people have run into problems with the current naming scheme:

In most of these cases you could argue that the application developer should adapt to snapd’s way of doing things, but I don’t think that holds for the notifications case. I’ll describe my reasoning for that in a follow-up post so as not to bog down the proposal.

Proposed Change

The common use case here is for applications that want to use the same identifier for their desktop file and a bus name they acquire on the D-Bus session bus. This is also commonly used as an AppStream identifier, which snaps can currently provide via the common-id key.

So I propose that if a snap provides any desktop files in meta/gui that are named like common-id + ".desktop" for any of the snap’s apps, that they be installed without the $snapname_ prefix. Further more, that these desktop files be associated with the app in the same way a $snapname_$appname.desktop file would.

This obviously introduces the possibility for naming conflicts where they didn’t previously exist, so snapd should refuse to install/upgrade a snap if the common-id desktop file is provided by another snap, which can be done by checking the X-SnapInstanceName key in the existing file.

It is also incompatible with parallel installs of a snap, but many desktop applications will try to acquire a particular D-Bus name. So they are likely already incompatible with parallel installation.

To achieve this, I think the following changes would be necessary:

  1. As we’re actually making use of the AppStream ID, we should perform actual validation of the field beyond that it is unique within a given snap. The specification provides some guidance, but we might want to check the two AppStream libraries too. We should check the existing corpus of snaps against whatever validation rules we decide on.

  2. wrappers.AddSnapDesktopFiles should recognise desktop files whose name matches a common-id for the snap and install them without the snap name prefix. A check should be added that we aren’t overwriting a desktop file owned by a different snap.

  3. Rather than using a $snapname_*.desktop glob, wrappers.RemoveSnapDesktopFiles should remove all desktop files with a matching X-SnapInstanceName key.

  4. cmd.ClientAppInfosFromSnapAppInfos should check for the existence of a desktop file named for the common-id of the app, and include it in the client.AppInfo metadata.


#2

Now for a rundown of the specific issue the current desktop file naming scheme causes for notifications.

GTK Notifications

GNOME 3 introduced a new desktop notifications API that I’ll refer to as “GTK Notifications” from here on since it uses the bus name org.gtk.Notifications.

Posting new notifications is done via an AddNotification method that takes the desktop ID of the application, a notification identifier local to the application, and the notification body.

When an action associated with the notification is fired, the shell uses the D-Bus activation feature of the Desktop Entry Specification to deliver action to the application via the Activate or ActivateAction methods. The main benefits of this over the older FDO Notifications spec is that shell can direct the action to relevant action rather than broadcasting a signal that wakes up every application, and that the application need not be running to receive the action.

For a desktop file to be D-Bus activatable, it’s name must be a valid D-Bus bus name. The desktop file names snapd assigns to applications include an underscore, which is invalid in bus names. So at present a snap app’s desktop file can never be D-Bus activatable.

And we can’t just pass a D-Bus name that the snap application is allowed to acquire, since gnome-shell explicitly checks to see if a file matching the passed in desktop ID actually exists:

https://gitlab.gnome.org/GNOME/gnome-shell/blob/master/js/ui/notificationDaemon.js#L627

Portal Notifications

The xdg-desktop-portal service does provide an API to let confined applications post notifications without being granted access to the FDO or GTK notification APIs:

Unfortunately, this does not help us. If we are running on a GNOME 3 system, the portal is effectively a simple proxy to the GTK notifications API that forces desktop ID to the one associated with the confined application (so it can’t spoof notifications for other apps), and the shell will then deliver actions to the app as normal. This means we run into exactly the same problems as if we granted the confined app access to org.gtk.Notifications directly.


#3

So far common-id has been used only has a hint for searches. Also while its documentation refers to AppStream its name is for a generic concept on our side.

Anyway as you mentioned because of the possibility of clashes (so possibly disputes, priority issues) is not clear to me that we can do this without some store side blessing mechanism like we have for aliases.

I would be interested in @jdstrand thoughts on this.