[glib/wip/session] Add session support



commit def83cd90925caf2137b5a2099f3eb17070e227d
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Dec 17 15:37:29 2011 -0500

    Add session support
    
    This is a port of the eggsmclient dbus implementation,
    plus an inhibit api.

 docs/reference/gio/gio-sections.txt |    6 +
 gio/gapplication.c                  |  223 +++++++++++++++++++++++++++++
 gio/gapplication.h                  |   18 +++-
 gio/gapplicationimpl-dbus.c         |  268 ++++++++++++++++++++++++++++++++++-
 gio/gapplicationimpl.h              |   30 ++++
 gio/gio.symbols                     |    5 +
 gio/gioenums.h                      |   26 ++++-
 7 files changed, 572 insertions(+), 4 deletions(-)
---
diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt
index 7acd2ce..3d94ea1 100644
--- a/docs/reference/gio/gio-sections.txt
+++ b/docs/reference/gio/gio-sections.txt
@@ -2834,6 +2834,12 @@ g_application_open
 g_application_run
 g_application_set_default
 g_application_get_default
+<SUBSECTION>
+g_application_quit_response
+GApplicationInhibitFlags
+g_application_inhibit
+g_application_uninhibit
+g_application_is_inhibited
 <SUBSECTION Standard>
 G_TYPE_APPLICATION
 G_APPLICATION
diff --git a/gio/gapplication.c b/gio/gapplication.c
index a4e6185..577056d 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;
diff --git a/gio/gapplication.h b/gio/gapplication.h
index 76fcf93..d0f9ed2 100644
--- a/gio/gapplication.h
+++ b/gio/gapplication.h
@@ -90,8 +90,12 @@ struct _GApplicationClass
   void                      (* run_mainloop)        (GApplication              *application);
   void                      (* shutdown)            (GApplication              *application);
 
+  void                      (*quit_requested)       (GApplication              *application);
+  void                      (*quit_cancelled)       (GApplication              *application);
+  void                      (*quit)                 (GApplication              *application);
+
   /*< private >*/
-  gpointer padding[11];
+  gpointer padding[8];
 };
 
 GType                   g_application_get_type                          (void) G_GNUC_CONST;
@@ -146,6 +150,18 @@ int                     g_application_run                               (GApplic
                                                                          int                       argc,
                                                                          char                    **argv);
 
+void                    g_application_quit_response                     (GApplication             *application,
+                                                                         gboolean                  will_quit,
+                                                                         const gchar              *reason);
+
+guint                   g_application_inhibit                           (GApplication             *application,
+                                                                         GApplicationInhibitFlags  flags,
+                                                                         const gchar              *reason);
+void                    g_application_uninhibit                         (GApplication             *application,
+                                                                         guint                     cookie);
+gboolean                g_application_is_inhibited                      (GApplication             *application,
+                                                                         GApplicationInhibitFlags  flags);
+
 GApplication *          g_application_get_default                       (void);
 void                    g_application_set_default                       (GApplication             *application);
 
diff --git a/gio/gapplicationimpl-dbus.c b/gio/gapplicationimpl-dbus.c
index d8999d7..a0212e3 100644
--- a/gio/gapplicationimpl-dbus.c
+++ b/gio/gapplicationimpl-dbus.c
@@ -30,6 +30,7 @@
 #include "gdbusconnection.h"
 #include "gdbusintrospection.h"
 #include "gdbuserror.h"
+#include "gdbusproxy.h"
 #include "gmenuexporter.h"
 
 #include <string.h>
@@ -103,6 +104,11 @@ struct _GApplicationImpl
   gboolean         properties_live;
   gboolean         primary;
   gpointer         app;
+
+  gchar           *app_id;
+  GDBusProxy      *sm_proxy;
+  gchar           *client_path;
+  GDBusProxy      *client_proxy;
 };
 
 
@@ -467,11 +473,15 @@ g_application_impl_destroy (GApplicationImpl *impl)
 {
   g_application_impl_stop_primary (impl);
 
-  if (impl->session_bus)
-    g_object_unref (impl->session_bus);
+  g_clear_object (&impl->session_bus);
 
   g_free (impl->object_path);
 
+  g_clear_object (&impl->sm_proxy);
+  g_clear_object (&impl->client_proxy);
+  g_free (impl->client_path);
+  g_free (impl->app_id);
+
   g_slice_free (GApplicationImpl, impl);
 }
 
