Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow a flatpak to discover/call another flatpak #283

Open
Jehan opened this issue Dec 7, 2017 · 12 comments

Comments

@Jehan
Copy link

commented Dec 7, 2017

Hi!

GIMP has this nifty new feature for opening RAW images, which is we use third-party advanced RAW software for the job. The idea is: why bother reimplementing a shitty 3-slider RAW developer as a plugin which will mostly be a toy when there are really good complete ones, and several being Free Software, like darktable or rawtherapee.
So now when someone tries to open a RAW in GIMP, we detect installed darktable and rawtherapee and redirect the call to the user's favorite RAW software (if both are installed, one can choose one's favorite in GIMP's preferences). When the editing stops on this third-party software, it automatically sends back the result to GIMP for further editing.

Unfortunately this feature stopped working with flatpak. Flatpaked GIMP don't see DT/RT installed by the system packaging, nor installed as flatpak.

Let's say we don't mind not detecting non-flatpak DT/RT. After all, flatpak is a sandbox and one of the goal is to shield the system. But couldn't there be an API to detect other flatpaks and being able to run them? I see there is a darktable flatpak for instance. It would be awesome if we could detect it within GIMP flatpak and run org.darktable.Darktable.

@TingPing

This comment has been minimized.

Copy link
Member

commented Dec 7, 2017

You can open URIs but it doesn't work for local file://'s so that is probably the best way to expose that. It does create an easy sandbox escape but the user will have to explicitly allow it.. don't know if that makes it ok.

@Jehan

This comment has been minimized.

Copy link
Author

commented Dec 7, 2017

How would it work exactly? I'm not sure I understand your workaround.

For info, right now (out of flatpak), we discover the third-party app in a Linux OS by simply checking its availability in the path.

@TingPing

This comment has been minimized.

Copy link
Member

commented Dec 7, 2017

You let the host handle file associations and you would just pass it the raw file.

@Jehan

This comment has been minimized.

Copy link
Author

commented Dec 7, 2017

Not all RAW software will work well with GIMP (currently only darktable and rawtherapee). There is a coded layer between GIMP and the RAW software. This specific feature has been closely created together by developers of all 3 projects (GIMP, darktable and RawTherapee) so that there is a back-and-forth interaction/connection.

In particular if we just let file association handle the file, once the user is done developing the RAW, the third party software would not give back the result to GIMP. And that also means we can't just give the file to the RAW software in a common way. GIMP actually runs a command with specific options.
Here is the workflow currently:

  • the photographer opens a RAW file in GIMP;
  • GIMP automatically opens the RAW file in DT/RT;
  • the photographer tweaks/develops the image in DT/RT;
  • when finished, the photographer closes DT/RT (no need to save/export anything);
  • GIMP automatically loads the result of the developed RAW;
  • the photographer can continue working on the image in GIMP.

So no, we can't just let the host handle file association. The point is not to redirect the file towards some other software and not hear about it anymore. That feature would make no sense at all (if that's what we want to do, we'd just say we don't support RAW images). The point is acknowledging that the RAW development is better done in a specialized software, but further image editing are better done in GIMP. This is basically a workflow where various more specialized software work together seamlessly and are connected, sharing images and work-in-progress at different steps, like a "Free Software graphics suite" or something.

@matthiasclasen

This comment has been minimized.

Copy link
Contributor

commented Dec 7, 2017

Well, thats just not how sandboxes work: they isolate applications from each other and from the host system. If you want deep integration, you can ship the auxiliary software as part of your flatpak, and have it run in the same sandbox. Otherwise, you may need an api between the two apps to facilitate this sort of interaction. A d-bus api would be much easier to integrate in the existing tooling than launching the app with special options.

@Jehan

This comment has been minimized.

Copy link
Author

commented Dec 7, 2017

Ok we'll discuss this.
It may indeed be better than a flatpak-specific communication protocol.
I opened this on our side: https://bugzilla.gnome.org/show_bug.cgi?id=791362

@matthiasclasen

This comment has been minimized.

Copy link
Contributor

