After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 621361 - Improve GApplication quit semantics
Improve GApplication quit semantics
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Class: GtkApplication
unspecified
Other Linux
: Normal enhancement
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2010-06-12 11:11 UTC by Matthew Barnes
Modified: 2012-03-05 03:46 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Matthew Barnes 2010-06-12 11:11:20 UTC
I was reading through GApplication and GtkApplication and was surprised at how similar some aspects of it are to Evolution's EShell class [1].

One area where I think the current GApplication API falls short is the assumption that applications can just quit immediately on command.  Often applications will need some time to finish ongoing network or disk operations.  Other times you may want to give the user a chance to cancel the quit (e.g. "You have unsaved changes, are you sure you want to quit?").

What I've tried to do in EShell is mimic the EggSMClient session shutdown protocol for normal application shutdown, where the application first emits a "quit-requested" signal which gives the user a chance to cancel quitting, followed by a "quit" signal.

I'd suggest mimicing the EggSMClient API as a starting point:

    Signals:

    void (*quit_requested)  (GApplication *application,
                             gint reason_for_quit);
    void (*quit_cancelled)  (GApplication *application);
    void (*quit)            (GApplication *application);

    Virtual Methods:

    void (*will_quit)       (GApplication *application,
                             gboolean will_quit);

The API is fairly obvious.  The quit_requested() handler must call will_quit() at some point (not necessarily immediately) to indicate whether to proceed with or cancel quitting.  The default quit_requested() handler would just call "will_quit(application, TRUE)", so simple applications that can always quit immediately don't need to bother with this.

I added a "reason_for_quit" argument to "quit_requested" because I'm discovering the need for it in Evolution, as you may want to handle the request differently in different scenarios.  I'd suggest predefining a few codes that applications can amend, like we do for dialog responses:

   - Quit action activated
   - Last window destroyed
   - Remote process requested quit
   - Session manager requested quit