@@ -817,6 +827,260 @@ g_dbus_command_line_new (GDBusMethodInvocation *invocation)
   return G_APPLICATION_COMMAND_LINE (gdbcl);
 }
 
+/* Session Management {{{1 */
+
+static void
+unregister_client (GApplicationImpl *impl)
+{
+  GError *error = NULL;
+
+  g_debug ("Unregistering client\n");
+
+  g_dbus_proxy_call_sync (impl->sm_proxy,
+                          "UnregisterClient",
+                          g_variant_new ("(o)", impl->client_path),
+                          0,
+                          G_MAXINT,
+                          NULL,
+                          &error);
+
+  if (error)
+    {
+      g_warning ("Failed to unregister client: %s\n", error->message);
+      g_error_free (error);
+    }
+
+  g_clear_object (&impl->client_proxy);
+
+  g_free (impl->client_path);
+  impl->client_path = NULL;
+}
+
+static void
+client_proxy_signal (GDBusProxy       *proxy,
+                     const gchar      *sender_name,
+                     const gchar      *signal_name,
+                     GVariant         *parameters,
+                     GApplicationImpl *impl)
+{
+  if (strcmp (signal_name, "QueryEndSession") == 0)
+    {
+      g_debug ("Received QueryEndSession\n");
+      g_application_emit_quit_requested (impl->app);
+    }
+  else if (strcmp (signal_name, "EndSession") == 0)
+    {
+      g_debug ("Received EndSession\n");
+      g_application_impl_quit_response (impl, TRUE, NULL);
+      unregister_client (impl);
+      g_application_emit_quit (impl->app);
+    }
+  else if (strcmp (signal_name, "CancelEndSession") == 0)
+    {
+      g_debug ("Received CancelEndSession\n");
+      g_application_emit_quit_cancelled (impl->app);
+    }
+  else if (strcmp (signal_name, "Stop") == 0)
+    {
+      g_debug ("Received Stop\n");
+      unregister_client (impl);
+      g_application_emit_quit (impl->app);
+    }
+}
+
+void
+g_application_impl_session_startup (GApplicationImpl *impl)
+{
+  static gchar *client_id;
+  GError *error = NULL;
+  GVariant *res;
+
+  if (client_id == NULL)
+    {
+      const gchar *desktop_autostart_id;
+
+      desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID");
+      /* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to
+       * use the same client id.
+       */
+      g_unsetenv ("DESKTOP_AUTOSTART_ID");
+      client_id = g_strdup (desktop_autostart_id ? desktop_autostart_id : "");
+    }
+
+  g_debug ("Connecting to session manager\n");
+
+  impl->sm_proxy = g_dbus_proxy_new_sync (impl->session_bus, 0,
+                                          NULL, /* FIXME */
+                                          "org.gnome.SessionManager",
+                                          "/org/gnome/SessionManager",
+                                          "org.gnome.SessionManager",
+                                          NULL,
+                                          &error);
+  if (error)
+    {
+      g_warning ("Failed to get a session proxy: %s", error->message);
+      g_error_free (error);
+      return;
+    }
+
+  impl->app_id = g_strdup (g_get_prgname ());
+
+  g_debug ("Registering client '%s' '%s'\n", impl->app_id, client_id);
+
+  res = g_dbus_proxy_call_sync (impl->sm_proxy,
+                                "RegisterClient",
+                                g_variant_new ("(ss)", impl->app_id, client_id),
+                                0,
+                                -1,
+                                NULL,
+                                &error);
+
+  if (error)
+    {
+      g_warning ("Failed to register client: %s\n", error->message);
+      g_error_free (error);
+      g_clear_object (&impl->sm_proxy);
+      return;
+    }
+
+  g_variant_get (res, "(o)", &impl->client_path);
+  g_variant_unref (res);
+
+  g_debug ("Registered client at '%s'\n", impl->client_path);
+
+  impl->client_proxy = g_dbus_proxy_new_sync (impl->session_bus, 0,
+                                              NULL, /* FIXME */
+                                              "org.gnome.SessionManager",
+                                              impl->client_path,
+                                              "org.gnome.SessionManager.ClientPrivate",
+                                              NULL,
+                                              &error);
+  if (error)
+    {
+      g_warning ("Failed to get client proxy: %s\n", error->message);
+      g_error_free (error);
+      g_clear_object (&impl->sm_proxy);
+      g_free (impl->client_path);
+      impl->client_path = NULL;
+      return;
+    }
+
+  g_signal_connect (impl->client_proxy, "g-signal", G_CALLBACK (client_proxy_signal), impl);
+}
+
+void
+g_application_impl_quit_response (GApplicationImpl *impl,
+                                  gboolean          will_quit,
+                                  const gchar      *reason)
+{
+  g_return_if_fail (impl->client_proxy != NULL);
+
+  g_debug ("Calling EndSessionResponse %d '%s'\n", will_quit, reason);
+
+  g_dbus_proxy_call (impl->client_proxy,
+                     "EndSessionResponse",
+                     g_variant_new ("(bs)", will_quit, reason ? reason : ""),
+                     0, G_MAXINT,
+                     NULL, NULL, NULL);
+}
+
+guint
+g_application_impl_inhibit (GApplicationImpl         *impl,
+                            GApplicationInhibitFlags  flags,
+                            const gchar              *reason)
+{
+  GVariant *res;
+  GError *error = NULL;
+  guint cookie;
+
+  g_return_val_if_fail (impl->sm_proxy != NULL, 0);
+
+  g_debug ("Calling Inhibit\n");
+
+  res = g_dbus_proxy_call_sync (impl->sm_proxy,
+                                "Inhibit",
+                                g_variant_new ("(susu)",
+                                               impl->app_id,
+                                               0, /* toplevel XID */
+                                               reason,
+                                               flags),
+                                0,
+                                -1,
+                                NULL,
+                                &error);
+  if (error)
+    {
+      g_warning ("Calling Inhibit failed: %s\n", error->message);
+      g_error_free (error);
+      return 0;
+    }
+
+  g_variant_get (res, "(u)", &cookie);
+  g_variant_unref (res);
+
+  return cookie;
+}
+
+void
+g_application_impl_uninhibit (GApplicationImpl *impl,
+                              guint             cookie)
+{
+  GVariant *res;
+  GError *error = NULL;
+
+  g_return_if_fail (impl->sm_proxy != NULL);
+
+  g_debug ("Calling Uninhibit\n");
+
+  res = g_dbus_proxy_call_sync (impl->sm_proxy,
+                                "Uninhibit",
+                                g_variant_new ("(u)", cookie),
+                                0,
+                                -1,
+                                NULL,
+                                &error);
+  if (error)
+    {
+      g_warning ("Calling Uninhibit failed: %s\n", error->message);
+      g_error_free (error);
+      return;
+    }
+
+  g_variant_unref (res);
+}
+
+gboolean
+g_application_impl_is_inhibited (GApplicationImpl         *impl,
+                                 GApplicationInhibitFlags  flags)
+{
+  GVariant *res;
+  GError *error = NULL;
+  gboolean inhibited;
+
+  g_return_val_if_fail (impl->sm_proxy != NULL, FALSE);
+
+  g_debug ("Calling IsInhibited\n");
+
+  res = g_dbus_proxy_call_sync (impl->sm_proxy,
+                                "IsInhibited",
+                                g_variant_new ("(u)", flags),
+                                0,
+                                -1,
+                                NULL,
+                                &error);
+  if (error)
+    {
+      g_warning ("Calling IsInhibited failed: %s\n", error->message);
+      g_error_free (error);
+      return FALSE;
+    }
+
+  inhibited = g_variant_get_boolean (res);
+  g_variant_unref (res);
+
+  return inhibited;
+}
+
 /* Epilogue {{{1 */
 
 /* vim:set foldmethod=marker: */
