Discussion:
expanding the inhibit spec
Ryan Lortie
2014-01-07 18:16:30 UTC
Permalink
hi,

(with the toolkit maintainer hat on) I want to expand the Inhibit spec:

http://standards.freedesktop.org/idle-inhibit-spec/0.1/

Specifically, I am interested in supporting this API:

https://developer.gnome.org/gtk3/stable/GtkApplication.html#GtkApplicationInhibitFlags

with exactly one common D-Bus interface that is implemented by any
freedesktop desktop environment that I may find Gtk applications running
on (ie: anywhere other than macos and win32, which already have their
own backends).

Right now, we use gnome-session. That's obviously problematic from the
standpoint of Gtk running anywhere other than desktops based on GNOME.
We have a proposal to add support for attempting first to use the idle
inhibit spec in the case of wanting to inhibit idle, with a fallback
path for other cases or the case that this interface is not available,
but this is precisely the sort of thing I want to avoid.

I just want one interface that I always use.

Some more prior art for this is the logind inhibit interface:

http://www.freedesktop.org/wiki/Software/systemd/inhibit/

In my opinion, the flavour of this interface is more or less correct but
there's a couple of reasons why I don't think that using the systemd
interface directly is appropriate:

- not everyone is using logind
- the logind interface is on the system bus
- it is labelled as being a "privileged operation"

I'd want an interface that is on the session bus and designed to be used
by normal applications (perhaps subject to sandboxing restrictions).

I also find the use of "delay" inhibits to be slightly distasteful, at
least for logout or shutdown. In my opinion, applications that want to
do cleanup tasks on exit should register SIGTERM handlers and deal with
them that way, exiting when done. I understand that it may be useful to
know when the system about to suspend or hibernate, however, in order to
sync up files on disk (just in case) or close network connections.

The service that implements this in the session would surely need to
communicate with other processes in order to coordinate this. It would
at least have to communicate with the process responsible for the
screensaver to prevent it from being activated and with logind in order
to forward information that it might care about. I believe that this is
a good argument for having a single "one stop shopping" interface
instead of many finger-grained ones. It's easier to use on the consumer
side and on the implementation side, no matter what, there is going to
have to be some forwarding of requests.

I'm sure there will be a lot of input on these ideas. My plan is to
just propose something that looks vaguely like logind's API, but on the
session bus level, and based on application IDs (or desktop file names)
but I will wait until hearing some feedback before proceeding on to more
concrete proposals.

Thanks in advance for the input.
Simon McVittie
2014-01-07 18:42:33 UTC
Permalink
Post by Ryan Lortie
I also find the use of "delay" inhibits to be slightly distasteful, at
least for logout or shutdown. In my opinion, applications that want to
do cleanup tasks on exit should register SIGTERM handlers and deal with
them that way, exiting when done. I understand that it may be useful to
know when the system about to suspend or hibernate, however, in order to
sync up files on disk (just in case) or close network connections.
Delaying suspend is necessary if you want the screen to lock reliably,
to avoid this bug:

* system tells screensaver, asynchronously, "hey, I'm suspending"
* screensaver doesn't get scheduled because the system is busy
* system suspends
* system resumes (potentially after being stolen)
* user's secret files are briefly visible
* screensaver finally locks

That's why current GNOME uses that part of the logind interface.

Delaying logout/shutdown seems like the only way to get "save changes?"
prompts to work? Or do you think "authoring" applications (e.g. word
processor, image editor) should write out current unsaved state to some
sort of cache periodically or on SIGTERM, and restore it next time
they're run, like Firefox does?

