diff options
author | Matthias Clasen <mclasen@redhat.com> | 2011-12-17 15:37:29 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2011-12-17 20:33:26 -0500 |
commit | def83cd90925caf2137b5a2099f3eb17070e227d (patch) | |
tree | cf3c9777962547428705410cd29ee7b9ef4d5194 /gio/gapplication.c | |
parent | 0971d36e4b8338f4f3f96d751f5275517514d3b1 (diff) | |
download | glib-wip/session.tar.gz |
Add session supportwip/session
This is a port of the eggsmclient dbus implementation,
plus an inhibit api.
Diffstat (limited to 'gio/gapplication.c')
-rw-r--r-- | gio/gapplication.c | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/gio/gapplication.c b/gio/gapplication.c index a4e6185e6..577056d3e 100644 --- a/gio/gapplication.c +++ b/gio/gapplication.c @@ -239,6 +239,9 @@ enum SIGNAL_OPEN, SIGNAL_ACTION, SIGNAL_COMMAND_LINE, + SIGNAL_QUIT_REQUESTED, + SIGNAL_QUIT_CANCELLED, + SIGNAL_QUIT, NR_SIGNALS }; @@ -353,6 +356,9 @@ static void g_application_real_startup (GApplication *application) { application->priv->did_startup = TRUE; + + if (!(application->priv->flags & G_APPLICATION_NO_SESSION)) + g_application_impl_session_startup (application->priv->impl); } static void @@ -952,6 +958,73 @@ g_application_class_init (GApplicationClass *class) NULL, G_TYPE_INT, 1, G_TYPE_APPLICATION_COMMAND_LINE); + /** + * GApplication::quit-requested: + * @application: the #GApplication + * + * Emitted when the session manager requests that the application + * exit (generally because the user is logging out). The application + * should decide whether or not it is willing to quit and then call + * g_application_quit_response(), passing %TRUE or %FALSE to give its + * answer to the session manager. It does not need to give an answer + * before returning from the signal handler; the answer can be given + * later on, but <emphasis>the application must not attempt to perform + * any actions or interact with the user</emphasis> in response to + * this signal. Any actions required for a clean shutdown should take + * place in response to the #GApplication::quit signal. + * + * The application should limit its operations until either the + * #GApplication::quit or #GApplication::quit-cancelled signals is + * emitted. + * + * If the application does not connect to this signal, then + * #GApplication will automatically return %TRUE on its behalf. + * + * Since: 2.32 + */ + g_application_signals[SIGNAL_QUIT_REQUESTED] = + g_signal_new ("quit-requested", G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GApplicationClass, quit_requested), + NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + /** + * GApplication::quit-cancelled: + * @application: the #GApplication + * + * Emitted when the session manager decides to cancel a logout after + * the application has already agreed to quit. After receiving this + * signal, the application can go back to what it was doing before + * receiving the #GApplication::quit-requested signal. + * + * Since: 2.32 + */ + g_application_signals[SIGNAL_QUIT_CANCELLED] = + g_signal_new ("quit-cancelled", G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GApplicationClass, quit_cancelled), + NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + /** + * GApplication::quit: + * @application: the #GApplication + * + * Emitted when the session manager wants the application to quit + * (generally because the user is logging out). The application + * should exit as soon as possible after receiving this signal; if + * it does not, the session manager may choose to forcibly kill it. + * + * Normally a GUI application would only be sent a ::quit if it + * agreed to quit in response to a #GApplication::quit-requested + * signal. However, this is not guaranteed; in some situations the + * session manager may decide to end the session without giving + * applications a chance to object. + * + * Since: 2.32 + */ + g_application_signals[SIGNAL_QUIT] = + g_signal_new ("quit", G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GApplicationClass, quit), + NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + g_type_class_add_private (class, sizeof (GApplicationPrivate)); } @@ -1810,6 +1883,156 @@ g_application_action_map_iface_init (GActionMapInterface *iface) iface->remove_action = g_application_remove_action; } +/* Session Management {{{1 */ + +void +g_application_emit_quit_requested (GApplication *application) +{ + if (!g_signal_has_handler_pending (application, g_application_signals[SIGNAL_QUIT_REQUESTED], 0, FALSE)) + { + g_debug ("Not emitting quit_requested because no one is listening"); + g_application_quit_response (application, TRUE, NULL); + return; + } + + g_debug ("Emitting quit-requested"); + g_signal_emit (application, g_application_signals[SIGNAL_QUIT_REQUESTED], 0); + g_debug ("Done emitting quit-requested"); +} + +void +g_application_emit_quit (GApplication *application) +{ + g_debug ("Emitting quit"); + g_signal_emit (application, g_application_signals[SIGNAL_QUIT], 0); + g_debug ("Done emitting quit"); +} + +void +g_application_emit_quit_cancelled (GApplication *application) +{ + g_debug ("Emitting quit-cancelled"); + g_signal_emit (application, g_application_signals[SIGNAL_QUIT_CANCELLED], 0); + g_debug ("Done emitting quit-cancelled"); +} + +/** + * g_application_quit_response: + * @application: the #GApplication + * @will_quit: whether the application agrees to quit + * @reason: (null-allowed): a short human-readable string that explains + * why quitting is not possible + * + * This function <emphasis>must</emphasis> be called in response to the + * #GApplication::quit-requested signal, to indicate whether or + * not the application is willing to quit. The application may call + * it either directly from the signal handler, or at some later point. + * + * It should be stressed that <emphasis>applications should not assume + * that they have the ability to block logout or shutdown</emphasis>, + * even when %FALSE is passed for @will_quit. + * + * After calling this method, the application should wait to receive + * either #GApplication::quit-cancelled or #GApplication::quit. + * + * If the application does not connect to #GApplication::quit-requested, + * #GApplication will call this method on its behalf (passing %TRUE + * for @will_quit). + * + * Since: 2.32 + */ +void +g_application_quit_response (GApplication *application, + gboolean will_quit, + const gchar *reason) +{ + g_return_if_fail (G_IS_APPLICATION (application)); + g_return_if_fail (!application->priv->is_remote); + + g_application_impl_quit_response (application->priv->impl, will_quit, reason); +} + +/** + * g_application_inhibit: + * @application: the #GApplication + * @flags: what types of actions should be inhibited + * @reason: (null-allowed): a short, human-readable string that explains + * why these operations are inhibited + * + * Inform the session manager that certain types of actions should be + * inhibited. + * + * Applications should invoke this method when they begin an operation + * that should not be interrupted, such as creating a CD or DVD. The + * types of actions that may be blocked are specified by the @flags + * parameter. When the application completes the operation it should + * call g_application_uninhibit() to remove the inhibitor. Inhibitors + * are also cleared when the application exits. + * + * Applications should not expect that they will always be able to block + * the action. In most cases, users will be given the option to force + * the action to take place. + * + * Reasons should be short and to the point. + * + * Returns: A cookie that is used to uniquely identify this request. + * It should be used as an argument to g_application_uninhibit() + * in order to remove the request. + * + * Since: 2.32 + */ +guint +g_application_inhibit (GApplication *application, + GApplicationInhibitFlags flags, + const gchar *reason) +{ + g_return_val_if_fail (G_IS_APPLICATION (application), 0); + g_return_val_if_fail (!application->priv->is_remote, 0); + + return g_application_impl_inhibit (application->priv->impl, flags, reason); +} + +/** + * g_application_uninhibit: + * @application: the #GApplication + * @cookie: a cookie that was returned by g_application_inhibit() + * + * Removes an inhibitor that has been established with g_application_inhibit(). + * + * Since: 2.32 + */ +void +g_application_uninhibit (GApplication *application, + guint cookie) +{ + g_return_if_fail (G_IS_APPLICATION (application)); + g_return_if_fail (!application->priv->is_remote); + + g_application_impl_uninhibit (application->priv->impl, cookie); +} + +/** + * g_application_is_inhibited: + * @application: the #GApplication + * @flags: what types of actions should be queried + * + * Determines if any of the actions specified in @flags are + * currently inhibited (possibly by another application). + * + * Returns: %TRUE if any of the actions specified in @flags are inhibited + * + * Since: 2.32 + */ +gboolean +g_application_is_inhibited (GApplication *application, + GApplicationInhibitFlags flags) +{ + g_return_val_if_fail (G_IS_APPLICATION (application), FALSE); + g_return_val_if_fail (!application->priv->is_remote, FALSE); + + return g_application_impl_is_inhibited (application->priv->impl, flags); +} + /* Default Application {{{1 */ static GApplication *default_app; |