Thanks for asking all the right questions. To an extend I’ve been exploring this problem space by seeing how far I can get, fixing the next pain point and iterating. My instinct at this point is to go for the simplest set of requirements that might possibly be usable and reassess after that.
A simple, confined desktop
A confined graphical shell that launches other snaps based on /var/lib/snapd/desktop/applications
provides a lot of flexibility. (In a classic environment it would even allow “classic” snaps to be run and arbitrary execution from there.)
As you say, reading this directory should just be an AppAmor rule. But that’s just the start.
Executables or .desktop files
Sticking to desktop files avoids a slippery slope that leads to something like execvpe()
and passing file descriptors.
It just leaves the questions of how to pass any % arguments used in Exec
and what interprets the .desktop contents. (I see xdg-open
in the Launcher
source, but, to the Internet’s surprise xdg-open
doesn’t understand .desktop files - a shame as otherwise they could be passed to OpenURL.)
I guess a first iteration could simply the Exec
line and exec that. (Which is what I do in egmde currently.)
Icons
Currently, as you observer, icon’s won’t work (and are already broken on some distros):
$ grep Icon= /var/lib/snapd/desktop/applications/*.desktop
/var/lib/snapd/desktop/applications/cevelop_cevelop.desktop:Icon=/snap/cevelop/x1/icon.xpm
/var/lib/snapd/desktop/applications/classic-snap-analyzer_classic-snap-analyzer.desktop:Icon=/snap/classic-snap-analyzer/5/meta/gui/classic-snap-analyzer.png
/var/lib/snapd/desktop/applications/clion_clion.desktop:Icon=/snap/clion/81/bin/clion.png
/var/lib/snapd/desktop/applications/gnome-calculator_gnome-calculator.desktop:Icon=/snap/gnome-calculator/406/meta/gui/org.gnome.Calculator.svg
/var/lib/snapd/desktop/applications/gnome-characters_gnome-characters.desktop:Icon=/snap/gnome-characters/296/meta/gui/org.gnome.Characters.svg
/var/lib/snapd/desktop/applications/gnome-logs_gnome-logs.desktop:Icon=/snap/gnome-logs/61/meta/gui/org.gnome.Logs.svg
/var/lib/snapd/desktop/applications/gnome-system-monitor_gnome-system-monitor.desktop:Icon=/snap/gnome-system-monitor/100/meta/gui/org.gnome.SystemMonitor.svg
/var/lib/snapd/desktop/applications/inkscape_inkscape.desktop:Icon=/snap/inkscape/4693/share/inkscape/branding/inkscape.svg
/var/lib/snapd/desktop/applications/multipass_multipass-gui.desktop:Icon=/snap/multipass/1002/meta/gui/multipass-gui.svg
/var/lib/snapd/desktop/applications/vlc_vlc.desktop:Icon=/snap/vlc/1049/usr/share/icons/hicolor/256x256/apps/vlc.png
I’m going to declare that “out of scope” for the current discussion. if a standard location materializes then it becomes easy.
Environment variables to launch desktop apps
The only successfully confined desktop environment I know of is egmde-confined-desktop. In this, the environment variables are not available in the host user environment (if any).
Variable |
Source |
Comment |
XDG_RUNTIME_DIR |
Set by snapd |
on classic, different to the user session |
WAYLAND_DISPLAY |
Set by egmde when launching an app |
|
DISPLAY |
This snap doesn’t enable X11 apps |
Would set by egmde when launching an app |
XDG_RUNTIME_DIR and WAYLAND_DISPLAY
We need a way to map the file $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY
in requesting context to $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY
in the application context.
There’s discussion elsewhere (Wayland interface, $XDG_RUNTIME_DIR and connecting clients to server) about managing XDG_RUNTIME_DIR. (WAYLAND_DISPLAY ought to be considered there too, but is assumed to be unset). If we assume that both server and client snaps do the “dance” described there, then it should work.
DISPLAY
I’m content to leave support for X11 based applications for a later iteration.
Opening files
I’m tempted to say “not a problem”. Any application that can be passed a filename should cope with the filename being invalid or the file being inaccessible. But if we don’t pass filenames in the first iteration we can postpone further consideration of this.
A first iteration
With the limitations discussed above, it seems much could be achieved by adding an OpenDesktop
method to io.snapcraft.Launcher
that accepts the name of the .desktop file, extracts and sanitizes the Exec
line and execs the resulting command in much the same manner as OpenURL
execs xdg-open
.
Do you see anything I am missing?