commented Dec 31, 2018

This is basically a portal question, so moving it over to xdg-desktop-portal

@matthiasclasen matthiasclasen transferred this issue from flatpak/flatpak Dec 31, 2018

@wjt

This comment has been minimized.

Copy link

commented Sep 3, 2019

Given an application-specific D-Bus API, and --talk-name=com.example.Foo in the app which needs to be able to tell Foo to do things, that app can tell whether Foo is installed by either trying to call a method on it (which would fail if it's not installed) or using ListActivatableNames to see whether it's present. The other half of this would be a “please install this app” portal.


The status quo is that, if you don't mind being GNOME specific and your app can talk to org.gnome.Software, you can tell it to show the details page for an app:

org.gtk.Actions.Activate("details", [GLib.Variant("(ss)", ("system/flatpak/flathub/desktop/org.gnome.dfeet/stable", ""))], {})

Or to install it (without user confirmation):

Activate("install", [GLib.Variant("(su)", ("system/flatpak/flathub/desktop/org.wesnoth.Wesnoth/stable", 1))], {})

Aside from the GNOME-specificity, there are some big caveats:

  • You have to know the remote name and branch name for the app
  • You can't tell when the app has been installed (or cancelled) without polling

I imagine that a better interaction would be (on GNOME):

  • App calls InstallApp(window_id, "com.example.Foo", {"preferred-remote": "org.flathub.Stable"})
  • If Foo is not installed:
    • User gets a cut-down version of the GNOME Software details page as a dialog, where they can choose to install Foo or cancel
    • Once they do one or the other, Response fires
  • If Foo is already installed:
    • Response fires at once? Unfortunately, this would allow any application to test for what other applications are installed, which has been deemed undesirable in the past, though at least the user would be spammed with dialogs for each app that's not installed so it would be visible…
  • Assuming success, App can now activate and talk to Foo over D-Bus

Seem plausible? @manuq can you comment from the point of view of wanting an API like this?

One thought was whether we could instead add a hint to OpenURI / OpenFile of the preferred application to use to open something, and in the case where that app is not installed, the portal could offer to install it.

@manuq

This comment has been minimized.

Copy link

commented Sep 3, 2019

@wjt yes, your description matches exactly what an ideal portal API would look like.

  • Ability to check if another app is installed from a flatpaked app.
  • Ability to offer the user to install the app if not installed (through gnome-software in GNOME).
  • Continue the original app flow once the other app is installed.

And I agree, making this a user-facing portal mitigates the sandbox flaw of discovering other apps.

Regarding app A start talking to app B, our use-case only needs app B installed. We talk to gnome-shell to launch the other app with the org.gnome.Shell.AppLauncher.Launch() DBus method, and if that doesn't work we try org.gtk.Application.Activate().

@matthiasclasen

This comment has been minimized.

Copy link
Contributor

commented Sep 3, 2019

I think sneaking this into OpenURI might not work for all cases - you might not have a uri / file to open with the app, but instead a D-Bus request to make, or sth.

The overall plan sounds good to me.

If we are concerned about discovering installed apps, we could add a separate permission for that.

@hadess

This comment has been minimized.

Copy link
Contributor

commented Sep 3, 2019

One thing that I'm really not sure about is how you'd solve that original workflow without either questions that the user can't answer naturally, or a lack of question that would mean that too much is opened.

What would the UI look like for those apps? How do you trigger those links/API calls between applications?

From afar, it looks like a souped-up "OpenURI" with a signal back when editing is done, an "Edit In..." call, something which Android's Intent can already do.

Should this be part of a wider "Sharing" mechanism between apps instead? Or do we really want to poke holes just between those applications and no others?

@hadess

This comment has been minimized.

Copy link
Contributor

commented Sep 3, 2019

Or do we really want to poke holes just between those applications and no others?

On that, applications from the same domain on iOS have more open permissions between themselves, so that Google's YouTube application can offer to open a location in Google's Maps application rather than in the native/default maps application. I don't know if there's a mechanism to do that for arbitrary applications though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants
You can’t perform that action at this time.