summaryrefslogtreecommitdiff
path: root/applets/clock/clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'applets/clock/clock.c')
-rw-r--r--applets/clock/clock.c535
1 files changed, 399 insertions, 136 deletions
diff --git a/applets/clock/clock.c b/applets/clock/clock.c
index 8b427d2e..2e26b39f 100644
--- a/applets/clock/clock.c
+++ b/applets/clock/clock.c
@@ -51,10 +51,20 @@
#include <gdk/gdkkeysyms.h>
#include <gio/gio.h>
+#if defined (CLOCK_INPROCESS) && defined (HAVE_WAYLAND)
+#include <gdk/gdkwayland.h>
+#include <gtk-layer-shell/gtk-layer-shell.h>
+#endif
+
#ifdef HAVE_X11
#include <gdk/gdkx.h>
#endif
+#ifndef HAVE_X11
+#include <gdk/gdkwayland.h>
+#define GDK_IS_X11_DISPLAY(object) !(G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_DISPLAY))
+#endif
+
#include <libmateweather/mateweather-prefs.h>
#include <libmateweather/location-entry.h>
#include <libmateweather/timezone-menu.h>
@@ -84,6 +94,18 @@
#define KEY_CITIES "cities"
#define KEY_TEMPERATURE_UNIT "temperature-unit"
#define KEY_SPEED_UNIT "speed-unit"
+#define KEY_SHOW_CALENDAR_EVENTS "show-calendar-events"
+#define KEY_SHOW_TASKS "show-tasks"
+
+/* 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))))
@@ -112,6 +134,7 @@ struct _ClockData {
GtkWidget *props;
GtkWidget *calendar_popup;
+ gboolean calendar_popup_destroying;
GtkWidget *clock_vbox;
GtkSizeGroup *clock_group;
@@ -186,6 +209,12 @@ struct _ClockData {
GSettings *settings;
const gchar *weather_icon_name;
+
+ GDBusProxy *system_manager_proxy;
+
+#ifdef HAVE_EDS
+ CalendarClient *calendar_client;
+#endif
};
/* Used to count the number of clock instances. It's there to know when we
@@ -441,7 +470,7 @@ get_updated_timeformat (ClockData *cd)
/* Translators: This is a strftime format string.
* It is used to display the time in 12-hours format (eg, like
* in the US: 8:10 am). The %p expands to am/pm. */
- time_format = cd->showseconds ? _("%l:%M:%S %p") : _("%l:%M %p");
+ time_format = cd->showseconds ? _("%_I:%M:%S %p") : _("%_I:%M %p");
else
/* Translators: This is a strftime format string.
* It is used to display the time in 24-hours format (eg, like
@@ -747,6 +776,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);
@@ -765,9 +800,12 @@ destroy_clock (GtkWidget * widget, ClockData *cd)
gtk_widget_destroy (cd->props);
cd->props = NULL;
- if (cd->calendar_popup)
+ if (cd->calendar_popup && !cd->calendar_popup_destroying) {
+ cd->calendar_popup_destroying = TRUE;
gtk_widget_destroy (cd->calendar_popup);
+ }
cd->calendar_popup = NULL;
+ cd->calendar_popup_destroying = FALSE;
g_free (cd->timeformat);
@@ -794,6 +832,13 @@ destroy_clock (GtkWidget * widget, ClockData *cd)
cd->builder = NULL;
}
+#ifdef HAVE_EDS
+ if (cd->calendar_client) {
+ g_object_unref (cd->calendar_client);
+ cd->calendar_client = NULL;
+ }
+#endif
+
g_free (cd);
}
@@ -834,13 +879,31 @@ create_calendar (ClockData *cd)
{
GtkWidget *window;
char *prefs_path;
+ char *fallback_path = NULL;
prefs_path = mate_panel_applet_get_preferences_path (MATE_PANEL_APPLET (cd->applet));
+
+ /* Provide a fallback preferences path in case the applet doesn't
+ * provide one. This happens when running outside the actual panel,
+ * like in mate-panel-test-applets */
+ if (!prefs_path || !prefs_path[0]) {
+ fallback_path = g_strdup ("/org/mate/panel/applets/clock/");
+ g_free (prefs_path);
+ prefs_path = fallback_path;
+ }
+
window = calendar_window_new (&cd->current_time,
prefs_path,
- cd->orient == MATE_PANEL_APPLET_ORIENT_UP);
+ cd->orient == MATE_PANEL_APPLET_ORIENT_UP,
+ cd->settings);
g_free (prefs_path);
+#ifdef HAVE_EDS
+ if (cd->calendar_client) {
+ calendar_window_set_client (CALENDAR_WINDOW (window), cd->calendar_client);
+ }
+#endif
+
calendar_window_set_show_weeks (CALENDAR_WINDOW (window),
cd->showweek);
@@ -870,105 +933,204 @@ create_calendar (ClockData *cd)
static void
position_calendar_popup (ClockData *cd)
{
-#ifdef HAVE_X11
- GtkRequisition req;
- GtkAllocation allocation;
- GdkDisplay *display;
- GdkScreen *screen;
- GdkRectangle monitor;
- GdkGravity gravity = GDK_GRAVITY_NORTH_WEST;
- int button_w, button_h;
- int x, y;
- int w, h;
- int i, n;
- gboolean found_monitor = FALSE;
-
- if (!GDK_IS_X11_DISPLAY (gdk_display_get_default ()))
- return;
+#if defined(HAVE_X11) && defined(GDK_WINDOWING_X11)
+ if (GDK_IS_X11_DISPLAY (gdk_display_get_default ()))
+ {
+ GtkRequisition req;
+ GtkAllocation allocation;
+ GdkDisplay *display;
+ GdkScreen *screen;
+ GdkRectangle monitor;
+ GdkGravity gravity = GDK_GRAVITY_NORTH_WEST;
+ int button_w, button_h;
+ int x, y;
+ int w, h;
+ int i, n;
+ gboolean found_monitor = FALSE;
+
+
+ /* Get root origin of the toggle button, and position above that. */
+ gdk_window_get_origin (gtk_widget_get_window (cd->panel_button),
+ &x, &y);
+
+ gtk_window_get_size (GTK_WINDOW (cd->calendar_popup), &w, &h);
+ gtk_widget_get_preferred_size (cd->calendar_popup, &req, NULL);
+ w = req.width;
+ h = req.height;
+
+ gtk_widget_get_allocation (cd->panel_button, &allocation);
+ button_w = allocation.width;
+ button_h = allocation.height;
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (cd->calendar_popup));
+ display = gtk_widget_get_display (GTK_WIDGET (cd->calendar_popup));
+
+ n = gdk_display_get_n_monitors (display);
+ for (i = 0; i < n; i++) {
+ gdk_monitor_get_geometry (gdk_display_get_monitor (display, i), &monitor);
+ if (x >= monitor.x && x <= monitor.x + monitor.width &&
+ y >= monitor.y && y <= monitor.y + monitor.height) {
+ found_monitor = TRUE;
+ break;
+ }
+ }
- /* Get root origin of the toggle button, and position above that. */
- gdk_window_get_origin (gtk_widget_get_window (cd->panel_button),
- &x, &y);
+ if (!found_monitor) {
+ /* eek, we should be on one of those xinerama
+ monitors */
+ monitor.x = 0;
+ monitor.y = 0;
+ monitor.width = WidthOfScreen (gdk_x11_screen_get_xscreen (screen));
+ monitor.height = HeightOfScreen (gdk_x11_screen_get_xscreen (screen));
+ }
- gtk_window_get_size (GTK_WINDOW (cd->calendar_popup), &w, &h);
- gtk_widget_get_preferred_size (cd->calendar_popup, &req, NULL);
- w = req.width;
- h = req.height;
+ /* Based on panel orientation, position the popup.
+ * Ignore window gravity since the window is undecorated.
+ * The orientations are all named backward from what
+ * I expected.
+ */
+ switch (cd->orient) {
+ case MATE_PANEL_APPLET_ORIENT_RIGHT:
+ x += button_w;
+ if ((y + h) > monitor.y + monitor.height)
+ y -= (y + h) - (monitor.y + monitor.height);
+
+ if ((y + h) > (monitor.height / 2))
+ gravity = GDK_GRAVITY_SOUTH_WEST;
+ else
+ gravity = GDK_GRAVITY_NORTH_WEST;
- gtk_widget_get_allocation (cd->panel_button, &allocation);
- button_w = allocation.width;
- button_h = allocation.height;
-
- screen = gtk_window_get_screen (GTK_WINDOW (cd->calendar_popup));
- display = gdk_screen_get_display (screen);
-
- n = gdk_display_get_n_monitors (display);
- for (i = 0; i < n; i++) {
- gdk_monitor_get_geometry (gdk_display_get_monitor (display, i), &monitor);
- if (x >= monitor.x && x <= monitor.x + monitor.width &&
- y >= monitor.y && y <= monitor.y + monitor.height) {
- found_monitor = TRUE;
break;
- }
- }
+ case MATE_PANEL_APPLET_ORIENT_LEFT:
+ x -= w;
+ if ((y + h) > monitor.y + monitor.height)
+ y -= (y + h) - (monitor.y + monitor.height);
- if (!found_monitor) {
- /* eek, we should be on one of those xinerama
- monitors */
- monitor.x = 0;
- monitor.y = 0;
- monitor.width = WidthOfScreen (gdk_x11_screen_get_xscreen (screen));
- monitor.height = HeightOfScreen (gdk_x11_screen_get_xscreen (screen));
- }
+ if ((y + h) > (monitor.height / 2))
+ gravity = GDK_GRAVITY_SOUTH_EAST;
+ else
+ gravity = GDK_GRAVITY_NORTH_EAST;
- /* Based on panel orientation, position the popup.
- * Ignore window gravity since the window is undecorated.
- * The orientations are all named backward from what
- * I expected.
- */
- switch (cd->orient) {
- case MATE_PANEL_APPLET_ORIENT_RIGHT:
- x += button_w;
- if ((y + h) > monitor.y + monitor.height)
- y -= (y + h) - (monitor.y + monitor.height);
+ break;
+ case MATE_PANEL_APPLET_ORIENT_DOWN:
+ y += button_h;
+ if ((x + w) > monitor.x + monitor.width)
+ x -= (x + w) - (monitor.x + monitor.width);
- if ((y + h) > (monitor.height / 2))
- gravity = GDK_GRAVITY_SOUTH_WEST;
- else
gravity = GDK_GRAVITY_NORTH_WEST;
- break;
- case MATE_PANEL_APPLET_ORIENT_LEFT:
- x -= w;
- if ((y + h) > monitor.y + monitor.height)
- y -= (y + h) - (monitor.y + monitor.height);
+ break;
+ case MATE_PANEL_APPLET_ORIENT_UP:
+ y -= h;
+ if ((x + w) > monitor.x + monitor.width)
+ x -= (x + w) - (monitor.x + monitor.width);
- if ((y + h) > (monitor.height / 2))
- gravity = GDK_GRAVITY_SOUTH_EAST;
- else
- gravity = GDK_GRAVITY_NORTH_EAST;
+ gravity = GDK_GRAVITY_SOUTH_WEST;
- break;
- case MATE_PANEL_APPLET_ORIENT_DOWN:
- y += button_h;
- if ((x + w) > monitor.x + monitor.width)
- x -= (x + w) - (monitor.x + monitor.width);
+ break;
+ }
- gravity = GDK_GRAVITY_NORTH_WEST;
+ gtk_window_move (GTK_WINDOW (cd->calendar_popup), x, y);
+ gtk_window_set_gravity (GTK_WINDOW (cd->calendar_popup), gravity);
+ }
+#endif
- break;
- case MATE_PANEL_APPLET_ORIENT_UP:
- y -= h;
- if ((x + w) > monitor.x + monitor.width)
- x -= (x + w) - (monitor.x + monitor.width);
+ /*Only build wayland support when building in process*/
+#if defined(CLOCK_INPROCESS) && defined(HAVE_WAYLAND) && defined(GDK_WINDOWING_WAYLAND)
+ if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ()))
+ {
+ GtkWindow *window;
+ GdkWindow *panelwin;
+ GtkWidget *toplevel;
+ int x, y, w, h, panel_w, panel_h;
+
+ /*Get the calendar window dimensions*/
+ window = (GTK_WINDOW (cd->calendar_popup));
+ gtk_window_get_size (window, &w, &h);
+ /*Find the position of the applet*/
+ gdk_window_get_origin (gtk_widget_get_window (cd->panel_button),
+ &x, &y);
+
+ /*Get the panel dimensions*/
+ toplevel = gtk_widget_get_toplevel (cd->applet);
+ panelwin = gtk_widget_get_window (toplevel);
+ gdk_window_get_geometry (panelwin, NULL, NULL, &panel_w, &panel_h);
+
+ /*Set up GTK Layer Shell*/
+ gtk_layer_init_for_window (window);
+ gtk_layer_set_layer (window, GTK_LAYER_SHELL_LAYER_TOP);
+
+ switch (cd->orient) {
+ case MATE_PANEL_APPLET_ORIENT_RIGHT:
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_LEFT, TRUE);
+ gtk_layer_set_margin (window, GTK_LAYER_SHELL_EDGE_LEFT, 0);
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_RIGHT, FALSE);
+ if (y < (panel_h - h))
+ {
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_TOP, TRUE);
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_BOTTOM, FALSE);
+ gtk_layer_set_margin (window, GTK_LAYER_SHELL_EDGE_TOP, y);
+ }
+ else
+ {
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_BOTTOM, TRUE);
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_TOP, FALSE);
+ }
+ break;
- gravity = GDK_GRAVITY_SOUTH_WEST;
+ case MATE_PANEL_APPLET_ORIENT_LEFT:
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_RIGHT, TRUE);
+ gtk_layer_set_margin (window, GTK_LAYER_SHELL_EDGE_RIGHT, 0);
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_LEFT, FALSE);
+ if (y < (panel_h - h))
+ {
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_TOP, TRUE);
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_BOTTOM, FALSE);
+ gtk_layer_set_margin (window, GTK_LAYER_SHELL_EDGE_TOP, y);
+ }
+ else
+ {
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_BOTTOM, TRUE);
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_TOP, FALSE);
+ }
+ break;
- break;
- }
+ case MATE_PANEL_APPLET_ORIENT_DOWN:
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_TOP, TRUE);
+ gtk_layer_set_margin (window, GTK_LAYER_SHELL_EDGE_TOP, 0);
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_BOTTOM, FALSE);
+ if (x < (panel_w - w))
+ {
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_LEFT, TRUE);
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_RIGHT, FALSE);
+ gtk_layer_set_margin (window, GTK_LAYER_SHELL_EDGE_LEFT, x);
+ }
+ else
+ {
+ gtk_layer_set_anchor(window, GTK_LAYER_SHELL_EDGE_RIGHT, TRUE);
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_LEFT, FALSE);
+ }
+ break;
- gtk_window_move (GTK_WINDOW (cd->calendar_popup), x, y);
- gtk_window_set_gravity (GTK_WINDOW (cd->calendar_popup), gravity);
+ case MATE_PANEL_APPLET_ORIENT_UP:
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_BOTTOM, TRUE);
+ gtk_layer_set_margin (window, GTK_LAYER_SHELL_EDGE_BOTTOM, 0);
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_TOP, FALSE);
+ if (x < (panel_w - w))
+ {
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_LEFT, TRUE);
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_RIGHT, FALSE);
+ gtk_layer_set_margin (window, GTK_LAYER_SHELL_EDGE_LEFT, x);
+ }
+ else
+ {
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_RIGHT, TRUE);
+ gtk_layer_set_anchor (window, GTK_LAYER_SHELL_EDGE_LEFT, FALSE);
+ }
+ break;
+ }
+ return;
+ }
#endif
}
@@ -1065,35 +1227,17 @@ sort_locations_by_time (gconstpointer a, gconstpointer b)
clock_location_localtime (loc_a, &tm_a);
clock_location_localtime (loc_b, &tm_b);
- ret = (tm_a.tm_year == tm_b.tm_year) ? 0 : 1;
- if (ret) {
- return (tm_a.tm_year < tm_b.tm_year) ? -1 : 1;
- }
-
- ret = (tm_a.tm_mon == tm_b.tm_mon) ? 0 : 1;
- if (ret) {
- return (tm_a.tm_mon < tm_b.tm_mon) ? -1 : 1;
- }
-
- ret = (tm_a.tm_mday == tm_b.tm_mday) ? 0 : 1;
- if (ret) {
- return (tm_a.tm_mday < tm_b.tm_mday) ? -1 : 1;
- }
-
- ret = (tm_a.tm_hour == tm_b.tm_hour) ? 0 : 1;
- if (ret) {
- return (tm_a.tm_hour < tm_b.tm_hour) ? -1 : 1;
- }
-
- ret = (tm_a.tm_min == tm_b.tm_min) ? 0 : 1;
- if (ret) {
- return (tm_a.tm_min < tm_b.tm_min) ? -1 : 1;
- }
-
- ret = (tm_a.tm_sec == tm_b.tm_sec) ? 0 : 1;
- if (ret) {
- return (tm_a.tm_sec < tm_b.tm_sec) ? -1 : 1;
- }
+ ret = tm_a.tm_year - tm_b.tm_year;
+ if (! ret)
+ ret = tm_a.tm_mon - tm_b.tm_mon;
+ if (! ret)
+ ret = tm_a.tm_mday - tm_b.tm_mday;
+ if (! ret)
+ ret = tm_a.tm_hour - tm_b.tm_hour;
+ if (! ret)
+ ret = tm_a.tm_min - tm_b.tm_min;
+ if (! ret)
+ ret = tm_a.tm_sec - tm_b.tm_sec;
return ret;
}
@@ -1144,6 +1288,7 @@ location_tile_need_clock_format_cb(ClockLocationTile *tile, gpointer data)
static void
create_cities_section (ClockData *cd)
{
+ GtkWidget *cities_box;
GSList *node;
GSList *cities;
GSList *l;
@@ -1157,8 +1302,16 @@ create_cities_section (ClockData *cd)
g_slist_free (cd->location_tiles);
cd->location_tiles = NULL;
- cd->cities_section = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
- gtk_container_set_border_width (GTK_CONTAINER (cd->cities_section), 0);
+ cd->cities_section = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (cd->cities_section),
+ GTK_POLICY_NEVER,
+ GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (cd->cities_section),
+ GTK_SHADOW_NONE);
+ gtk_scrolled_window_set_propagate_natural_height (GTK_SCROLLED_WINDOW (cd->cities_section),
+ TRUE);
+
+ cities_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
cities = cd->locations;
if (g_slist_length (cities) == 0) {
@@ -1180,7 +1333,7 @@ create_cities_section (ClockData *cd)
g_signal_connect (city, "need-clock-format",
G_CALLBACK (location_tile_need_clock_format_cb), cd);
- gtk_box_pack_start (GTK_BOX (cd->cities_section),
+ gtk_box_pack_start (GTK_BOX (cities_box),
GTK_WIDGET (city),
FALSE, FALSE, 0);
@@ -1191,6 +1344,8 @@ create_cities_section (ClockData *cd)
g_slist_free (node);
+ gtk_container_add (GTK_CONTAINER (cd->cities_section), cities_box);
+
gtk_box_pack_end (GTK_BOX (cd->clock_vbox),
cd->cities_section, FALSE, FALSE, 0);
@@ -1234,9 +1389,11 @@ static void
update_calendar_popup (ClockData *cd)
{
if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cd->panel_button))) {
- if (cd->calendar_popup) {
+ if (cd->calendar_popup && !cd->calendar_popup_destroying) {
+ cd->calendar_popup_destroying = TRUE;
gtk_widget_destroy (cd->calendar_popup);
cd->calendar_popup = NULL;
+ cd->calendar_popup_destroying = FALSE;
cd->cities_section = NULL;
cd->map_widget = NULL;
cd->clock_vbox = NULL;
@@ -1249,7 +1406,7 @@ update_calendar_popup (ClockData *cd)
return;
}
- if (!cd->calendar_popup) {
+ if (!cd->calendar_popup && !cd->calendar_popup_destroying) {
cd->calendar_popup = create_calendar (cd);
g_object_add_weak_pointer (G_OBJECT (cd->calendar_popup),
(gpointer *) &cd->calendar_popup);
@@ -2115,9 +2272,6 @@ location_set_current_cb (ClockLocation *loc,
static void
locations_changed (ClockData *cd)
{
- GSList *l;
- glong id;
-
if (!cd->locations) {
if (cd->weather_obox)
gtk_widget_hide (cd->weather_obox);
@@ -2132,8 +2286,9 @@ locations_changed (ClockData *cd)
gtk_widget_show (cd->weather_obox);
}
- for (l = cd->locations; l; l = l->next) {
+ for (GSList *l = cd->locations; l; l = l->next) {
ClockLocation *loc = l->data;
+ glong id;
id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (loc), "weather-updated"));
if (id == 0) {
@@ -2393,18 +2548,8 @@ show_week_changed (GSettings *settings,
static void
setup_gsettings (ClockData *cd)
{
- gint format;
- gchar *custom_format;
-
cd->settings = mate_panel_applet_settings_new (MATE_PANEL_APPLET (cd->applet), CLOCK_SCHEMA);
- /* hack to allow users to set custom format in dconf-editor */
- format = g_settings_get_enum (cd->settings, KEY_FORMAT);
- custom_format = g_settings_get_string (cd->settings, KEY_CUSTOM_FORMAT);
- g_settings_set_enum (cd->settings, KEY_FORMAT, format);
- g_settings_set_string (cd->settings, KEY_CUSTOM_FORMAT, custom_format);
- g_free (custom_format);
-
g_signal_connect (cd->settings, "changed::" KEY_FORMAT, G_CALLBACK (format_changed), cd);
g_signal_connect (cd->settings, "changed::" KEY_SHOW_SECONDS, G_CALLBACK (show_seconds_changed), cd);
g_signal_connect (cd->settings, "changed::" KEY_SHOW_DATE, G_CALLBACK (show_date_changed), cd);
@@ -2420,7 +2565,6 @@ setup_gsettings (ClockData *cd)
static GSList *
parse_gsettings_cities (ClockData *cd, gchar **values)
{
- gint i;
LocationParserData data;
GMarkupParseContext *context;
@@ -2430,7 +2574,7 @@ parse_gsettings_cities (ClockData *cd, gchar **values)
context = g_markup_parse_context_new (&location_parser, 0, &data, NULL);
if (values) {
- for (i = 0; values[i]; i++) {
+ for (gint i = 0; values[i]; i++) {
g_markup_parse_context_parse (context, values[i], strlen(values[i]), NULL);
}
}
@@ -2478,6 +2622,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)
+{
+ if (g_strcmp0 (signal_name, "PrepareForSleep") == 0)
+ {
+ GVariant *variant;
+ gboolean active;
+
+ 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 +2775,16 @@ 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);
+
+#ifdef HAVE_EDS
+ /* Initialize persistent calendar client */
+ cd->calendar_client = calendar_client_new (cd->settings);
+#endif
+
return TRUE;
}
@@ -3100,6 +3334,35 @@ fill_prefs_window (ClockData *cd)
g_settings_bind (cd->settings, KEY_SHOW_TEMPERATURE, widget, "active",
G_SETTINGS_BIND_DEFAULT);
+#ifdef HAVE_EDS
+ /* Set the EDS calendar event checkboxes */
+ widget = _clock_get_widget (cd, "show_calendar_events_check");
+ if (widget) {
+ /* Bind to gsettings - this should sync with calendar window automatically */
+ g_settings_bind (cd->settings, KEY_SHOW_CALENDAR_EVENTS, widget, "active",
+ G_SETTINGS_BIND_DEFAULT);
+ } else {
+ g_warning ("Could not find show_calendar_events_check widget in preferences");
+ }
+
+ /* Set the EDS tasks checkboxes */
+ widget = _clock_get_widget (cd, "show_tasks_check");
+ if (widget) {
+ /* Bind to gsettings - this should sync with calendar window automatically */
+ g_settings_bind (cd->settings, KEY_SHOW_TASKS, widget, "active",
+ G_SETTINGS_BIND_DEFAULT);
+ } else {
+ g_warning ("Could not find show_tasks_check widget in preferences");
+ }
+
+#else
+ /* Hide the Calendar tab if EDS is not available */
+ widget = _clock_get_widget (cd, "vbox-calendar");
+ gtk_widget_hide (widget);
+ widget = _clock_get_widget (cd, "label-calendar-tab");
+ gtk_widget_hide (widget);
+#endif
+
/* Fill the Cities list */
widget = _clock_get_widget (cd, "cities_list");