summaryrefslogtreecommitdiff
path: root/gnome-session/gsm-manager.c
diff options
context:
space:
mode:
authorBastien Nocera <hadess@hadess.net>2013-01-25 09:34:38 +0100
committerBastien Nocera <hadess@hadess.net>2013-01-25 14:33:56 +0100
commita0057debeccdc5331bca9bc23daa2ddedcbc6b38 (patch)
treec3891484432ccf2ebf9bb01e1b3e6b6cd7f5118d /gnome-session/gsm-manager.c
parentaecdecb19dea81119327e1815182be3b020d70fb (diff)
downloadgnome-session-a0057debeccdc5331bca9bc23daa2ddedcbc6b38.tar.gz
manager: Add InhibitedActions D-Bus property
This makes it easier for system-level applications to check whether a particular action is inhibited without calling "IsInhibited" for each action separately. https://bugzilla.gnome.org/show_bug.cgi?id=692517
Diffstat (limited to 'gnome-session/gsm-manager.c')
-rw-r--r--gnome-session/gsm-manager.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/gnome-session/gsm-manager.c b/gnome-session/gsm-manager.c
index fe34e77d..10a77d1b 100644
--- a/gnome-session/gsm-manager.c
+++ b/gnome-session/gsm-manager.c
@@ -126,6 +126,7 @@ struct GsmManagerPrivate
gboolean failsafe;
GsmStore *clients;
GsmStore *inhibitors;
+ GsmInhibitorFlag inhibited_actions;
GsmStore *apps;
GsmPresence *presence;
GsmXsmpServer *xsmp_server;
@@ -175,6 +176,7 @@ struct GsmManagerPrivate
enum {
PROP_0,
PROP_CLIENT_STORE,
+ PROP_INHIBITED_ACTIONS,
PROP_SESSION_NAME,
PROP_SESSION_IS_ACTIVE,
PROP_FALLBACK,
@@ -2388,6 +2390,9 @@ gsm_manager_get_property (GObject *object,
case PROP_CLIENT_STORE:
g_value_set_object (value, self->priv->clients);
break;
+ case PROP_INHIBITED_ACTIONS:
+ g_value_set_uint (value, self->priv->inhibited_actions);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -2416,11 +2421,61 @@ gsm_manager_constructor (GType type,
}
static void
+update_inhibited_actions (GsmManager *manager,
+ GsmInhibitorFlag new_inhibited_actions)
+{
+ DBusGConnection *gconnection;
+ DBusConnection *connection;
+ DBusMessage *message;
+ DBusMessageIter iter;
+ DBusMessageIter subiter;
+ DBusMessageIter dict_iter;
+ DBusMessageIter v_iter;
+ const char *iface_name = GSM_MANAGER_DBUS_NAME;
+ const char *prop_name = "InhibitedActions";
+
+ if (manager->priv->inhibited_actions == new_inhibited_actions)
+ return;
+
+ manager->priv->inhibited_actions = new_inhibited_actions;
+ g_object_notify (G_OBJECT (manager), "inhibited-for");
+
+ /* Now, the following bits emit the PropertiesChanged signal
+ * that GDBus expects. This code should just die in a port to
+ * GDBus.
+ */
+ gconnection = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
+ g_assert (gconnection);
+ connection = dbus_g_connection_get_connection (gconnection);
+ message = dbus_message_new_signal (GSM_MANAGER_DBUS_PATH, "org.freedesktop.DBus.Properties",
+ "PropertiesChanged");
+ g_assert (message != NULL);
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &iface_name);
+ /* changed */
+ dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "{sv}", &subiter);
+ dbus_message_iter_open_container (&subiter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_iter);
+ dbus_message_iter_append_basic (&dict_iter, DBUS_TYPE_STRING, &prop_name);
+ dbus_message_iter_open_container (&dict_iter, DBUS_TYPE_VARIANT, "u", &v_iter);
+ dbus_message_iter_append_basic (&v_iter, DBUS_TYPE_UINT32, &new_inhibited_actions);
+ dbus_message_iter_close_container (&dict_iter, &v_iter);
+ dbus_message_iter_close_container (&subiter, &dict_iter);
+ dbus_message_iter_close_container (&iter, &subiter);
+ /* invalidated */
+ dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "s", &subiter);
+ dbus_message_iter_close_container (&iter, &subiter);
+
+ dbus_connection_send (connection, message, NULL);
+ dbus_message_unref (message);
+}
+
+static void
on_store_inhibitor_added (GsmStore *store,
const char *id,
GsmManager *manager)
{
GsmInhibitor *i;
+ GsmInhibitorFlag new_inhibited_actions;
g_debug ("GsmManager: Inhibitor added: %s", id);
@@ -2428,20 +2483,45 @@ on_store_inhibitor_added (GsmStore *store,
gsm_system_add_inhibitor (manager->priv->system, id,
gsm_inhibitor_peek_flags (i));
+ new_inhibited_actions = manager->priv->inhibited_actions | gsm_inhibitor_peek_flags (i);
+ update_inhibited_actions (manager, new_inhibited_actions);
+
g_signal_emit (manager, signals [INHIBITOR_ADDED], 0, id);
+
update_idle (manager);
}
+static gboolean
+collect_inhibition_flags (const char *id,
+ GObject *object,
+ gpointer user_data)
+{
+ GsmInhibitorFlag *new_inhibited_actions = user_data;
+
+ *new_inhibited_actions |= gsm_inhibitor_peek_flags (GSM_INHIBITOR (object));
+
+ return FALSE;
+}
+
static void
on_store_inhibitor_removed (GsmStore *store,
const char *id,
GsmManager *manager)
{
+ GsmInhibitorFlag new_inhibited_actions;
+
g_debug ("GsmManager: Inhibitor removed: %s", id);
gsm_system_remove_inhibitor (manager->priv->system, id);
+ new_inhibited_actions = 0;
+ gsm_store_foreach (manager->priv->inhibitors,
+ collect_inhibition_flags,
+ &new_inhibited_actions);
+ update_inhibited_actions (manager, new_inhibited_actions);
+
g_signal_emit (manager, signals [INHIBITOR_REMOVED], 0, id);
+
update_idle (manager);
}
@@ -2568,6 +2648,22 @@ gsm_manager_class_init (GsmManagerClass *klass)
NULL,
FALSE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ /**
+ * GsmManager::inhibited-actions
+ *
+ * A bitmask of flags to indicate which actions are inhibited. See the Inhibit()
+ * function's description for a list of possible values.
+ */
+ g_object_class_install_property (object_class,
+ PROP_INHIBITED_ACTIONS,
+ g_param_spec_uint ("inhibited-actions",
+ NULL,
+ NULL,
+ 0,
+ G_MAXUINT,
+ 0,
+ G_PARAM_READABLE));
/**
* GsmManager::session-name
*