[gnome-panel/wip/applets/clock: 8/18] clock: rewrite ClockLocationTile



commit 84d6662db323f9740012508d7ed1b1b4749e121f
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Sun Nov 9 22:26:15 2014 +0200

    clock: rewrite ClockLocationTile

 applets/clock/clock-location-tile.c | 1025 +++++++++++++++++++++--------------
 applets/clock/clock-location-tile.h |   83 ++-
 applets/clock/clock.c               |   39 +--
 3 files changed, 669 insertions(+), 478 deletions(-)
---
diff --git a/applets/clock/clock-location-tile.c b/applets/clock/clock-location-tile.c
index 04900dc..6ad6a8d 100644
--- a/applets/clock/clock-location-tile.c
+++ b/applets/clock/clock-location-tile.c
@@ -1,399 +1,319 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <stdlib.h>
+/*
+ * Copyright (C) 2014 Alberts Muktupāvels
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *    Alberts Muktupāvels <alberts muktupavels gmail com>
+ *    Carlos Garcia Campos <carlosgc gnome org>
+ *    Federico Mena Quintero <federico novell com>
+ *    Frank Solensky <frank src gnome org>
+ *    Frédéric Crozat <fcrozat src gnome org>
+ *    Giovanni Campagna <gcampagna src gnome org>
+ *    Jens Granseuer <jensgr gmx net>
+ *    Jeremy Bicha <jbicha ubuntu com>
+ *    Matthias Clasen <mclasen redhat com>
+ *    Milan Bouchet-Valat <nalimilan club fr>
+ *    Vincent Untz <vuntz gnome org>
+ */
 
+#include <config.h>
 #include <glib/gi18n.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkx.h>
+#include <stdlib.h>
 
-#include "clock.h"
 #include "clock-face.h"
-#include "clock-time.h"
 #include "clock-location-tile.h"
-#include "clock-location.h"
-#include "clock-utils.h"
-#include "clock-marshallers.h"
+#include "clock-time.h"
 #include "set-timezone.h"
 