diff --git a/gio/gapplicationimpl.h b/gio/gapplicationimpl.h
index ef25f2b..8910c94 100644
--- a/gio/gapplicationimpl.h
+++ b/gio/gapplicationimpl.h
@@ -41,3 +41,33 @@ int                     g_application_impl_command_line                 (GApplic
 
 G_GNUC_INTERNAL
 void                    g_application_impl_flush                        (GApplicationImpl   *impl);
+
+G_GNUC_INTERNAL
+void                    g_application_impl_session_startup              (GApplicationImpl   *impl);
+
+G_GNUC_INTERNAL
+void                    g_application_impl_quit_response                (GApplicationImpl   *impl,
+                                                                         gboolean            will_quit,
+                                                                         const gchar        *reason);
+
+G_GNUC_INTERNAL
+guint                   g_application_impl_inhibit                      (GApplicationImpl         *impl,
+                                                                         GApplicationInhibitFlags  flags,
+                                                                         const gchar              *reason);
+
+G_GNUC_INTERNAL
+void                    g_application_impl_uninhibit                    (GApplicationImpl         *impl,
+                                                                         guint                     cookie);
+
+G_GNUC_INTERNAL
+gboolean                g_application_impl_is_inhibited                 (GApplicationImpl         *impl,
+                                                                         GApplicationInhibitFlags  flags);
+
+G_GNUC_INTERNAL
+void                    g_application_emit_quit_requested               (GApplication             *app);
+
+G_GNUC_INTERNAL
+void                    g_application_emit_quit                         (GApplication             *app);
+
+G_GNUC_INTERNAL
+void                    g_application_emit_quit_cancelled               (GApplication             *app);
diff --git a/gio/gio.symbols b/gio/gio.symbols
index 74e7e84..af60c2b 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -23,8 +23,12 @@ g_application_get_app_menu
 g_application_get_menubar
 g_application_hold
 g_application_id_is_valid
+g_application_inhibit
+g_application_inhibit_flags_get_type
+g_application_is_inhibited
 g_application_new
 g_application_open
+g_application_quit_response
 g_application_register
 g_application_release
 g_application_run
@@ -35,6 +39,7 @@ g_application_set_application_id
 g_application_set_default
 g_application_set_flags
 g_application_set_inactivity_timeout
+g_application_uninhibit
 g_application_command_line_get_arguments
 g_application_command_line_get_cwd
 g_application_command_line_get_environ
diff --git a/gio/gioenums.h b/gio/gioenums.h
index 47d72bd..5e54c01 100644
--- a/gio/gioenums.h
+++ b/gio/gioenums.h
@@ -1274,6 +1274,8 @@ typedef enum
  *     attempts to become the owner of the application ID nor does it
  *     check if an existing owner already exists.  Everything occurs in
  *     the local process.  Since: 2.30.
+ * @G_APPLICATION_NO_SESSION: Don't register with the session manager.
+ *     Since: 2.32.
  *
  * Flags used to define the behaviour of a #GApplication.
  *
@@ -1289,10 +1291,32 @@ typedef enum
   G_APPLICATION_HANDLES_COMMAND_LINE = (1 << 3),
   G_APPLICATION_SEND_ENVIRONMENT    =  (1 << 4),
 
-  G_APPLICATION_NON_UNIQUE =           (1 << 5)
+  G_APPLICATION_NON_UNIQUE =           (1 << 5),
+
+  G_APPLICATION_NO_SESSION =           (1 << 6)
 } GApplicationFlags;
 
 /**
+ * GApplicationInhibitFlags:
+ * @G_APPLICATION_INHIBIT_LOGOUT: Inhibit logging out
+ * @G_APPLICATION_INHIBIT_SWITCH: Inhibit user switching
+ * @G_APPLICATION_INHIBIT_SUSPEND: Inhibit suspending the
+ *     session or computer
+ * @G_APPLICATION_INHIBIT_IDLE: Inhibit the session being
+ *     marked as idle
+ *
+ * Types of actions that may be blocked by g_application_inhibit().
+ *
+ * Since: 2.32
+ */
+typedef enum {
+  G_APPLICATION_INHIBIT_LOGOUT  = 1,
+  G_APPLICATION_INHIBIT_SWITCH  = 2,
+  G_APPLICATION_INHIBIT_SUSPEND = 4,
+  G_APPLICATION_INHIBIT_IDLE    = 8
+} GApplicationInhibitFlags;
+
+/**
  * GTlsError:
  * @G_TLS_ERROR_UNAVAILABLE: No TLS provider is available
  * @G_TLS_ERROR_MISC: Miscellaneous TLS error



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]