flatpak / xdg-desktop-portal

Desktop integration portal
https://flatpak.github.io/xdg-desktop-portal/
GNU Lesser General Public License v2.1
589 stars 191 forks source link

Inhibit portal and PrepareForSleep signal #137

Open bochecha opened 6 years ago

bochecha commented 6 years ago

Note: I was told on IRC this might be the right place to report this. If it isn't, please point me to the right bug tracker.

We have a portal apps can use to inhibit/uninhibit things like suspending the laptop, powering it off, or logging the user out.

GNOME apps will normally use this through GtkApplication.

I'm looking at flatpaking a Gtk chat application which currently talks directly to org.freedesktop.login1.Manager and I thought I would port it to the GtkApplication inhibit API.

However, the app doesn't actually take inhibitors, instead it connects to the PrepareForSleep signal, so it can disconnect from the chat server. (this is necessary to handle presence correctly, so contacts see that you are now offline)

I can't find a way to do that with GtkApplication, or with the inhibit portal.

Did I miss something? Or is this a feature which could be added?

hadess commented 6 years ago

Best way would be to add a separate API for that to GtkApplication so it can work on both sandboxed and non-sandboxed applications.

matthiasclasen commented 6 years ago

the portal api was modeled on what GtkApplication (and the org.gnome.SessionManager inhibit api) support. Both don't have any 'prepare' signals - those are inherently racy. Not sure we want to add them, tbh. It would require to either extend all the session manager apis to support something like it, or require complicated code in the portal to mix session manager and logind apis, which I don't think is a great idea.

bochecha commented 6 years ago

When you get the PrepareForSleep signal the app would want to take an inhibitor anyway during the time it does its thing then release it. (which the app I'm looking at doesn't do currently)

Is the race you talk about between the reception of the PrepareForSleep signal and taking the inhibitor? If so, that can probably be dealt with by taking an inhibitor when the app starts, then when the computer tries to suspend the app does its thing then release the inhibitor. But the app still needs to know that the computer wants to sleep, and can't because the app inhibits it.

There seems to be a general use-case here, of apps needing to do something before suspend. Forgetting about PrePareForSleep, what would be the right way to allow that?

hadess commented 6 years ago

Given the use case (giving the opportunity for network applications to log off gracefully), we might want NetworkManager (which uses this delay inhibitor) to delay the suspend, and send a signal about the network coming down shortly through GNetworkMonitor.

Looking at my desktop session, I'm not sure there's another use case for a non-sandboxed application for listening to this signal.

bochecha commented 6 years ago

Given the use case (giving the opportunity for network applications to log off gracefully), we might want NetworkManager (which uses this delay inhibitor) to delay the suspend, and send a signal about the network coming down shortly through GNetworkMonitor.

So NM would delay suspending the machine by a fix time, and apps would have just that much to do what they need? NM wouldn't wait for apps to signal back that they finished, and it would release the inhibitor no matter what after a set time? (short enough to not have the machine overheat in my backpack)

That could work I guess. 🙂

smcv commented 6 years ago

Is the race you talk about between the reception of the PrepareForSleep signal and taking the inhibitor? If so, that can probably be dealt with by taking an inhibitor when the app starts, then when the computer tries to suspend the app does its thing then release the inhibitor.

That is indeed how you're meant to use PrepareForSleep. telepathy-mission-control implements this logic in src/connectivity-monitor.c, for the same use-case as the original reporter (logging out from chat accounts before suspending). That particular source file is LGPL-2.1+ and reasonably self-contained, if anyone wants to copy it into other projects.

matthiasclasen commented 6 years ago

I think to make progres on this, we'd need a PrepareForSleep signal in org.gnome.SessionManager, since I don't really want GtkApplication to get on the system bus to talk to logind (in the unsandboxed case).