-G_DEFINE_TYPE (ClockLocationTile, clock_location_tile, GTK_TYPE_BIN)
+struct _ClockLocationTilePrivate
+{
+       ClockLocation       *location;
+       ClockTime           *time;
+       GDesktopClockFormat  clock_format;
+
+       gulong               weather_updated_id;
 
-enum {
+       GtkWidget           *time_label;
+
+       GtkWidget           *button_label;
+       GtkWidget           *button;
+       GtkWidget           *marker;
+       GtkWidget           *spacer;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (ClockLocationTile,
+                            clock_location_tile,
+                            GTK_TYPE_EVENT_BOX)
+
+enum
+{
        TILE_PRESSED,
-       NEED_CLOCK_FORMAT,
        LAST_SIGNAL
 };
 
-static guint signals[LAST_SIGNAL];
+enum
+{
+       PROP_0,
+       PROP_LOCATION,
+       PROP_CLOCK_FORMAT,
+       N_PROPERTIES
+};
 
-typedef struct {
-        ClockLocation *location;
+static guint object_signals[LAST_SIGNAL] = { 0, };
+static GParamSpec *object_properties[N_PROPERTIES] = { NULL, };
 
-        GDateTime *last_refresh;
-       long last_offset;
+static void
+make_current_cb (gpointer  user_data,
+                 GError   *error)
+{
+       GtkWidget *dialog;
 
+       if (!error)
+               return;
 
-       GtkWidget *box;
-        GtkWidget *clock_face;
-        GtkWidget *city_label;
-        GtkWidget *time_label;
+       dialog = gtk_message_dialog_new (NULL,
+                                        0,
+                                        GTK_MESSAGE_ERROR,
+                                        GTK_BUTTONS_CLOSE,
+                                        _("Failed to set the system timezone"));
 
-        GtkWidget *current_button;
-        GtkWidget *current_label;
-        GtkWidget *current_marker;
-        GtkWidget *current_spacer;
+       gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                                                 "%s",
+                                                 error->message);
+       g_error_free (error);
 
-        GtkWidget *weather_icon;
+       g_signal_connect (dialog, "response",
+                         G_CALLBACK (gtk_widget_destroy), NULL);
 
-       gulong location_weather_updated_id;
-} ClockLocationTilePrivate;
+       gtk_window_present (GTK_WINDOW (dialog));
+}
 
-static void clock_location_tile_finalize (GObject *);
+static void
+make_current (GtkWidget *widget,
+              gpointer   user_data)
+{
+       ClockLocationTile *tile;
 
-#define PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CLOCK_LOCATION_TILE_TYPE, ClockLocationTilePrivate))
+       tile = CLOCK_LOCATION_TILE (user_data);
 
-static void clock_location_tile_fill (ClockLocationTile *this);
-static void update_weather_icon (ClockLocation *loc, GWeatherInfo *info, gpointer data);
-static gboolean weather_tooltip (GtkWidget *widget,
-                                 gint x, gint y,
-                                gboolean    keyboard_mode,
-                                GtkTooltip *tooltip,
-                                gpointer    data);
+       clock_location_make_current (tile->priv->location,
+                                    (GFunc) make_current_cb,
+                                    NULL,
+                                    NULL);
+}
 
-ClockLocationTile *
-clock_location_tile_new (ClockLocation *loc)
+static gboolean
+clock_location_tile_enter_or_leave (GtkWidget        *widget,
+                                    GdkEventCrossing *event,
+                                    gpointer          user_data)
 {
-        ClockLocationTile *this;
-        ClockLocationTilePrivate *priv;
+       ClockLocationTile *tile;
 
-        this = g_object_new (CLOCK_LOCATION_TILE_TYPE, NULL);
-        priv = PRIVATE (this);
+       if (event->mode != GDK_CROSSING_NORMAL)
+               return TRUE;
 
-        priv->location = g_object_ref (loc);
+       tile = CLOCK_LOCATION_TILE (user_data);
 
-        clock_location_tile_fill (this);
+       if (clock_location_is_current (tile->priv->location)) {
+               gtk_widget_hide (tile->priv->button);
+               gtk_widget_show (tile->priv->marker);
+               gtk_widget_hide (tile->priv->spacer);
 
-       update_weather_icon (loc, clock_location_get_weather_info (loc), this);
-       gtk_widget_set_has_tooltip (priv->weather_icon, TRUE);
+               return TRUE;
+       }
 
-       g_signal_connect (priv->weather_icon, "query-tooltip",
-                         G_CALLBACK (weather_tooltip), this);
-       priv->location_weather_updated_id = g_signal_connect (G_OBJECT (loc), "weather-updated",
-                                                             G_CALLBACK (update_weather_icon), this);
+       if (event->type == GDK_ENTER_NOTIFY) {
+               gint can_set;
 
-        return this;
-}
+               if (clock_location_is_current_timezone (tile->priv->location)) {
+                       can_set = 2;
+               } else {
+                       can_set = can_set_system_timezone ();
+               }
 
-static void
-clock_location_tile_class_init (ClockLocationTileClass *this_class)
-{
-        GObjectClass *g_obj_class = G_OBJECT_CLASS (this_class);
-
-        g_obj_class->finalize = clock_location_tile_finalize;
-
-        g_type_class_add_private (this_class, sizeof (ClockLocationTilePrivate));
-
-       signals[TILE_PRESSED] = g_signal_new ("tile-pressed",
-                                             G_TYPE_FROM_CLASS (g_obj_class),
-                                             G_SIGNAL_RUN_FIRST,
-                                             G_STRUCT_OFFSET (ClockLocationTileClass, tile_pressed),
-                                             NULL,
-                                             NULL,
-                                             g_cclosure_marshal_VOID__VOID,
-                                             G_TYPE_NONE, 0);
-       signals[NEED_CLOCK_FORMAT] = g_signal_new ("need-clock-format",
-                                                  G_TYPE_FROM_CLASS (g_obj_class),
-                                                  G_SIGNAL_RUN_LAST,
-                                                  G_STRUCT_OFFSET (ClockLocationTileClass, 
need_clock_format),
-                                                  NULL,
-                                                  NULL,
-                                                  _clock_marshal_INT__VOID,
-                                                  G_TYPE_INT, 0);
+               if (can_set != 0) {
+                       const gchar *markup;
+
+                       if (can_set == 1) {
+                               markup = _("<small>Set...</small>");
+                       } else {
+                               markup = _("<small>Set</small>");
+                       }
+
+                       gtk_label_set_markup (GTK_LABEL (tile->priv->button_label),
+                                             markup);
+
+                       gtk_widget_show (tile->priv->button);
+                       gtk_widget_hide (tile->priv->marker);
+                       gtk_widget_hide (tile->priv->spacer);
+               } else {
+                       gtk_widget_hide (tile->priv->button);
+                       gtk_widget_hide (tile->priv->marker);
+                       gtk_widget_show (tile->priv->spacer);
+               }
+       } else {
+               if (event->detail != GDK_NOTIFY_INFERIOR) {
+                       gtk_widget_hide (tile->priv->button);
+                       gtk_widget_hide (tile->priv->marker);
+                       gtk_widget_show (tile->priv->spacer);
+               }
+       }
+
+       return TRUE;
 }
 
-static void
-clock_location_tile_init (ClockLocationTile *this)
+/*
+ * Should match enum values in gdesktop-enums.h:
+ * https://git.gnome.org/browse/gsettings-desktop-schemas/tree/headers/gdesktop-enums.h
+ */
+static GType
+g_desktop_clock_format_get_type (void)
 {
-        ClockLocationTilePrivate *priv = PRIVATE (this);
-
-        priv->location = NULL;
+       static GType etype = 0;
 
-       priv->last_refresh = NULL;
-       priv->last_offset = 0;
+       if (etype == 0) {
+               static const GEnumValue values[] = {
+                       { G_DESKTOP_CLOCK_FORMAT_24H, "G_DESKTOP_CLOCK_FORMAT_24H", "24h" },
+                       { G_DESKTOP_CLOCK_FORMAT_12H, "G_DESKTOP_CLOCK_FORMAT_12H", "12h" },
+                       { 0, NULL, NULL }
+               };
 
+               etype = g_enum_register_static ("GDesktopClockFormat", values);
+       }
 
-        priv->clock_face = NULL;
-        priv->city_label = NULL;
-        priv->time_label = NULL;
+       return etype;
 }
 
-static void
-clock_location_tile_finalize (GObject *g_obj)
+static gboolean
+show_weather_tooltip (GtkWidget  *widget,
+                      gint        x,
+                      gint        y,
+                      gboolean    keyboard_mode,
+                      GtkTooltip *tooltip,
+                      gpointer    user_data)
 {
-        ClockLocationTilePrivate *priv = PRIVATE (g_obj);
+       ClockLocationTile *tile;
+       GWeatherInfo      *info;
 
-       if (priv->last_refresh) {
-               g_date_time_unref (priv->last_refresh);
-               priv->last_refresh = NULL;
-       }
+       tile = CLOCK_LOCATION_TILE (user_data);
+       info = clock_location_get_weather_info (tile->priv->location);
 
-        if (priv->location) {
-               g_signal_handler_disconnect (priv->location, priv->location_weather_updated_id);
-               priv->location_weather_updated_id = 0;
+       if (!info || !gweather_info_is_valid (info))
+               return FALSE;
 
-                g_object_unref (priv->location);
-                priv->location = NULL;
-        }
+       weather_info_setup_tooltip (info,
+                                   tile->priv->location,
+                                   tooltip,
+                                   tile->priv->clock_format);
 
-        G_OBJECT_CLASS (clock_location_tile_parent_class)->finalize (g_obj);
-}
-
-static gboolean
-press_on_tile      (GtkWidget             *widget,
-                    GdkEventButton        *event,
-                    ClockLocationTile *tile)
-{
-       g_signal_emit (tile, signals[TILE_PRESSED], 0);
-
-        return TRUE;
+       return TRUE;
 }
 
 static void
-make_current_cb (gpointer data, GError *error)
+update_weather_icon (ClockLocation *location,
+                     GWeatherInfo  *info,
+                     gpointer       user_data)
 {
-       GtkWidget *dialog;
+       GtkWidget   *icon;
+       const gchar *icon_name;
 
-        if (error) {
-                dialog = gtk_message_dialog_new (NULL,
-                                                 0,
-                                                 GTK_MESSAGE_ERROR,
-                                                 GTK_BUTTONS_CLOSE,
-                                                 _("Failed to set the system timezone"));
-                gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error->message);
-                g_signal_connect (dialog, "response",
-                                  G_CALLBACK (gtk_widget_destroy), NULL);
-                gtk_window_present (GTK_WINDOW (dialog));
-
-                g_error_free (error);
-        }
-}
+       icon = GTK_WIDGET (user_data);
 
