summaryrefslogtreecommitdiff
path: root/gio/gapplication.c
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2011-12-17 15:37:29 -0500
committerMatthias Clasen <mclasen@redhat.com>2011-12-17 20:33:26 -0500
commitdef83cd90925caf2137b5a2099f3eb17070e227d (patch)
treecf3c9777962547428705410cd29ee7b9ef4d5194 /gio/gapplication.c
parent0971d36e4b8338f4f3f96d751f5275517514d3b1 (diff)
downloadglib-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.c223
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;