diff options
author | Gordon Norman Squash <[email protected]> | 2023-03-17 21:06:33 -0400 |
---|---|---|
committer | Luke from DC <[email protected]> | 2023-03-27 03:16:17 +0000 |
commit | 061193aca2309da9caeecf228857631a40739d9a (patch) | |
tree | 5a8bdaaca618d03128ea8784c746fd82c7db2256 /applets/clock/clock.c | |
parent | e504576092e499bdc5ecb14fc8b99db74ee9382d (diff) | |
download | mate-panel-061193aca2309da9caeecf228857631a40739d9a.tar.bz2 mate-panel-061193aca2309da9caeecf228857631a40739d9a.tar.xz |
Clock Applet: Update date/time and weather after resume from sleep mode
Before this commit, the Clock Applet was unaware of when the system
resumed from sleep mode (e.g. suspend or hibernate). This meant that,
if the user suspended the system and then woke it up some time later,
the clock might not show the real current time, but instead would continue
to show the time at which the system was suspended for up to a minute
after the system woke up. This could be confusing to the user if they
peered up at the clock immediately after, say, opening their laptop lid.
This commit connects to ConsoleKit or (if available) systemd-logind via
D-Bus, and listens for a signal that indicates when the system wakes up
from sleep mode. When the system does wake up, the Clock Applet updates
the date/time immediately, and also updates all the weather/temperature
readings if possible.
Note that if logind is missing, ConsoleKit2 is required for this feature
to work; the original ConsoleKit lacked the signal required to implement
this feature. This should not be a problem since it is unlikely that
anyone would even consider using the original ConsoleKit in this day and
age.
Diffstat (limited to 'applets/clock/clock.c')
-rw-r--r-- | applets/clock/clock.c | 103 |
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; } |