-static void
-make_current (GtkWidget *widget, ClockLocationTile *tile)
-{
-        ClockLocationTilePrivate *priv = PRIVATE (tile);
+       if (!info || !gweather_info_is_valid (info)) {
+               gtk_widget_hide (icon);
+               return;
+       }
 
-       clock_location_make_current (priv->location,
-                                    (GFunc)make_current_cb, tile, NULL);
+       icon_name = gweather_info_get_icon_name (info);
+       gtk_image_set_from_icon_name (GTK_IMAGE (icon),
+                                     icon_name,
+                                     GTK_ICON_SIZE_INVALID);
+       gtk_image_set_pixel_size (GTK_IMAGE (icon), 16);
+       gtk_widget_show (icon);
 }
 
-static gboolean
-enter_or_leave_tile (GtkWidget             *widget,
-                     GdkEventCrossing      *event,
-                     ClockLocationTile *tile)
+static GtkWidget *
+clock_location_tile_get_weather_icon (ClockLocationTile *tile)
 {
-       ClockLocationTilePrivate *priv = PRIVATE (tile);
+       ClockLocation *location;
+       GtkWidget     *icon;
 
-       if (event->mode != GDK_CROSSING_NORMAL) {
-               return TRUE;
-       }
+       location = tile->priv->location;
+       icon = gtk_image_new ();
 
-       if (clock_location_is_current (priv->location)) {
-               gtk_widget_hide (priv->current_button);
-               gtk_widget_hide (priv->current_spacer);
-               gtk_widget_show (priv->current_marker);
+       gtk_widget_set_no_show_all (icon, TRUE);
+       gtk_widget_set_has_tooltip (icon, TRUE);
+       gtk_widget_set_valign (icon, GTK_ALIGN_START);
 
-               return TRUE;
-       }
+       g_signal_connect (icon, "query-tooltip",
+                         G_CALLBACK (show_weather_tooltip), tile);
 
-       if (event->type == GDK_ENTER_NOTIFY) {
-               gint can_set;
+       tile->priv->weather_updated_id =
+               g_signal_connect (location, "weather-updated",
+                                 G_CALLBACK (update_weather_icon), icon);
 
-               if (clock_location_is_current_timezone (priv->location))
-                       can_set = 2;
-               else
-                       can_set = can_set_system_timezone ();
-               if (can_set != 0) {
-                       gtk_label_set_markup (GTK_LABEL (priv->current_label),
-                                               can_set == 1 ?
-                                                       _("<small>Set...</small>") :
-                                                       _("<small>Set</small>"));
-                       gtk_widget_hide (priv->current_spacer);
-                       gtk_widget_hide (priv->current_marker);
-                       gtk_widget_show (priv->current_button);
-               }
-               else {
-                       gtk_widget_hide (priv->current_marker);
-                       gtk_widget_hide (priv->current_button);
-                       gtk_widget_show (priv->current_spacer);
-               }
-       }
-       else {
-               if (event->detail != GDK_NOTIFY_INFERIOR) {
-                       gtk_widget_hide (priv->current_button);
-                       gtk_widget_hide (priv->current_marker);
-                       gtk_widget_show (priv->current_spacer);
-               }
-       }
+       update_weather_icon (location,
+                            clock_location_get_weather_info (location),
+                            icon);
 
-       return TRUE;
+       return icon;
 }
 
