412 lines
15 KiB
Diff
412 lines
15 KiB
Diff
From cea7cb81dd95b447a8d5cb279307c435d9dc968c Mon Sep 17 00:00:00 2001
|
|
From: Eric Koegel <eric.koegel@gmail.com>
|
|
Date: Mon, 17 Nov 2014 10:16:26 +0300
|
|
Subject: [PATCH 05/12] Add the PrepareForSleep/Shutdown signals
|
|
|
|
This patch adds the PrepareForSleep/Shutdown signals so apps can
|
|
listed for these signals and perform operations prior to the event
|
|
such as logging out of online chatrooms.
|
|
---
|
|
po/ConsoleKit2.pot | 14 +-
|
|
src/ck-manager.c | 210 +++++++++++++++++++++++++----
|
|
src/ck-manager.h | 4 +
|
|
src/org.freedesktop.ConsoleKit.Manager.xml | 31 +++++
|
|
4 files changed, 224 insertions(+), 35 deletions(-)
|
|
|
|
diff --git a/po/ConsoleKit2.pot b/po/ConsoleKit2.pot
|
|
index 331b9e2..31f9ec7 100644
|
|
--- a/po/ConsoleKit2.pot
|
|
+++ b/po/ConsoleKit2.pot
|
|
@@ -8,7 +8,7 @@ msgid ""
|
|
msgstr ""
|
|
"Project-Id-Version: PACKAGE VERSION\n"
|
|
"Report-Msgid-Bugs-To: https://github.com/ConsoleKit2/ConsoleKit2/issues\n"
|
|
-"POT-Creation-Date: 2014-11-02 15:43+0300\n"
|
|
+"POT-Creation-Date: 2014-11-17 10:15+0300\n"
|
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
@@ -65,29 +65,29 @@ msgstr ""
|
|
msgid "No consoles available"
|
|
msgstr ""
|
|
|
|
-#: src/ck-manager.c:2516 src/ck-manager.c:2615 src/ck-manager.c:2672
|
|
+#: src/ck-manager.c:2648 src/ck-manager.c:2747 src/ck-manager.c:2804
|
|
msgid "Unable to get information about the calling process"
|
|
msgstr ""
|
|
|
|
-#: src/ck-manager.c:2529 src/ck-session.c:278
|
|
+#: src/ck-manager.c:2661 src/ck-session.c:278
|
|
#, c-format
|
|
msgid "Unable to lookup information about calling process '%d'"
|
|
msgstr ""
|
|
|
|
-#: src/ck-manager.c:2553 src/ck-manager.c:2565 src/ck-manager.c:2822
|
|
+#: src/ck-manager.c:2685 src/ck-manager.c:2697 src/ck-manager.c:2954
|
|
msgid "Unable to find session for cookie"
|
|
msgstr ""
|
|
|
|
-#: src/ck-manager.c:2629
|
|
+#: src/ck-manager.c:2761
|
|
#, c-format
|
|
msgid "Unable to lookup session information for process '%d'"
|
|
msgstr ""
|
|
|
|
-#: src/ck-manager.c:2830
|
|
+#: src/ck-manager.c:2962
|
|
msgid "User ID does not match the owner of cookie"
|
|
msgstr ""
|
|
|
|
-#: src/ck-manager.c:2840
|
|
+#: src/ck-manager.c:2972
|
|
msgid "Process ID does not match the owner of cookie"
|
|
msgstr ""
|
|
|
|
diff --git a/src/ck-manager.c b/src/ck-manager.c
|
|
index cf5a40b..0110d89 100644
|
|
--- a/src/ck-manager.c
|
|
+++ b/src/ck-manager.c
|
|
@@ -83,15 +83,31 @@ struct CkManagerPrivate
|
|
gboolean system_idle_hint;
|
|
GTimeVal system_idle_since_hint;
|
|
|
|
+ /* How long to delay after emitting the PREPARE_FOR_SHUTDOWN or
|
|
+ * PREPARE_FOR_SLEEP signal */
|
|
+ guint system_action_idle_delay;
|
|
+
|
|
CkInhibitManager *inhibit_manager;
|
|
};
|
|
|
|
-enum {
|
|
+typedef enum {
|
|
SEAT_ADDED,
|
|
SEAT_REMOVED,
|
|
SYSTEM_IDLE_HINT_CHANGED,
|
|
+ PREPARE_FOR_SHUTDOWN,
|
|
+ PREPARE_FOR_SLEEP,
|
|
LAST_SIGNAL
|
|
-};
|
|
+} SIGNALS;
|
|
+
|
|
+typedef struct
|
|
+{
|
|
+ CkManager *manager;
|
|
+ DBusGMethodInvocation *context;
|
|
+ const gchar *command;
|
|
+ CkLogEventType event_type;
|
|
+ const gchar *description;
|
|
+ SIGNALS signal;
|
|
+} SystemActionData;
|
|
|
|
static guint signals [LAST_SIGNAL] = { 0, };
|
|
|
|
@@ -1198,7 +1214,7 @@ do_system_action (CkManager *manager,
|
|
g_debug ("command is %s", command);
|
|
|
|
error = NULL;
|
|
- res = g_spawn_command_line_async (command, &error);
|
|
+ res = g_spawn_command_line_sync (command, NULL, NULL, NULL, &error);
|
|
|
|
if (! res) {
|
|
GError *new_error;
|
|
@@ -1218,15 +1234,55 @@ do_system_action (CkManager *manager,
|
|
}
|
|
}
|
|
|
|
+static gboolean
|
|
+system_action_idle_cb(SystemActionData *data)
|
|
+{
|
|
+ g_return_val_if_fail (data != NULL, FALSE);
|
|
+
|
|
+ /* Perform the action */
|
|
+ do_system_action (data->manager,
|
|
+ data->context,
|
|
+ data->command,
|
|
+ data->event_type,
|
|
+ data->description);
|
|
+
|
|
+ /* If we got here the sleep action is done and we're awake again
|
|
+ * or the operation failed. Either way we can signal to the apps */
|
|
+ g_signal_emit (data->manager, signals [data->signal], 0, FALSE);
|
|
+
|
|
+ g_free (data);
|
|
+
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
static void
|
|
do_restart (CkManager *manager,
|
|
DBusGMethodInvocation *context)
|
|
{
|
|
- do_system_action (manager,
|
|
- context,
|
|
- PREFIX "/lib/ConsoleKit/scripts/ck-system-restart",
|
|
- CK_LOG_EVENT_SYSTEM_RESTART,
|
|
- "Restart");
|
|
+ SystemActionData *data;
|
|
+
|
|
+ /* Emit the signal */
|
|
+ g_signal_emit (manager, signals [PREPARE_FOR_SHUTDOWN], 0, TRUE);
|
|
+
|
|
+ /* Allocate and fill the data struct to pass to the idle cb */
|
|
+ data = g_new0 (SystemActionData, 1);
|
|
+ if (data == NULL) {
|
|
+ g_critical ("failed to allocate memory to perform shutdown\n");
|
|
+ g_signal_emit (manager, signals [PREPARE_FOR_SHUTDOWN], 0, FALSE);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ data->manager = manager;
|
|
+ data->context = context;
|
|
+ data->command = PREFIX "/lib/ConsoleKit/scripts/ck-system-restart";
|
|
+ data->event_type = CK_LOG_EVENT_SYSTEM_RESTART;
|
|
+ data->description = "Restart";
|
|
+ data->signal = PREPARE_FOR_SHUTDOWN;
|
|
+
|
|
+ /* Sleep so user applications have time to respond */
|
|
+ g_timeout_add (data->manager->priv->system_action_idle_delay,
|
|
+ (GSourceFunc)system_action_idle_cb,
|
|
+ data);
|
|
}
|
|
|
|
/*
|
|
@@ -1289,11 +1345,30 @@ static void
|
|
do_stop (CkManager *manager,
|
|
DBusGMethodInvocation *context)
|
|
{
|
|
- do_system_action (manager,
|
|
- context,
|
|
- PREFIX "/lib/ConsoleKit/scripts/ck-system-stop",
|
|
- CK_LOG_EVENT_SYSTEM_STOP,
|
|
- "Stop");
|
|
+ SystemActionData *data;
|
|
+
|
|
+ /* Emit the signal */
|
|
+ g_signal_emit (manager, signals [PREPARE_FOR_SHUTDOWN], 0, TRUE);
|
|
+
|
|
+ /* Allocate and fill the data struct to pass to the idle cb */
|
|
+ data = g_new0 (SystemActionData, 1);
|
|
+ if (data == NULL) {
|
|
+ g_critical ("failed to allocate memory to perform shutdown\n");
|
|
+ g_signal_emit (manager, signals [PREPARE_FOR_SHUTDOWN], 0, FALSE);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ data->manager = manager;
|
|
+ data->context = context;
|
|
+ data->command = PREFIX "/lib/ConsoleKit/scripts/ck-system-stop";
|
|
+ data->event_type = CK_LOG_EVENT_SYSTEM_STOP;
|
|
+ data->description = "Stop";
|
|
+ data->signal = PREPARE_FOR_SHUTDOWN;
|
|
+
|
|
+ /* Sleep so user applications have time to respond */
|
|
+ g_timeout_add (data->manager->priv->system_action_idle_delay,
|
|
+ (GSourceFunc)system_action_idle_cb,
|
|
+ data);
|
|
}
|
|
|
|
gboolean
|
|
@@ -1486,11 +1561,30 @@ static void
|
|
do_suspend (CkManager *manager,
|
|
DBusGMethodInvocation *context)
|
|
{
|
|
- do_system_action (manager,
|
|
- context,
|
|
- PREFIX "/lib/ConsoleKit/scripts/ck-system-suspend",
|
|
- CK_LOG_EVENT_SYSTEM_SUSPEND,
|
|
- "Suspend");
|
|
+ SystemActionData *data;
|
|
+
|
|
+ /* Emit the signal */
|
|
+ g_signal_emit (manager, signals [PREPARE_FOR_SLEEP], 0, TRUE);
|
|
+
|
|
+ /* Allocate and fill the data struct to pass to the idle cb */
|
|
+ data = g_new0 (SystemActionData, 1);
|
|
+ if (data == NULL) {
|
|
+ g_critical ("failed to allocate memory to perform suspend\n");
|
|
+ g_signal_emit (manager, signals [PREPARE_FOR_SLEEP], 0, FALSE);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ data->manager = manager;
|
|
+ data->context = context;
|
|
+ data->command = PREFIX "/lib/ConsoleKit/scripts/ck-system-suspend";
|
|
+ data->event_type = CK_LOG_EVENT_SYSTEM_SUSPEND;
|
|
+ data->description = "Suspend";
|
|
+ data->signal = PREPARE_FOR_SLEEP;
|
|
+
|
|
+ /* Sleep so user applications have time to respond */
|
|
+ g_timeout_add (data->manager->priv->system_action_idle_delay,
|
|
+ (GSourceFunc)system_action_idle_cb,
|
|
+ data);
|
|
}
|
|
|
|
/*
|
|
@@ -1572,11 +1666,30 @@ static void
|
|
do_hibernate (CkManager *manager,
|
|
DBusGMethodInvocation *context)
|
|
{
|
|
- do_system_action (manager,
|
|
- context,
|
|
- PREFIX "/lib/ConsoleKit/scripts/ck-system-hibernate",
|
|
- CK_LOG_EVENT_SYSTEM_HIBERNATE,
|
|
- "Hibernate");
|
|
+ SystemActionData *data;
|
|
+
|
|
+ /* Emit the signal */
|
|
+ g_signal_emit (manager, signals [PREPARE_FOR_SLEEP], 0, TRUE);
|
|
+
|
|
+ /* Allocate and fill the data struct to pass to the idle cb */
|
|
+ data = g_new0 (SystemActionData, 1);
|
|
+ if (data == NULL) {
|
|
+ g_critical ("failed to allocate memory to perform suspend\n");
|
|
+ g_signal_emit (manager, signals [PREPARE_FOR_SLEEP], 0, FALSE);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ data->manager = manager;
|
|
+ data->context = context;
|
|
+ data->command = PREFIX "/lib/ConsoleKit/scripts/ck-system-hibernate";
|
|
+ data->event_type = CK_LOG_EVENT_SYSTEM_HIBERNATE;
|
|
+ data->description = "Hibernate";
|
|
+ data->signal = PREPARE_FOR_SLEEP;
|
|
+
|
|
+ /* Sleep so user applications have time to respond */
|
|
+ g_timeout_add (data->manager->priv->system_action_idle_delay,
|
|
+ (GSourceFunc)system_action_idle_cb,
|
|
+ data);
|
|
}
|
|
|
|
/*
|
|
@@ -1658,11 +1771,30 @@ static void
|
|
do_hybrid_sleep (CkManager *manager,
|
|
DBusGMethodInvocation *context)
|
|
{
|
|
- do_system_action (manager,
|
|
- context,
|
|
- PREFIX "/lib/ConsoleKit/scripts/ck-system-hybridsleep",
|
|
- CK_LOG_EVENT_SYSTEM_HIBERNATE,
|
|
- "Hybrid Sleep");
|
|
+ SystemActionData *data;
|
|
+
|
|
+ /* Emit the signal */
|
|
+ g_signal_emit (manager, signals [PREPARE_FOR_SLEEP], 0, TRUE);
|
|
+
|
|
+ /* Allocate and fill the data struct to pass to the idle cb */
|
|
+ data = g_new0 (SystemActionData, 1);
|
|
+ if (data == NULL) {
|
|
+ g_critical ("failed to allocate memory to perform suspend\n");
|
|
+ g_signal_emit (manager, signals [PREPARE_FOR_SLEEP], 0, FALSE);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ data->manager = manager;
|
|
+ data->context = context;
|
|
+ data->command = PREFIX "/lib/ConsoleKit/scripts/ck-system-hybridsleep";
|
|
+ data->event_type = CK_LOG_EVENT_SYSTEM_HIBERNATE;
|
|
+ data->description = "Hybrid Sleep";
|
|
+ data->signal = PREPARE_FOR_SLEEP;
|
|
+
|
|
+ /* Sleep so user applications have time to respond */
|
|
+ g_timeout_add (data->manager->priv->system_action_idle_delay,
|
|
+ (GSourceFunc)system_action_idle_cb,
|
|
+ data);
|
|
}
|
|
|
|
/*
|
|
@@ -3043,6 +3175,26 @@ ck_manager_class_init (CkManagerClass *klass)
|
|
g_cclosure_marshal_VOID__BOOLEAN,
|
|
G_TYPE_NONE,
|
|
1, G_TYPE_BOOLEAN);
|
|
+ signals [PREPARE_FOR_SHUTDOWN] =
|
|
+ g_signal_new ("prepare-for-shutdown",
|
|
+ G_TYPE_FROM_CLASS (object_class),
|
|
+ G_SIGNAL_RUN_LAST,
|
|
+ G_STRUCT_OFFSET (CkManagerClass, prepare_for_shutdown),
|
|
+ NULL,
|
|
+ NULL,
|
|
+ g_cclosure_marshal_VOID__BOOLEAN,
|
|
+ G_TYPE_NONE,
|
|
+ 1, G_TYPE_BOOLEAN);
|
|
+ signals [PREPARE_FOR_SLEEP] =
|
|
+ g_signal_new ("prepare-for-sleep",
|
|
+ G_TYPE_FROM_CLASS (object_class),
|
|
+ G_SIGNAL_RUN_LAST,
|
|
+ G_STRUCT_OFFSET (CkManagerClass, prepare_for_sleep),
|
|
+ NULL,
|
|
+ NULL,
|
|
+ g_cclosure_marshal_VOID__BOOLEAN,
|
|
+ G_TYPE_NONE,
|
|
+ 1, G_TYPE_BOOLEAN);
|
|
|
|
dbus_g_object_type_install_info (CK_TYPE_MANAGER, &dbus_glib_ck_manager_object_info);
|
|
dbus_g_error_domain_register (CK_MANAGER_ERROR, NULL, CK_MANAGER_TYPE_ERROR);
|
|
@@ -3256,6 +3408,8 @@ ck_manager_init (CkManager *manager)
|
|
|
|
manager->priv->inhibit_manager = ck_inhibit_manager_get ();
|
|
|
|
+ manager->priv->system_action_idle_delay = 4 * 1000;
|
|
+
|
|
create_seats (manager);
|
|
}
|
|
|
|
diff --git a/src/ck-manager.h b/src/ck-manager.h
|
|
index 098d464..5bdc76e 100644
|
|
--- a/src/ck-manager.h
|
|
+++ b/src/ck-manager.h
|
|
@@ -54,6 +54,10 @@ typedef struct
|
|
const char *sid);
|
|
void (* system_idle_hint_changed) (CkManager *manager,
|
|
gboolean idle_hint);
|
|
+ void (* prepare_for_shutdown) (CkManager *manager,
|
|
+ gboolean active);
|
|
+ void (* prepare_for_sleep) (CkManager *manager,
|
|
+ gboolean active);
|
|
} CkManagerClass;
|
|
|
|
typedef enum
|
|
diff --git a/src/org.freedesktop.ConsoleKit.Manager.xml b/src/org.freedesktop.ConsoleKit.Manager.xml
|
|
index eb44d45..9b94120 100644
|
|
--- a/src/org.freedesktop.ConsoleKit.Manager.xml
|
|
+++ b/src/org.freedesktop.ConsoleKit.Manager.xml
|
|
@@ -603,5 +603,36 @@
|
|
</doc:description>
|
|
</doc:doc>
|
|
</signal>
|
|
+ <signal name="PrepareForShutdown">
|
|
+ <arg name="active" type="b">
|
|
+ <doc:doc>
|
|
+ <doc:summary>TRUE when the system is starting to halt.</doc:summary>
|
|
+ </doc:doc>
|
|
+ </arg>
|
|
+ <doc:doc>
|
|
+ <doc:description>
|
|
+ <doc:para>Emitted when the system is halting (active = TRUE). If
|
|
+ successful there will not be a FALSE signal emitted since
|
|
+ the system will poweroff or reboot. It will emit a FALSE
|
|
+ signal if the shutdown operation failed.
|
|
+ </doc:para>
|
|
+ </doc:description>
|
|
+ </doc:doc>
|
|
+ </signal>
|
|
+ <signal name="PrepareForSleep">
|
|
+ <arg name="active" type="b">
|
|
+ <doc:doc>
|
|
+ <doc:summary>TRUE when starting to sleep.</doc:summary>
|
|
+ </doc:doc>
|
|
+ </arg>
|
|
+ <doc:doc>
|
|
+ <doc:description>
|
|
+ <doc:para>Emitted when the system is starting the sleep process.
|
|
+ It will emit with an active = FALSE when resuming from sleep
|
|
+ or if the sleep operation failed.
|
|
+ </doc:para>
|
|
+ </doc:description>
|
|
+ </doc:doc>
|
|
+ </signal>
|
|
</interface>
|
|
</node>
|
|
--
|
|
2.2.1
|
|
|