(A word processor etc. blindly doing a normal "Save" when killed with
TERM doesn't seem good - if the user had intended to "Save As..." a
different filename, you've just overwritten the wrong file.)

S
Ryan Lortie
2014-01-07 18:50:11 UTC
Permalink
hi,

Thanks for the reply.
Post by Simon McVittie
Delaying suspend is necessary if you want the screen to lock reliably,
I agree that delaying suspend as useful (as I mentioned before).

It seems like the screensaver situation could be handled more gracefully
as a special-case, though... although my use of "gracefully" and
"special case" together there is already setting off alarm bells in my
own head...
Post by Simon McVittie
Delaying logout/shutdown seems like the only way to get "save changes?"
prompts to work? Or do you think "authoring" applications (e.g. word
processor, image editor) should write out current unsaved state to some
sort of cache periodically or on SIGTERM, and restore it next time
they're run, like Firefox does?
(A word processor etc. blindly doing a normal "Save" when killed with
TERM doesn't seem good - if the user had intended to "Save As..." a
different filename, you've just overwritten the wrong file.)
It's my opinion that in this case you should not use "delay logout" but
rather "block logout", with the understanding that a blocked logout will
always involve user interaction in the case that a logout is attempted.

In your mentioned case of a word processor I expect that the word
processor would have to keep track of if it has any unsaved changes. At
the state transition (between unsaved changes and not) it would have to
contact the session to explicitly register the inhibit.

The one thing I absolutely want to avoid is applications that tell the
session "I may want to pop a dialog at logout; ask me about it then..."
The application should explicitly inform the session about if a dialog
is necessary or not. If it is necessary, the dialog _will_ be popped up
(probably by the session, as is the case for gnome-shell). If it is
not, then the session _will_ logout, and the only courtesy that an
application will receive is a SIGTERM signal followed by a short grace
period before it sees SIGKILL.


Perhaps what is really needed is a block-only (no delay) inhibit API
alongside a separate "inform of suspend/hibernate with allowances for
short delays" API.

Cheers
Jasper St. Pierre
2014-01-07 21:27:52 UTC
Permalink
Post by Ryan Lortie
hi,
Thanks for the reply.
Post by Simon McVittie
Delaying suspend is necessary if you want the screen to lock reliably,
I agree that delaying suspend as useful (as I mentioned before).
It seems like the screensaver situation could be handled more gracefully
as a special-case, though... although my use of "gracefully" and
"special case" together there is already setting off alarm bells in my
own head...
Post by Simon McVittie
Delaying logout/shutdown seems like the only way to get "save changes?"
prompts to work? Or do you think "authoring" applications (e.g. word
processor, image editor) should write out current unsaved state to some
sort of cache periodically or on SIGTERM, and restore it next time
they're run, like Firefox does?
(A word processor etc. blindly doing a normal "Save" when killed with
TERM doesn't seem good - if the user had intended to "Save As..." a
different filename, you've just overwritten the wrong file.)
It's my opinion that in this case you should not use "delay logout" but
rather "block logout", with the understanding that a blocked logout will
always involve user interaction in the case that a logout is attempted.
I've seen users click "Shut Down" and then close the lid or turn the
monitor off. Delay is exactly what we want here. An app shouldn't
permanently inhibit Shut Down. Yes, the user may lose some data, but
staying open forever wouldn't help here, you'd just run out of battery and
crash.
Post by Ryan Lortie
In your mentioned case of a word processor I expect that the word
processor would have to keep track of if it has any unsaved changes. At
the state transition (between unsaved changes and not) it would have to
contact the session to explicitly register the inhibit.
The one thing I absolutely want to avoid is applications that tell the
session "I may want to pop a dialog at logout; ask me about it then..."
The application should explicitly inform the session about if a dialog
is necessary or not. If it is necessary, the dialog _will_ be popped up
(probably by the session, as is the case for gnome-shell). If it is
not, then the session _will_ logout, and the only courtesy that an
application will receive is a SIGTERM signal followed by a short grace
period before it sees SIGKILL.
Perhaps what is really needed is a block-only (no delay) inhibit API
alongside a separate "inform of suspend/hibernate with allowances for
short delays" API.
Cheers
_______________________________________________
xdg mailing list
http://lists.freedesktop.org/mailman/listinfo/xdg
--
Jasper
Ryan Lortie
2014-01-07 22:40:21 UTC
Permalink
hi,
Post by Jasper St. Pierre
I've seen users click "Shut Down" and then close the lid or turn the
monitor off. Delay is exactly what we want here. An app shouldn't
permanently inhibit Shut Down. Yes, the user may lose some data, but
staying open forever wouldn't help here, you'd just run out of battery and
crash.
This is not what "delay" means in this context. Delay here is used for
apps that want to add a (very) short delay to suspend, etc. so that they
can do some task just before the machine powers down. It's for cases
like the one Simon brought up earlier -- where the screensaver wants to
make sure the screen is in the locked state before the machine goes
down.

I consider that it would be a matter of system policy if the session
elects to ignore the "block" inhibits after some period of time. For
example, if I have gedit blocking logout with "You have unsaved changes;
are you sure?" and the user doesn't reply to that dialog for 60 seconds,
it may well be the policy of the desktop environment that the system
will go down anyway, gedit be damned.

Cheers
Lennart Poettering
2014-01-08 09:21:00 UTC
Permalink
Post by Ryan Lortie
Post by Simon McVittie
Delaying suspend is necessary if you want the screen to lock reliably,
I agree that delaying suspend as useful (as I mentioned before).
It seems like the screensaver situation could be handled more gracefully
as a special-case, though... although my use of "gracefully" and
"special case" together there is already setting off alarm bells in my
own head...
There are a lot more cases like this. For example service discovery
frameworks want to tell other hosts on the network that they re no
longer available so that other UIs can be nicely updated. THink gupnp or
Avahi.

Jabber clients want to change the idle state before suspending, and so
on...
Post by Ryan Lortie
Post by Simon McVittie
Delaying logout/shutdown seems like the only way to get "save changes?"
prompts to work? Or do you think "authoring" applications (e.g. word
processor, image editor) should write out current unsaved state to some
sort of cache periodically or on SIGTERM, and restore it next time
they're run, like Firefox does?
(A word processor etc. blindly doing a normal "Save" when killed with
TERM doesn't seem good - if the user had intended to "Save As..." a
different filename, you've just overwritten the wrong file.)
It's my opinion that in this case you should not use "delay logout" but
rather "block logout", with the understanding that a blocked logout will
always involve user interaction in the case that a logout is
attempted.
How's that supposed to work? If the shutdown was blocked, its is
entirely denied, so who will then reschedule the shutdown later? The
word processor which wanted to show this dialog?
Post by Ryan Lortie
The one thing I absolutely want to avoid is applications that tell the
session "I may want to pop a dialog at logout; ask me about it
then..."
Note that our upstream wiki page about shutdown/suspend delay inhibition
actually explicitly explains that the delay locks should only be taken
when the files they edit "are dirty", and that they should be released
as soon as everything is synced to disk.

I am pretty sure it's a matter of documentation and getting the APIs
right to make people not take these locks too early and unnecessarily.

Lennart
--
Lennart Poettering, Red Hat
Ryan Lortie
2014-01-08 14:44:23 UTC
Permalink
hi,
Post by Lennart Poettering
How's that supposed to work? If the shutdown was blocked, its is
entirely denied, so who will then reschedule the shutdown later? The
word processor which wanted to show this dialog?
Note that our upstream wiki page about shutdown/suspend delay inhibition
actually explicitly explains that the delay locks should only be taken
when the files they edit "are dirty", and that they should be released
as soon as everything is synced to disk.
We talked about this once before, last year. In my opinion, this case
should be handled by the applications all getting SIGTERM at logout time
(assuming that there are no proper full "blocks"). If they have things
that they want to take care of before being killed, they will install a
SIGTERM handler. If not, they will die immediately. After a while
(5s...), if processes are still around, SIGKILL.

Cheers
Lennart Poettering
2014-01-09 12:47:56 UTC
Permalink
Post by Ryan Lortie
hi,
Post by Lennart Poettering
How's that supposed to work? If the shutdown was blocked, its is
entirely denied, so who will then reschedule the shutdown later? The
word processor which wanted to show this dialog?
Note that our upstream wiki page about shutdown/suspend delay inhibition
actually explicitly explains that the delay locks should only be taken
when the files they edit "are dirty", and that they should be released
as soon as everything is synced to disk.
We talked about this once before, last year. In my opinion, this case
should be handled by the applications all getting SIGTERM at logout time
(assuming that there are no proper full "blocks"). If they have things
that they want to take care of before being killed, they will install a
SIGTERM handler. If not, they will die immediately. After a while
(5s...), if processes are still around, SIGKILL.
Well, I certainly think apps should handle SIGTERM properly, and what
you describe above is actually what systemd does for all processes it
runs. However, it's something that only works if the operation to delay
is actually one that necessarily ends up in process termination, and
which never needs to be reversed. This is not true for
hibernation/suspending/hybrid for example...

The delay locks how logind implements them right now have the benefit
that they are globally staged: we ask programs to prepare for shutdown
without actually telling them to shutdown. Only when everything went
according to plan and we still desire to execute the operation then we
will go to the next step and actually shut down things... Your SIGTER
approach otoh is destructive immediately: it's a much stricter request
to apps, they not only have to prepare for the operation they also hve
to do it.

Lennart
--
Lennart Poettering, Red Hat
Ryan Lortie
2014-01-09 17:49:19 UTC
Permalink
hi,
Post by Lennart Poettering
Well, I certainly think apps should handle SIGTERM properly, and what
you describe above is actually what systemd does for all processes it
runs. However, it's something that only works if the operation to delay
is actually one that necessarily ends up in process termination, and
which never needs to be reversed. This is not true for
hibernation/suspending/hybrid for example...
This is specifically why I believe that suspend(/hibernate) should have
a separate delay mechanism still made available.
Post by Lennart Poettering
The delay locks how logind implements them right now have the benefit
that they are globally staged: we ask programs to prepare for shutdown
without actually telling them to shutdown. Only when everything went
according to plan and we still desire to execute the operation then we
will go to the next step and actually shut down things... Your SIGTER
approach otoh is destructive immediately: it's a much stricter request
to apps, they not only have to prepare for the operation they also hve
to do it.
From a UI standpoint this "we must do it now" approach it exactly what I
want. I don't like the possibility that an application can go from
"tell me when you're shutting down so I can tend to some last minute
things" to "oh wait! stop! abort!". Once the first app has been told
"prepare yourself", it should not be possible for another app to
interrupt the process.

That's why I prefer two completely separate mechanisms: block to stop
the process from occurring in the first place, and (if no blocks are
there) a round of signals, after which there is absolutely nothing that
apps can do to prevent the shutdown from proceeding.

Cheers
Oswald Buddenhagen
2014-01-11 09:11:54 UTC
Permalink
Post by Lennart Poettering
Post by Lennart Poettering
The delay locks how logind implements them right now have the benefit
that they are globally staged: we ask programs to prepare for shutdown
without actually telling them to shutdown. Only when everything went
according to plan and we still desire to execute the operation then we
will go to the next step and actually shut down things...
XSMP reloaded. ^^
Post by Lennart Poettering
Post by Lennart Poettering
Your SIGTER approach otoh is destructive immediately: it's a much
stricter request to apps, they not only have to prepare for the
operation they also hve to do it.
From a UI standpoint this "we must do it now" approach it exactly what
I want. I don't like the possibility that an application can go from
"tell me when you're shutting down so I can tend to some last minute
things" to "oh wait! stop! abort!".
nice parody ...
Post by Lennart Poettering
That's why I prefer two completely separate mechanisms: block to stop
the process from occurring in the first place, and (if no blocks are
there) a round of signals, after which there is absolutely nothing that
apps can do to prevent the shutdown from proceeding.
there is no need to have two separate mechanisms here.
of course there should be an additional safety net (say, systemd nukes the
complete cgroup after the session manager exits), but there is no need
at all to implement the actual session management via two independent
mechanisms.
David Faure
2014-02-02 10:24:16 UTC
Permalink
Post by Ryan Lortie
That's why I prefer two completely separate mechanisms: block to stop
the process from occurring in the first place, and (if no blocks are
there) a round of signals, after which there is absolutely nothing that
apps can do to prevent the shutdown from proceeding.
Note that this is exactly how good old X11 session management works :-)

I don't know the low-level XSMP names for these things, but that the Qt level
it ends up with "commitDataRequest" (where users can be prompted to save
unsaved data) and "saveStateRequest" in the second round, for saving just
before exiting.
I much rather prefer that over SIGTERM, which is not modular (can't have more
than one handler) and awkward to integrate in C++.
--
David Faure, ***@kde.org, http://www.davidfaure.fr
Working on KDE, in particular KDE Frameworks 5
Ted Gould
2014-01-07 21:00:36 UTC
Permalink
On Tue, 2014-01-07 at 13:16 -0500, Ryan Lortie wrote:

+AD4 (with the toolkit maintainer hat on) I want to expand the Inhibit spec:
+AD4
+AD4 http://standards.freedesktop.org/idle-inhibit-spec/0.1/
+AD4
+AD4 Specifically, I am interested in supporting this API:
+AD4
+AD4 https://developer.gnome.org/gtk3/stable/GtkApplication.html+ACM-GtkApplicationInhibitFlags
+AD4
+AD4 with exactly one common D-Bus interface that is implemented by any
+AD4 freedesktop desktop environment that I may find Gtk applications running
+AD4 on (ie: anywhere other than macos and win32, which already have their
+AD4 own backends).



It seems to me that what is odd about that API is that it conflates two
different types of inhibition, one is application lifecycle and the
other system lifecycle. I don't think it makes sense at a system level
to merge those two together because they're handled very differently in
different parts of the stack.

For example on Unity/Mir we're managing the application lifecycle using
the Mir connection. This way we can suspend apps based on their
position in the window management stack and usage as well as session
based things like logging out. For applications being put into a deep
sleep and the session being closed are virtually identical. For
information on the app lifecycle:

http://samohtv.wordpress.com/2013/08/15/application-lifecycle-model-policies/

On the side of system policy like controlling the screen blanking and
other power saving mechanisms (for instance you're watching a movie) we
have a system service powerd. It runs on the system bus as switching
sessions can also have an effect on how it determines how to operate.

http://www.mattfischer.com/blog/?p+AD0-460

I think that the two types of APIs are sufficiently different that
co-mingling them isn't really a gain.

Ted
Ryan Lortie
2014-01-07 22:38:05 UTC
Permalink
hi,
Post by Ted Gould
It seems to me that what is odd about that API is that it conflates two
different types of inhibition, one is application lifecycle and the
other system lifecycle. I don't think it makes sense at a system level
to merge those two together because they're handled very differently in
different parts of the stack.
There is nothing here that is directed toward the 'app lifecycle' that
you're talking about. This is just an API for inhibiting system-level
stuff (like 'logout', 'suspend', 'lock screen', etc).

Cheers
Ted Gould
2014-01-08 01:53:05 UTC
Permalink
On Tue, 2014-01-07 at 17:38 -0500, Ryan Lortie wrote:

+AD4 On Tue, Jan 7, 2014, at 16:00, Ted Gould wrote:
+AD4 +AD4 It seems to me that what is odd about that API is that it conflates two
+AD4 +AD4 different types of inhibition, one is application lifecycle and the
+AD4 +AD4 other system lifecycle. I don't think it makes sense at a system level
+AD4 +AD4 to merge those two together because they're handled very differently in
+AD4 +AD4 different parts of the stack.
+AD4
+AD4 There is nothing here that is directed toward the 'app lifecycle' that
+AD4 you're talking about. This is just an API for inhibiting system-level
+AD4 stuff (like 'logout', 'suspend', 'lock screen', etc).


It seems to me that +ACI-logout+ACI is a special case of +ACI-don't kill me.+ACI This
is because logout is basically just killing all the applications.

Ted
Ryan Lortie
2014-01-08 06:30:54 UTC
Permalink
hi,
It seems to me that "logout" is a special case of "don't kill me." This
is because logout is basically just killing all the applications.
If you have applications that are designed to work in a framework that
may kill them at any time then they would certainly not want to use this
sort of mechanism to prevent themselves from being killed.

If (for example) memory pressure increased and caused the OS to decide
that it wants to quit my process, just about the last thing I'd want to
see is a randomly popping-up dialog asking me to save my documents.
That's the sort of thing that this feature targets.

I think your usecase is very much different and will require
applications to be written differently to cope with it, in any case.

Cheers
Bastien Nocera
2014-01-08 13:50:50 UTC
Permalink
Post by Ryan Lortie
hi,
Post by Ted Gould
It seems to me that what is odd about that API is that it conflates two
different types of inhibition, one is application lifecycle and the
other system lifecycle. I don't think it makes sense at a system level
to merge those two together because they're handled very differently in
different parts of the stack.
There is nothing here that is directed toward the 'app lifecycle' that
you're talking about. This is just an API for inhibiting system-level
stuff (like 'logout', 'suspend', 'lock screen', etc).
They inhibit *automatic* logout and suspend. Lock screen is never
inhibited (the user can always lock the screen), idle is inhibited which
stops the screensaver coming on. Please use the correct vocabulary when
discussing this, otherwise we'll end up with one big mess of a
discussion.
Ryan Lortie
2014-01-08 07:08:21 UTC
Permalink
Here's a bit more concrete of a proposal after thinking about it for a
day. I really like the logind API (and am particularly fond of using
fds instead of integer cookies) so my design borrows heavily from there.
Here's what I expect in terms of an app-facing API. It's a single
method:


bus name org.freedesktop.Inhibit
object path /org/freedesktop/Inhibit
interface org.freedesktop.Inhibit

Inhibit (in s what,
in a{sv} who,
in s why,
out h fd);


Where 'what' and 'why' are as per the logind spec.

Who is a dictionary that has these optional keys:

- desktop-file-name: the name of the desktop file of this app
- application-id: the org.freedesktop.Application-style app id
- window-xid: the (uint32) xid of the window causing the
inhibit, if on X11
- window-wayland-id: ???

with the requirement that at least one of these things must be set.


The output fd would work in the same way as it does for logind. You
simply close the fd when you're no longer interested.


Copying the fd-based design from logind means that we can in many cases
trivially forward the requests and pass the fd from logind directly back
to the application, allowing for the possibility of a simple stateless
forwarding proxy implementation (which could even exit after a period of
inactivity).


Eventually, if we are convinced that it is widely useful, we may want to
add an additional API to deal with (what I consider to be the separate
case of) delaying the suspend process for a short while:

Delay (in s what,
out h fd);

with "what" limited to "sleep" and the following semantics for the fd
(from the client's viewpoint):

- reads a \1 byte when suspend wants to occur
- replies by writing a \1 byte to say "okay. i'm ready"
- reads a \0 byte when suspend has come back
- can close at any time to cancel the delay

This allows us to avoid having a PrepareToSleep() signal that must be
emitted (in particular, when it must be emitted in the "welcome back"
case in order for clients to re-establish their delays). Clients can
reuse the same fd for as many sleep cycles as they like. As with
logind, the delay would only work for a short period of time. logind's
default of 5s seems reasonable.

Note that there is no "why" or "who" about delays -- this is because
delays never result in any kind of UI being presented. The only reason
"who" might be useful is for debugging and in that case it will be
possible to discover the bus name of the requester and map it back to
them in that way.


Individual desktop environments might want to have ways for other
components in the desktop to query the list of things that are causing
the logout/screensaver/etc to be inhibited, but I do not consider this
to be a desirable feature of an application-facing API. Desktops would
be free to decide these details for themselves.

Cheers
Simon McVittie
2014-01-08 11:28:27 UTC
Permalink
Post by Ryan Lortie
Eventually, if we are convinced that it is widely useful, we may want to
add an additional API to deal with (what I consider to be the separate
Delay (in s what,
out h fd);
with "what" limited to "sleep" and the following semantics for the fd
- reads a \1 byte when suspend wants to occur
- replies by writing a \1 byte to say "okay. i'm ready"
- reads a \0 byte when suspend has come back
- can close at any time to cancel the delay
This allows us to avoid having a PrepareToSleep() signal that must be
emitted (in particular, when it must be emitted in the "welcome back"
case in order for clients to re-establish their delays).
Having implemented "delay logout until we've tried to disconnect IM
connections" in telepathy-mission-control, in terms of the logind API
(which only has Inhibit and PrepareToSleep), I'm not sure that a
separate Delay API is really needed. You can get the same effect just as
easily by inhibiting suspend, and responding to PrepareToSleep by doing
whatever async thing you need to do (disconnecting IM connections or
saving files or whatever), then when that finishes, releasing the
inhibit "lock".

AIUI, logind already has a system-policy timeout after which it will
ignore inhibit "locks" (or at least those opened by unprivileged
processes) and suspend anyway.

For the concrete use-cases I've seen for this (apps prompting to save
documents, Telepathy disconnecting IM connections), we don't necessarily
even need the "welcome back" handling - the app could just get a new
inhibit fd when it goes back from "clean" to "dirty" state (the user
edits the document, or Telepathy reconnects the IM connection).

S
Ryan Lortie
2014-01-08 14:48:56 UTC
Permalink
hi,
Post by Simon McVittie
Having implemented "delay logout until we've tried to disconnect IM
connections" in telepathy-mission-control, in terms of the logind API
(which only has Inhibit and PrepareToSleep), I'm not sure that a
separate Delay API is really needed.
As I mentioned before, I'm concerned that not everyone will be using
logind.

That said, delay-before-suspend is sort of a separate thing from
Inhibit, and I'm not sure I want to support it at all in the API I
propose, so my concerns about "able to do all kinds of inhibit from one
place" don't necessarily apply here.

This would still land us in a place that means that those who want to do
tasks before suspend could only do it on logind systems. I don't really
consider that to be a substantial problem (particularly because
non-logind systems may not even have this ability to begin with), but I
guess it would be nice to have a more generic mechanism for that as
well... one day...

Cheers
Lennart Poettering
2014-01-09 12:50:32 UTC
Permalink
Post by Ryan Lortie
hi,
Post by Simon McVittie
Having implemented "delay logout until we've tried to disconnect IM
connections" in telepathy-mission-control, in terms of the logind API
(which only has Inhibit and PrepareToSleep), I'm not sure that a
separate Delay API is really needed.
As I mentioned before, I'm concerned that not everyone will be using
logind.
That said, delay-before-suspend is sort of a separate thing from
Inhibit, and I'm not sure I want to support it at all in the API I
propose, so my concerns about "able to do all kinds of inhibit from one
place" don't necessarily apply here.
This would still land us in a place that means that those who want to do
tasks before suspend could only do it on logind systems. I don't really
consider that to be a substantial problem (particularly because
non-logind systems may not even have this ability to begin with), but I
guess it would be nice to have a more generic mechanism for that as
well... one day...
So, let's turn this around: which operations precisely do you want to
cover here, and in which modes?

You only want blocking locks, and you want to cover
suspending/hibernation, and the screenlock, and ...?

Lennart
--
Lennart Poettering, Red Hat
Bastien Nocera
2014-01-09 13:13:43 UTC
Permalink
Post by Lennart Poettering
Post by Ryan Lortie
hi,
Post by Simon McVittie
Having implemented "delay logout until we've tried to disconnect IM
connections" in telepathy-mission-control, in terms of the logind API
(which only has Inhibit and PrepareToSleep), I'm not sure that a
separate Delay API is really needed.
As I mentioned before, I'm concerned that not everyone will be using
logind.
That said, delay-before-suspend is sort of a separate thing from
Inhibit, and I'm not sure I want to support it at all in the API I
propose, so my concerns about "able to do all kinds of inhibit from one
place" don't necessarily apply here.
This would still land us in a place that means that those who want to do
tasks before suspend could only do it on logind systems. I don't really
consider that to be a substantial problem (particularly because
non-logind systems may not even have this ability to begin with), but I
guess it would be nice to have a more generic mechanism for that as
well... one day...
So, let's turn this around: which operations precisely do you want to
cover here, and in which modes?
You only want blocking locks, and you want to cover
suspending/hibernation, and the screenlock, and ...?
The listed inhibit flags in GtkApplication are here:
https://developer.gnome.org/gtk3/stable/GtkApplication.html#GtkApplicationInhibitFlags

Cheers
Lennart Poettering
2014-01-10 04:35:09 UTC
Permalink
Post by Ryan Lortie
Post by Lennart Poettering
So, let's turn this around: which operations precisely do you want to
cover here, and in which modes?
You only want blocking locks, and you want to cover
suspending/hibernation, and the screenlock, and ...?
https://developer.gnome.org/gtk3/stable/GtkApplication.html#GtkApplicationInhibitFlags
OK, that looks like a pretty short list, and as an abstraction API for
the logind API (for _INHIBIT_SUSPEND and _INHIBIT_IDLE) and for some
gnome-session/fdo API (for _INHIBIT_SWITCH, _INHIBIT_LOGOUT and
_INHIBIT_IDLE) this sounds pretty close to what I'd like to see.

Lennart
--
Lennart Poettering, Red Hat
Lennart Poettering
2014-01-08 09:13:16 UTC
Permalink
Post by Ryan Lortie
- not everyone is using logind
- the logind interface is on the system bus
On its own this one is a pretty pointless reason, no?
Post by Ryan Lortie
- it is labelled as being a "privileged operation"
Well, PolicyKit is used, and the default policy we install for that
actually allows all users that are logged in to at least get a delay
lock.
Post by Ryan Lortie
The service that implements this in the session would surely need to
communicate with other processes in order to coordinate this. It would
at least have to communicate with the process responsible for the
screensaver to prevent it from being activated and with logind in order
to forward information that it might care about. I believe that this is
a good argument for having a single "one stop shopping" interface
instead of many finger-grained ones. It's easier to use on the consumer
side and on the implementation side, no matter what, there is going to
have to be some forwarding of requests.
I am not convinced that passing these things around though a number of
layers is really a good design choice. I mean, abstraction for the sake
of abstraction is not somethign we should do.

The screensaver and logout inhibition logic is certainly something that
logind has no business with, and will never have any business
with. However, I'd claim it would be a better choice if the different
places where these inhibtors are implemented was abstracted behind a
single interface on the client side (e.g. in a unified gtk API) rather
than stacking layers upon layers in a variety of dbus services....

This is particularly a problem since logind's inhibition APIs will
actually record UID and PID of the client requesting these inhibitors,
and if the inhibition would be proxied via some session dbus service
then all inhibitors would appear as being owned by that proxy rarther
then the actual client. The UID/PID of the client taking the inhibitor
is both used for the Polkit decision and is available as queriable
metadata for other clients when they list existing inhibitors. (This
would also break a little feature I recently added to logind, which is
that i logs about inhibiting clients that delay suspend so long so that
the timeout hits. it would be a pitty if this was lost because
everything is proxyied via some other process).
Post by Ryan Lortie
I'm sure there will be a lot of input on these ideas. My plan is to
just propose something that looks vaguely like logind's API, but on the
session bus level, and based on application IDs (or desktop file names)
but I will wait until hearing some feedback before proceeding on to more
concrete proposals.
I certainly welcome standardization efforts for doing the
session-specific inhibitors, but I really don't buy the ideas of
stacking this on top of the lower level stuff.

If the lower level stuff is missing features, we can certainly add those
to the lower level bits...

Lennart
--
Lennart Poettering, Red Hat
Ryan Lortie
2014-01-08 14:39:54 UTC
Permalink
hi,
Post by Lennart Poettering
I certainly welcome standardization efforts for doing the
session-specific inhibitors, but I really don't buy the ideas of
stacking this on top of the lower level stuff.
If the lower level stuff is missing features, we can certainly add those
to the lower level bits...
The main issue of everything you've said is that it assumes that
everyone will use logind. That's your opinion about how the world
should work, but I don't think we're quite there yet.

If logind could put a service on the session bus which implemented a
common API (ie: not one that was part of the org.freedesktop.login1 API)
for this then I'd already be much happier. I really think the session
bus part is necessary because other people implementing this API are
much more likely to be in a position to do it as a session service than
as a system service.

Even that would not make me completely happy, however, because I
couldn't handle all of my inhibit needs there (unless you were willing
to expand the list of things you support inhibiting, for informational
purposes for the session to see).

Cheers
Lennart Poettering
2014-01-09 12:39:48 UTC
Permalink
Post by Ryan Lortie
hi,
Post by Lennart Poettering
I certainly welcome standardization efforts for doing the
session-specific inhibitors, but I really don't buy the ideas of
stacking this on top of the lower level stuff.
If the lower level stuff is missing features, we can certainly add those
to the lower level bits...
The main issue of everything you've said is that it assumes that
everyone will use logind. That's your opinion about how the world
should work, but I don't think we're quite there yet.
No, that is expressly not what I am assuming. All I am saying is that
this should be abstracted at the client side, and not in yet another
service in the middle. Because if you proxy all this, then you actually
break the one case that most of us actually care for (which is the
logind case)...

I mean, I am pretty sure that most other inhibition APIs would also try
to record who actually took the lock, and would thus be affected too if
you always proxy everything via some other daemon so that everything
looks like it came from the very same processs...
Post by Ryan Lortie
If logind could put a service on the session bus which implemented a
common API (ie: not one that was part of the org.freedesktop.login1 API)
for this then I'd already be much happier. I really think the session
bus part is necessary because other people implementing this API are
much more likely to be in a position to do it as a session service than
as a system service.
I am not following here. What are you trying to do? THese are platform
APIs. D-Bus is not a plugin framework to make it possible to avoid
changing glib or gtk to support different platform backends directly.

I mean, what I am really not getting here: you are trying to abstract
something here so that multiple backends are possible. I assume you have
at least two backends in mind there? Which ones are those? logind is
one, but what is the other? It can't be Windows, since your proposed API
uses fd passing, but what is the other backend you want to abstract
here? FreeBSD? Do they even have an inhibition framewrk?

Abstracting this with just the vague idea that maybe one day there might
be a second backend, and that then maybe when that day comes it would be
better to run that on the session bus sounds just awfully wrong.

So, what precisely are you trying to make work here?
Post by Ryan Lortie
Even that would not make me completely happy, however, because I
couldn't handle all of my inhibit needs there (unless you were willing
to expand the list of things you support inhibiting, for informational
purposes for the session to see).
"things logind supports inhibiting"? what would those be?

I'd really prefer if you abstracted this in gtk or glib on the client
side. I mean, note that for some kind of inhibitors, like for example
the "idle" inhibitor the backend might not even be a bus service but
simly some local syscall. "idle" inhibitors are pretty close to android
wakelocks or suspend blockers in the kernel. It would only be natural to
expose them behind the same API. Wakelocks are cheap locks, programs can
take the often and for short periods, and you shouldn't need to involve
a mandatory bus service with that...

At the moment I can think of at different three different APIs that gtk
might want to provide a single API for: kernel suspend blockers, logind
suspend locks, and gnome-session screen-lock or logout locks. All of
them would greatly benefit if the actual client would talk directly to
them: to get the accounting right, to get permissions right and to get
the latency right.

Note that if you type "poweroff" on a systemd system right now, and some
desktop app "foobar" has taken a system shutdown lock, then poweroff
will actually tell you about that and tell you exactly which
process/user, and request you retry with "--ignore-inhibit" if you still
want to shutdown.... Please don't break this. it would be quite a loss
of usefulness if it would always say "gnome-session" as process...

Lennart
--
Lennart Poettering, Red Hat
Ryan Lortie
2014-01-09 18:08:22 UTC
Permalink
hi,
Post by Lennart Poettering
No, that is expressly not what I am assuming. All I am saying is that
this should be abstracted at the client side, and not in yet another
service in the middle. Because if you proxy all this, then you actually
break the one case that most of us actually care for (which is the
logind case)...
I mean, I am pretty sure that most other inhibition APIs would also try
to record who actually took the lock, and would thus be affected too if
you always proxy everything via some other daemon so that everything
looks like it came from the very same processs...
I agree that this is a weakness. It's a weakness that could be
addressed by logind implementing this API for itself (or trusting
forwarded information from gnome-session or other designated processes).

I think this is a problem that we already have though, because
GtkApplication is currently doing all inhibit via gnome-session and I
don't plan to change that to use logind directly until we have a more
reasonable way to do so...
Post by Lennart Poettering
I am not following here. What are you trying to do? THese are platform
APIs. D-Bus is not a plugin framework to make it possible to avoid
changing glib or gtk to support different platform backends directly.
I mean, what I am really not getting here: you are trying to abstract
something here so that multiple backends are possible. I assume you have
at least two backends in mind there? Which ones are those? logind is
one, but what is the other? It can't be Windows, since your proposed API
uses fd passing, but what is the other backend you want to abstract
here? FreeBSD? Do they even have an inhibition framewrk?
Abstracting this with just the vague idea that maybe one day there might
be a second backend, and that then maybe when that day comes it would be
better to run that on the session bus sounds just awfully wrong.
So, what precisely are you trying to make work here?
First, it's a pain for me (with Gtk hat on) to have to test for the
existence of various D-Bus services in order to decide which one I
should talk to. This is the kind of thing we're used to, though... we
have a bug open about it right now. I'm using this thread as a way to
resist adding code complexity on my side about it.

It's a whole other issue, though, when we start to talk about
independent app vendors who don't want to use Gtk. People who want to
make something in SDL and have it just work. What do we tell them? I
guess we could start by asking them "what is your intended platform?"

"I don't know.. GNOME? The freedesktop APIs? Linux? systemd-using
systems?"

It turns out that in order to answer this question I actually have to
ask another question: "what type of thing are you trying to suspend?"

If they say "screensaver due to idle", the answer is "GNOME" (because
logind doesn't handle this).

If they say "logout, because I have unsaved files", answer again is
"GNOME".

If they say "suspend, due to idle" or "suspend, because I want to do
cleanup tasks" the answer is now "logind" (or "Linux", if we want to
take the somewhat reasonable approach that logind is universal at least
for Linux systems).

This sort of lack of coherence is at the root of what is bothering me.
It's bad enough to approach from the standpoint of trying to make Gtk
work... it's nearly unapproachable from the standpoint of third parties.

After that, it only gets worse if they want their app to work nicely on
KDE as well, or maybe some non-Linux system (or a Linux system not using
logind). There's no good reason that application authors should be
forced to #ifdef the hell out of their code just because they care about
portability. POSIX isn't pointless, nor is what I'm asking for here.

I'm not saying that this would somehow magically cause FreeBSD to start
working tomorrow, but at least we give the FreeBSD guys a chance to
implement a reasonable/simple interface that would allow them to exist
on the same level of functionality as GNOME+logind+Linux. Ditto other
desktops.
Post by Lennart Poettering
Post by Ryan Lortie
Even that would not make me completely happy, however, because I
couldn't handle all of my inhibit needs there (unless you were willing
to expand the list of things you support inhibiting, for informational
purposes for the session to see).
"things logind supports inhibiting"? what would those be?
What I meant by this is that logind could start state-tracking for
things that it doesn't care about itself, such as "logout" or "prevent
screensaver". gnome-session could then watch logind to determine which
flags have been set and decide how to modify its own behaviour based on
that.

Note about "screensaver": I am assuming here that applications may want
to inhibit "idle" for more than one reason. If I'm downloading a file,
I may want to inhibit suspend-due-to-idle while still allowing the
screen to lock. If I'm playing a video, I probably want to inhibit
both.
Post by Lennart Poettering
I'd really prefer if you abstracted this in gtk or glib on the client
side. I mean, note that for some kind of inhibitors, like for example
the "idle" inhibitor the backend might not even be a bus service but
simly some local syscall. "idle" inhibitors are pretty close to android
wakelocks or suspend blockers in the kernel. It would only be natural to
expose them behind the same API. Wakelocks are cheap locks, programs can
take the often and for short periods, and you shouldn't need to involve
a mandatory bus service with that...
At the moment I can think of at different three different APIs that gtk
might want to provide a single API for: kernel suspend blockers, logind
suspend locks, and gnome-session screen-lock or logout locks. All of
them would greatly benefit if the actual client would talk directly to
them: to get the accounting right, to get permissions right and to get
the latency right.
Note that if you type "poweroff" on a systemd system right now, and some
desktop app "foobar" has taken a system shutdown lock, then poweroff
will actually tell you about that and tell you exactly which
process/user, and request you retry with "--ignore-inhibit" if you still
want to shutdown.... Please don't break this. it would be quite a loss
of usefulness if it would always say "gnome-session" as process...
I agree with all of your arguments here about the value of direct
communication, but I still don't accept that Gtk (and every 3rd party
app developer) should have to go to three different desktop-specific or
system-specific APIs to get the job done.

People do care about portability, and they generally prefer if they can
do it without a huge mess of #ifdef and runtime checking.

As for kernel suspend blocking or wakelocks... well, that's just outside
of the scope of what I'm proposing here. It's obviously not reasonable
to mediate this sort of this via D-Bus. It seems like something in GLib
would be more appropriate for that (and probably we'd need to abstract
it, if non-Linux systems ever added support).

Cheers
Lennart Poettering
2014-01-09 22:31:41 UTC
Permalink
Post by Ryan Lortie
Post by Lennart Poettering
I mean, I am pretty sure that most other inhibition APIs would also try
to record who actually took the lock, and would thus be affected too if
you always proxy everything via some other daemon so that everything
looks like it came from the very same processs...
I agree that this is a weakness. It's a weakness that could be
addressed by logind implementing this API for itself (or trusting
forwarded information from gnome-session or other designated
processes).
logind is not going to listen on session busses. Having trusted code on
untrusted client busses is never going to work.
Post by Ryan Lortie
Post by Lennart Poettering
Abstracting this with just the vague idea that maybe one day there might
be a second backend, and that then maybe when that day comes it would be
better to run that on the session bus sounds just awfully wrong.
So, what precisely are you trying to make work here?
First, it's a pain for me (with Gtk hat on) to have to test for the
existence of various D-Bus services in order to decide which one I
should talk to. This is the kind of thing we're used to, though... we
have a bug open about it right now. I'm using this thread as a way to
resist adding code complexity on my side about it.
Note that at least on kdbus checking for the presence of logind is a
single simple, synchronous ioctl, nothing more. It cannot get much
simpler than that...
Post by Ryan Lortie
It's a whole other issue, though, when we start to talk about
independent app vendors who don't want to use Gtk. People who want to
make something in SDL and have it just work. What do we tell them? I
guess we could start by asking them "what is your intended platform?"
"I don't know.. GNOME? The freedesktop APIs? Linux? systemd-using
systems?"
How many systems are those currently, and how many are those going to be
in a year or two? I mean, by then the set of systems that have dbus (and
possibly a future fdo inhibitor service) and the set of systems that
have logind is probably going to be identical, no? I mean, if people
avoid logind, aren't they also avoiding dbus?
Post by Ryan Lortie
It turns out that in order to answer this question I actually have to
ask another question: "what type of thing are you trying to suspend?"
If they say "screensaver due to idle", the answer is "GNOME" (because
logind doesn't handle this).
If they say "logout, because I have unsaved files", answer again is
"GNOME".
If they say "suspend, due to idle" or "suspend, because I want to do
cleanup tasks" the answer is now "logind" (or "Linux", if we want to
take the somewhat reasonable approach that logind is universal at least
for Linux systems).
This sort of lack of coherence is at the root of what is bothering me.
It's bad enough to approach from the standpoint of trying to make Gtk
work... it's nearly unapproachable from the standpoint of third parties.
I can certainly see the problem, but I think an abstract fdo service on
the session bus is not an answer to that.

I mean, if people decide not to use a library that abstracts these
things, like glib (or qt...), then they get to keep both pieces, the
have to deal with the compatibility problems, and the incoherent
interfaces...

I think it would be great if the difference between the major desktops
regarding inhibition locks for screenlock/logout could be dealt with by
agreeing on some common bus interface. With that in place you'd cover >
80% of the cases by just supporting logind and this new session api in
your app.

This would still mean incoherent interfaces, but at least the number of
backends to explicitly support is just 2.
Post by Ryan Lortie
Post by Lennart Poettering
Post by Ryan Lortie
Even that would not make me completely happy, however, because I
couldn't handle all of my inhibit needs there (unless you were willing
to expand the list of things you support inhibiting, for informational
purposes for the session to see).
"things logind supports inhibiting"? what would those be?
What I meant by this is that logind could start state-tracking for
things that it doesn't care about itself, such as "logout" or "prevent
screensaver". gnome-session could then watch logind to determine which
flags have been set and decide how to modify its own behaviour based on
that.
Note about "screensaver": I am assuming here that applications may want
to inhibit "idle" for more than one reason. If I'm downloading a file,
I may want to inhibit suspend-due-to-idle while still allowing the
screen to lock. If I'm playing a video, I probably want to inhibit
both.
I am vaguely negative about this, but I could be convinced. Can you
explain how precisely you'd assume the API for this would look like in logind?