[1] http://library.gnome.org/devel/eshell/stable/EShell.html
Comment 1 Matthias Clasen 2010-06-15 04:48:55 UTC
That gets dangerously close to session management.
Comment 2 Colin Walters 2010-06-15 18:58:56 UTC
(In reply to comment #0)
> I was reading through GApplication and GtkApplication and was surprised at how
> similar some aspects of it are to Evolution's EShell class [1].
> 
> One area where I think the current GApplication API falls short is the
> assumption that applications can just quit immediately on command.  Often
> applications will need some time to finish ongoing network or disk operations. 
> Other times you may want to give the user a chance to cancel the quit (e.g.
> "You have unsaved changes, are you sure you want to quit?").

You can create a dialog or whatever from inside your quit vfunc, and return FALSE to cancel the quit.

> I added a "reason_for_quit" argument to "quit_requested" because I'm
> discovering the need for it in Evolution, as you may want to handle the request
> differently in different scenarios.  I'd suggest predefining a few codes that
> applications can amend, like we do for dialog responses:
> 
>    - Quit action activated
>    - Last window destroyed
>    - Remote process requested quit
>    - Session manager requested quit

What do you do differently in these situations?
Comment 3 Matthew Barnes 2010-06-15 19:23:29 UTC
(In reply to comment #2)
> What do you do differently in these situations?

It's mainly for deciding whether to prompt the user and wait for his reponse or just wrap things up and shut down as quickly as possible.

For Evolution this most often comes up while composing an email: we can either save the draft to disk and automatically restore it in the next session, or prompt if you want to save to your drafts folder, send now, or discard it.  If a remote Evolution process is telling us to quit, we quit without prompting.

Another use case might be during some critical operation like burning a CD, you may want to just not allow the application to quit at all, unless perhaps when the whole desktop session is shutting down.

I guess the first two scenarios in the list above could be collapsed down to "user requested quit".
Comment 4 Paolo Borelli 2010-06-15 19:27:11 UTC
> You can create a dialog or whatever from inside your quit vfunc, and return
> FALSE to cancel the quit.
> 

One of the problems to take into account is that quit may not be a sync operation: you show a dialog to confirm exit, the user answers, some potentially slow and fallible operation is started and only after a while you know if you can actually exit or if an error should be reported etc.
Comment 5 Colin Walters 2010-06-15 19:35:40 UTC
(In reply to comment #3)
> (In reply to comment #2)
> > What do you do differently in these situations?
> 
> It's mainly for deciding whether to prompt the user and wait for his reponse or
> just wrap things up and shut down as quickly as possible.
> 
> For Evolution this most often comes up while composing an email: we can either
> save the draft to disk and automatically restore it in the next session,

You should be saving drafts to disk automatically anyways as defensive programming against crashes.

>  or
> prompt if you want to save to your drafts folder, send now, or discard it.  If
> a remote Evolution process is telling us to quit, we quit without prompting.

Hm...is this sort of like a "Do you really want to quit?" type thing under the assumption that if a user is composing a mail, they are more likely to have accidentally chosen Quit?

> 
> Another use case might be during some critical operation like burning a CD, you
> may want to just not allow the application to quit at all, unless perhaps when
> the whole desktop session is shutting down.

That's an entirely separate thing (and currently not wrapped in GtkApplication, but under GNOME you can talk to gnome-session directly via dbus to grab an inhibit).
Comment 6 Matthew Barnes 2010-06-15 20:13:38 UTC
Hmm, I guess I was assuming GApplication would be the natural replacement for EggSMClient, among other things.  Is session management support out of scope for GApplication?
Comment 7 Colin Walters 2010-06-15 20:21:16 UTC
(In reply to comment #6)
> Hmm, I guess I was assuming GApplication would be the natural replacement for
> EggSMClient, among other things.  Is session management support out of scope
> for GApplication?

Not out of scope, no.  But "session management" only exists on the X11 platform.  Some sort of operating system "session is terminating" signal is slightly more portable...but again, I'm wondering why it wouldn't work to call "quit" for "session is terminating".
Comment 8 Matthias Clasen 2010-06-16 01:55:00 UTC
> > Another use case might be during some critical operation like burning a CD, you
> > may want to just not allow the application to quit at all, unless perhaps when
> > the whole desktop session is shutting down.
> 
> That's an entirely separate thing (and currently not wrapped in GtkApplication,
> but under GNOME you can talk to gnome-session directly via dbus to grab an
> inhibit).

If we decide that Quit is the equivalent of gnome-sessions "Stop" I very much want to see the win32/gnome-session QueryEndSession and Inhibit machinery worked into GtkApplication.
Comment 9 Dan Winship 2010-06-16 14:24:24 UTC
(In reply to comment #8)
> If we decide that Quit is the equivalent of gnome-sessions "Stop" I very much
> want to see the win32/gnome-session QueryEndSession and Inhibit machinery
> worked into GtkApplication.

I'd mentioned this to Colin before, but EggSMClient has working implementations of both win32 and OS X "QueryEndSession" support. (As well as XSMP-based and gnome-session-D-Bus-based obviously.)

eggsmclient-win32 does not implement the win32 inhibit API (since we never added inhibit to eggsmclient), but there's a link to the relevant MSDN docs in the source code. IIRC it's pretty simple. But it only exists on Vista and later, and I'm pretty sure the rest of glib/gtk still fully supports XP, so the inhibit part would have to be conditional.

(Also, eggsmclient-win32 does a bunch of stuff using windows-native thread calls so that it would still work if you hadn't called g_thread_init(), but that could be simplified now that threads are always enabled.)

OS X does not have an inhibit API, it only has notify/cancel, like XSMP.

For platforms that don't have Inhibit (XSMP, Win XP, OS X), GtkApplication can just fall back to popping up the dialog with the inhibit reason on its own when it gets the QueryEndSession message.

(Why, yes, this *is* a last-ditch attempt to make EggSMClient not have been a complete waste of my time :-)
Comment 10 Colin Walters 2010-06-16 15:21:22 UTC
(In reply to comment #4)
> > You can create a dialog or whatever from inside your quit vfunc, and return
> > FALSE to cancel the quit.
> > 
> 
> One of the problems to take into account is that quit may not be a sync
> operation: you show a dialog to confirm exit, the user answers, some
> potentially slow and fallible operation is started and only after a while you
> know if you can actually exit or if an error should be reported etc.

Hmm...well, I'm not sure I see how GApplication can help here.  Even if we had (*start_quit) and (*really_quit_now), nothing is going to guarantee that your slow operation is going to be done by the time (*really_quit_now) is called.

The best you can do here is start your slow async operation after the dialog is done, and run a recursive mainloop waiting for slow async operation to complete.
Comment 11 Paolo Borelli 2010-06-16 21:02:11 UTC
(In reply to comment #10)
> (In reply to comment #4)
> > > You can create a dialog or whatever from inside your quit vfunc, and return
> > > FALSE to cancel the quit.
> > > 
> > 
> > One of the problems to take into account is that quit may not be a sync
> > operation: you show a dialog to confirm exit, the user answers, some
> > potentially slow and fallible operation is started and only after a while you
> > know if you can actually exit or if an error should be reported etc.
> 
> Hmm...well, I'm not sure I see how GApplication can help here.  Even if we had
> (*start_quit) and (*really_quit_now), nothing is going to guarantee that your
> slow operation is going to be done by the time (*really_quit_now) is called.
> 

It is not about quit() and really_quit(): the api proposed in comment 1 get it right because it is up to the app to signal that it is now ready to quit by calling the will_quit() vfunc.

> The best you can do here is start your slow async operation after the dialog is
> done, and run a recursive mainloop waiting for slow async operation to
> complete.

no no no, please no, recursive main loop are pure evil and should not be encouraged, especially in now that gapplication finally makes easy to have single instance apps with multilple independent windows
Comment 12 Colin Walters 2010-06-16 22:14:15 UTC
(In reply to comment #11)
> 
> It is not about quit() and really_quit(): the api proposed in comment 1 get it
> right because it is up to the app to signal that it is now ready to quit by
> calling the will_quit() vfunc.

Why can't your app not having exited be an implicit signal you're not ready to quit?

> > The best you can do here is start your slow async operation after the dialog is
> > done, and run a recursive mainloop waiting for slow async operation to
> > complete.
> 
> no no no, please no, recursive main loop are pure evil and should not be
> encouraged, especially in now that gapplication finally makes easy to have
> single instance apps with multilple independent windows

They definitely have of disadvantages, but in this case, we're almost always launching the recursive loop from a pretty low point in the stack (e.g. out of the gdbus idle handler or from a menu item), which is going to be pretty safe; in other words, you generally avoid having to make sure parts of your application are re-entrant.

Or - even simpler, queue an idle handler to display your "You need to save stuff" dialog, and just return FALSE.

Okay, let's be concrete here; what are we trying to accomplish?  In the case of GNOME, what I plan to do is simply (as mentioned above), take the fact that an app's still running as an implicit lock on exiting.  We'll call Quit on each app, and allow the user to interact with the ones that remain.  After some timeout, there will be user interface to allow terminating non-responding applications.

For Win32, I believe we could implement this by handle WM_QUERYENDSESSION - queue a handler for the main thread to call quit(), and if that quit response returns FALSE, we send a message to the win32 thread to tell it to respond with FALSE.
Comment 13 Paolo Borelli 2010-06-16 22:39:44 UTC
(In reply to comment #12)
> Why can't your app not having exited be an implicit signal you're not ready to
> quit?
> 

That is ok, the api proposed just allows the app to "collaborate" and be able to tell "ok, I am obeying now. I am exiting".


> They definitely have of disadvantages, but in this case, we're almost always
> launching the recursive loop from a pretty low point in the stack (e.g. out of
> the gdbus idle handler or from a menu item), which is going to be pretty safe;
> in other words, you generally avoid having to make sure parts of your
> application are re-entrant.
> 
> Or - even simpler, queue an idle handler to display your "You need to save
> stuff" dialog, and just return FALSE.
>

Not sure I follow here... my main problem with recursive main loops is that they block *all* the windows. So if I have two windows of the same single-instance app and show a modal dialog on one of the window using a recursive main loop, the other window (maybe on another workspace) is completely frozen to the user, without any reasonable reason.
 
> Okay, let's be concrete here; what are we trying to accomplish?  In the case of
> GNOME, what I plan to do is simply (as mentioned above), take the fact that an
> app's still running as an implicit lock on exiting.  We'll call Quit on each
> app, and allow the user to interact with the ones that remain.  After some
> timeout, there will be user interface to allow terminating non-responding
> applications.
> 

That sounds good, but will you poll the applications? Or wait a long timeout even the application already exited? Or wait a short timeout and maybe not give the user a proper chance to close things properly? The proposed api just let the application help the manager, by giving a hint that it is now ready to quit.

Also with just "quit" I do not see a way to cancel the process: the application receives quit, returns false and asks the user, the user decides that he wants to abort the quit process and clean up things properly. However all you know is that the process is still running, so you end up with the "force quit" dialog even if the user decided to keep the application
Comment 14 Matthias Clasen 2010-06-16 22:54:40 UTC
> Okay, let's be concrete here; what are we trying to accomplish?  In the case of
> GNOME, what I plan to do is simply (as mentioned above), take the fact that an
> app's still running as an implicit lock on exiting.  We'll call Quit on each
> app, and allow the user to interact with the ones that remain.  After some
> timeout, there will be user interface to allow terminating non-responding
> applications.

Colin, I'm still getting mixed messages from you here on whether the shell is going to take over session mgmt or not... Can we get this sorted out on the shell side, please ?
Comment 15 Colin Walters 2010-06-17 00:26:30 UTC
(In reply to comment #13)
> (In reply to comment #12)
> > Why can't your app not having exited be an implicit signal you're not ready to
> > quit?
> > 
> 
> That is ok, the api proposed just allows the app to "collaborate" and be able
> to tell "ok, I am obeying now. I am exiting".

But why don't you just obey by...exiting?

> Not sure I follow here... my main problem with recursive main loops is that
> they block *all* the windows. So if I have two windows of the same
> single-instance app and show a modal dialog on one of the window using a
> recursive main loop, the other window (maybe on another workspace) is
> completely frozen to the user, without any reasonable reason.

Well, yes in the presence of workspaces things get pretty ugly but this is fixable eventually.

> That sounds good, but will you poll the applications? Or wait a long timeout
> even the application already exited? 

I don't see a reason to poll - again, the fact that the app is running is an implicit block.

> Or wait a short timeout and maybe not give
> the user a proper chance to close things properly?

We need a way to kill non-responsive applications (in the _NET_WM_PING sense), and perhaps some sort of emergency "ok, we have 1% battery, kill the apps and sync the ext3 journal()" type thing.  But no, I think we need to try as hard as possible to ensure the apps have saved state, because we can't be assured that it's safe.

Now, I'd like a metadata flag that says "I can be killed any time", but I haven't gotten that through xdg-list yet...

>  The proposed api just let
> the application help the manager, by giving a hint that it is now ready to
> quit.

If you're ready to quit, quit.

> Also with just "quit" I do not see a way to cancel the process: 

The UI shell itself should be providing the means to cancel the process; we do this in GNOME 2 and will continue to in 3.

> the application
> receives quit, returns false and asks the user, the user decides that he wants
> to abort the quit process and clean up things properly. However all you know is
> that the process is still running, so you end up with the "force quit" dialog
> even if the user decided to keep the application

Mmm...I think if the app is responding to _NET_WM_PING we'd avoid showing force quit, but we probably need some "Ok, really shut down now" button.

(Thanks for the good discussion by the way, I'm not saying there's not real problems here, but I still think they're solvable with just a (*quit) callback).
Comment 16 Matthew Barnes 2010-06-17 01:59:48 UTC
(In reply to comment #15)
> >  The proposed api just let
> > the application help the manager, by giving a hint that it is now ready to
> > quit.
> 
> If you're ready to quit, quit.

This ties back into my assumption that G(tk)Application would also serve as a session management client.  In that case it's useful to have separate "ready-to-quit" and "quit" signals.  Consider the following fictitious interaction:

Session Mgr: User asked me to shutdown, everybody okay to quit?
My App: I'm not busy right now, ready to quit by your command.
Some Other App: I'm burning a CD, don't shutdown on me!
Session Mgr: User forgot he was burning a CD.  Shutdown cancelled, continue running.

... user pops out the CD ...

Session Mgr: User asked me to shutdown again, everybody okay to quit?
Some Other App: Ready.

... short time later ...

My App: I had to ask the user, but he says go ahead.
Session Mgr: Everybody quit!
Comment 17 Milan Bouchet-Valat 2010-06-17 08:27:06 UTC
(In reply to comment #15 by Colin)
> (In reply to comment #13 by Paolo)
> > Also with just "quit" I do not see a way to cancel the process: 
> 
> The UI shell itself should be providing the means to cancel the process; we do
> this in GNOME 2 and will continue to in 3.
I think he was referring to the case where e.g. gedit has to save modifications from a document, and it asks Save/Discard/Cancel. In that scenario, if you hit Cancel, how can gedit tell the session manager that it should cancel shutdown?


(In reply to comment #16 by Matthew)
> This ties back into my assumption that G(tk)Application would also serve as a
> session management client.  In that case it's useful to have separate
> "ready-to-quit" and "quit" signals.  Consider the following fictitious
> interaction:
> 
> Session Mgr: User asked me to shutdown, everybody okay to quit?
> My App: I'm not busy right now, ready to quit by your command.
> Some Other App: I'm burning a CD, don't shutdown on me!
> Session Mgr: User forgot he was burning a CD.  Shutdown cancelled, continue
> running.
This should not be handled this way currently and in the future AFAIK. You have to send an Inhibit() signal to gnome-session, which will then know it shouldn't shutdown.
Comment 18 Allison Karlitskaya (desrt) 2010-10-02 02:56:58 UTC
So the GApplication replacement API has lifecycle management based on a concept similar to refcounts.

g_application_hold() -- increase use count
g_application_release() -- decrease use count

The application runs for as long as the use count is positive (ie: last call to g_application_release() causes an exit).

There is also an 'inactivity timeout' flag, so that the application doesn't quit immediately on the last _release() but waits around to see if some other _hold() might be coming soon.  This makes sense for single-instance apps that may be receiving more "open this file..." requests over DBus soon.



What if there were a variant of the g_application_hold() API like this:

typedef void (* request_release) (GApplication *application,
                                  gpointer      user_data);

void g_application_hold2 (GApplication    *application,
                          request_release  release_func,
                          gpointer         user_data);

void g_application_release2 (GApplication    *application,
                             request_release  release_func,
                             gpointer         user_data);




The idea is that you could then call:

  g_application_hold2 (app, verify_quit_dialog, window);

for each open window in your app.

Then when the 'quit' request comes, verify_quit_dialog() gets called for each 'window'.  That function might call _release() immediately, or it may display a dialog that causes release() to be called later (or not).
Comment 19 Allison Karlitskaya (desrt) 2010-10-25 18:48:57 UTC
I've decided that the base GApplication class should not have quit.

That said, probably we should somehow support it in GtkApplication...
Comment 20 Matthias Clasen 2011-04-08 23:50:47 UTC
Moving this to gtk then
Comment 21 Matthias Clasen 2011-12-18 01:37:12 UTC
I've pushed a quick port of the eggsmclient dbus implementation to the wip/session glib branch.
Comment 22 Matthias Clasen 2012-01-04 00:23:07 UTC
Another iteration of the session support is now in the wip/session branch of GTK+.

Overall, I like it a bit better in gtk than in gio. One currently unsolved problem is extending the GApplicationFlags with new values in GTK+.
Comment 23 Matthias Clasen 2012-01-04 01:34:20 UTC
After playing around with this a bit, I think the sanest approach is to simply keep the flag in GApplicationFlags, even when the implementation is in gtk. Anything else requires excessive hacks and doesn't fully work.
Comment 24 Colin Walters 2012-01-05 18:38:34 UTC
I don't like the implementation of talking to gnome-session by default.  In my view the simplest thing is if an app is running it's registered, if it's not running, it's not registered.  

Here "running" means specifically it's showing a window that gnome-shell recognizes.  So we could change gnome-shell to push the necessary data into gnome-session possibly.  Or this could wait for further merging of the two.

Basically the fewer fragile DBus calls and application identifiers we need to care about, the better.

There's also the concern I mentioned where I'd really like log out to not context switch and possibly page in every app that happens to be running if they *don't* care about getting the "I'm logging out" signal.

Since we don't have a sane way to take action when someone calls g_signal_connect(), I think we should change the flag to GTK_APPLICATION_INTERACTS_SESSION or something.
Comment 25 Colin Walters 2012-01-05 18:51:42 UTC
Ultimately where I'd like to get is something like this:

gtk_application_set_has_unsaved_state (GtkApplication *app,
                                       gboolean        has_state);

For compatibility, having unsaved state would be the default.

What would happen underneath the covers is that if the app has set this to FALSE, we tell the kernel:

  prctl (PR_SET_PURE, 1);

"Pure" here means the process has no unsaved state.

Then we add a new Unix signal SIGTERM_IF_PURE.

What that means is that at logout time, gnome-shell (or gnome-session) can iterate over all the processes that it knows about, send them SIGTERM_IF_PURE.  If they were a pure process, the kernel kills them immediately.  We don't even schedule them in only to have them call g_main_loop_quit() and then exit().

Note SIGTERM_IF_PURE probably should also to check the process isn't scheduled to be runnable for example this mean if there were pending events in the X socket.
Comment 26 Colin Walters 2012-01-05 19:10:19 UTC
The inhibit stuff seems OK to me.
Comment 27 Dan Winship 2012-01-05 19:22:25 UTC
You don't really need new signals and stuff... the app's pure/impure state doesn't change that rapidly, so the overhead of having the session manager keep track of it isn't that great. (ie, the app would sent a message to the SM whenever it's unsaved-state-ness changed). Then at logout time, the SM can just immediately kill any app that it knows has no unsaved state.
Comment 28 Colin Walters 2012-01-05 19:29:10 UTC
(In reply to comment #27)
> You don't really need new signals and stuff... the app's pure/impure state
> doesn't change that rapidly, so the overhead of having the session manager keep
> track of it isn't that great. (ie, the app would sent a message to the SM
> whenever it's unsaved-state-ness changed). Then at logout time, the SM can just
> immediately kill any app that it knows has no unsaved state.

The problem with doing this in userspace is that it's racy - imagine an app that's accepting a TCP stream and saving it to disk, invoking fdatasync() after writing, and then sending an acknowledgement to the sender.  Email over SMTP is probably the classic case.

Unless we have a way to pause all apps during the logout request (which may be a good idea, and we *could* send SIGSTOP), then we're open to these races.

In theory for desktop apps since we're holding an exclusive grab the apps shouldn't get any input events and thus shouldn't schedule, but the network case is at least worth thinking about.
Comment 29 Matthias Clasen 2012-01-06 06:12:29 UTC
I've pushed a rebased wip/session branch to gtk which flips the NO_SESSION flag around to the INTERACTS_SESSION flag that Colin proposed. Now the app only registers with the session (and emits ::quit-requested etc) if that flag is given.

The inhibitor api works regardless of registering.

I'm not too worried about (small) races here; this entire shutdown protocol is inherently racy. Adding a SetKillable (bool) method to the org.gnome.SessionManager.ClientPrivate interface sounds like an ok addition that would let gnome-session forego the entire QueryEnd dance and just go directly to SIGTERM.
Comment 30 Matthias Clasen 2012-01-06 06:14:40 UTC
Here is the Android story, btw: http://developer.android.com/guide/topics/fundamentals/activities.html#Lifecycle
Comment 31 Colin Walters 2012-01-06 17:30:39 UTC
(In reply to comment #29)
>
> I'm not too worried about (small) races here; this entire shutdown protocol is
> inherently racy. Adding a SetKillable (bool) method to the
> org.gnome.SessionManager.ClientPrivate interface sounds like an ok addition
> that would let gnome-session forego the entire QueryEnd dance and just go
> directly to SIGTERM.

Actually, how about we rebase this entire thing on SIGTERM?  So basically if you install a handler for Quit, that means we use g_unix_signal_add_watch to catch SIGTERM.  That way gnome-session can just send SIGTERM to registered clients on logout, and if you don't have a handler, the kernel cleanly exits the process without it even being scheduled.
Comment 32 Matthias Clasen 2012-01-06 19:18:47 UTC
So, you are proposing to redo the session api in unix signals instead of dbus ?
Comment 33 Colin Walters 2012-01-06 20:44:37 UTC
(In reply to comment #32)
> So, you are proposing to redo the session api in unix signals instead of dbus ?

It has some nice properties...anyways though this is really more of an implementation detail/optimization we can revisit later.

If apps want to watch for session quit and do inhibit, let's not block this patch series more; the current API is ok.
Comment 34 Matthias Clasen 2012-01-07 02:50:14 UTC
the SIGTERM idea doesn't actually work, thinking about it some more. We really do want a two-phase session end, where we first check if any application has a reason to block, and if that is not the case, we kill them all. 

With your SIGTERM idea, we may have already terminated 9/10th of your session before we hit upon the one app that has a reason to keep the session alive...
Comment 35 Matthias Clasen 2012-01-07 22:48:06 UTC
I've pushed this to master.
Leaving this open to deal with the question of a 'quit' action for GtkApplication and how to support it.
Comment 36 Matthias Clasen 2012-03-05 03:46:42 UTC
g_application_quit has now appeared