[gnome-clocks/zbrown/more-awkward-places-stuff] general: enable vala (experimental) null checker



commit 5a08869493feb4e4b60a5434d9af8cd0a0d25195
Author: Zander Brown <zbrown gnome org>
Date:   Sun May 10 09:45:29 2020 +0100

    general: enable vala (experimental) null checker
    
    Add more explicit casts and null checks to fix the build
    
    Hopefully fix https://gitlab.gnome.org/GNOME/gnome-clocks/-/issues/106
    Reinforce https://gitlab.gnome.org/GNOME/gnome-clocks/-/issues/91 fixes
    
    Nice bonuses:
     - Variant unpacking is less verbose and less fragile
     - Fix warning from the dbus service
     - Probably fix other bugs we didn't even know about

 src/alarm.vala           | 135 +++++++++++++++++++------------------
 src/application.vala     |  48 +++++++------
 src/clock.vala           |   2 +-
 src/geocoding.vala       |  60 +++++++++--------
 src/headerbar.vala       |   4 +-
 src/meson.build          |   3 +-
 src/search-provider.vala |  59 +++++++++-------
 src/stopwatch.vala       |  10 +--
 src/timer.vala           |  31 +++++----
 src/utils.vala           |  29 ++++----
 src/widgets.vala         |  19 +++---
 src/window.vala          |  28 ++++----
 src/world.vala           | 171 +++++++++++++++++++++++++++++------------------
 13 files changed, 335 insertions(+), 264 deletions(-)
---
diff --git a/src/alarm.vala b/src/alarm.vala
index 28836fc..231ca45 100644
--- a/src/alarm.vala
+++ b/src/alarm.vala
@@ -37,26 +37,24 @@ private class Item : Object, ContentItem {
         SNOOZING
     }
 
-    public string title_icon { get; set; default = null; }
-
     public bool editing { get; set; default = false; }
 
     public string id { get; construct set; }
 
-    public string name {
+    public string? name {
         get {
             return _name;
         }
 
         set {
-            _name = value;
+            _name = (string) value;
             setup_bell ();
         }
     }
 
     public AlarmTime time { get; set; }
 
-    public Utils.Weekdays days { get; set; }
+    public Utils.Weekdays? days { get; set; }
 
     public State state { get; private set; }
 
@@ -72,9 +70,9 @@ private class Item : Object, ContentItem {
          }
     }
 