Lennart
--
Lennart Poettering, Red Hat
Michal Suchanek
2014-01-22 18:43:25 UTC
Permalink
Post by Lennart Poettering
Post by Ryan Lortie
It's a whole other issue, though, when we start to talk about
independent app vendors who don't want to use Gtk. People who want to
make something in SDL and have it just work. What do we tell them? I
guess we could start by asking them "what is your intended platform?"
"I don't know.. GNOME? The freedesktop APIs? Linux? systemd-using
systems?"
How many systems are those currently, and how many are those going to be
in a year or two? I mean, by then the set of systems that have dbus (and
possibly a future fdo inhibitor service) and the set of systems that
have logind is probably going to be identical, no? I mean, if people
avoid logind, aren't they also avoiding dbus?
What is logind and can I start it after the fact when I find it's needed for
some weird GTK feature to work?

I can certainly do that with dbus when I find that GTK insists on using dbus
to notify the screensaver that the user is not idle.

Thanks

Michal
Bastien Nocera
2014-01-10 10:40:14 UTC
Permalink
On Thu, 2014-01-09 at 13:08 -0500, Ryan Lortie wrote:
<snip>
Post by Ryan Lortie
It's a whole other issue, though, when we start to talk about
independent app vendors who don't want to use Gtk. People who want to
make something in SDL and have it just work. What do we tell them? I
guess we could start by asking them "what is your intended platform?"
SDL is a bad example. The only inhibitor it uses is idle inhibition, and
I already cooked up a patch for it to use the (existing) fd.o spec for
that:
https://bugzilla.libsdl.org/show_bug.cgi?id=2169
Àlex Fiestas
2014-01-12 15:42:59 UTC
Permalink
Having read the whole thread (and about to write the power management support
for KDE5/Plasma 2) I think we do need a session daemon handling the things
that are out of logind1 scope and its api must be in fd.o, but I would like to
avoid duplicating api with it, and even worse end up proxying calls.

The way we have currently implemented logind1 support is just by adding one
inhibition with description "KDE Handlers this" which sucks since systemd is
not aware of what applications are inhibiting. This is valuable information we
must have in systemd in the future and that's why on future releases (KDE5)
the plan was to talk directly to logind1 whenever possible.

Distributions that don't want to use logind1 can implement a dbus service with
the same api, maybe we can move the inhibition api to its own service to make
it more obvious that that api doesn't depend on all the other logind1
features.

So in short:
+1 to have a common fd.o spec for things that can't be in logind1
-1 to duplicate api with logind1

Cheers.
Loading...