-static void
-clock_location_tile_fill (ClockLocationTile *this)
+static GtkWidget *
+clock_location_tile_get_title (ClockLocation *location)
 {
-        ClockLocationTilePrivate *priv = PRIVATE (this);
-        GtkWidget *strut;
-        GtkWidget *box;
-        GtkWidget *tile;
-        GtkWidget *head_section;
-        GtkSizeGroup *current_group;
-        GtkSizeGroup *button_group;
-
-        priv->box = gtk_event_box_new ();
-
-        gtk_widget_add_events (priv->box, GDK_BUTTON_PRESS_MASK | GDK_ENTER_NOTIFY_MASK | 
GDK_LEAVE_NOTIFY_MASK);
-        g_signal_connect (priv->box, "button-press-event",
-                          G_CALLBACK (press_on_tile), this);
-        g_signal_connect (priv->box, "enter-notify-event",
-                          G_CALLBACK (enter_or_leave_tile), this);
-        g_signal_connect (priv->box, "leave-notify-event",
-                          G_CALLBACK (enter_or_leave_tile), this);
-
-        tile = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
-        gtk_widget_set_margin_top (tile, 3);
-        gtk_widget_set_margin_bottom (tile, 3);
-        gtk_widget_set_margin_start (tile, 3);
-
-        head_section = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-
-        priv->city_label = gtk_label_new (NULL);
-        gtk_widget_set_margin_end (priv->city_label, 3);
-        gtk_label_set_xalign (GTK_LABEL (priv->city_label), 0);
-
-        gtk_box_pack_start (GTK_BOX (head_section), priv->city_label, FALSE, FALSE, 0);
-
-        priv->time_label = gtk_label_new (NULL);
-        gtk_widget_set_margin_end (priv->time_label, 3);
-        gtk_label_set_yalign (GTK_LABEL (priv->time_label), 0);
-
-        priv->weather_icon = gtk_image_new ();
-        gtk_widget_set_valign (priv->weather_icon, GTK_ALIGN_START);
-
-        box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-        gtk_box_pack_start (GTK_BOX (head_section), box, FALSE, FALSE, 0);
-        gtk_box_pack_start (GTK_BOX (box), priv->weather_icon, FALSE, FALSE, 0);
-        gtk_box_pack_start (GTK_BOX (box), priv->time_label, FALSE, FALSE, 0);
-
-        priv->current_button = gtk_button_new ();
-       /* The correct label is set on EnterNotify events */
-       priv->current_label = gtk_label_new ("");
-        gtk_widget_show (priv->current_label);
-        gtk_widget_set_no_show_all (priv->current_button, TRUE);
-        gtk_container_add (GTK_CONTAINER (priv->current_button), priv->current_label);
-        gtk_widget_set_tooltip_text (priv->current_button,
-                                    _("Set location as current location and use its timezone for this 
computer"));
-
-       priv->current_marker = gtk_image_new_from_icon_name ("go-home", GTK_ICON_SIZE_BUTTON);
-       gtk_widget_set_no_show_all (priv->current_marker, TRUE);
-
-       priv->current_spacer = gtk_event_box_new ();
-       gtk_widget_set_no_show_all (priv->current_spacer, TRUE);
-
-        strut = gtk_event_box_new ();
-        gtk_box_pack_start (GTK_BOX (box), strut, TRUE, TRUE, 0);
-        gtk_box_pack_start (GTK_BOX (box), priv->current_button, FALSE, FALSE, 0);
-        gtk_box_pack_start (GTK_BOX (box), priv->current_marker, FALSE, FALSE, 0);
-        gtk_box_pack_start (GTK_BOX (box), priv->current_spacer, FALSE, FALSE, 0);
-
-        button_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
-        gtk_size_group_set_ignore_hidden (button_group, FALSE);
-        gtk_size_group_add_widget (button_group, strut);
-        gtk_size_group_add_widget (button_group, priv->current_button);
-        g_object_unref (button_group);
-
-       /* 
-        * Avoid resizing the popup as the tiles display the current marker, 
-        * set button or nothing. For that purpose, replace 'nothing' with 
-        * an event box, and force the button, marker and spacer to have the 
-        * same size via a size group. The visibility of the three is managed
-        * manually to ensure that only one of them is shown at any time. 
-        * (The all have to be shown initially to get the sizes worked out, 
-        * but they are never visible together). 
-        */
-        current_group = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
-        gtk_size_group_set_ignore_hidden (current_group, FALSE);
-        gtk_size_group_add_widget (current_group, priv->current_button);
-        gtk_size_group_add_widget (current_group, priv->current_marker);
-        gtk_size_group_add_widget (current_group, priv->current_spacer);
-        g_object_unref (current_group);
-       
-       gtk_widget_show (priv->current_button);
-       gtk_widget_show (priv->current_marker);
-       gtk_widget_show (priv->current_spacer);
-
-        g_signal_connect (priv->current_button, "clicked",
-                          G_CALLBACK (make_current), this);
-
-        ClockTime *time = clock_time_new (priv->location);
-        priv->clock_face = clock_face_new (priv->location, time, FALSE);
-        gtk_widget_set_size_request (priv->clock_face, 52, 52);
-               g_object_unref (time);
-
-        gtk_box_pack_start (GTK_BOX (tile), priv->clock_face, FALSE, FALSE, 0);
-        gtk_box_pack_start (GTK_BOX (tile), head_section, TRUE, TRUE, 0);
-
-        gtk_container_add (GTK_CONTAINER (priv->box), tile);
-        gtk_container_add (GTK_CONTAINER (this), priv->box);
-}
+       GtkWidget *label;
+       gchar     *markup;
 
-static gboolean
-clock_needs_label_refresh (ClockLocationTile *this)
-{
-        ClockLocationTilePrivate *priv = PRIVATE (this);
-       GDateTime *now;
-       long offset;
-       gboolean retval;
+       label = gtk_label_new (NULL);
+       markup = g_strdup_printf ("<big><b>%s</b></big>",
+                                 clock_location_get_name (location));
 
-       if (!priv->last_refresh)
-               return TRUE;
+       gtk_label_set_markup (GTK_LABEL (label), markup);
+       g_free (markup);
 
-        now = clock_location_localtime (priv->location);
-       offset = clock_location_get_offset (priv->location);
-
-       retval = FALSE;
-        if (g_date_time_get_year (now) > g_date_time_get_year (priv->last_refresh)
-            || g_date_time_get_month (now) > g_date_time_get_month (priv->last_refresh)
-            || g_date_time_get_day_of_month (now) > g_date_time_get_day_of_month (priv->last_refresh)
-            || g_date_time_get_hour (now) > g_date_time_get_hour (priv->last_refresh)
-            || g_date_time_get_minute (now) > g_date_time_get_minute (priv->last_refresh)
-           || offset != priv->last_offset) {
-               retval = TRUE;
-        }
-
-       g_date_time_unref (now);
-        return retval;
+       gtk_label_set_xalign (GTK_LABEL (label), 0);
+
+       return label;
 }
 
-static char *
-format_time (GDateTime   *now, 
-             const char  *tzname,
-             GDesktopClockFormat  clock_format,
-            long         offset)
+static gchar *
+format_time (ClockLocationTile *tile)
 {
-       const char *format;
-       GDateTime *local_now;
-       char *buf;      
-       char *tmp;      
-       long hours, minutes;
-
-       local_now = g_date_time_new_now_local ();
-
-       if (g_date_time_get_day_of_week (local_now) !=
-           g_date_time_get_day_of_week (now)) {
-               if (clock_format == G_DESKTOP_CLOCK_FORMAT_12H) {
+       GDateTime   *time;
+       GDateTime   *time_local;
+       const gchar *tzname;
+       glong        offset;
+       gint         day_of_week;
+       gint         day_of_week_local;
+       const gchar *format;
+       gchar       *buf;
+       glong        hours;
+       glong        minutes;
+       gchar       *tmp;
+
+       time = clock_location_localtime (tile->priv->location);
+       time_local = g_date_time_new_now_local ();
+       tzname = clock_location_get_tzname (tile->priv->location);
+       offset = -clock_location_get_offset (tile->priv->location);
+
+       day_of_week = g_date_time_get_day_of_week (time);
+       day_of_week_local = g_date_time_get_day_of_week (time_local);
+
+       if (day_of_week != day_of_week_local) {
+               if (tile->priv->clock_format == G_DESKTOP_CLOCK_FORMAT_12H) {
                        /* 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), when the local
@@ -410,9 +330,8 @@ format_time (GDateTime   *now,
                         * (the %A expands to the weekday). */
                        format = _("%H:%M <small>(%A)</small>");
                }
-       }
-       else {
-               if (clock_format == G_DESKTOP_CLOCK_FORMAT_12H) {
+       } else {
+               if (tile->priv->clock_format == G_DESKTOP_CLOCK_FORMAT_12H) {
                        /* 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
@@ -427,135 +346,401 @@ format_time (GDateTime   *now,
                }
        }
 
-        g_date_time_unref (local_now);
+       g_date_time_unref (time_local);
+
+       buf = g_date_time_format (time, format);
+       g_date_time_unref (time);
 
-        buf = g_date_time_format (now, format);
-        hours = offset / 3600;
-        minutes = labs (offset % 3600) / 60;
+       hours = offset / 3600;
+       minutes = labs (offset % 3600) / 60;
 
        if (hours != 0 && minutes != 0) {
                tmp = g_strdup_printf ("%s <small>%s %+ld:%ld</small>", buf, tzname, hours, minutes);
-       }
-       else if (hours != 0) {
+       } else if (hours != 0) {
                tmp = g_strdup_printf ("%s <small>%s %+ld</small>", buf, tzname, hours);
-       }
-       else {
+       } else {
                tmp = g_strdup_printf ("%s <small>%s</small>", buf, tzname);
        }
 
        g_free (buf);
+
        return tmp;
 }
 
-void
-clock_location_tile_refresh (ClockLocationTile *this, gboolean force_refresh)
+static GtkWidget *
+clock_location_tile_get_time (ClockLocationTile *tile)
 {
-        ClockLocationTilePrivate *priv = PRIVATE (this);
-        gchar *tmp;
-       const char *tzname;
-       GDateTime *now;
-       long offset;
-       int format;
-
-       g_return_if_fail (IS_CLOCK_LOCATION_TILE (this));
-
-        if (clock_location_is_current (priv->location)) {
-               gtk_widget_hide (priv->current_spacer);
-               gtk_widget_hide (priv->current_button);
-               gtk_widget_show (priv->current_marker);
-       }
-       else {
-               if (gtk_widget_get_visible (priv->current_marker)) {
-                       gtk_widget_hide (priv->current_marker);
-                       gtk_widget_hide (priv->current_button);
-                       gtk_widget_show (priv->current_spacer);
-               }
-       }
+       GtkWidget *label;
+       gchar     *markup;
 
-        if (!force_refresh && !clock_needs_label_refresh (this)) {
-                return;
-        }
+       label = gtk_label_new (NULL);
+       markup = format_time (tile);
 
-        now = clock_location_localtime (priv->location);
-        tzname = clock_location_get_tzname (priv->location);
+       gtk_label_set_markup (GTK_LABEL (label), markup);
+       g_free (markup);
 
-       if (priv->last_refresh)
-               g_date_time_unref (priv->last_refresh);
-       priv->last_refresh = g_date_time_ref (now);
-       priv->last_offset = clock_location_get_offset (priv->location);
+       gtk_label_set_xalign (GTK_LABEL (label), 0);
+       gtk_label_set_yalign (GTK_LABEL (label), 0);
+
+       return label;
+}
+
+static void
+update_clock_face_size (GtkWidget     *widget,
+                        GtkAllocation *allocation,
+                        gpointer       user_data)
+{
+       GtkWidget *face;
+       guint      size;
+
+       face = GTK_WIDGET (user_data);
+       size = allocation->height;
+
+       gtk_widget_set_size_request (face, size, size);
+}
+
+static GtkWidget *
+clock_location_tile_get_button (ClockLocationTile *tile)
+{
+       const gchar *tooltip;
+       GtkWidget   *button;
+       GtkWidget   *label;
 
-        tmp = g_strdup_printf ("<big><b>%s</b></big>",
-                               clock_location_get_name (priv->location));
-        gtk_label_set_markup (GTK_LABEL (priv->city_label), tmp);
-        g_free (tmp);
+       button = gtk_button_new ();
+       gtk_widget_set_no_show_all (button, TRUE);
+       gtk_widget_hide (button);
 
-       g_signal_emit (this, signals[NEED_CLOCK_FORMAT], 0, &format);
+       tooltip = _("Set location as current location and use its timezone for this computer");
+       gtk_widget_set_tooltip_text (button, tooltip);
 
-       offset = - priv->last_offset;
+       label = gtk_label_new (NULL);
+       gtk_container_add (GTK_CONTAINER (button), label);
+       gtk_widget_show (label);
 
-       tmp = format_time (now, tzname, format, offset);
+       g_signal_connect (button, "clicked",
+                         G_CALLBACK (make_current), tile);
 
-        gtk_label_set_markup (GTK_LABEL (priv->time_label), tmp);
+       tile->priv->button = button;
+       tile->priv->button_label = label;
 
-        g_free (tmp);
+       return button;
 }
 
-static gboolean
-weather_tooltip (GtkWidget  *widget,
-                gint        x,
-                gint        y,
-                gboolean    keyboard_mode,
-                GtkTooltip *tooltip,
-                gpointer    data)
+static GtkWidget *
+clock_location_tile_get_marker (ClockLocationTile *tile)
 {
-        ClockLocationTile *tile = data;
-        ClockLocationTilePrivate *priv = PRIVATE (tile);
-       GWeatherInfo *info;
-       int clock_format;
+       GtkWidget *marker;
 
-       info = clock_location_get_weather_info (priv->location);
+       marker = gtk_image_new_from_icon_name ("go-home",
+                                              GTK_ICON_SIZE_BUTTON);
+       gtk_widget_set_no_show_all (marker, TRUE);
+       if (clock_location_is_current (tile->priv->location))
+               gtk_widget_show (marker);
 
-       if (!info || !gweather_info_is_valid (info))
-               return FALSE;
+       tile->priv->marker = marker;
 
-       g_signal_emit (tile, signals[NEED_CLOCK_FORMAT], 0, &clock_format);
+       return marker;
+}
+
+static void
+clock_location_tile_fill (ClockLocationTile *tile)
+{
+       GtkWidget    *box1;
+       GtkWidget    *face;
+       GtkWidget    *info;
+       GtkWidget    *city;
+       GtkWidget    *box2;
+       GtkWidget    *icon;
+       GtkWidget    *time;
+       GtkWidget    *button;
+       GtkWidget    *marker;
+       GtkWidget    *strut;
+       GtkSizeGroup *button_group;
+       GtkSizeGroup *group;
+
+       gtk_container_set_border_width (GTK_CONTAINER (tile), 3);
+
+       box1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+       gtk_container_add (GTK_CONTAINER (tile), box1);
+
+       face = clock_face_new (tile->priv->location,
+                              tile->priv->time,
+                              FALSE);
+       gtk_box_pack_start (GTK_BOX (box1), face, FALSE, FALSE, 0);
+       gtk_widget_show (face);
+
+       g_signal_connect (box1, "size-allocate",
+                         G_CALLBACK (update_clock_face_size), face);
+
+       info = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
+       gtk_box_pack_start (GTK_BOX (box1), info, TRUE, TRUE, 0);
+       gtk_widget_show (info);
+
+       city = clock_location_tile_get_title (tile->priv->location);
+       gtk_box_pack_start (GTK_BOX (info), city, FALSE, FALSE, 0);
+       gtk_widget_show (city);
+
+       box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+       gtk_box_pack_start (GTK_BOX (info), box2, FALSE, FALSE, 0);
+       gtk_widget_show (box2);
+
+       icon = clock_location_tile_get_weather_icon (tile);
+       gtk_box_pack_start (GTK_BOX (box2), icon, FALSE, FALSE, 0);
+
+       time = clock_location_tile_get_time (tile);
+       gtk_box_pack_start (GTK_BOX (box2), time, FALSE, FALSE, 0);
+       gtk_widget_show (time);
+       tile->priv->time_label = time;
+
+       button = clock_location_tile_get_button (tile);
+       gtk_box_pack_end (GTK_BOX (box2), button, FALSE, FALSE, 0);
+       tile->priv->button = button;
+
+       marker = clock_location_tile_get_marker (tile);
+       gtk_box_pack_end (GTK_BOX (box2), marker, FALSE, FALSE, 0);
+       tile->priv->marker = marker;
+
+       tile->priv->spacer = gtk_event_box_new ();
+       gtk_widget_set_no_show_all (tile->priv->spacer, TRUE);
+       gtk_box_pack_start (GTK_BOX (box2), tile->priv->spacer, FALSE, FALSE, 0);
+
+       strut = gtk_event_box_new ();
+       gtk_box_pack_start (GTK_BOX (box2), strut, TRUE, TRUE, 0);
+
+       button_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
+       gtk_size_group_set_ignore_hidden (button_group, FALSE);
+       gtk_size_group_add_widget (button_group, strut);
+       gtk_size_group_add_widget (button_group, tile->priv->button);
+       g_object_unref (button_group);
+
+       group = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
+       gtk_size_group_set_ignore_hidden (group, FALSE);
+       gtk_size_group_add_widget (group, tile->priv->button);
+       gtk_size_group_add_widget (group, tile->priv->marker);
+       gtk_size_group_add_widget (group, tile->priv->spacer);
+       g_object_unref (group);
+}
+
+static gboolean
+clock_location_tile_button_press (GtkWidget      *widget,
+                                  GdkEventButton *event,
+                                  gpointer        user_data)
+{
+       ClockLocationTile *tile;
 
-       weather_info_setup_tooltip (info, priv->location, tooltip, clock_format);
+       tile = CLOCK_LOCATION_TILE (user_data);
+
+       g_signal_emit (tile, object_signals[TILE_PRESSED], 0,
+                      tile->priv->location);
 
        return TRUE;
 }
 
 static void
-update_weather_icon (ClockLocation *loc, GWeatherInfo *info, gpointer data)
+update_time_label (ClockLocationTile *tile)
 {
-        ClockLocationTile *tile = data;
-        ClockLocationTilePrivate *priv = PRIVATE (tile);
-        GdkPixbuf *pixbuf = NULL;
-        GtkIconTheme *theme = NULL;
-        const gchar *icon_name;
-
-        if (!info || !gweather_info_is_valid (info))
-                return;
-
-        icon_name = gweather_info_get_icon_name (info);
-        theme = gtk_icon_theme_get_default ();
-        pixbuf = gtk_icon_theme_load_icon (theme, icon_name, 16,
-                                           GTK_ICON_LOOKUP_GENERIC_FALLBACK, NULL);
-
-        if (pixbuf) {
-                gtk_image_set_from_pixbuf (GTK_IMAGE (priv->weather_icon), pixbuf);
-                gtk_widget_set_margin_end (priv->weather_icon, 6);
-        }
+       gchar *markup;
+
+       markup = format_time (tile);
+
+       gtk_label_set_markup (GTK_LABEL (tile->priv->time_label),
+                             markup);
+
+       g_free (markup);
 }
 
-ClockLocation *
-clock_location_tile_get_location (ClockLocationTile *this)
+static void
+clock_location_tile_minute_changed (ClockTime *time,
+                                    gint       hour,
+                                    gint       minute,
+                                    gpointer   user_data)
 {
-        ClockLocationTilePrivate *priv;
+       ClockLocationTile *tile;
 
-       g_return_val_if_fail (IS_CLOCK_LOCATION_TILE (this), NULL);
+       tile = CLOCK_LOCATION_TILE (user_data);
+
+       update_time_label (tile);
+}
+
+static void
+clock_location_tile_set_location (ClockLocationTile *tile,
+                                  ClockLocation     *location)
+{
+       if (tile->priv->location)
+               g_object_unref (tile->priv->location);
+
+       if (tile->priv->time)
+               g_object_unref (tile->priv->time);
+
+       tile->priv->location = g_object_ref (location);
+       tile->priv->time = clock_time_new (location);
+
+       g_signal_connect (tile->priv->time, "minute-changed",
+                         G_CALLBACK (clock_location_tile_minute_changed), tile);
+}
+
+static GObject *
+clock_location_tile_constructor (GType                  gtype,
+                                 guint                  n_properties,
+                                 GObjectConstructParam *properties)
+{
+       GObject           *object;
+       ClockLocationTile *tile;
+
+       object = G_OBJECT_CLASS (clock_location_tile_parent_class)->constructor (gtype,
+                                                                                n_properties,
+                                                                                properties);
+       tile = CLOCK_LOCATION_TILE (object);
+
+       gtk_widget_add_events (GTK_WIDGET (tile),
+                              GDK_BUTTON_PRESS_MASK |
+                              GDK_ENTER_NOTIFY_MASK |
+                              GDK_LEAVE_NOTIFY_MASK);
+
+       g_signal_connect (tile, "button-press-event",
+                         G_CALLBACK (clock_location_tile_button_press), tile);
+       g_signal_connect (tile, "enter-notify-event",
+                         G_CALLBACK (clock_location_tile_enter_or_leave), tile);
+       g_signal_connect (tile, "leave-notify-event",
+                         G_CALLBACK (clock_location_tile_enter_or_leave), tile);
+
+       clock_location_tile_fill (tile);
+
+       return object;
+}
+
+static void
+clock_location_tile_finalize (GObject *object)
+{
+       ClockLocationTile *tile;
+
+       tile = CLOCK_LOCATION_TILE (object);
+
+       if (tile->priv->weather_updated_id > 0) {
+               g_signal_handler_disconnect (tile->priv->location,
+                                            tile->priv->weather_updated_id);
+               tile->priv->weather_updated_id = 0;
+       }
+
+       g_clear_object (&tile->priv->time);
+       g_clear_object (&tile->priv->location);
+
+       G_OBJECT_CLASS (clock_location_tile_parent_class)->finalize (object);
+}
+
+static void
+clock_location_tile_set_property (GObject      *object,
+                                  guint         property_id,
+                                  const GValue *value,
+                                  GParamSpec   *pspec)
+{
+       ClockLocationTile *tile;
+
+       tile = CLOCK_LOCATION_TILE (object);
+
+       switch (property_id)
+       {
+               case PROP_LOCATION:
+                       clock_location_tile_set_location (tile,
+                                                         g_value_get_object (value));
+                       break;
+               case PROP_CLOCK_FORMAT:
+                       tile->priv->clock_format = g_value_get_enum (value);
+                       update_time_label (tile);
+                       break;
+               default:
+                       G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
+                                                          property_id,
+                                                          pspec);
+                       break;
+       }
+}
+
+static void
+clock_location_tile_get_property (GObject    *object,
+                                  guint       property_id,
+                                  GValue     *value,
+                                  GParamSpec *pspec)
+{
+       ClockLocationTile *tile;
+
+       tile = CLOCK_LOCATION_TILE (object);
+
+       switch (property_id)
+       {
+               case PROP_LOCATION:
+                       g_value_set_object (value, tile->priv->location);
+                       break;
+               case PROP_CLOCK_FORMAT:
+                       g_value_set_enum (value, tile->priv->clock_format);
+                       break;
+               default:
+                       G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
+                                                          property_id,
+                                                          pspec);
+                       break;
+       }
+}
+
+static void
+clock_location_tile_class_init (ClockLocationTileClass *class)
+{
+       GObjectClass *object_class;
+
+       object_class = G_OBJECT_CLASS (class);
+
+       object_class->constructor = clock_location_tile_constructor;
+       object_class->finalize = clock_location_tile_finalize;
+       object_class->set_property = clock_location_tile_set_property;
+       object_class->get_property = clock_location_tile_get_property;
+
+       object_signals[TILE_PRESSED] =
+               g_signal_new ("tile-pressed",
+                             G_OBJECT_CLASS_TYPE (object_class),
+                             G_SIGNAL_RUN_FIRST,
+                             G_STRUCT_OFFSET (ClockLocationTileClass, tile_pressed),
+                             NULL,
+                             NULL,
+                             NULL,
+                             G_TYPE_NONE,
+                             1,
+                             CLOCK_TYPE_LOCATION);
+
+       object_properties[PROP_LOCATION] =
+               g_param_spec_object ("location",
+                                    "location",
+                                    "location",
+                                    CLOCK_TYPE_LOCATION,
+                                    G_PARAM_CONSTRUCT_ONLY |
+                                    G_PARAM_READWRITE);
+
+       object_properties[PROP_CLOCK_FORMAT] =
+               g_param_spec_enum ("clock-format",
+                                  "clock-format",
+                                  "clock-format",
+                                  g_desktop_clock_format_get_type (),
+                                  G_DESKTOP_CLOCK_FORMAT_24H,
+                                  G_PARAM_READWRITE);
+
+       g_object_class_install_properties (object_class,
+                                          N_PROPERTIES,
+                                          object_properties);
+}
+
+static void
+clock_location_tile_init (ClockLocationTile *tile)
+{
+       tile->priv = clock_location_tile_get_instance_private (tile);
+}
+
+GtkWidget *
+clock_location_tile_new (ClockLocation *location)
+{
+       GObject *object;
 
-       priv = PRIVATE (this);
+       object = g_object_new (CLOCK_TYPE_LOCATION_TILE,
+                              "location", location,
+                              NULL);
 
-       return g_object_ref (priv->location);
+       return GTK_WIDGET (object);
 }
diff --git a/applets/clock/clock-location-tile.h b/applets/clock/clock-location-tile.h
index d165bb9..95896eb 100644
--- a/applets/clock/clock-location-tile.h
+++ b/applets/clock/clock-location-tile.h
@@ -1,42 +1,73 @@
-#ifndef __CLOCK_LOCATION_TILE_H__
-#define __CLOCK_LOCATION_TILE_H__
+/*
+ * Copyright (C) 2014 Alberts Muktupāvels
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *    Alberts Muktupāvels <alberts muktupavels gmail com>
+ *    Federico Mena Quintero <federico novell com>
+ *    Giovanni Campagna <gcampagna src gnome org>
+ *    Matthias Clasen <mclasen redhat com>
+ *    Vincent Untz <vuntz gnome org>
+ */
+
+#ifndef CLOCK_LOCATION_TILE_H
+#define CLOCK_LOCATION_TILE_H
 
 #include <gtk/gtk.h>
 
-#include "clock.h"
-#include "clock-face.h"
 #include "clock-location.h"
 
 G_BEGIN_DECLS
 
-#define CLOCK_LOCATION_TILE_TYPE         (clock_location_tile_get_type ())
-#define CLOCK_LOCATION_TILE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), CLOCK_LOCATION_TILE_TYPE, 
ClockLocationTile))
-#define CLOCK_LOCATION_TILE_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c), CLOCK_LOCATION_TILE_TYPE, 
ClockLocationTileClass))
-#define IS_CLOCK_LOCATION_TILE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), CLOCK_LOCATION_TILE_TYPE))
-#define IS_CLOCK_LOCATION_TILE_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c), CLOCK_LOCATION_TILE_TYPE))
-#define CLOCK_LOCATION_TILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CLOCK_LOCATION_TILE_TYPE, 
ClockLocationTileClass))
+#define CLOCK_TYPE_LOCATION_TILE         (clock_location_tile_get_type ())
+#define CLOCK_LOCATION_TILE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), \
+                                          CLOCK_TYPE_LOCATION_TILE,        \
+                                          ClockLocationTile))
+#define CLOCK_LOCATION_TILE_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c),    \
+                                          CLOCK_TYPE_LOCATION_TILE,        \
+                                          ClockLocationTileClass))
+#define CLOCK_IS_LOCATION_TILE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), \
+                                          CLOCK_TYPE_LOCATION_TILE))
+#define CLOCK_IS_LOCATION_TILE_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c),    \
+                                          CLOCK_TYPE_LOCATION_TILE))
+#define CLOCK_LOCATION_TILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o),  \
+                                          CLOCK_TYPE_LOCATION_TILE,        \
+                                          ClockLocationTileClass))
 