-    public string days_label {
+    public string? days_label {
          owned get {
-            return days != null ? days.get_label () : null;
+            return days != null ? (string?) ((Utils.Weekdays) days).get_label () : null;
          }
     }
 
@@ -106,7 +104,7 @@ private class Item : Object, ContentItem {
     private GLib.Notification notification;
 
     public Item (string? id = null) {
-        var guid = id != null ? id : GLib.DBus.generate_guid ();
+        var guid = id != null ? (string) id : GLib.DBus.generate_guid ();
         Object (id: guid);
     }
 
@@ -135,7 +133,7 @@ private class Item : Object, ContentItem {
                                     time.minute,
                                     0);
 
-        if (days == null || days.empty) {
+        if (days == null || ((Utils.Weekdays) days).empty) {
             // Alarm without days.
             if (dt.compare (now) <= 0) {
                 // Time already passed, ring tomorrow.
@@ -144,7 +142,7 @@ private class Item : Object, ContentItem {
         } else {
             // Alarm with at least one day set.
             // Find the next possible day for ringing
-            while (dt.compare (now) <= 0 || ! days.get ((Utils.Weekdays.Day) (dt.get_day_of_week () - 1))) {
+            while (dt.compare (now) <= 0 || ! ((Utils.Weekdays) days).get ((Utils.Weekdays.Day) 
(dt.get_day_of_week () - 1))) {
                 dt = dt.add_days (1);
             }
         }
@@ -157,7 +155,7 @@ private class Item : Object, ContentItem {
     }
 
     public virtual signal void ring () {
-        var app = GLib.Application.get_default () as Clocks.Application;
+        var app = (Clocks.Application) GLib.Application.get_default ();
         app.send_notification ("alarm-clock-elapsed", notification);
         bell.ring ();
     }
@@ -226,39 +224,43 @@ private class Item : Object, ContentItem {
 
     public void serialize (GLib.VariantBuilder builder) {
         builder.open (new GLib.VariantType ("a{sv}"));
-        builder.add ("{sv}", "name", new GLib.Variant.string (name));
+        builder.add ("{sv}", "name", new GLib.Variant.string ((string) name));
         builder.add ("{sv}", "id", new GLib.Variant.string (id));
         builder.add ("{sv}", "active", new GLib.Variant.boolean (active));
         builder.add ("{sv}", "hour", new GLib.Variant.int32 (time.hour));
         builder.add ("{sv}", "minute", new GLib.Variant.int32 (time.minute));
-        builder.add ("{sv}", "days", days.serialize ());
+        builder.add ("{sv}", "days", ((Utils.Weekdays) days).serialize ());
         builder.close ();
     }
 
-    public static ContentItem? deserialize (GLib.Variant alarm_variant) {
+    public static ContentItem? deserialize (Variant alarm_variant) {
+        string key;
+        Variant val;
         string? name = null;
         string? id = null;
         bool active = true;
         int hour = -1;
         int minute = -1;
-        Utils.Weekdays days = null;
-        foreach (var v in alarm_variant) {
-            var key = v.get_child_value (0).get_string ();
+        Utils.Weekdays? days = null;
+
+        var iter = alarm_variant.iterator ();
+        while (iter.next ("{sv}", out key, out val)) {
             if (key == "name") {
-                name = v.get_child_value (1).get_child_value (0).get_string ();
+                name = (string) val;
             } else if (key == "id") {
-                id = v.get_child_value (1).get_child_value (0).get_string ();
+                id = (string) val;
             } else if (key == "active") {
-                active = v.get_child_value (1).get_child_value (0).get_boolean ();
+                active = (bool) val;
             } else if (key == "hour") {
-                hour = v.get_child_value (1).get_child_value (0).get_int32 ();
+                hour = (int32) val;
             } else if (key == "minute") {
-                minute = v.get_child_value (1).get_child_value (0).get_int32 ();
+                minute = (int32) val;
             } else if (key == "days") {
-                days = Utils.Weekdays.deserialize (v.get_child_value (1).get_child_value (0));
+                days = Utils.Weekdays.deserialize (val);
             }
         }
-        if (name != null && hour >= 0 && minute >= 0) {
+
+        if (hour >= 0 && minute >= 0) {
             Item alarm = new Item (id);
             alarm.name = name;
             alarm.active = active;
@@ -267,8 +269,9 @@ private class Item : Object, ContentItem {
             alarm.reset ();
             return alarm;
         } else {
-            warning ("Invalid alarm %s", name != null ? name : "name missing");
+            warning ("Invalid alarm %s", name != null ? (string) name : "[unnamed]");
         }
+
         return null;
     }
 }
@@ -308,8 +311,8 @@ private class Row : Gtk.ListBoxRow {
     }
 
     private void update_repeats () {
-        repeats_reveal.reveal_child = !alarm.days.empty;
-        repeats.label = alarm.days_label;
+        repeats_reveal.reveal_child = !((Utils.Weekdays) alarm.days).empty;
+        repeats.label = (string) alarm.days_label;
     }
 
     private void update () {
@@ -337,17 +340,17 @@ private class Row : Gtk.ListBoxRow {
         }
 
         if (alarm.state == Item.State.SNOOZING) {
-            if (label != null && label.length > 0) {
+            if (label != null && ((string) label).length > 0) {
                 // Translators: The alarm for the time %s titled %s has been "snoozed"
-                label = _("Snoozed from %s: %s").printf (alarm.time_label, label);
+                label = _("Snoozed from %s: %s").printf (alarm.time_label, (string) label);
             } else {
                 // Translators: %s is a time
                 label = _("Snoozed from %s").printf (alarm.time_label);
             }
         }
 
-        title_reveal.reveal_child = label != null && label.length > 0;
-        title.label = label;
+        title_reveal.reveal_child = label != null && ((string) label).length > 0;
+        title.label = (string) label;
     }
 
     [GtkCallback]
@@ -571,9 +574,9 @@ private class SetupDialog : Hdy.Dialog {
         other_alarms = new List<Item> ();
         var n = all_alarms.get_n_items ();
         for (int i = 0; i < n; i++) {
-            var item = all_alarms.get_object (i) as Item;
+            var item = (Item) all_alarms.get_object (i);
             if (alarm != item) {
-                other_alarms.prepend (all_alarms.get_object (i) as Item);
+                other_alarms.prepend ((Item) all_alarms.get_object (i));
             }
         }
 
@@ -603,7 +606,7 @@ private class SetupDialog : Hdy.Dialog {
 
     // Sets up the dialog to show the values of alarm.
     public void set_from_alarm (Item? alarm) {
-        string name;
+        string? name;
         bool active;
         int hour;
         int minute;
@@ -618,11 +621,11 @@ private class SetupDialog : Hdy.Dialog {
             days = null;
             active = true;
         } else {
-            name = alarm.name;
-            hour = alarm.time.hour;
-            minute = alarm.time.minute;
-            days = alarm.days;
-            active = alarm.active;
+            name = ((Item) alarm).name;
+            hour = ((Item) alarm).time.hour;
+            minute = ((Item) alarm).time.minute;
+            days = ((Item) alarm).days;
+            active = ((Item) alarm).active;
         }
 
         // Set the time.
@@ -642,10 +645,10 @@ private class SetupDialog : Hdy.Dialog {
         m_spinbutton.set_value (minute);
 
         // Set the name.
-        name_entry.set_text (name);
+        name_entry.set_text ((string) name);
 
         if (days != null) {
-            repeats.load (days);
+            repeats.load ((Utils.Weekdays) days);
         }
     }
 
@@ -718,20 +721,20 @@ private class SetupDialog : Hdy.Dialog {
 
 [GtkTemplate (ui = "/org/gnome/clocks/ui/alarmringing.ui")]
 private class RingingPanel : Gtk.Grid {
-    public Item alarm {
+    public Item? alarm {
         get {
             return _alarm;
         }
         set {
             if (_alarm != null) {
-                _alarm.disconnect (alarm_state_handler);
+                ((Item) _alarm).disconnect (alarm_state_handler);
             }
 
             _alarm = value;
 
             if (_alarm != null) {
-                alarm_state_handler = _alarm.notify["state"].connect (() => {
-                    if (alarm.state != Item.State.RINGING) {
+                alarm_state_handler = ((Item) _alarm).notify["state"].connect (() => {
+                    if (((Item) _alarm).state != Item.State.RINGING) {
                         dismiss ();
                     }
                 });
@@ -747,14 +750,14 @@ private class RingingPanel : Gtk.Grid {
     private Gtk.Label time_label;
 
     [GtkCallback]
-    private void stop_clicked () {
-        alarm.stop ();
+    private void stop_clicked () requires (alarm != null) {
+        ((Item) alarm).stop();
     }
 
     [GtkCallback]
-    private void snooze_clicked () {
-        if (alarm.state != Item.State.SNOOZING) {
-            alarm.snooze ();
+    private void snooze_clicked () requires (alarm != null) {
+        if (((Item) alarm).state != Item.State.SNOOZING) {
+            ((Item) alarm).snooze ();
         } else {
             // The alarm is already snoozed, simply dismiss the panel.
             dismiss ();
@@ -767,11 +770,11 @@ private class RingingPanel : Gtk.Grid {
 
     public void update () {
         if (alarm != null) {
-            title_label.label = alarm.name;
-            if (alarm.state == Item.State.SNOOZING) {
-                time_label.label = alarm.snooze_time_label;
+            title_label.label = (string) ((Item) alarm).name;
+            if (((Item) alarm).state == SNOOZING) {
+                time_label.label = ((Item) alarm).snooze_time_label;
             } else {
-                time_label.label = alarm.time_label;
+                time_label.label = ((Item) alarm).time_label;
             }
         } else {
             title_label.label = "";
@@ -788,7 +791,7 @@ public class Face : Gtk.Stack, Clocks.Clock {
     public string title { get; set; default = _("Clocks"); }
     public string subtitle { get; set; }
     // Translators: Tooltip for the + button
-    public string new_label { get; default = _("New Alarm"); }
+    public string? new_label { get; default = _("New Alarm"); }
 
     private ContentStore alarms;
     private GLib.Settings settings;
@@ -808,23 +811,25 @@ public class Face : Gtk.Stack, Clocks.Clock {
         settings = new GLib.Settings ("org.gnome.clocks");
 
         var app = GLib.Application.get_default ();
-        var action = app.lookup_action ("stop-alarm");
-        ((GLib.SimpleAction)action).activate.connect ((action, param) => {
-            var a = (Item)alarms.find ((a) => {
-                return ((Item)a).id == param.get_string ();
+        var action = (GLib.SimpleAction) app.lookup_action ("stop-alarm");
+        action.activate.connect ((action, param) => {
+            var a = alarms.find ((a) => {
+                return ((Item) a).id == ((Variant) param).get_string ();
             });
+
             if (a != null) {
-                a.stop ();
+                ((Item) a).stop ();
             }
         });
 
-        action = app.lookup_action ("snooze-alarm");
-        ((GLib.SimpleAction)action).activate.connect ((action, param) => {
-            var a = (Item)alarms.find ((a) => {
-                return ((Item)a).id == param.get_string ();
+        action = (GLib.SimpleAction) app.lookup_action ("snooze-alarm");
+        action.activate.connect ((action, param) => {
+            var a = alarms.find ((a) => {
+                return ((Item) a).id == ((Variant) param).get_string ();
             });
+
             if (a != null) {
-                a.snooze ();
+                ((Item) a).stop ();
             }
         });
 
diff --git a/src/application.vala b/src/application.vala
index 3a880cd..8945d7d 100644
--- a/src/application.vala
+++ b/src/application.vala
@@ -21,7 +21,7 @@ namespace Clocks {
 public class Application : Gtk.Application {
     const OptionEntry[] OPTION_ENTRIES = {
         { "version", 'v', 0, OptionArg.NONE, null, N_("Print version information and exit"), null },
-        { null }
+        { (string) null }
     };
 
     const GLib.ActionEntry[] ACTION_ENTRIES = {
@@ -35,16 +35,17 @@ public class Application : Gtk.Application {
     private uint search_provider_id = 0;
     private World.ShellWorldClocks world_clocks;
     private uint world_clocks_id = 0;
-    private Window window;
+    private Window? window;
     private List<string> system_notifications;
 
-    private void ensure_window () {
+    private Window ensure_window () ensures (window != null) {
         if (window == null) {
             window = new Window (this);
-            window.delete_event.connect (() => {
-               return window.hide_on_delete ();
+            ((Window) window).delete_event.connect (() => {
+               return ((Window) window).hide_on_delete ();
             });
         }
+        return (Window) window;
     }
 
     public Application () {
@@ -57,9 +58,9 @@ public class Application : Gtk.Application {
 
         search_provider = new SearchProvider ();
         search_provider.activate.connect ((timestamp) => {
-            ensure_window ();
-            window.show_world ();
-            window.present_with_time (timestamp);
+            var win = ensure_window ();
+            win.show_world ();
+            win.present_with_time (timestamp);
         });
 
         system_notifications = new List<string> ();
@@ -97,10 +98,10 @@ public class Application : Gtk.Application {
     protected override void activate () {
         base.activate ();
 
-        ensure_window ();
-        window.present ();
+        var win = ensure_window ();
+        win.present ();
 
-        window.focus_in_event.connect (() => {
+        win.focus_in_event.connect (() => {
             withdraw_notifications ();
 
             return false;
@@ -124,7 +125,7 @@ public class Application : Gtk.Application {
         var theme = Gtk.IconTheme.get_default ();
         theme.add_resource_path ("/org/gnome/clocks/icons");
 
-        var settings = Gtk.Settings.get_default ();
+        var settings = (Gtk.Settings) Gtk.Settings.get_default ();
         settings.notify["gtk-theme-name"].connect (() => {
             update_theme (settings);
         });
@@ -139,7 +140,7 @@ public class Application : Gtk.Application {
 
     protected override int handle_local_options (GLib.VariantDict options) {
         if (options.contains ("version")) {
-            print ("%s %s\n", Environment.get_application_name (), Config.VERSION);
+            print ("%s %s\n", (string) Environment.get_application_name (), Config.VERSION);
             return 0;
         }
 
@@ -151,14 +152,19 @@ public class Application : Gtk.Application {
             return;
         }
 
-        ensure_window ();
-        window.show_world ();
-        window.present ();
+        var win = ensure_window ();
+        win.show_world ();
+        win.present ();
 
         var world = GWeather.Location.get_world ();
-        var location = world.deserialize (parameter.get_child_value (0));
-        if (location != null) {
-            window.add_world_location (location);
+        if (world != null) {
+            // The result is actually nullable
+            var location = (GWeather.Location?) ((GWeather.Location) world).deserialize ((Variant) 
parameter);
+            if (location != null) {
+                win.add_world_location ((GWeather.Location) location);
+            }
+        } else {
+            warning ("the world is missing");
         }
     }
 
@@ -181,7 +187,9 @@ public class Application : Gtk.Application {
     }
 
     void on_quit_activate () {
-        window.destroy ();
+        if (window != null) {
+            ((Window) window).destroy ();
+        }
         quit ();
     }
 }
diff --git a/src/clock.vala b/src/clock.vala
index 739edae..7449085 100644
--- a/src/clock.vala
+++ b/src/clock.vala
@@ -30,7 +30,7 @@ public interface Clocks.Clock : GLib.Object {
     public abstract ViewMode view_mode { get; set; }
     public abstract string title { get; protected set; }
     public abstract string subtitle { get; protected set; }
-    public abstract string new_label { get; }
+    public abstract string? new_label { get; }
 
     public virtual void activate_new () {
     }
diff --git a/src/geocoding.vala b/src/geocoding.vala
index 9277fbf..11d4706 100644
--- a/src/geocoding.vala
+++ b/src/geocoding.vala
@@ -55,19 +55,20 @@ public class Info : Object {
 
         yield seek_country_code ();
 
-        yield search_locations (GWeather.Location.get_world ());
+        yield search_locations ((GWeather.Location) GWeather.Location.get_world ());
 
         if (found_location != null) {
-            location_changed (found_location);
+            location_changed ((GWeather.Location) found_location);
         }
     }
 
-    private async void seek_country_code () {
-        Geocode.Location location = new Geocode.Location (geo_location.latitude, geo_location.longitude);
-        Geocode.Reverse reverse = new Geocode.Reverse.for_location (location);
+    private async void seek_country_code () requires (geo_location != null) {
+        var location = new Geocode.Location (((GClue.Location) geo_location).latitude,
+                                             ((GClue.Location) geo_location).longitude);
+        var reverse = new Geocode.Reverse.for_location (location);
 
         try {
-            Geocode.Place place = yield reverse.resolve_async ();
+            var place = yield reverse.resolve_async ();
 
             country_code = place.get_country_code ();
         } catch (Error e) {
@@ -91,7 +92,7 @@ public class Info : Object {
                           Math.sin (lat1) * Math.sin (lat2)) * EARTH_RADIUS;
     }
 
-    private async void search_locations (GWeather.Location location) {
+    private async void search_locations (GWeather.Location location) requires (geo_location != null) {
         if (this.country_code != null) {
             string? loc_country_code = location.get_country ();
             if (loc_country_code != null) {
@@ -101,39 +102,40 @@ public class Info : Object {
             }
         }
 
-        GWeather.Location? [] locations = location.get_children ();
-        if (locations != null) {
-            for (int i = 0; i < locations.length; i++) {
-                if (locations[i].get_level () == GWeather.LocationLevel.CITY) {
-                    if (locations[i].has_coords ()) {
-                        double latitude, longitude, distance;
-
-                        locations[i].get_coords (out latitude, out longitude);
-                        distance = get_distance (geo_location.latitude, geo_location.longitude, latitude, 
longitude);
-
-                        if (distance < minimal_distance) {
-                            found_location = locations[i];
-                            minimal_distance = distance;
-                        }
+        var locations = location.get_children ();
+        for (int i = 0; i < locations.length; i++) {
+            if (locations[i].get_level () == GWeather.LocationLevel.CITY) {
+                if (locations[i].has_coords ()) {
+                    double latitude, longitude, distance;
+
+                    locations[i].get_coords (out latitude, out longitude);
+                    distance = get_distance (((GClue.Location) geo_location).latitude,
+                                             ((GClue.Location) geo_location).longitude,
+                                             latitude,
+                                             longitude);
+
+                    if (distance < minimal_distance) {
+                        found_location = locations[i];
+                        minimal_distance = distance;
                     }
                 }
-
-                yield search_locations (locations[i]);
             }
+
+            yield search_locations (locations[i]);
         }
     }
 
     public bool is_location_similar (GWeather.Location location) {
         if (this.found_location != null) {
-            string? country_code = location.get_country ();
-            string? found_country_code = found_location.get_country ();
+            var country_code = location.get_country ();
+            var found_country_code = ((GWeather.Location) found_location).get_country ();
             if (country_code != null && country_code == found_country_code) {
-                GWeather.Timezone? timezone = location.get_timezone ();
-                GWeather.Timezone? found_timezone = found_location.get_timezone ();
+                var timezone = location.get_timezone ();
+                var found_timezone = ((GWeather.Location) found_location).get_timezone ();
 
                 if (timezone != null && found_timezone != null) {
-                    string? tzid = timezone.get_tzid ();
-                    string? found_tzid = found_timezone.get_tzid ();
+                    var tzid = ((GWeather.Timezone) timezone).get_tzid ();
+                    var found_tzid = ((GWeather.Timezone) found_timezone).get_tzid ();
                     if (tzid == found_tzid) {
                         return true;
                     }
diff --git a/src/headerbar.vala b/src/headerbar.vala
index f623ed4..039637d 100644
--- a/src/headerbar.vala
+++ b/src/headerbar.vala
@@ -83,7 +83,7 @@ public class Clocks.HeaderBar : Hdy.HeaderBar {
 
     public Gtk.Stack stack { get; set; }
     public Hdy.ViewSwitcherBar switcher_bar { get; set; }
-    public string new_label { get; set; }
+    public string? new_label { get; set; }
 
     private ViewMode _mode;
     private ButtonMode _button_mode;
@@ -103,7 +103,7 @@ public class Clocks.HeaderBar : Hdy.HeaderBar {
 
     [GtkCallback]
     private void subtitle_changed () {
-        reveal_subtitle.reveal_child = subtitle != null && subtitle.length > 0;
+        reveal_subtitle.reveal_child = ((string?) subtitle) != null && subtitle.length > 0;
     }
 
     [GtkCallback]
diff --git a/src/meson.build b/src/meson.build
index 8c8015e..8ddd6ca 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -31,9 +31,10 @@ clocks_sources = [
 ]
 
 clocks_vala_args = [
-  '--target-glib', '2.44',
+  '--target-glib', '2.58',
   '--vapidir', meson.current_source_dir(),
   '--gresources', resource_files,
+  '--enable-experimental-non-null',
 ]
 
 clocks_c_args = [
diff --git a/src/search-provider.vala b/src/search-provider.vala
index 7fe6927..f2d2f92 100644
--- a/src/search-provider.vala
+++ b/src/search-provider.vala
@@ -34,15 +34,16 @@ public class SearchProvider : Object {
     }
 
     private bool location_matches (GWeather.Location location, string[] normalized_terms) {
-        string city = location.get_city_name ();
-        string country = location.get_country_name ();
+        var city = location.get_city_name ();
+        var country = location.get_country_name ();
+
         if (city == null || country == null) {
             return false;
         }
 
         foreach (string t in normalized_terms) {
-            if (!city.normalize ().casefold ().contains (t) &&
-                !country.normalize ().casefold ().contains (t)) {
+            if (!((string) city).normalize ().casefold ().contains (t) &&
+                !((string) country).normalize ().casefold ().contains (t)) {
                 return false;
             }
         }
@@ -55,7 +56,7 @@ public class SearchProvider : Object {
     }
 
     private GWeather.Location? deserialize_location (string str) {
-        Variant? variant;
+        Variant variant;
 
         try {
             variant = Variant.parse (new VariantType ("(uv)"), str, null, null);
@@ -65,24 +66,25 @@ public class SearchProvider : Object {
         }
 
         var world = GWeather.Location.get_world ();
-        return world.deserialize (variant);
+        if (world != null) {
+            return ((GWeather.Location) world).deserialize (variant);
+        } else {
+            return null;
+        }
     }
 
     private async void search_locations_recurse (GWeather.Location location, string[] normalized_terms,
-                                                    GenericArray<GWeather.Location> matches) {
-        GWeather.Location? []locations = location.get_children ();
-        if (locations != null) {
-            for (int i = 0; i < locations.length; i++) {
-                var level = locations[i].get_level ();
-                if (level == GWeather.LocationLevel.CITY ||
-                    level == GWeather.LocationLevel.NAMED_TIMEZONE) {
-                    if (location_matches (locations[i], normalized_terms)) {
-                        matches.add (locations[i]);
-                    }
+                                                 GenericArray<GWeather.Location> matches) {
+        var locations = location.get_children ();
+        foreach (var child_location in locations) {
+            var level = child_location.get_level ();
+            if (level == CITY || level == NAMED_TIMEZONE) {
+                if (location_matches (child_location, normalized_terms)) {
+                    matches.add (child_location);
                 }
-
-                yield search_locations_recurse (locations[i], normalized_terms, matches);
             }
+
+            yield search_locations_recurse (child_location, normalized_terms, matches);
         }
     }
 
@@ -90,7 +92,13 @@ public class SearchProvider : Object {
         var world = GWeather.Location.get_world ();
         var matches = new GenericArray<GWeather.Location> ();
 
-        yield search_locations_recurse (world, normalized_terms, matches);
+        if (world == null) {
+            return {};
+        }
+
+        yield search_locations_recurse ((GWeather.Location) world,
+                                        normalized_terms,
+                                        matches);
 
         string[] result = {};
         matches.foreach ((location) => {
@@ -121,7 +129,8 @@ public class SearchProvider : Object {
         foreach (var str in previous_results) {
             var location = deserialize_location (str);
 
-            if (location != null && location_matches (location, normalized_terms)) {
+            if (location != null &&
+                location_matches ((GWeather.Location) location, normalized_terms)) {
                 result += (str);
             }
         }
@@ -141,16 +150,16 @@ public class SearchProvider : Object {
             }
 
             var meta = new HashTable<string, Variant> (str_hash, str_equal);
-            var item = new World.Item (location);
-            string time_label = item.time_label;
-            string day = item.day_label;
+            var item = new World.Item ((GWeather.Location) location);
+            var time_label = item.time_label;
+            var day = item.day_label;
             if (day != null) {
-                time_label += " " + day;
+                time_label += " " + (string) day;
             }
             count++;
             meta.insert ("id", count.to_string ());
             meta.insert ("name", time_label);
-            meta.insert ("description", item.name);
+            meta.insert ("description", (string) item.name);
 
             result.add (meta);
         }
diff --git a/src/stopwatch.vala b/src/stopwatch.vala
index 88c6039..f67a5bd 100644
--- a/src/stopwatch.vala
+++ b/src/stopwatch.vala
@@ -60,7 +60,9 @@ private class LapsRow : Gtk.ListBoxRow {
         duration_label.label = this.get_duration_label ();
 
         if (this.before != null) {
-            difference_label.label = this.get_delta_label ();
+            // So get_delta_label() can be null, but Vala doesn't
+            // know that .label can be as well
+            difference_label.label = (string) this.get_delta_label ();
 
             var difference = this.get_delta_duration ();
             if (difference > 0) {
@@ -77,14 +79,14 @@ private class LapsRow : Gtk.ListBoxRow {
 
     private double get_delta_duration () {
         if (this.before != null) {
-            return this.current.duration - this.before.duration;
+            return this.current.duration - ((Lap) this.before).duration;
         }
         return 0;
     }
 
     private string? get_delta_label () {
         if (this.before != null) {
-            var difference = this.current.duration - this.before.duration;
+            var difference = this.current.duration - ((Lap) this.before).duration;
             var delta_label = render_duration (difference);
             string sign = "+";
             if (difference < 0) {
@@ -121,7 +123,7 @@ public class Face : Gtk.Box, Clocks.Clock {
     public ViewMode view_mode { get; set; default = NORMAL; }
     public string title { get; set; default = _("Clocks"); }
     public string subtitle { get; set; }
-    public string new_label { get; default = null; }
+    public string? new_label { get; default = null; }
 
     public State state { get; private set; default = State.RESET; }
 
diff --git a/src/timer.vala b/src/timer.vala
index 0c3cbdc..6ce6ddd 100644
--- a/src/timer.vala
+++ b/src/timer.vala
@@ -29,7 +29,7 @@ public class Item : Object, ContentItem {
 
     public State state { get; private set; default = State.STOPPED; }
 
-    public string name { get ; set; }
+    public string? name { get ; set; }
     public int hours { get; set; default = 0; }
     public int minutes { get; set; default = 0; }
     public int seconds { get; set; default = 0; }
@@ -49,27 +49,30 @@ public class Item : Object, ContentItem {
         builder.open (new GLib.VariantType ("a{sv}"));
         builder.add ("{sv}", "duration", new GLib.Variant.int32 (get_total_seconds ()));
         if (name != null) {
-            builder.add ("{sv}", "name", new GLib.Variant.string (name));
+            builder.add ("{sv}", "name", new GLib.Variant.string ((string) name));
         }
         builder.close ();
     }
 
-    public static Item? deserialize (GLib.Variant time_variant) {
+    public static Item? deserialize (Variant time_variant) {
+        string key;
+        Variant val;
         int duration = 0;
         string? name = null;
 
-        foreach (var v in time_variant) {
-            var key = v.get_child_value (0).get_string ();
+        var iter = time_variant.iterator ();
+        while (iter.next ("{sv}", out key, out val)) {
             switch (key) {
                 case "duration":
-                    duration = v.get_child_value (1).get_child_value (0).get_int32 ();
+                    duration = (int32) val;
                     break;
                 case "name":
-                    name = v.get_child_value (1).get_child_value (0).get_string ();
+                    name = (string) val;
                     break;
             }
         }
-        return duration != 0 ? new Item.from_seconds (duration, name) : null;
+
+        return duration != 0 ? (Item?) new Item.from_seconds (duration, name) : null;
     }
 
     public Item.from_seconds (int seconds, string? name) {
@@ -171,7 +174,7 @@ public class Setup : Gtk.Box {
         var duration_type = new GLib.VariantType ("i");
         var set_duration_action = new SimpleAction ("set-duration", duration_type);
         set_duration_action.activate.connect ((action, param) => {
-            var total_minutes = param.get_int32 ();
+            var total_minutes = (int32) param;
             var hours = total_minutes / 60;
             var minutes = total_minutes - hours * 60;
             this.h_spinbutton.value = hours;
@@ -256,15 +259,15 @@ public class Row : Gtk.ListBoxRow {
         construct set {
             _item = value;
 
-            title.text = _item.name;
+            title.text = (string) _item.name;
             title.bind_property ("text", _item, "name");
-            timer_name.label = _item.name;
+            timer_name.label = (string) _item.name;
             title.bind_property ("text", timer_name, "label");
 
             _item.notify["name"].connect (() => edited ());
         }
     }
-    private Item _item = null;
+    private Item _item;
 
 
     [GtkChild]
@@ -385,7 +388,7 @@ public class Face : Gtk.Stack, Clocks.Clock {
     public string title { get; set; default = _("Clocks"); }
     public string subtitle { get; set; }
     // Translators: Tooltip for the + button
-    public string new_label { get; default = _("New Timer"); }
+    public string? new_label { get; default = _("New Timer"); }
 
     private ContentStore timers;
     private GLib.Settings settings;
@@ -480,7 +483,7 @@ public class Face : Gtk.Stack, Clocks.Clock {
     }
 
     public virtual signal void ring () {
-        var app = GLib.Application.get_default () as Clocks.Application;
+        var app = (Clocks.Application) GLib.Application.get_default ();
         app.send_notification ("timer-is-up", notification);
         bell.ring_once ();
     }
diff --git a/src/utils.vala b/src/utils.vala
index 8b89988..68f0a4f 100644
--- a/src/utils.vala
+++ b/src/utils.vala
@@ -17,7 +17,7 @@
  */
 
 extern int clocks_cutils_get_week_start ();
-extern void calculate_sunrise_sunset (double lat,
+extern bool calculate_sunrise_sunset (double lat,
                                       double lon,
                                       int year,
                                       int month,
@@ -41,7 +41,7 @@ public void load_css (string css) {
     try {
         var data = resources_lookup_data ("/org/gnome/clocks/css/" + css + ".css", NONE);
         provider.load_from_data ((string) data.get_data ());
-        Gtk.StyleContext.add_provider_for_screen (Gdk.Screen.get_default (),
+        Gtk.StyleContext.add_provider_for_screen ((Gdk.Screen) Gdk.Screen.get_default (),
                                                   provider,
                                                   Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
     } catch (ResourceError.NOT_FOUND e) {
@@ -70,13 +70,14 @@ public class WallClock : Object {
         TWENTYFOUR
     }
 
-    private static WallClock instance;
+    private static WallClock? instance;
 
     public static WallClock get_default () {
         if (instance == null) {
             instance = new WallClock ();
         }
-        return instance;
+        // If it's still null something has gone horribly wrong
+        return (WallClock) instance;
     }
 
     public GLib.DateTime date_time { get; private set; }
@@ -140,8 +141,8 @@ public class WallClock : Object {
 }
 
 public class Weekdays {
-    private static string[] abbreviations = null;
-    private static string[] names = null;
+    private static string[]? abbreviations = null;
+    private static string[]? names = null;
 
     public enum Day {
         MON = 0,
@@ -285,7 +286,7 @@ public class Weekdays {
     }
 
     public string get_label () {
-        string r = null;
+        string? r = null;
         int n = 0;
         int first = -1;
         for (int i = 0; i < 7; i++) {
@@ -308,7 +309,7 @@ public class Weekdays {
         } else if (days_equal (WEEKENDS)) {
             r = _("Weekends");
         } else {
-            string[] abbrs = {};
+            string?[]? abbrs = {};
             for (int i = 0; i < 7; i++) {
                 Day d = (Day.get_first_weekday () + i) % 7;
                 if (get (d)) {
@@ -317,7 +318,7 @@ public class Weekdays {
             }
             r = string.joinv (", ", abbrs);
         }
-        return r;
+        return (string) r;
     }
 
     // Note that we serialze days according to ISO 8601
@@ -338,7 +339,7 @@ public class Weekdays {
     public static Weekdays deserialize (GLib.Variant days_variant) {
         Weekdays d = new Weekdays ();
         foreach (var v in days_variant) {
-            int32 i = v.get_int32 ();
+            var i = (int32) v;
             if (i > 0 && i <= 7) {
                 d.set ((Day) (i - 1), true);
             } else {
@@ -379,10 +380,10 @@ public class Bell : Object {
 
         try {
             do {
-                yield gsound.play_full (cancellable,
-                                        GSound.Attribute.EVENT_ID, sound,
-                                        GSound.Attribute.CANBERRA_XDG_THEME_NAME, soundtheme,
-                                        GSound.Attribute.MEDIA_ROLE, "alarm");
+                yield ((GSound.Context) gsound).play_full (cancellable,
+                                                           GSound.Attribute.EVENT_ID, sound,
+                                                           GSound.Attribute.CANBERRA_XDG_THEME_NAME, 
soundtheme,
+                                                           GSound.Attribute.MEDIA_ROLE, "alarm");
             } while (repeat);
         } catch (GLib.IOError.CANCELLED e) {
             // ignore
diff --git a/src/widgets.vala b/src/widgets.vala
index 06e934e..a071f2d 100644
--- a/src/widgets.vala
+++ b/src/widgets.vala
@@ -19,13 +19,13 @@
 namespace Clocks {
 
 public interface ContentItem : GLib.Object {
-    public abstract string name { get; set; }
+    public abstract string? name { get; set; }
     public abstract void serialize (GLib.VariantBuilder builder);
 }
 
 public class ContentStore : GLib.Object, GLib.ListModel {
     private ListStore store;
-    private CompareDataFunc sort_func;
+    private CompareDataFunc? sort_func;
 
 
     public ContentStore () {
@@ -88,7 +88,7 @@ public class ContentStore : GLib.Object, GLib.ListModel {
     public void foreach (ForeachFunc func) {
         var n = store.get_n_items ();
         for (int i = 0; i < n; i++) {
-            func (store.get_object (i) as ContentItem);
+            func ((ContentItem) store.get_object (i));
         }
     }
 
@@ -97,7 +97,7 @@ public class ContentStore : GLib.Object, GLib.ListModel {
     public ContentItem? find (FindFunc func) {
         var n = store.get_n_items ();
         for (int i = 0; i < n; i++) {
-            var item = store.get_object (i) as ContentItem;
+            var item = (ContentItem) store.get_object (i);
             if (func (item)) {
                 return item;
             }
@@ -125,8 +125,7 @@ public class ContentStore : GLib.Object, GLib.ListModel {
         var builder = new GLib.VariantBuilder (new VariantType ("aa{sv}"));
         var n = store.get_n_items ();
         for (int i = 0; i < n; i++) {
-            var item = store.get_object (i) as ContentItem;
-            item.serialize (builder);
+            ((ContentItem) store.get_object (i)).serialize (builder);
         }
         return builder.end ();
     }
@@ -134,10 +133,12 @@ public class ContentStore : GLib.Object, GLib.ListModel {
     public delegate ContentItem? DeserializeItemFunc (Variant v);
 
     public void deserialize (Variant variant, DeserializeItemFunc deserialize_item) {
-        foreach (var v in variant) {
-            ContentItem? i = deserialize_item (v);
+        Variant item;
+        var iter = variant.iterator ();
+        while (iter.next ("@a{sv}", out item)) {
+            ContentItem? i = deserialize_item (item);
             if (i != null) {
-                add (i);
+                add ((ContentItem) i);
             }
         }
     }
diff --git a/src/window.vala b/src/window.vala
index ab4e3fb..215b590 100644
--- a/src/window.vala
+++ b/src/window.vala
@@ -45,11 +45,11 @@ public class Window : Gtk.ApplicationWindow {
     private GLib.Settings settings;
 
     // DIY DzlBindingGroup
-    private Binding bind_button_mode = null;
-    private Binding bind_view_mode = null;
-    private Binding bind_title = null;
-    private Binding bind_subtitle = null;
-    private Binding bind_new_label = null;
+    private Binding? bind_button_mode = null;
+    private Binding? bind_view_mode = null;
+    private Binding? bind_title = null;
+    private Binding? bind_subtitle = null;
+    private Binding? bind_new_label = null;
 
     private bool inited = false;
 
@@ -213,7 +213,7 @@ public class Window : Gtk.ApplicationWindow {
         const uint BUTTON_BACK = 8;
         uint button;
 
-        if (((Gdk.Event)(event)).get_button (out button) && button == BUTTON_BACK) {
+        if (((Gdk.Event) (event)).get_button (out button) && button == BUTTON_BACK) {
             ((Clock) stack.visible_child).activate_back ();
             return true;
         }
@@ -222,7 +222,7 @@ public class Window : Gtk.ApplicationWindow {
     }
 
     protected override bool configure_event (Gdk.EventConfigure event) {
-        if (get_realized () && !(Gdk.WindowState.MAXIMIZED in get_window ().get_state ())) {
+        if (get_realized () && !(Gdk.WindowState.MAXIMIZED in ((Gdk.Window) get_window ()).get_state ())) {
             int width, height;
 
             get_size (out width, out height);
@@ -251,7 +251,7 @@ public class Window : Gtk.ApplicationWindow {
                                  "Eslam Mostafa, Paolo Borelli, Volker Sobek\n" +
                                  "Copyright \xc2\xa9 2019 Bilal Elmoussaoui & Zander Brown et al";
 
-        const string AUTHORS[] = {
+        const string? AUTHORS[] = {
             "Alex Anthony",
             "Paolo Borelli",
             "Allan Day",
@@ -293,14 +293,14 @@ public class Window : Gtk.ApplicationWindow {
             return;
         }
 
-        help_overlay.view_name = Type.from_instance (panel).name ();
+        ((Gtk.ShortcutsWindow) help_overlay).view_name = Type.from_instance (panel).name ();
 
         if (inited) {
             settings.set_enum ("panel-id", panel.panel_id);
         }
 
         if (bind_button_mode != null) {
-            bind_button_mode.unbind ();
+            ((Binding) bind_button_mode).unbind ();
         }
         bind_button_mode = panel.bind_property ("button-mode",
                                                 header_bar,
@@ -308,7 +308,7 @@ public class Window : Gtk.ApplicationWindow {
                                                 SYNC_CREATE);
 
         if (bind_view_mode != null) {
-            bind_view_mode.unbind ();
+            ((Binding) bind_view_mode).unbind ();
         }
         bind_view_mode = panel.bind_property ("view-mode",
                                               header_bar,
@@ -316,7 +316,7 @@ public class Window : Gtk.ApplicationWindow {
                                               SYNC_CREATE);
 
         if (bind_title != null) {
-            bind_title.unbind ();
+            ((Binding) bind_title).unbind ();
         }
         bind_title = panel.bind_property ("title",
                                           header_bar,
@@ -324,7 +324,7 @@ public class Window : Gtk.ApplicationWindow {
                                           SYNC_CREATE);
 
         if (bind_subtitle != null) {
-            bind_subtitle.unbind ();
+            ((Binding) bind_subtitle).unbind ();
         }
         bind_subtitle = panel.bind_property ("subtitle",
                                              header_bar,
@@ -332,7 +332,7 @@ public class Window : Gtk.ApplicationWindow {
                                              SYNC_CREATE);
 
         if (bind_new_label != null) {
-            bind_new_label.unbind ();
+            ((Binding) bind_new_label).unbind ();
         }
         bind_new_label = panel.bind_property ("new-label",
                                               header_bar,
diff --git a/src/world.vala b/src/world.vala
index c212b02..7e341b1 100644
--- a/src/world.vala
+++ b/src/world.vala
@@ -22,14 +22,25 @@ namespace World {
 // Export world clock locations to GNOME Shell
 [DBus (name = "org.gnome.Shell.ClocksIntegration")]
 public class ShellWorldClocks : Object {
-    public GLib.Variant[] locations {
+    [DBus (signature = "av")]
+    public Variant locations {
         owned get {
-            GLib.Variant[] rv = {};
-            GLib.Variant locations = settings.get_value ("world-clocks");
-
-            for (int i = 0; i < locations.n_children (); i++) {
-                rv += locations.get_child_value (i).lookup_value ("location", null);
+            Variant dict;
+            Variant[] rv = {};
+            var locations = settings.get_value ("world-clocks");
+            var iter = locations.iterator ();
+
+            while (iter.next ("@a{sv}", out dict)) {
+                string key;
+                Variant val;
+                var dict_iter = dict.iterator ();
+                while (dict_iter.next ("{sv}", out key, out val)) {
+                    if (key == "location") {
+                        rv += val;
+                    }
+                }
             }
+
             return rv;
         }
     }
@@ -72,15 +83,15 @@ public class Item : Object, ContentItem {
 
     public bool automatic { get; set; default = false; }
 
-    public string name {
+    public string? name {
         get {
             // We store it in a _name member even if we overwrite it every time
             // since the abstract name property does not return an owned string
             if (country_name != null) {
                 if (state_name != null) {
-                    _name = "%s, %s, %s".printf (city_name, state_name, country_name);
+                    _name = "%s, %s, %s".printf (city_name, (string) state_name, (string) country_name);
                 } else {
-                    _name = "%s, %s".printf (city_name, country_name);
+                    _name = "%s, %s".printf (city_name, (string) country_name);
                 }
             } else {
                 _name = city_name;
@@ -100,7 +111,7 @@ public class Item : Object, ContentItem {
             if (city_name == null) {
                 city_name = location.get_name ();
             }
-            return city_name;
+            return (string) city_name;
         }
     }
 
@@ -109,8 +120,8 @@ public class Item : Object, ContentItem {
             GWeather.Location? parent = location.get_parent ();
 
             if (parent != null) {
-                if (parent.get_level () == GWeather.LocationLevel.ADM1) {
-                    return parent.get_name ();
+                if (((GWeather.Location) parent).get_level () == ADM1) {
+                    return ((GWeather.Location) parent).get_name ();
                 }
             }
 
@@ -127,7 +138,7 @@ public class Item : Object, ContentItem {
     public bool is_daytime {
          get {
             if (weather_info != null) {
-                return weather_info.is_daytime ();
+                return ((GWeather.Info) weather_info).is_daytime ();
             }
             return true;
         }
@@ -140,11 +151,16 @@ public class Item : Object, ContentItem {
             }
 
             ulong sunrise;
-            if (!weather_info.get_value_sunrise (out sunrise)) {
+            if (!((GWeather.Info) weather_info).get_value_sunrise (out sunrise)) {
+                return "-";
+            }
+
+            if (time_zone == null) {
                 return "-";
             }
+
             var sunrise_time = new GLib.DateTime.from_unix_local (sunrise);
-            sunrise_time = sunrise_time.to_timezone (time_zone);
+            sunrise_time = sunrise_time.to_timezone ((TimeZone) time_zone);
             return Utils.WallClock.get_default ().format_time (sunrise_time);
         }
     }
@@ -156,11 +172,16 @@ public class Item : Object, ContentItem {
             }
 
             ulong sunset;
-            if (!weather_info.get_value_sunset (out sunset)) {
+            if (!((GWeather.Info) weather_info).get_value_sunset (out sunset)) {
+                return "-";
+            }
+
+            if (time_zone == null) {
                 return "-";
             }
+
             var sunset_time = new GLib.DateTime.from_unix_local (sunset);
-            sunset_time = sunset_time.to_timezone (time_zone);
+            sunset_time = sunset_time.to_timezone ((TimeZone) time_zone);
             return Utils.WallClock.get_default ().format_time (sunset_time);
         }
     }
@@ -203,19 +224,19 @@ public class Item : Object, ContentItem {
                 return "none";
             }
 
-            if (date_time.compare (sun_rise) > 0 && date_time.compare (sun_set) < 0) {
+            if (date_time.compare ((DateTime) sun_rise) > 0 && date_time.compare ((DateTime) sun_set) < 0) {
                 return "day";
             }
 
-            if (date_time.compare (civil_rise) > 0 && date_time.compare (civil_set) < 0) {
+            if (date_time.compare ((DateTime) civil_rise) > 0 && date_time.compare ((DateTime) civil_set) < 
0) {
                 return "civil";
             }
 
-            if (date_time.compare (naut_rise) > 0 && date_time.compare (naut_set) < 0) {
+            if (date_time.compare ((DateTime) naut_rise) > 0 && date_time.compare ((DateTime) naut_set) < 0) 
{
                 return "naut";
             }
 
-            if (date_time.compare (astro_rise) > 0 && date_time.compare (astro_set) < 0) {
+            if (date_time.compare ((DateTime) astro_rise) > 0 && date_time.compare ((DateTime) astro_set) < 
0) {
                 return "astro";
             }
 
@@ -224,10 +245,10 @@ public class Item : Object, ContentItem {
     }
 
     private string _name;
-    private GLib.TimeZone time_zone;
+    private GLib.TimeZone? time_zone;
     private GLib.DateTime local_time;
     private GLib.DateTime date_time;
-    private GWeather.Info weather_info;
+    private GWeather.Info? weather_info;
 
     // When sunrise/sunset happens, at different corrections, in locations
     // timezone for calculating the colour pill
@@ -245,8 +266,15 @@ public class Item : Object, ContentItem {
     public Item (GWeather.Location location) {
         Object (location: location);
 
-        var weather_time_zone = location.get_timezone ();
-        time_zone = new GLib.TimeZone (weather_time_zone.get_tzid ());
+        var weather_time_zone = location.get_timezone_str ();
+        if (weather_time_zone != null) {
+            time_zone = new GLib.TimeZone ((string) weather_time_zone);
+            if (time_zone == null) {
+                warning ("Unrecognised timezone %s", (string) weather_time_zone);
+            }
+        } else {
+            warning ("Failed to get a timezone for %s", location.get_name ());
+        }
 
         tick ();
     }
@@ -257,8 +285,8 @@ public class Item : Object, ContentItem {
                                                   int month,
                                                   int day,
                                                   double correction,
-                                                  out DateTime sunrise,
-                                                  out DateTime sunset) {
+                                                  out DateTime? sunrise,
+                                                  out DateTime? sunset) requires (time_zone != null) {
         int rise_hour, rise_min;
         int set_hour, set_min;
 
@@ -273,9 +301,9 @@ public class Item : Object, ContentItem {
                                   out set_hour,
                                   out set_min);
 
-        var utc_sunrise = new DateTime.utc (year, month, day, rise_hour, rise_min, 0);
+        var utc_sunrise = (DateTime?) new DateTime.utc (year, month, day, rise_hour, rise_min, 0);
         if (utc_sunrise != null) {
-            sunrise = utc_sunrise.to_timezone (time_zone);
+            sunrise = ((DateTime) utc_sunrise).to_timezone ((TimeZone) time_zone);
         } else {
             sunrise = null;
             warning ("Sunrise for (%f,%f) resulted in %04i-%02i-%02i %02i:%02i",
@@ -288,10 +316,10 @@ public class Item : Object, ContentItem {
                      rise_min);
         }
 
-        var utc_sunset = new DateTime.utc (year, month, day, set_hour, set_min, 0);
-        if (utc_sunset != null) {
-            var local_sunset = utc_sunset.to_timezone (time_zone);
-            if (local_sunset.compare (sun_rise) < 0) {
+        var utc_sunset = (DateTime?) new DateTime.utc (year, month, day, set_hour, set_min, 0);
+        if (utc_sunset != null && sunrise != null) {
+            var local_sunset = ((DateTime) utc_sunset).to_timezone ((TimeZone) time_zone);
+            if (local_sunset.compare ((DateTime) sunrise) < 0) {
                 sunset = local_sunset.add_days (1);
             } else {
                 sunset = local_sunset;
@@ -370,7 +398,12 @@ public class Item : Object, ContentItem {
     public virtual signal void tick () {
         var wallclock = Utils.WallClock.get_default ();
         local_time = wallclock.date_time;
-        date_time = local_time.to_timezone (time_zone);
+
+        if (time_zone == null) {
+            return;
+        }
+
+        date_time = local_time.to_timezone ((TimeZone) time_zone);
 
         calculate_riseset ();
 
@@ -391,18 +424,24 @@ public class Item : Object, ContentItem {
         }
     }
 
-    public static ContentItem? deserialize (GLib.Variant location_variant) {
+    public static ContentItem? deserialize (Variant location_variant) {
         GWeather.Location? location = null;
-
+        string key;
+        Variant val;
         var world = GWeather.Location.get_world ();
 
-        foreach (var v in location_variant) {
-            var key = v.get_child_value (0).get_string ();
+        if (world == null) {
+            return null;
+        }
+
+        var iter = location_variant.iterator ();
+        while (iter.next ("{sv}", out key, out val)) {
             if (key == "location") {
-                location = world.deserialize (v.get_child_value (1).get_child_value (0));
+                location = ((GWeather.Location) world).deserialize (val);
             }
         }
-        return location != null ? new Item (location) : null;
+
+        return location == null ? null : (Item?) new Item ((GWeather.Location) location);
     }
 }
 
@@ -468,7 +507,7 @@ private class Tile : Gtk.ListBoxRow {
         }
 
         if (location.day_label != null && location.day_label != "") {
-            desc.label = "%s • %s".printf (location.day_label, message);
+            desc.label = "%s • %s".printf ((string) location.day_label, message);
             delete_stack.visible_child = delete_button;
         } else if (location.automatic) {
             // Translators: This clock represents the local time
@@ -515,12 +554,12 @@ private class LocationDialog : Hdy.Dialog {
         if (location_entry.get_text () != "") {
             l = location_entry.get_location ();
 
-            if (l != null && !world.location_exists (l)) {
-                t = l.get_timezone ();
+            if (l != null && !world.location_exists ((GWeather.Location) l)) {
+                t = ((GWeather.Location) l).get_timezone ();
 
                 if (t == null) {
-                    GLib.warning ("Timezone not defined for %s. This is a bug in libgweather database",
-                                  l.get_city_name ());
+                    warning ("Timezone not defined for %s. This is a bug in libgweather database",
+                             (string) ((GWeather.Location) l).get_city_name ());
                 }
             }
         }
@@ -530,7 +569,7 @@ private class LocationDialog : Hdy.Dialog {
 
     public Item? get_location () {
         var location = location_entry.get_location ();
-        return location != null ? new Item (location) : null;
+        return location != null ? (Item?) new Item ((GWeather.Location) location) : null;
     }
 }
 
@@ -542,11 +581,11 @@ public class Face : Gtk.Stack, Clocks.Clock {
     public string title { get; set; default = _("Clocks"); }
     public string subtitle { get; set; }
     // Translators: Tooltip for the + button
-    public string new_label { get; default = _("Add Location"); }
+    public string? new_label { get; default = _("Add Location"); }
 
     private ContentStore locations;
     private GLib.Settings settings;
-    private Item standalone_location;
+    private Item? standalone_location;
     [GtkChild]
     private Gtk.Widget empty_view;
     [GtkChild]
@@ -572,8 +611,8 @@ public class Face : Gtk.Stack, Clocks.Clock {
         settings = new GLib.Settings ("org.gnome.clocks");
 
         locations.set_sorting ((item1, item2) => {
-            var offset1 = ((Item) item1).location.get_timezone ().get_offset ();
-            var offset2 = ((Item) item2).location.get_timezone ().get_offset ();
+            var offset1 = ((GWeather.Timezone) ((Item) item1).location.get_timezone ()).get_offset ();
+            var offset2 = ((GWeather.Timezone) ((Item) item2).location.get_timezone ()).get_offset ();
             if (offset1 < offset2)
                 return -1;
             if (offset1 > offset2)
@@ -629,7 +668,7 @@ public class Face : Gtk.Stack, Clocks.Clock {
             view_mode = NORMAL;
             button_mode = NEW;
             title = _("Clocks");
-            subtitle = null;
+            subtitle = (string) null;
         } else if (visible_child == standalone) {
             view_mode = STANDALONE;
             button_mode = BACK;
@@ -638,10 +677,10 @@ public class Face : Gtk.Stack, Clocks.Clock {
 
     private void update_standalone () {
         if (standalone_location != null) {
-            standalone_time_label.label = standalone_location.time_label;
-            standalone_day_label.label = standalone_location.day_label;
-            standalone_sunrise_label.label = standalone_location.sunrise_label;
-            standalone_sunset_label.label = standalone_location.sunset_label;
+            standalone_time_label.label = ((Item) standalone_location).time_label;
+            standalone_day_label.label = (string) ((Item) standalone_location).day_label;
+            standalone_sunrise_label.label = ((Item) standalone_location).sunrise_label;
+            standalone_sunset_label.label = ((Item) standalone_location).sunset_label;
         }
     }
 
@@ -649,12 +688,12 @@ public class Face : Gtk.Stack, Clocks.Clock {
         standalone_location = location;
         update_standalone ();
         visible_child = standalone;
-        if (standalone_location.state_name != null) {
-            title = "%s, %s".printf (standalone_location.city_name, standalone_location.state_name);
+        if (location.state_name != null) {
+            title = "%s, %s".printf (location.city_name, (string) location.state_name);
         } else {
-            title = standalone_location.city_name;
+            title = location.city_name;
         }
-        subtitle = standalone_location.country_name;
+        subtitle = (string) location.country_name;
     }
 
     private void load () {
@@ -669,17 +708,17 @@ public class Face : Gtk.Stack, Clocks.Clock {
         Geo.Info geo_info = new Geo.Info ();
 
         geo_info.location_changed.connect ((found_location) => {
-            var item = (Item)locations.find ((l) => {
-                return geo_info.is_location_similar (((Item)l).location);
+            var item = (Item?) locations.find ((l) => {
+                return geo_info.is_location_similar (((Item) l).location);
             });
 
             if (item != null) {
                 return;
             }
 
-            item = new Item (found_location);
-            item.automatic = true;
-            locations.add (item);
+            var auto_item = new Item (found_location);
+            auto_item.automatic = true;
+            locations.add (auto_item);
         });
 
         yield geo_info.seek ();
@@ -694,7 +733,7 @@ public class Face : Gtk.Stack, Clocks.Clock {
         var exists = false;
         var n = locations.get_n_items ();
         for (int i = 0; i < n; i++) {
-            var l = locations.get_object (i) as Item;
+            var l = (Item) locations.get_object (i);
             if (l.location.equal (location)) {
                 exists = true;
                 break;
@@ -716,7 +755,7 @@ public class Face : Gtk.Stack, Clocks.Clock {
         dialog.response.connect ((dialog, response) => {
             if (response == 1) {
                 var location = ((LocationDialog) dialog).get_location ();
-                add_location_item (location);
+                add_location_item ((Item) location);
             }
             dialog.destroy ();
         });


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