summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--applets/clock/clock.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/applets/clock/clock.c b/applets/clock/clock.c
index 8b427d2e..0ee49628 100644
--- a/applets/clock/clock.c
+++ b/applets/clock/clock.c
@@ -85,6 +85,16 @@
#define KEY_TEMPERATURE_UNIT "temperature-unit"
#define KEY_SPEED_UNIT "speed-unit"
+/* For watching for when the system resumes from sleep mode (e.g. suspend)
+ * and updating the clock as soon as that happens. */
+#define LOGIND_RUNNING() (access("/run/systemd/seats/", F_OK) >= 0)
+#define SYSTEMD_LOGIND_SERVICE "org.freedesktop.login1"
+#define SYSTEMD_LOGIND_PATH "/org/freedesktop/login1"
+#define SYSTEMD_LOGIND_INTERFACE "org.freedesktop.login1.Manager"
+#define CK_SERVICE "org.freedesktop.ConsoleKit"
+#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager"
+#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
+
#define _clock_get_widget(x,y) (GTK_WIDGET (gtk_builder_get_object ((x)->builder, (y))))
enum {
@@ -186,6 +196,8 @@ struct _ClockData {
GSettings *settings;
const gchar *weather_icon_name;
+
+ GDBusProxy *system_manager_proxy;
};
/* Used to count the number of clock instances. It's there to know when we
@@ -747,6 +759,12 @@ free_locations (ClockData *cd)
static void
destroy_clock (GtkWidget * widget, ClockData *cd)
{
+ if (cd->system_manager_proxy)
+ {
+ g_signal_handlers_disconnect_by_data (cd->system_manager_proxy, cd);
+ g_object_unref (cd->system_manager_proxy);
+ }
+
if (cd->settings)
g_signal_handlers_disconnect_by_data( cd->settings, cd);
@@ -2478,6 +2496,86 @@ load_gsettings (ClockData *cd)
set_locations (cd, cities);
}
+/* When the system manager (ConsoleKit or systemd-logind) reports that
+ * the system has just resumed from sleep mode (e.g. suspend/hibernate),
+ * update the clock and the weather/temperature readings. That way, if
+ * the user suspended the system for an hour and then wakes the system up,
+ * the user will immediately see the current time and (if possible)
+ * updated weather data. Without this extra code, the user would most
+ * likely wake the system up and see the weather from an hour ago, and if
+ * the clock is set to not display seconds (only minutes), the clock may
+ * show an inaccurate time for up to a minute after resume.
+ */
+static void
+system_manager_signal_cb (GDBusProxy *proxy,
+ gchar *sender_name,
+ gchar *signal_name,
+ GVariant *parameters,
+ ClockData *cd)
+{
+ GVariant *variant;
+ gboolean active;
+
+ if (g_strcmp0 (signal_name, "PrepareForSleep") == 0)
+ {
+ variant = g_variant_get_child_value (parameters, 0);
+ active = g_variant_get_boolean (variant);
+ g_variant_unref (variant);
+
+ /* The PrepareForSleep signal is emitted by ConsoleKit2 and
+ * logind, both before sleep mode is entered, and
+ * immediately after the system has resumed from sleep mode.
+ * Listeners of this signal distinguish between the two
+ * states by checking the parameter to this signal. If the
+ * parameter is TRUE, the system is about to enter sleep
+ * mode; if FALSE, the system has resumed from sleep mode.
+ * We only care about updating the clock after resumption,
+ * so test if the parameter is FALSE.
+ */
+ if (active == FALSE)
+ {
+ update_clock (cd);
+ update_weather_locations (cd);
+ }
+ }
+}
+
+static void
+setup_monitor_for_resume (ClockData *cd)
+{
+ gboolean logind_running;
+ const char * service;
+ const char * path;
+ const char * interface;
+
+ /* If logind is running, connect to logind; otherwise use ConsoleKit.
+ */
+ logind_running = LOGIND_RUNNING ();
+ if (logind_running) {
+ service = SYSTEMD_LOGIND_SERVICE;
+ path = SYSTEMD_LOGIND_PATH;
+ interface = SYSTEMD_LOGIND_INTERFACE;
+ } else {
+ service = CK_SERVICE;
+ path = CK_MANAGER_PATH;
+ interface = CK_MANAGER_INTERFACE;
+ }
+
+ cd->system_manager_proxy = g_dbus_proxy_new_for_bus_sync
+ (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
+ NULL,
+ service, path, interface,
+ NULL, NULL);
+
+ if (cd->system_manager_proxy != NULL) {
+ g_signal_connect (cd->system_manager_proxy,
+ "g-signal",
+ G_CALLBACK (system_manager_signal_cb),
+ cd);
+ }
+}
+
static gboolean
fill_clock_applet (MatePanelApplet *applet)
{
@@ -2551,6 +2649,11 @@ fill_clock_applet (MatePanelApplet *applet)
G_CALLBACK (weather_icon_updated_cb),
cd);
+ /* If ConsoleKit or systemd-logind is available, set up to update
+ * the clock if/when the system resumes from sleep (e.g. suspend/
+ * hibernate). */
+ setup_monitor_for_resume (cd);
+
return TRUE;
}