-typedef struct
-{
-        GtkBin parent;
-} ClockLocationTile;
+typedef struct _ClockLocationTile        ClockLocationTile;
+typedef struct _ClockLocationTileClass   ClockLocationTileClass;
+typedef struct _ClockLocationTilePrivate ClockLocationTilePrivate;
 
-typedef struct
+struct _ClockLocationTile
 {
-        GtkBinClass parent_class;
-
-       void (* tile_pressed) (ClockLocationTile *tile);
-        int  (* need_clock_format) (ClockLocationTile *tile);
-} ClockLocationTileClass;
+       GtkEventBox               parent;
+       ClockLocationTilePrivate *priv;
+};
 
-GType clock_location_tile_get_type (void);
+struct _ClockLocationTileClass
+{
+       GtkEventBoxClass parent_class;
 
-ClockLocationTile *clock_location_tile_new (ClockLocation *loc);
+       void (* tile_pressed) (ClockLocationTile *tile,
+                              ClockLocation     *location);
+};
 
-ClockLocation *clock_location_tile_get_location (ClockLocationTile *this);
+GType      clock_location_tile_get_type (void);
 
-void clock_location_tile_refresh (ClockLocationTile *this,
-                                  gboolean           force_refresh);
+GtkWidget *clock_location_tile_new      (ClockLocation *location);
 
 G_END_DECLS
