[gnome-session] Add system inhibitors
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-session] Add system inhibitors
- Date: Sun, 8 Jul 2012 03:18:46 +0000 (UTC)
commit 3cc2619f53fb13a8ea2a32405ab3ad9476725572
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Jul 7 20:58:56 2012 -0400
Add system inhibitors
When we get a suspend inhibitor, we pass it on to the GsmSystem
implementation, which may try to inhibit suspending system-wide.
This is only implemented for systemd.
https://bugzilla.gnome.org/show_bug.cgi?id=677265
configure.ac | 2 +-
gnome-session/gsm-consolekit.c | 15 +++++++
gnome-session/gsm-manager.c | 10 ++++
gnome-session/gsm-system.c | 15 +++++++
gnome-session/gsm-system.h | 14 ++++++
gnome-session/gsm-systemd.c | 92 +++++++++++++++++++++++++++++++++++++++-
6 files changed, 145 insertions(+), 3 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index c39d772..4adf0e2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -81,7 +81,7 @@ AC_ARG_ENABLE([systemd],
[enable_systemd=auto])
PKG_CHECK_MODULES(SYSTEMD,
- [libsystemd-login >= 183 libsystemd-daemon],
+ [gio-unix-2.0 libsystemd-login >= 183 libsystemd-daemon],
[have_systemd=yes], [have_systemd=no])
AC_MSG_CHECKING([whether to use systemd])
diff --git a/gnome-session/gsm-consolekit.c b/gnome-session/gsm-consolekit.c
index d1cb945..4c0eca5 100644
--- a/gnome-session/gsm-consolekit.c
+++ b/gnome-session/gsm-consolekit.c
@@ -856,6 +856,19 @@ gsm_consolekit_hibernate (GsmSystem *system)
}
static void
+gsm_consolekit_add_inhibitor (GsmSystem *system,
+ const gchar *id,
+ GsmInhibitorFlag flag)
+{
+}
+
+static void
+gsm_consolekit_remove_inhibitor (GsmSystem *system,
+ const gchar *id)
+{
+}
+
+static void
gsm_consolekit_system_init (GsmSystemInterface *iface)
{
iface->can_switch_user = gsm_consolekit_can_switch_user;
@@ -869,6 +882,8 @@ gsm_consolekit_system_init (GsmSystemInterface *iface)
iface->hibernate = gsm_consolekit_hibernate;
iface->set_session_idle = gsm_consolekit_set_session_idle;
iface->is_login_session = gsm_consolekit_is_login_session;
+ iface->add_inhibitor = gsm_consolekit_add_inhibitor;
+ iface->remove_inhibitor = gsm_consolekit_remove_inhibitor;
}
GsmConsolekit *
diff --git a/gnome-session/gsm-manager.c b/gnome-session/gsm-manager.c
index 14957f0..a222210 100644
--- a/gnome-session/gsm-manager.c
+++ b/gnome-session/gsm-manager.c
@@ -2472,7 +2472,14 @@ on_store_inhibitor_added (GsmStore *store,
const char *id,
GsmManager *manager)
{
+ GsmInhibitor *i;
+
g_debug ("GsmManager: Inhibitor added: %s", id);
+
+ i = GSM_INHIBITOR (gsm_store_lookup (store, id));
+ gsm_system_add_inhibitor (manager->priv->system, id,
+ gsm_inhibitor_peek_flags (i));
+
g_signal_emit (manager, signals [INHIBITOR_ADDED], 0, id);
update_idle (manager);
}
@@ -2483,6 +2490,9 @@ on_store_inhibitor_removed (GsmStore *store,
GsmManager *manager)
{
g_debug ("GsmManager: Inhibitor removed: %s", id);
+
+ gsm_system_remove_inhibitor (manager->priv->system, id);
+
g_signal_emit (manager, signals [INHIBITOR_REMOVED], 0, id);
update_idle (manager);
}
diff --git a/gnome-session/gsm-system.c b/gnome-session/gsm-system.c
index 9a522f0..259cc19 100644
--- a/gnome-session/gsm-system.c
+++ b/gnome-session/gsm-system.c
@@ -124,6 +124,21 @@ gsm_system_set_session_idle (GsmSystem *system,
GSM_SYSTEM_GET_IFACE (system)->set_session_idle (system, is_idle);
}
+void
+gsm_system_add_inhibitor (GsmSystem *system,
+ const gchar *id,
+ GsmInhibitorFlag flag)
+{
+ GSM_SYSTEM_GET_IFACE (system)->add_inhibitor (system, id, flag);
+}
+
+void
+gsm_system_remove_inhibitor (GsmSystem *system,
+ const gchar *id)
+{
+ GSM_SYSTEM_GET_IFACE (system)->remove_inhibitor (system, id);
+}
+
gboolean
gsm_system_is_login_session (GsmSystem *system)
{
diff --git a/gnome-session/gsm-system.h b/gnome-session/gsm-system.h
index e93505f..b284e16 100644
--- a/gnome-session/gsm-system.h
+++ b/gnome-session/gsm-system.h
@@ -27,6 +27,8 @@
#include <glib.h>
#include <glib-object.h>
+#include "gsm-inhibitor.h"
+
G_BEGIN_DECLS
#define GSM_TYPE_SYSTEM (gsm_system_get_type ())
@@ -59,6 +61,11 @@ struct _GsmSystemInterface
void (* set_session_idle) (GsmSystem *system,
gboolean is_idle);
gboolean (* is_login_session) (GsmSystem *system);
+ void (* add_inhibitor) (GsmSystem *system,
+ const gchar *id,
+ GsmInhibitorFlag flags);
+ void (* remove_inhibitor) (GsmSystem *system,
+ const gchar *id);
};
enum _GsmSystemError {
@@ -95,6 +102,13 @@ void gsm_system_set_session_idle (GsmSystem *system,
gboolean gsm_system_is_login_session (GsmSystem *system);
+void gsm_system_add_inhibitor (GsmSystem *system,
+ const gchar *id,
+ GsmInhibitorFlag flags);
+
+void gsm_system_remove_inhibitor (GsmSystem *system,
+ const gchar *id);
+
G_END_DECLS
#endif /* __GSM_SYSTEM_H__ */
diff --git a/gnome-session/gsm-systemd.c b/gnome-session/gsm-systemd.c
index 3c83329..ed45f83 100644
--- a/gnome-session/gsm-systemd.c
+++ b/gnome-session/gsm-systemd.c
@@ -39,6 +39,7 @@
#include <glib-object.h>
#include <glib/gi18n.h>
#include <gio/gio.h>
+#include <gio/gunixfdlist.h>
#include "gsm-marshal.h"
#include "gsm-system.h"
@@ -54,6 +55,9 @@ struct _GsmSystemdPrivate
GDBusProxy *sd_proxy;
gchar *session_id;
gchar *session_path;
+
+ GSList *inhibitors;
+ gint inhibit_fd;
};
static void gsm_systemd_system_init (GsmSystemInterface *iface);
@@ -72,6 +76,11 @@ gsm_systemd_finalize (GObject *object)
g_free (systemd->priv->session_id);
g_free (systemd->priv->session_path);
+ if (systemd->priv->inhibitors != NULL) {
+ g_slist_free_full (systemd->priv->inhibitors, g_free);
+ close (systemd->priv->inhibit_fd);
+ }
+
G_OBJECT_CLASS (gsm_systemd_parent_class)->finalize (object);
}
@@ -422,7 +431,6 @@ suspend_done (GObject *source,
gpointer user_data)
{
GDBusProxy *proxy = G_DBUS_PROXY (source);
- GsmSystemd *manager = user_data;
GError *error = NULL;
GVariant *res;
@@ -442,7 +450,6 @@ hibernate_done (GObject *source,
gpointer user_data)
{
GDBusProxy *proxy = G_DBUS_PROXY (source);
- GsmSystemd *manager = user_data;
GError *error = NULL;
GVariant *res;
@@ -487,6 +494,85 @@ gsm_systemd_hibernate (GsmSystem *system)
}
static void
+inhibit_done (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GDBusProxy *proxy = G_DBUS_PROXY (source);
+ GsmSystemd *manager = GSM_SYSTEMD (user_data);
+ GError *error = NULL;
+ GVariant *res;
+ GUnixFDList *fd_list = NULL;
+ gint idx;
+
+ res = g_dbus_proxy_call_with_unix_fd_list_finish (proxy, &fd_list, result, &error);
+
+ if (!res) {
+ g_warning ("Unable to inhibit system: %s", error->message);
+ g_error_free (error);
+ } else {
+ g_variant_get (res, "(h)", &idx);
+ manager->priv->inhibit_fd = g_unix_fd_list_get (fd_list, idx, &error);
+ if (manager->priv->inhibit_fd == -1) {
+ g_warning ("Failed to receive system inhibitor fd: %s", error->message);
+ g_error_free (error);
+ }
+ g_debug ("System inhibitor fd is %d", manager->priv->inhibit_fd);
+ g_object_unref (fd_list);
+ g_variant_unref (res);
+ }
+}
+
+static void
+gsm_systemd_add_inhibitor (GsmSystem *system,
+ const gchar *id,
+ GsmInhibitorFlag flag)
+{
+ GsmSystemd *manager = GSM_SYSTEMD (system);
+
+ if ((flag & GSM_INHIBITOR_FLAG_SUSPEND) == 0)
+ return;
+
+ if (manager->priv->inhibitors == NULL) {
+ g_debug ("Adding system inhibitor");
+ g_dbus_proxy_call_with_unix_fd_list (manager->priv->sd_proxy,
+ "Inhibit",
+ g_variant_new ("(ssss)",
+ "sleep:shutdown",
+ g_get_user_name (),
+ "user session inhibited",
+ "block"),
+ 0,
+ G_MAXINT,
+ NULL,
+ NULL,
+ inhibit_done,
+ manager);
+ }
+ manager->priv->inhibitors = g_slist_prepend (manager->priv->inhibitors, g_strdup (id));
+}
+
+static void
+gsm_systemd_remove_inhibitor (GsmSystem *system,
+ const gchar *id)
+{
+ GsmSystemd *manager = GSM_SYSTEMD (system);
+ GSList *l;
+
+ l = g_slist_find_custom (manager->priv->inhibitors, id, (GCompareFunc)g_strcmp0);
+ if (l == NULL)
+ return;
+
+ g_free (l->data);
+ manager->priv->inhibitors = g_slist_delete_link (manager->priv->inhibitors, l);
+ if (manager->priv->inhibitors == NULL) {
+ g_debug ("Dropping system inhibitor");
+ close (manager->priv->inhibit_fd);
+ manager->priv->inhibit_fd = -1;
+ }
+}
+
+static void
gsm_systemd_system_init (GsmSystemInterface *iface)
{
iface->can_switch_user = gsm_systemd_can_switch_user;
@@ -500,6 +586,8 @@ gsm_systemd_system_init (GsmSystemInterface *iface)
iface->hibernate = gsm_systemd_hibernate;
iface->set_session_idle = gsm_systemd_set_session_idle;
iface->is_login_session = gsm_systemd_is_login_session;
+ iface->add_inhibitor = gsm_systemd_add_inhibitor;
+ iface->remove_inhibitor = gsm_systemd_remove_inhibitor;
}
GsmSystemd *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]