Classic confinement request: draftman


Hi –

I’m the developer of a draft-management writing tool called draftman ( and would like to add a snap to my distribution methods ( Currently, I use a PPA ( for distribution.

The classic refinement request comes because draftman lets users choose any editor they wish for editing – most writing software with draft management features comes with an editor built in. To select an editor, the user uses a file-chooser dialog to select, for example, “/usr/bin/gedit” or “/whatever/path/foobar.editor”. When the user double clicks a scene, the editor of choice is opened with the scene for editing. Access to the binary is obviously read-only. While experimenting with this, classic was the only way I could get things to work properly without permission issues. I still have theming problems, but they are minor.

xdg-open was suggested to me, but is not an option because very often, writers use different editors for casual markdown editing (where xdg-open might be set to use gedit) vs. writing long-form fiction or non-fiction (for which a user might prefer typora). In other words, a global mime-type handler doesn’t necessarily work well here.

I have other snaps published (jgalaxian, dodge) and was actually a member of your snap team briefly (about 5 days) last summer as a tech writer before I was moved to MaaS, where I contributed not only documentation but their API-annotation code. I’ve sadly moved on from Canonical for now, but I’m still an advocate for all things Ubuntu.

Happy to entertain other ideas about ways not to use classic confinement, of course.


Read-only access to binaries within app

The requirements are understood and it seems like we would have a way forward for strict confinement with the application, but I’m having a hard time coming up with that path. It seems like portals would be a good fit due to the use of the file selector, but portals, afaik, doesn’t allow you to choose something to launch. There is a roadmap item for a more general prompting mechanism that could probably be used, but it isn’t available yet (@alexmurray - any news on the apparmor prompting front?).

In essence, everything about draftman sounds like it would be a good candidate for strict, except it has the arbitrary applications launching facility (that is user driven). @jamesh - curious on your thoughts on this.

@Wimpress, @popey, @igor, @evan - can you perform publishing vetting?


Thanks for taking a look. I realize it’s a bit of an edge case.


Portals should handle this okay. If I call the OpenURI.OpenFile portal method on a text file from a snap, I get the following popup:


In this case, the file was detected as text/plain on the host system, and these were the applications that claim to be able to open that mime type.

The main problem is that there is currently no guarantee that the portal service will be available on the user’s system. We’ve got xdg-desktop-portal 1.0.3 successfully backported to xenial, bionic, and cosmic, but there’s nothing to get it installed on people’s computers. That will probably require adding it as a dep for ubuntu-desktop, since it’s not really an appropriate dep for snapd itself (since that would bring the whole desktop stack into server images, for instance).


I’m unfamiliar with xdg-desktop-portal, but it sounds to me from your description that I could add it as a dependency of draftman and then change draftman to use it whether it was being run from a snap or not. Is that right?


xdg-desktop-portal is a set of services designed to make sandboxed desktop applications more useful. It originated from the Flatpak team, but was designed to be useful with multiple confinement systems.

It is primarily useful for cases where the coarse grained access decisions we make with AppArmor, mount name spaces, etc are not enough. So instead we give the confined process access to a service that can perform actions on its behalf.

In this particular case, the action is “launching an application associated with a file” when the confined application has no ability to enumerate or execute installed applications. The chooser dialog also forms part of the security policy by requiring user action outside of the confinement sandbox to complete the request.


I’m a little confused by the xdg-desktop-portal API docs, which are thorough but not helpful if you’re a newb. You mentioned that you had a simple example running. Can you point me to a snap repo with code that actually uses this?


I used the test-snapd-portal-client snap to test this: a simple Python client that directly calls the portal D-Bus APIs (primarily intended to support some spread tests, but also useful for simple proof of concept tests like this). This is not the usual way an application would be expected to use xdg-desktop-portal though.

There is portal support code baked into glib and GTK that you can enable by setting GTK_USE_PORTAL=1 in the environment. The support relies on up to date glib and GTK inside the sandbox though: some features are not yet fully enabled even if you’re building a core18 snap. That’s something we’re still working on.

On the Qt side, there is a platform theme plugin that fills a similar role of adapting the standard APIs to delegate to xdg-desktop-portal where appropriate:


This is all great info. Thanks for that.

So, unless I misunderstand, it sounds like in the near (?) future, there will in fact be an accepted method for doing this soft of thing, but at the moment, it’s still in the works.

@jdstrand, can we move forward with --classic for now and revisit this wheen the features @jamesh has explained are readily available and documented? (I never loved having to select a path for editing apps via a filechooser and the xdg-desktop-portal seems like a much more elegant solution, but I’d rather wait until there is a blessed method for doing this.)

Hopefully, I can get through the publishing vetting. Forgot to include my launchpad id ( This might help with that process as well.

Thanks again for taking a closer look at things.


@advocacy - ping, can you do the vetting?


Bump. Just a reminder.