-#endif /* __CLOCK_H__ */
+
+#endif
diff --git a/applets/clock/clock.c b/applets/clock/clock.c
index 747280c..e86d117 100644
--- a/applets/clock/clock.c
+++ b/applets/clock/clock.c
@@ -247,18 +247,6 @@ set_atk_name_description (GtkWidget  *widget,
                atk_object_set_name (obj, name);
 }
 
-static void
-update_location_tiles (ClockData *cd)
-{
-        GList *l;
-
-        for (l = cd->location_tiles; l; l = l->next) {
-                ClockLocationTile *tile;
-
-                tile = CLOCK_LOCATION_TILE (l->data);
-                clock_location_tile_refresh (tile, FALSE);
-        }
-}
 
 static void
 update_clock (GnomeWallClock *wall_clock, GParamSpec *pspec, ClockData * cd)
@@ -272,7 +260,6 @@ update_clock (GnomeWallClock *wall_clock, GParamSpec *pspec, ClockData * cd)
        gtk_widget_queue_resize (cd->panel_button);
 
        update_tooltip (cd);
-        update_location_tiles (cd);
 
         if (cd->map_widget && cd->calendar_popup && gtk_widget_get_visible (cd->calendar_popup))
                 clock_map_update_time (CLOCK_MAP (cd->map_widget));
@@ -635,24 +622,13 @@ sort_locations_by_time (gconstpointer a, gconstpointer b)
 }
 
 static void
-location_tile_pressed_cb (ClockLocationTile *tile, gpointer data)
+location_tile_pressed_cb (ClockLocationTile *tile,
+                          ClockLocation     *loc,
+                          gpointer           data)
 {
         ClockData *cd = data;
-        ClockLocation *loc;
-
-        loc = clock_location_tile_get_location (tile);
 
         clock_map_blink_location (CLOCK_MAP (cd->map_widget), loc);
-
-        g_object_unref (loc);
-}
-
-static int
-location_tile_need_clock_format_cb(ClockLocationTile *tile, gpointer data)
-{
-        ClockData *cd = data;
-
-        return g_settings_get_enum (cd->clock_settings, "clock-format");
 }
 
 static void
@@ -692,8 +668,10 @@ create_cities_section (ClockData *cd)
                 city = clock_location_tile_new (loc);
                 g_signal_connect (city, "tile-pressed",
                                   G_CALLBACK (location_tile_pressed_cb), cd);
-                g_signal_connect (city, "need-clock-format",
-                                  G_CALLBACK (location_tile_need_clock_format_cb), cd);
+
+                g_settings_bind (cd->clock_settings, "clock-format",
+                                 city, "clock-format",
+                                 G_SETTINGS_BIND_GET);
 
                 gtk_box_pack_start (GTK_BOX (cd->cities_section),
                                     GTK_WIDGET (city),
@@ -701,8 +679,6 @@ create_cities_section (ClockData *cd)
 
                 cd->location_tiles = g_list_prepend (cd->location_tiles, city);
 
-                clock_location_tile_refresh (city, TRUE);
-
                 node = g_list_next (node);
         }
 
@@ -1212,7 +1188,6 @@ location_set_current_cb (ClockLocation *loc,
 
        if (cd->map_widget)
                clock_map_refresh (CLOCK_MAP (cd->map_widget));
-        update_location_tiles (cd);
 }
 
 static void



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]