[gnome-weather/wip/ewlsh/gtk4] Initial port to GTK4




commit c4b471c146ef73a6d5431d9e92a9df3e156ff343
Author: Evan Welsh <contact evanwelsh com>
Date:   Sun Dec 27 12:01:35 2020 -0600

    Initial port to GTK4

 data/application.css      |   3 +-
 data/city.ui              |  52 +++----
 data/day-entry.ui         | 316 +++++++++++++++++++----------------------
 data/places-popover.ui    | 349 ++++++++++++++++++++++------------------------
 data/primary-menu.ui      |   2 +
 data/weather-widget.ui    | 254 +++++++++++++--------------------
 data/window.ui            | 115 ++++++---------
 meson.build               |   6 +-
 org.gnome.Weather.json    |  15 --
 src/app/city.js           |  16 +--
 src/app/dailyForecast.js  |  21 ++-
 src/app/hourlyForecast.js |  38 +++--
 src/app/main.js           |  17 +--
 src/app/window.js         |  34 +++--
 src/app/world.js          |  45 +++---
 src/misc/util.js          |  10 +-
 src/service/main.js       |   2 +-
 17 files changed, 578 insertions(+), 717 deletions(-)
---
diff --git a/data/application.css b/data/application.css
index 2aa0265..f8c9b6f 100644
--- a/data/application.css
+++ b/data/application.css
@@ -91,7 +91,8 @@ viewswitchertitle viewswitcher {
 
 button.osd.circular {
   border-radius: 9999px;
-  -gtk-outline-radius: 9999px;
+  /* TODO: GTK4 */
+  /* -gtk-outline-radius: 9999px; */
   min-width: 24px;
   min-height: 24px;
 }
diff --git a/data/city.ui b/data/city.ui
index f9d25b0..e017717 100644
--- a/data/city.ui
+++ b/data/city.ui
@@ -1,39 +1,31 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.16.1 -->
 <interface>
-  <requires lib="gtk+" version="3.0"/>
+  <requires lib="gtk" version="4.0"/>
   <template class="Gjs_WeatherView" parent="GtkStack">
-    <child internal-child="accessible">
-      <object class="AtkObject" id="weather-view-accessible">
-        <property name="accessible-name" translatable="yes">City view</property>
-      </object>
-    </child>
     <child>
-      <object class="GtkGrid" id="loading-grid">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="orientation">vertical</property>
-        <property name="halign">center</property>
-        <property name="valign">center</property>
-        <child>
-          <object class="GtkSpinner" id="spinner">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="height_request">128</property>
-            <property name="width_request">128</property>
-          </object>
-        </child>
-        <child>
-          <object class="GtkLabel">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="label" translatable="yes">Loading…</property>
+      <object class="GtkStackPage">
+        <property name="name">loading</property>
+        <property name="child">
+          <object class="GtkGrid" id="loading-grid">
+            <property name="can_focus">0</property>
+            <property name="orientation">vertical</property>
+            <property name="halign">center</property>
+            <property name="valign">center</property>
+            <child>
+              <object class="GtkSpinner" id="spinner">
+                <property name="can_focus">0</property>
+                <property name="height_request">128</property>
+                <property name="width_request">128</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="label" translatable="yes">Loading…</property>
+              </object>
+            </child>
           </object>
-        </child>
+        </property>
       </object>
-      <packing>
-        <property name="name">loading</property>
-      </packing>
     </child>
   </template>
 </interface>
diff --git a/data/day-entry.ui b/data/day-entry.ui
index b1c42ab..736f0bb 100644
--- a/data/day-entry.ui
+++ b/data/day-entry.ui
@@ -1,291 +1,265 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.22.0 -->
 <interface>
-  <requires lib="gtk+" version="3.20"/>
+  <requires lib="gtk" version="4.0"/>
   <object class="GtkPopoverMenu" id="more_menu">
-    <property name="can_focus">False</property>
-    <child>
+    <property name="can_focus">0</property>
+    <property name="child">
       <object class="GtkGrid">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
+        <property name="can_focus">0</property>
         <property name="row_spacing">8</property>
         <property name="column_spacing">16</property>
-        <property name="row_homogeneous">True</property>
+        <property name="row_homogeneous">1</property>
         <property name="margin_top">16</property>
         <property name="margin_bottom">16</property>
         <property name="margin_start">16</property>
         <property name="margin_end">16</property>
         <child>
           <object class="GtkLabel">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
+            <property name="can_focus">0</property>
             <property name="halign">end</property>
             <property name="label" translatable="yes">Night</property>
+            <layout>
+              <property name="column">0</property>
+              <property name="row">1</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">1</property>
-          </packing>
         </child>
         <child>
           <object class="GtkLabel">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
+            <property name="can_focus">0</property>
             <property name="halign">end</property>
             <property name="label" translatable="yes">Morning</property>
+            <layout>
+              <property name="column">0</property>
+              <property name="row">2</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">2</property>
-          </packing>
         </child>
         <child>
           <object class="GtkLabel">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
+            <property name="can_focus">0</property>
             <property name="halign">end</property>
             <property name="label" translatable="yes">Afternoon</property>
+            <layout>
+              <property name="column">0</property>
+              <property name="row">3</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">3</property>
-          </packing>
         </child>
         <child>
           <object class="GtkLabel">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
+            <property name="can_focus">0</property>
             <property name="halign">end</property>
             <property name="label" translatable="yes">Evening</property>
+            <layout>
+              <property name="column">0</property>
+              <property name="row">4</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">4</property>
-          </packing>
         </child>
         <child>
           <object class="GtkImage" id="nightImage">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
+            <property name="can_focus">0</property>
             <property name="icon_name">weather-showers-symbolic</property>
+            <layout>
+              <property name="column">1</property>
+              <property name="row">1</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">1</property>
-          </packing>
         </child>
         <child>
           <object class="GtkImage" id="morningImage">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
+            <property name="can_focus">0</property>
             <property name="icon_name">weather-showers-symbolic</property>
+            <layout>
+              <property name="column">1</property>
+              <property name="row">2</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">2</property>
-          </packing>
         </child>
         <child>
           <object class="GtkImage" id="afternoonImage">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
+            <property name="can_focus">0</property>
             <property name="icon_name">weather-showers-symbolic</property>
+            <layout>
+              <property name="column">1</property>
+              <property name="row">3</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">3</property>
-          </packing>
         </child>
         <child>
           <object class="GtkImage" id="eveningImage">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
+            <property name="can_focus">0</property>
             <property name="icon_name">weather-showers-symbolic</property>
+            <layout>
+              <property name="column">1</property>
+              <property name="row">4</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">4</property>
-          </packing>
         </child>
         <child>
           <object class="GtkGrid">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="vexpand">True</property>
+            <property name="can_focus">0</property>
+            <property name="vexpand">1</property>
             <property name="row_spacing">8</property>
-            <property name="row_homogeneous">True</property>
-            <property name="column_homogeneous">True</property>
+            <property name="row_homogeneous">1</property>
+            <property name="column_homogeneous">1</property>
             <child>
               <object class="GtkLabel" id="nightTemperatureLabel">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="label">16°</property>
+                <layout>
+                  <property name="column">0</property>
+                  <property name="row">1</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">1</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="morningTemperatureLabel">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="label">16°</property>
+                <layout>
+                  <property name="column">0</property>
+                  <property name="row">2</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">2</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="afternoonTemperatureLabel">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="label">16°</property>
+                <layout>
+                  <property name="column">0</property>
+                  <property name="row">3</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">3</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="eveningTemperatureLabel">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="label">16°</property>
+                <layout>
+                  <property name="column">0</property>
+                  <property name="row">4</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">4</property>
-              </packing>
             </child>
             <child>
               <object class="GtkImage">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="icon_name">weather-windy</property>
+                <layout>
+                  <property name="column">0</property>
+                  <property name="row">0</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkImage">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="icon_name">weather-windy</property>
+                <layout>
+                  <property name="column">1</property>
+                  <property name="row">0</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="top_attach">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkImage">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="icon_name">weather-windy</property>
+                <layout>
+                  <property name="column">2</property>
+                  <property name="row">0</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left_attach">2</property>
-                <property name="top_attach">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="nightHumidity">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="label">2.1 mm</property>
+                <layout>
+                  <property name="column">1</property>
+                  <property name="row">1</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="top_attach">1</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="morningHumidity">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="label">2.1 mm</property>
+                <layout>
+                  <property name="column">1</property>
+                  <property name="row">2</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="top_attach">2</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="afternoonHumidity">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="label">2.1 mm</property>
+                <layout>
+                  <property name="column">1</property>
+                  <property name="row">3</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="top_attach">3</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="eveningHumidity">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="label">2.1 mm</property>
+                <layout>
+                  <property name="column">1</property>
+                  <property name="row">4</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="top_attach">4</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="nightWind">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="label">5 m/s</property>
+                <layout>
+                  <property name="column">2</property>
+                  <property name="row">1</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left_attach">2</property>
-                <property name="top_attach">1</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="morningWind">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="label">5 m/s</property>
+                <layout>
+                  <property name="column">2</property>
+                  <property name="row">2</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left_attach">2</property>
-                <property name="top_attach">2</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="afternoonWind">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="label">5 m/s</property>
+                <layout>
+                  <property name="column">2</property>
+                  <property name="row">3</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left_attach">2</property>
-                <property name="top_attach">3</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="eveningWind">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="label">5 m/s</property>
+                <layout>
+                  <property name="column">2</property>
+                  <property name="row">4</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left_attach">2</property>
-                <property name="top_attach">4</property>
-              </packing>
             </child>
+            <layout>
+              <property name="column">2</property>
+              <property name="row">0</property>
+              <property name="row-span">5</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">2</property>
-            <property name="top_attach">0</property>
-            <property name="height">5</property>
-          </packing>
         </child>
         <child>
           <placeholder/>
@@ -294,71 +268,61 @@
           <placeholder/>
         </child>
       </object>
-    </child>
+    </property>
   </object>
   <template class="Gjs_DayEntry" parent="GtkBox">
     <property name="width_request">75</property>
     <property name="height_request">200</property>
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <property name="hexpand">True</property>
-    <property name="vexpand">True</property>
+    <property name="can_focus">0</property>
+    <property name="hexpand">1</property>
+    <property name="vexpand">1</property>
     <property name="orientation">vertical</property>
     <property name="spacing">8</property>
     <child>
       <object class="GtkLabel" id="nameLabel">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
+        <property name="can_focus">0</property>
         <property name="margin_top">8</property>
         <property name="label">Tues</property>
       </object>
     </child>
     <child>
       <object class="GtkLabel" id="dateLabel">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
+        <property name="can_focus">0</property>
         <property name="margin_top">8</property>
         <property name="label">7 June</property>
       </object>
     </child>
     <child>
       <object class="GtkImage" id="image">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
+        <property name="can_focus">0</property>
         <property name="valign">start</property>
-        <property name="vexpand">True</property>
+        <property name="vexpand">1</property>
         <property name="pixel_size">32</property>
         <property name="icon_name">weather-showers-symbolic</property>
       </object>
     </child>
     <child>
       <object class="GtkLabel" id="maxTemperatureLabel">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
+        <property name="can_focus">0</property>
         <property name="margin_top">8</property>
         <property name="label">18°</property>
       </object>
     </child>
     <child>
       <object class="GtkLabel" id="minTemperatureLabel">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
+        <property name="can_focus">0</property>
         <property name="margin_top">8</property>
         <property name="label">9°</property>
       </object>
     </child>
     <child>
       <object class="GtkMenuButton">
-        <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="receives_default">False</property>
         <property name="halign">center</property>
         <property name="valign">center</property>
         <property name="popover">more_menu</property>
         <child>
           <object class="GtkImage">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
+            <property name="can_focus">0</property>
             <property name="icon_name">view-more-symbolic</property>
           </object>
         </child>
diff --git a/data/places-popover.ui b/data/places-popover.ui
index 447e5e7..684a596 100644
--- a/data/places-popover.ui
+++ b/data/places-popover.ui
@@ -1,227 +1,206 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.16.1 -->
 <interface>
-  <requires lib="gtk+" version="3.0"/>
+  <requires lib="gtk" version="4.0"/>
   <object class="GtkGrid" id="popover-grid">
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
+    <property name="can_focus">0</property>
     <property name="orientation">vertical</property>
     <property name="row_spacing">10</property>
-    <property name="margin">12</property>
-    <property name="vexpand">False</property>
+    <property name="margin-start">12</property>
+    <property name="margin-end">12</property>
+    <property name="margin-top">12</property>
+    <property name="margin-bottom">12</property>
+    <property name="vexpand">0</property>
     <child>
-      <object class="GWeatherLocationEntry" id="location-entry">
+      <object class="GtkEntry" id="location-entry">
         <property name="visible">True</property>
         <property name="can_focus">True</property>
         <property name="width-request">300</property>
         <property name="activates_default">True</property>
+        <layout>
+          <property name="column">0</property>
+          <property name="row">0</property>
+        </layout>
       </object>
-      <packing>
-        <property name="left_attach">0</property>
-        <property name="top_attach">0</property>
-        <property name="width">1</property>
-        <property name="height">1</property>
-      </packing>
     </child>
     <child>
       <object class="GtkStack" id="auto-location-stack">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
-        <property name="vexpand">False</property>
-        <property name="homogeneous">False</property>
+        <property name="can-focus">0</property>
+        <property name="vexpand">0</property>
+        <property name="vhomogeneous">0</property>
+        <property name="hhomogeneous">0</property>
         <child>
-          <object class="GtkGrid" id="auto-location-grid">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="orientation">horizontal</property>
-            <property name="column_homogeneous">True</property>
-            <property name="margin_top">6</property>
-            <property name="margin_bottom">6</property>
-            <property name="vexpand">False</property>
-            <child>
-              <object class="GtkLabel" id="auto-location-label">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label" translatable="yes">Automatic Location</property>
-                <property name="halign">start</property>
-                <property name="vexpand">False</property>
-                <attributes>
-                  <attribute name="weight" value="PANGO_WEIGHT_BOLD"/>
-                </attributes>
-                <style>
-                  <class name="dim-label"/>
-                </style>
-              </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">0</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkSwitch" id="auto-location-switch">
-                <property name="visible">True</property>
-                <property name="halign">end</property>
-                <property name="vexpand">False</property>
+          <object class="GtkStackPage">
+            <property name="name">auto-location-switch-grid</property>
+            <property name="child">
+              <object class="GtkGrid" id="auto-location-grid">
+                <property name="can_focus">0</property>
+                <property name="column_homogeneous">1</property>
+                <property name="margin_top">6</property>
+                <property name="margin_bottom">6</property>
+                <property name="vexpand">0</property>
+                <child>
+                  <object class="GtkLabel" id="auto-location-label">
+                    <property name="can-focus">0</property>
+                    <property name="label" translatable="yes">Automatic Location</property>
+                    <property name="halign">start</property>
+                    <property name="vexpand">0</property>
+                    <attributes>
+                      <attribute name="weight" value="PANGO_WEIGHT_BOLD"></attribute>
+                    </attributes>
+                    <style>
+                      <class name="dim-label"/>
+                    </style>
+                    <layout>
+                      <property name="column">0</property>
+                      <property name="row">0</property>
+                    </layout>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkSwitch" id="auto-location-switch">
+                    <property name="halign">end</property>
+                    <property name="vexpand">0</property>
+                    <layout>
+                      <property name="column">1</property>
+                      <property name="row">0</property>
+                    </layout>
+                  </object>
+                </child>
               </object>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="top_attach">0</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
+            </property>
           </object>
-          <packing>
-            <property name="name">auto-location-switch-grid</property>
-          </packing>
         </child>
         <child>
-          <object class="GtkLabel" id="locating-label">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
-            <property name="label" translatable="yes">Locating…</property>
-            <property name="halign">center</property>
-            <property name="valign">center</property>
-            <property name="vexpand">False</property>
-          </object>
-          <packing>
+          <object class="GtkStackPage">
             <property name="name">locating-label</property>
-          </packing>
+            <property name="child">
+              <object class="GtkLabel" id="locating-label">
+                <property name="can-focus">0</property>
+                <property name="label" translatable="yes">Locating…</property>
+                <property name="halign">center</property>
+                <property name="valign">center</property>
+                <property name="vexpand">0</property>
+              </object>
+            </property>
+          </object>
         </child>
-        </object>
-        <packing>
-          <property name="left_attach">0</property>
-          <property name="top_attach">1</property>
-          <property name="width">1</property>
-          <property name="height">1</property>
-        </packing>
+        <layout>
+          <property name="column">0</property>
+          <property name="row">1</property>
+        </layout>
+      </object>
     </child>
     <child>
       <object class="GtkStack" id="popover-stack">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
-        <property name="vexpand">False</property>
-        <property name="homogeneous">False</property>
+        <property name="can-focus">0</property>
+        <property name="vexpand">0</property>
+        <property name="vhomogeneous">0</property>
+        <property name="hhomogeneous">0</property>
         <child>
-          <object class="GtkGrid" id="search-grid">
-            <property name="visible">True</property>
-            <property name="name">search-city-grid</property>
-            <property name="can_focus">False</property>
-            <property name="orientation">vertical</property>
-            <property name="margin_top">25</property>
-            <property name="margin_bottom">25</property>
-            <property name="halign">center</property>
-            <property name="valign">center</property>
-            <property name="row_homogeneous">True</property>
-            <property name="vexpand">False</property>
-            <child>
-              <object class="GtkImage" id="search-image">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="icon_name">edit-find-symbolic</property>
-                <property name="icon_size">6</property>
-                <property name="use_fallback">True</property>
-                <property name="halign">center</property>
-                <property name="valign">center</property>
-                <property name="vexpand">False</property>
-              </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">0</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="search-label">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label" translatable="yes">Search for a city</property>
+          <object class="GtkStackPage">
+            <property name="name">search-grid</property>
+            <property name="child">
+              <object class="GtkGrid" id="search-grid">
+                <property name="name">search-city-grid</property>
+                <property name="can_focus">0</property>
+                <property name="orientation">vertical</property>
+                <property name="margin_top">25</property>
+                <property name="margin_bottom">25</property>
                 <property name="halign">center</property>
                 <property name="valign">center</property>
-                <property name="vexpand">False</property>
-                <style>
-                  <class name="dim-label"/>
-                </style>
+                <property name="row_homogeneous">1</property>
+                <property name="vexpand">0</property>
+                <child>
+                  <object class="GtkImage" id="search-image">
+                    <property name="can_focus">0</property>
+                    <property name="icon_name">edit-find-symbolic</property>
+                    <property name="icon_size">2</property>
+                    <property name="use_fallback">1</property>
+                    <property name="halign">center</property>
+                    <property name="valign">center</property>
+                    <property name="vexpand">0</property>
+                    <layout>
+                      <property name="column">0</property>
+                      <property name="row">0</property>
+                    </layout>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="search-label">
+                    <property name="can-focus">0</property>
+                    <property name="label" translatable="yes">Search for a city</property>
+                    <property name="halign">center</property>
+                    <property name="valign">center</property>
+                    <property name="vexpand">0</property>
+                    <style>
+                      <class name="dim-label"/>
+                    </style>
+                    <layout>
+                      <property name="column">0</property>
+                      <property name="row">1</property>
+                    </layout>
+                  </object>
+                </child>
               </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">1</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
+            </property>
           </object>
-          <packing>
-            <property name="name">search-grid</property>
-          </packing>
         </child>
         <child>
-          <object class="GtkGrid" id="locations-grid">
-            <property name="visible">True</property>
+          <object class="GtkStackPage">
             <property name="name">locations-grid</property>
-            <property name="can_focus">False</property>
-            <property name="orientation">vertical</property>
-            <property name="row_spacing">10</property>
-            <property name="vexpand">False</property>
-            <child>
-              <object class="GtkLabel" id="recently-viewed-label">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label" translatable="yes">Viewed Recently</property>
-                <property name="halign">start</property>
-                <property name="vexpand">False</property>
-                <attributes>
-                  <attribute name="weight" value="PANGO_WEIGHT_BOLD"/>
-                </attributes>
-                <style>
-                  <class name="dim-label"/>
-                </style>
-              </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">0</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkFrame" id="locations-frame">
-                <property name="name">locations-frame</property>
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
+            <property name="child">
+              <object class="GtkGrid" id="locations-grid">
+                <property name="name">locations-grid</property>
+                <property name="can_focus">0</property>
+                <property name="orientation">vertical</property>
+                <property name="row_spacing">10</property>
+                <property name="vexpand">0</property>
                 <child>
-                  <object class="GtkListBox" id="locations-list-box">
-                    <property name="name">locations-list-box</property>
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="hexpand">True</property>
-                    <property name="vexpand">False</property>
-                    <property name="selection-mode">none</property>
+                  <object class="GtkLabel" id="recently-viewed-label">
+                    <property name="can-focus">0</property>
+                    <property name="label" translatable="yes">Viewed Recently</property>
+                    <property name="halign">start</property>
+                    <property name="vexpand">0</property>
+                    <attributes>
+                      <attribute name="weight" value="PANGO_WEIGHT_BOLD"></attribute>
+                    </attributes>
+                    <style>
+                      <class name="dim-label"/>
+                    </style>
+                    <layout>
+                      <property name="column">0</property>
+                      <property name="row">0</property>
+                    </layout>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkFrame" id="locations-frame">
+                    <property name="name">locations-frame</property>
+                    <property name="can-focus">0</property>
+                    <property name="child">
+                      <object class="GtkListBox" id="locations-list-box">
+                        <property name="name">locations-list-box</property>
+                        <property name="can-focus">0</property>
+                        <property name="hexpand">1</property>
+                        <property name="vexpand">0</property>
+                        <property name="selection-mode">none</property>
+                      </object>
+                    </property>
+                    <layout>
+                      <property name="column">0</property>
+                      <property name="row">1</property>
+                    </layout>
                   </object>
                 </child>
               </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">1</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
+            </property>
           </object>
-          <packing>
-            <property name="name">locations-grid</property>
-          </packing>
         </child>
+        <layout>
+          <property name="column">0</property>
+          <property name="row">2</property>
+        </layout>
       </object>
-      <packing>
-        <property name="left-attach">0</property>
-        <property name="top-attach">2</property>
-        <property name="width">1</property>
-        <property name="height">1</property>
-      </packing>
     </child>
   </object>
 </interface>
diff --git a/data/primary-menu.ui b/data/primary-menu.ui
index c6d55f0..67f0b35 100644
--- a/data/primary-menu.ui
+++ b/data/primary-menu.ui
@@ -1,4 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
 <interface>
+  <requires lib="gtk" version="4.0"/>
   <menu id="primary-menu">
     <submenu>
       <attribute translatable="yes" name="label">_Temperature Unit</attribute>
diff --git a/data/weather-widget.ui b/data/weather-widget.ui
index ba159d9..92d89b8 100644
--- a/data/weather-widget.ui
+++ b/data/weather-widget.ui
@@ -1,91 +1,74 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.22.0 -->
 <interface>
-  <requires lib="gtk+" version="3.0"/>
+  <requires lib="gtk" version="4.0"/>
   <template class="Gjs_WeatherWidget" parent="GtkFrame">
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <property name="label_xalign">0</property>
-    <child>
+    <property name="can_focus">0</property>
+    <property name="child">
       <object class="GtkFrame" id="contentFrame">
         <property name="name">weather-page-content-view</property>
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="label_xalign">0</property>
-        <property name="shadow_type">none</property>
-        <child>
+        <property name="can_focus">0</property>
+        <property name="child">
           <object class="GtkGrid" id="outerGrid">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="vexpand">True</property>
+            <property name="can_focus">0</property>
+            <property name="vexpand">1</property>
             <child>
               <object class="GtkOverlay" id="forecast-overlay">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="margin_bottom">24</property>
-                <child>
+                <property name="child">
                   <object class="GtkStack" id="forecastStack">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
+                    <property name="can_focus">0</property>
                     <child>
-                      <object class="GtkScrolledWindow" id="forecast-hourly">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="vscrollbar_policy">never</property>
-                        <property name="min_content_width">308</property>
-                        <child>
-                          <object class="GtkViewport" id="forecast-hourly-viewport">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="hscroll_policy">natural</property>
-                            <property name="vscroll_policy">natural</property>
-                          </object>
-                        </child>
-                      </object>
-                      <packing>
+                      <object class="GtkStackPage">
                         <property name="name">hourly</property>
                         <property name="title" translatable="yes">Hourly</property>
                         <property name="icon-name">preferences-system-time-symbolic</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkScrolledWindow" id="forecast-daily">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="vscrollbar_policy">never</property>
-                        <property name="min_content_width">308</property>
-                        <child>
-                          <object class="GtkViewport" id="forecast-daily-viewport">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="hscroll_policy">natural</property>
-                            <property name="vscroll_policy">natural</property>
+                        <property name="child">
+                          <object class="GtkScrolledWindow" id="forecast-hourly">
+                            <property name="vscrollbar_policy">never</property>
+                            <property name="min_content_width">308</property>
+                            <property name="child">
+                              <object class="GtkViewport" id="forecast-hourly-viewport">
+                                <property name="can_focus">0</property>
+                                <property name="hscroll_policy">natural</property>
+                                <property name="vscroll_policy">natural</property>
+                              </object>
+                            </property>
                           </object>
-                        </child>
+                        </property>
                       </object>
-                      <packing>
+                    </child>
+                    <child>
+                      <object class="GtkStackPage">
                         <property name="name">daily</property>
                         <property name="title" translatable="yes">Daily</property>
                         <property name="icon-name">x-office-calendar-symbolic</property>
-                      </packing>
+                        <property name="child">
+                          <object class="GtkScrolledWindow" id="forecast-daily">
+                            <property name="vscrollbar_policy">never</property>
+                            <property name="min_content_width">308</property>
+                            <property name="child">
+                              <object class="GtkViewport" id="forecast-daily-viewport">
+                                <property name="can_focus">0</property>
+                                <property name="hscroll_policy">natural</property>
+                                <property name="vscroll_policy">natural</property>
+                              </object>
+                            </property>
+                          </object>
+                        </property>
+                      </object>
                     </child>
                   </object>
-                  <packing>
-                    <property name="index">-1</property>
-                  </packing>
-                </child>
+                </property>
                 <child type="overlay">
                   <object class="GtkButton" id="rightButton">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
+                    <property name="receives_default">1</property>
                     <property name="halign">end</property>
                     <property name="valign">center</property>
                     <property name="margin_end">28</property>
                     <child>
                       <object class="GtkImage" id="right-image">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
+                        <property name="can_focus">0</property>
                         <property name="icon_name">go-next-symbolic</property>
                       </object>
                     </child>
@@ -97,16 +80,13 @@
                 </child>
                 <child type="overlay">
                   <object class="GtkButton" id="leftButton">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
+                    <property name="receives_default">1</property>
                     <property name="halign">start</property>
                     <property name="valign">center</property>
                     <property name="margin_start">28</property>
                     <child>
                       <object class="GtkImage" id="left-image">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
+                        <property name="can_focus">0</property>
                         <property name="icon_name">go-previous-symbolic</property>
                         <property name="icon_size">1</property>
                       </object>
@@ -116,78 +96,58 @@
                       <class name="circular"/>
                     </style>
                   </object>
-                  <packing>
-                    <property name="index">1</property>
-                  </packing>
                 </child>
+                <layout>
+                  <property name="column">0</property>
+                  <property name="row">1</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">1</property>
-              </packing>
             </child>
             <child>
               <object class="GtkGrid" id="inner-grid">
                 <property name="name">conditions-grid</property>
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="column_spacing">10</property>
                 <child>
                   <object class="GtkImage" id="conditionsImage">
                     <property name="name">conditions-image</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
+                    <property name="can_focus">0</property>
                     <property name="halign">start</property>
                     <property name="valign">center</property>
                     <style>
                       <class name="icon-dropshadow"/>
                     </style>
+                    <layout>
+                      <property name="column">0</property>
+                      <property name="row">0</property>
+                      <property name="row-span">2</property>
+                    </layout>
                   </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">0</property>
-                    <property name="height">2</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkMenuButton" id="placesButton">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="focus_on_click">False</property>
-                    <property name="receives_default">True</property>
+                    <property name="focus_on_click">0</property>
+                    <property name="receives_default">1</property>
                     <property name="halign">start</property>
                     <property name="valign">start</property>
                     <child>
                       <object class="GtkBox" id="placesBox">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
+                        <property name="can_focus">0</property>
                         <property name="spacing">12</property>
                         <child>
                           <object class="GtkLabel" id="placesLabel">
                             <property name="name">places-label</property>
-                            <property name="wrap">True</property>
+                            <property name="wrap">1</property>
                             <property name="wrap-mode">word-char</property>
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
+                            <property name="can_focus">0</property>
                             <property name="label" translatable="yes">Places</property>
                           </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">True</property>
-                            <property name="position">0</property>
-                          </packing>
                         </child>
                         <child>
                           <object class="GtkImage" id="placesImage">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
+                            <property name="can_focus">0</property>
                             <property name="icon_name">pan-down-symbolic</property>
                           </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">True</property>
-                            <property name="position">1</property>
-                          </packing>
                         </child>
                       </object>
                     </child>
@@ -195,16 +155,15 @@
                       <class name="text-button"/>
                       <class name="flat"/>
                     </style>
+                    <layout>
+                      <property name="column">1</property>
+                      <property name="row">0</property>
+                    </layout>
                   </object>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">0</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkBox" id="temperatureBox">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
+                    <property name="can_focus">0</property>
                     <property name="halign">start</property>
                     <property name="valign">start</property>
                     <property name="spacing">8</property>
@@ -212,91 +171,70 @@
                     <child>
                       <object class="GtkLabel" id="temperatureLabel">
                         <property name="name">temperature-label</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
+                        <property name="can_focus">0</property>
                         <property name="halign">start</property>
                         <property name="valign">baseline</property>
                       </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkLabel" id="apparentLabel">
                         <property name="name">apparent-label</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
+                        <property name="can_focus">0</property>
                         <property name="halign">start</property>
                         <property name="valign">baseline</property>
                       </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
                     </child>
-                  </object>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">1</property>
-                  </packing>
-                </child>
-                <child internal-child="accessible">
-                  <object class="AtkObject" id="inner-grid-atkobject">
-                    <property name="AtkObject::accessible-name" translatable="yes">Current 
conditions</property>
+                    <layout>
+                      <property name="column">1</property>
+                      <property name="row">1</property>
+                    </layout>
                   </object>
                 </child>
+                <layout>
+                  <property name="column">0</property>
+                  <property name="row">0</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkGrid">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="margin_start">18</property>
                 <property name="margin_bottom">20</property>
                 <property name="row_spacing">8</property>
                 <child>
                   <object class="GtkLabel" id="updatedTimeLabel">
                     <property name="name">updated-time-label</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
+                    <property name="can_focus">0</property>
                     <property name="halign">start</property>
+                    <layout>
+                      <property name="column">0</property>
+                      <property name="row">0</property>
+                    </layout>
                   </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">0</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkLabel" id="attributionLabel">
                     <property name="name">attribution-label</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="use_markup">True</property>
-                    <property name="wrap">True</property>
-                    <property name="track_visited_links">False</property>
+                    <property name="can_focus">0</property>
+                    <property name="use_markup">1</property>
+                    <property name="wrap">1</property>
                     <property name="xalign">0</property>
+                    <layout>
+                      <property name="column">0</property>
+                      <property name="row">1</property>
+                    </layout>
                   </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">1</property>
-                  </packing>
                 </child>
+                <layout>
+                  <property name="column">0</property>
+                  <property name="row">2</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">2</property>
-              </packing>
             </child>
           </object>
-        </child>
+        </property>
       </object>
-    </child>
+    </property>
   </template>
 </interface>
diff --git a/data/window.ui b/data/window.ui
index 24218b9..b0d1dcd 100644
--- a/data/window.ui
+++ b/data/window.ui
@@ -1,58 +1,42 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.22.0 -->
 <interface>
-  <requires lib="gtk+" version="3.10"/>
+  <requires lib="gtk" version="4.0"/>
   <object class="GtkBox" id="main-box">
-    <property name="visible">True</property>
     <property name="orientation">vertical</property>
     <child>
       <object class="HdyHeaderBar" id="header-bar">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
         <property name="vexpand">False</property>
-        <property name="show_close_button">True</property>
         <property name="centering_policy">strict</property>
         <child>
           <object class="GtkButton" id="refresh-button">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
             <property name="valign">center</property>
             <property name="action_name">win.refresh</property>
             <child>
               <object class="GtkImage" id="refresh-button-image">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="icon_name">view-refresh-symbolic</property>
                 <property name="icon_size">1</property>
               </object>
             </child>
-            <child internal-child="accessible">
-              <object class="AtkObject" id="refresh-button-atkobject">
-                <property name="AtkObject::accessible-name" translatable="yes">Refresh</property>
-              </object>
-            </child>
             <style>
               <class name="image-button"/>
             </style>
           </object>
         </child>
-       <child type="title">
-         <object class="HdyViewSwitcherTitle" id="switcher-title">
-           <property name="visible">True</property>
-           <property name="title" translatable="yes">Weather</property>
-         </object>
-       </child>
+        <child type="title">
+          <object class="HdyViewSwitcherTitle" id="switcher-title">
+            <property name="visible">True</property>
+            <property name="title" translatable="yes">Weather</property>
+          </object>
+        </child>
         <child>
           <object class="GtkMenuButton" id="primary-menu-button">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
             <property name="valign">center</property>
             <child>
               <object class="GtkImage" id="primary-menu-img">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="icon_name">open-menu-symbolic</property>
                 <property name="icon_size">1</property>
               </object>
@@ -61,103 +45,96 @@
               <class name="image-button"/>
             </style>
           </object>
-          <packing>
-            <property name="pack_type">end</property>
-          </packing>
+
         </child>
       </object>
     </child>
     <child>
       <object class="GtkGrid" id="main-panel">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
+        <property name="can_focus">0</property>
         <property name="orientation">vertical</property>
         <child>
           <object class="GtkStack" id="main-stack">
-            <property name="can_focus">False</property>
+            <property name="can_focus">0</property>
             <property name="transition_type">crossfade</property>
             <child>
               <object class="GtkGrid" id="initial-grid">
                 <property name="name">initial-grid</property>
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can_focus">0</property>
                 <property name="halign">center</property>
                 <property name="valign">center</property>
                 <property name="margin_top">25</property>
                 <property name="margin_bottom">25</property>
-                <property name="vexpand">False</property>
+                <property name="vexpand">0</property>
                 <property name="orientation">vertical</property>
-                <property name="row_homogeneous">True</property>
+                <property name="row_homogeneous">1</property>
                 <child>
                   <object class="GtkImage" id="mark-location-image">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
+                    <property name="can_focus">0</property>
                     <property name="halign">center</property>
                     <property name="valign">center</property>
-                    <property name="vexpand">False</property>
+                    <property name="vexpand">0</property>
                     <property name="icon_name">mark-location-symbolic</property>
-                    <property name="use_fallback">True</property>
-                    <property name="icon_size">6</property>
+                    <property name="use_fallback">1</property>
+                    <property name="icon_size">2</property>
+                    <layout>
+                      <property name="column">0</property>
+                      <property name="row">0</property>
+                    </layout>
                   </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">0</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkLabel" id="search-location-label">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
+                    <property name="can_focus">0</property>
                     <property name="halign">center</property>
                     <property name="valign">center</property>
-                    <property name="vexpand">False</property>
+                    <property name="vexpand">0</property>
                     <property name="label" translatable="yes">Search for a location</property>
+                    <layout>
+                      <property name="column">0</property>
+                      <property name="row">1</property>
+                    </layout>
                   </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">1</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkLabel" id="search-nereby-location-label">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
+                    <property name="can_focus">0</property>
                     <property name="halign">center</property>
                     <property name="valign">center</property>
-                    <property name="vexpand">False</property>
-                    <property name="wrap">True</property>
+                    <property name="vexpand">0</property>
+                    <property name="wrap">1</property>
                     <property name="label" translatable="yes">To see weather information, enter the name of 
a city.</property>
+                    <layout>
+                      <property name="column">0</property>
+                      <property name="row">2</property>
+                    </layout>
                   </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">2</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="GWeatherLocationEntry" id="initial-grid-location-entry">
+                  <object class="GtkEntry" id="initial-grid-location-entry">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="activates_default">True</property>
+                    <layout>
+                      <property name="column">0</property>
+                      <property name="row">3</property>
+                    </layout>
                   </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">3</property>
-                  </packing>
                 </child>
               </object>
             </child>
+            <layout>
+              <property name="column">0</property>
+              <property name="row">0</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">0</property>
-          </packing>
         </child>
       </object>
     </child>
     <child>
       <object class="HdyViewSwitcherBar" id="switcher-bar">
         <property name="visible">True</property>
-        <property name="reveal" bind-source="switcher-title" bind-property="title-visible" 
bind-flags="sync-create" />
+        <property name="reveal" bind-source="switcher-title" bind-property="title-visible" 
bind-flags="sync-create"/>
       </object>
     </child>
   </object>
diff --git a/meson.build b/meson.build
index 5601c4b..2ad1ef7 100644
--- a/meson.build
+++ b/meson.build
@@ -9,11 +9,11 @@ gnome = import('gnome')
 
 dependency('glib-2.0')
 dependency('gobject-introspection-1.0', version: '>=1.35.9')
-dependency('gtk+-3.0', version :'>=3.20')
+dependency('gtk4', version :'>=4.0')
 dependency('gjs-1.0', version: '>= 1.50.0')
 dependency('geoclue-2.0', version: '>= 0.12.99')
-dependency('gweather-3.0', version: '>= 3.28')
-dependency('libhandy-1', version: '>= 1.0.0')
+dependency('libhandy-4', version: '>= 1.1.0')
+dependency('gweather-4.0', version: '>= 40.0')
 
 # Profiles
 if get_option('profile') == 'development'
diff --git a/org.gnome.Weather.json b/org.gnome.Weather.json
index a1899fc..b878c53 100644
--- a/org.gnome.Weather.json
+++ b/org.gnome.Weather.json
@@ -57,21 +57,6 @@
                 }
             ]
         },
-        {
-            "name" : "gnome-desktop",
-            "buildsystem" : "meson",
-            "config-opts" : [
-                "-Ddebug_tools=false",
-                "-Dudev=disabled",
-                "-Ddesktop_docs=false"
-            ],
-            "sources" : [
-                {
-                    "type" : "git",
-                    "url" : "https://gitlab.gnome.org/GNOME/gnome-desktop.git";
-                }
-            ]
-        },
         {
             "name" : "libhandy",
             "buildsystem" : "meson",
diff --git a/src/app/city.js b/src/app/city.js
index 91a6996..04d6404 100644
--- a/src/app/city.js
+++ b/src/app/city.js
@@ -18,9 +18,9 @@
 
 const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;
-const Gnome = imports.gi.GnomeDesktop;
 const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
+const Gdk = imports.gi.Gdk;
 const GWeather = imports.gi.GWeather;
 
 const WorldView = imports.app.world;
@@ -47,7 +47,6 @@ var WeatherWidget = GObject.registerClass({
 
     _init(application, window, params) {
         super._init(Object.assign({
-            shadow_type: Gtk.ShadowType.NONE,
             name: 'weather-page'
         }, params));
 
@@ -69,7 +68,7 @@ var WeatherWidget = GObject.registerClass({
             }
 
             this._forecasts[t] = box;
-            this['_forecast_' + t + '_viewport'].add(box);
+            this['_forecast_' + t + '_viewport'].set_child(box);
 
             let fsw = this['_forecast_' + t];
             let hscrollbar = fsw.get_hscrollbar();
@@ -202,9 +201,11 @@ var WeatherWidget = GObject.registerClass({
 
         this._worldView.refilter();
 
-        const iconTheme = Gtk.IconTheme.get_default();
-        const icon = iconTheme.load_icon(info.get_icon_name(), 84, 0);
-        this._conditionsImage.set_from_pixbuf(icon);
+        // TODO: GTK4
+        //const iconTheme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default());
+        //const icon = iconTheme.lookup_icon(), 84, 0);
+        this._conditionsImage.set_from_icon_name(info.get_icon_name());
+        this._conditionsImage.set_icon_size(2);
 
         const [, tempValue] = info.get_value_temp(GWeather.TemperatureUnit.DEFAULT);
         this._temperatureLabel.label = '%.0f°'.format(tempValue);
@@ -291,9 +292,6 @@ var WeatherView = GObject.registerClass({
 
         this.connect('destroy', () => this._onDestroy());
 
-        this._wallClock = new Gnome.WallClock();
-        this._clockHandlerId = 0;
-
         this._desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
     }
 
diff --git a/src/app/dailyForecast.js b/src/app/dailyForecast.js
index c400782..c40ea21 100644
--- a/src/app/dailyForecast.js
+++ b/src/app/dailyForecast.js
@@ -20,7 +20,7 @@ const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;
 const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
-
+const Gdk = imports.gi.Gdk;
 const Util = imports.misc.util;
 
 var DailyForecastFrame = GObject.registerClass(class DailyForecastFrame extends Gtk.Frame {
@@ -30,15 +30,15 @@ var DailyForecastFrame = GObject.registerClass(class DailyForecastFrame extends
             halign: Gtk.Align.START,
             margin_start: 20,
             margin_end: 20,
-            shadow_type: Gtk.ShadowType.IN,
+        //    shadow_type: Gtk.ShadowType.IN,
             name: 'daily-forecast-frame',
         }, params));
 
-        this.get_accessible().accessible_name = _('Daily Forecast');
+        // this.get_accessible().accessible_name = _('Daily Forecast');
 
         this._box = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
                                   spacing: 0});
-        this.add(this._box);
+        this.set_child(this._box);
     }
 
     // get infos for the correct day
@@ -94,7 +94,7 @@ var DailyForecastFrame = GObject.registerClass(class DailyForecastFrame extends
             let label = new Gtk.Label({ label: _('Forecast not available'),
                                         use_markup: true,
                                         visible: true });
-            this._box.pack_start(label, true, false, 0);
+            this._box.prepend(label);
         }
     }
 
@@ -180,9 +180,8 @@ var DailyForecastFrame = GObject.registerClass(class DailyForecastFrame extends
         let dateFormat = _('%e %b');
         dayEntry.dateLabel.label = day.format(dateFormat);
 
-        const iconTheme = Gtk.IconTheme.get_default();
-        const icon = iconTheme.load_icon(dayInfo.get_icon_name() + '-small', 32, 0);
-        dayEntry.image.set_from_pixbuf(icon);
+        dayEntry.image.set_from_icon_name(dayInfo.get_icon_name());
+        dayEntry.image.set_icon_size(1);
 
         dayEntry.maxTemperatureLabel.label = Util.getTempString(maxInfo);
         dayEntry.minTemperatureLabel.label = Util.getTempString(minInfo);
@@ -207,17 +206,17 @@ var DailyForecastFrame = GObject.registerClass(class DailyForecastFrame extends
         dayEntry.eveningHumidity.label = eveningInfo.get_humidity();
         dayEntry.eveningWind.label = eveningInfo.get_wind();
 
-        this._box.pack_start(dayEntry, false, false, 0);
+        this._box.prepend(dayEntry);
     }
 
     _addSeparator() {
         let separator = new Gtk.Separator({ orientation: Gtk.Orientation.VERTICAL,
                                             visible: true});
-        this._box.pack_start(separator, false, false, 0);
+        this._box.prepend(separator);
     }
 
     clear() {
-        this._box.foreach(function(w) { w.destroy(); });
+  //      this._box.foreach(function(w) { w.destroy(); });
     }
 });
 
diff --git a/src/app/hourlyForecast.js b/src/app/hourlyForecast.js
index 5c3d2d5..1560f5e 100644
--- a/src/app/hourlyForecast.js
+++ b/src/app/hourlyForecast.js
@@ -22,6 +22,7 @@ const GObject = imports.gi.GObject;
 const Gdk = imports.gi.Gdk;
 const Gtk = imports.gi.Gtk;
 const GWeather = imports.gi.GWeather;
+const Graphene = imports.gi.Graphene;
 
 const Util = imports.misc.util;
 
@@ -35,17 +36,21 @@ var HourlyForecastFrame = GObject.registerClass(class ForecastFrame extends Gtk.
             halign: Gtk.Align.START,
             margin_start: 20,
             margin_end: 20,
-            shadow_type: Gtk.ShadowType.IN,
+            // TODO: GTK4
+            // Shadow types have been removed, fix up this styling.
+            // shadow_type: Gtk.ShadowType.IN,
             name: 'hourly-forecast-frame',
         }, params));
 
-        this.get_accessible().accessible_name = _('Hourly Forecast');
+        // TODO: GTK4
+        // Adapt to the new a11y APIs
+        // this.get_accessible().accessible_name = _('Hourly Forecast');
 
         this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
 
         this._box = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
                                   spacing: 0});
-        this.add(this._box);
+        this.set_child(this._box);
 
         this._hourlyInfo = [];
 
@@ -91,7 +96,7 @@ var HourlyForecastFrame = GObject.registerClass(class ForecastFrame extends Gtk.
             let label = new Gtk.Label({ label: _('Forecast not available'),
                                         use_markup: true,
                                         visible: true });
-            this._box.pack_start(label, true, false, 0);
+            this._box.prepend(label);
         }
 
         this._hourlyInfo = hourlyInfo;
@@ -113,13 +118,14 @@ var HourlyForecastFrame = GObject.registerClass(class ForecastFrame extends Gtk.
         let hourEntry = new HourEntry();
         hourEntry.timeLabel.label = datetime.format(timeFormat);
 
-        const iconTheme = Gtk.IconTheme.get_default();
-        const icon = iconTheme.load_icon(info.get_icon_name() + '-small', 32, 0);
-        hourEntry.image.set_from_pixbuf(icon);
+        hourEntry.image.set_from_icon_name(info.get_icon_name());
+        // TODO: GTK4
+        // Use the correct enum here, GTK4 only has 2 icon "sizes"
+        hourEntry.image.set_icon_size(1);
 
         hourEntry.temperatureLabel.label = Util.getTempString(info);
 
-        this._box.pack_start(hourEntry, false, false, 0);
+        this._box.prepend(hourEntry);
 
         this._hasForecastInfo = true;
     }
@@ -127,18 +133,26 @@ var HourlyForecastFrame = GObject.registerClass(class ForecastFrame extends Gtk.
     _addSeparator() {
         let separator = new Gtk.Separator({ orientation: Gtk.Orientation.VERTICAL,
                                             visible: true});
-        this._box.pack_start(separator, false, false, 0);
+        this._box.prepend(separator);
     }
 
     clear() {
-        this._box.foreach(function(w) { w.destroy(); });
+      // TODO: GTK4
+      // Figure out the best replacement for this pattern.
+      //  this._box.foreach(function(w) { w.destroy(); });
     }
 
     hasForecastInfo() {
         return this._hasForecastInfo;
     }
 
-    vfunc_draw(cr) {
+    vfunc_snapshot(snapshot) {
+        const allocation = this.get_allocation();
+        
+        const rect = new Graphene.Rect();
+        rect.init(0,0,allocation.width, allocation.height);
+        
+        let cr = snapshot.append_cairo(rect);
         const temps = this._hourlyInfo.map(info => Math.round(Util.getTemp(info)));
 
         const maxTemp = Math.max(...temps);
@@ -216,7 +230,7 @@ var HourlyForecastFrame = GObject.registerClass(class ForecastFrame extends Gtk.
         cr.lineTo(0, frameHeight);
         cr.fill();
 
-        super.vfunc_draw(cr);
+        super.vfunc_snapshot(snapshot);
         cr.$dispose();
 
         return Gdk.EVENT_PROPAGATE;
diff --git a/src/app/main.js b/src/app/main.js
index b413ca9..fd03b10 100644
--- a/src/app/main.js
+++ b/src/app/main.js
@@ -20,12 +20,13 @@ pkg.initFormat();
 pkg.initGettext();
 window.ngettext = imports.gettext.ngettext;
 
-pkg.require({ 'Gdk': '3.0',
+pkg.require({ 'Gdk': '4.0',
               'Gio': '2.0',
               'GLib': '2.0',
               'GObject': '2.0',
-              'Gtk': '3.0',
-              'GWeather': '3.0' });
+              'Gtk': '4.0',
+              'Handy': '4',
+              'GWeather': '4.0' });
 
 const ByteArray = imports.byteArray;
 const Handy = imports.gi.Handy;
@@ -90,7 +91,7 @@ const Application = GObject.registerClass(
         super.vfunc_startup();
         Handy.init();
         // ensure the type before we call to GtkBuilder
-        GWeather.LocationEntry;
+        Gtk.Entry;
 
         Util.loadStyleSheet('/org/gnome/Weather/application.css');
 
@@ -167,9 +168,9 @@ const Application = GObject.registerClass(
         });
         this.add_action(temperatureAction);
 
-        this.add_accelerator("Escape", "win.selection-mode", new GLib.Variant('b', false));
-        this.add_accelerator("<Primary>a", "win.select-all", null);
-        this.add_accelerator("<Primary>q", "app.quit", null);
+        // this.add_accelerator("Escape", "win.selection-mode", new GLib.Variant('b', false));
+        // this.add_accelerator("<Primary>a", "win.select-all", null);
+        // this.add_accelerator("<Primary>q", "app.quit", null);
     }
 
     vfunc_dbus_register(conn, path) {
@@ -193,7 +194,7 @@ const Application = GObject.registerClass(
             let timeoutId;
             let model = this.model;
 
-            timeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1000, function() {
+            timeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 10000, function() {
                 log('Timeout during model load, perhaps the network is not available?');
                 model.disconnect(notifyId);
                 win.show();
diff --git a/src/app/window.js b/src/app/window.js
index 0843091..28d3a68 100644
--- a/src/app/window.js
+++ b/src/app/window.js
@@ -38,7 +38,6 @@ var MainWindow = GObject.registerClass(
 
     _init(params) {
         super._init(params);
-
         this._world = this.application.world;
         this.currentInfo = null;
         this._currentPage = Page.SEARCH;
@@ -73,7 +72,8 @@ var MainWindow = GObject.registerClass(
 
         let grid = builder.get_object('main-panel');
         this._header = builder.get_object('header-bar');
-        this._header.set_title(_('Select Location'));
+        // TODO: GTK4
+        // this._header.set_title(_('Select Location'));
 
         this._model = this.application.model;
 
@@ -89,15 +89,15 @@ var MainWindow = GObject.registerClass(
 
         let primaryMenuModel = builder.get_object('primary-menu');
         let primaryMenuButton = builder.get_object('primary-menu-button');
-        let popover = Gtk.Popover.new_from_model(primaryMenuButton, primaryMenuModel);
+        let popover = Gtk.PopoverMenu.new_from_model(primaryMenuModel);
 
         primaryMenuButton.set_popover(popover);
 
         this._stack = builder.get_object('main-stack');
 
-        this._cityView = new City.WeatherView(this.application, this,
-                                              { hexpand: true, vexpand: true });
-        this._stack.add(this._cityView);
+        this._cityView = new City.WeatherView(this.application, this, { hexpand: true,
+                                                vexpand: true });
+        this._stack.add_child(this._cityView);
 
         this._forecastStackSwitcher = builder.get_object('switcher-title');
         this._forecastStackSwitcher.set_stack(this._cityView.getInfoPage().getForecastStack());
@@ -109,8 +109,10 @@ var MainWindow = GObject.registerClass(
 
         let box = builder.get_object('main-box');
 
-        this.add(box);
-        box.show_all();
+        this.set_child(box);
+        // TODO: GTK4
+        // Children are now shown by default, verify that everything is visible though.
+        // box.show_all();
 
         for (let i = 0; i < this._pageWidgets[Page.CITY].length; i++)
             this._pageWidgets[Page.CITY][i].hide();
@@ -135,10 +137,12 @@ var MainWindow = GObject.registerClass(
     }
 
     _setTitle(page) {
+        // TODO: GTK4
+        // We need to update all of our headerbar handling.
         if (page == Page.CITY)
-            this._header.set_custom_title(this._forecastStackSwitcher);
+            ;//this._header.set_custom_title(this._forecastStackSwitcher);
         else
-            this._header.set_custom_title(null);
+            ;//this._header.set_custom_title(null);
     }
 
     _goToPage(page) {
@@ -146,8 +150,10 @@ var MainWindow = GObject.registerClass(
             this._pageWidgets[this._currentPage][i].hide();
 
         for (let i = 0; i < this._pageWidgets[page].length; i++) {
-            let widget = this._pageWidgets[page][i];
-            if (!widget.no_show_all)
+            // TODO: GTK4
+            // I believe this property is no longer relevant
+            // let widget = this._pageWidgets[page][i];
+            // if (!widget.no_show_all)
                 this._pageWidgets[page][i].show();
         }
 
@@ -178,6 +184,7 @@ var MainWindow = GObject.registerClass(
     }
 
     showInfo(info, isCurrentLocation) {
+        log(info);
         if (!info) {
             if (isCurrentLocation && this._showingDefault)
                 this.showDefault();
@@ -237,8 +244,7 @@ var MainWindow = GObject.registerClass(
               website: 'https://wiki.gnome.org/Apps/Weather',
               wrap_license: true,
               modal: true,
-              transient_for: this,
-              use_header_bar: true
+              transient_for: this
             });
 
         // HACK: we need to poke into gtkaboutdialog internals
diff --git a/src/app/world.js b/src/app/world.js
index 8e1d5ce..09efe8a 100644
--- a/src/app/world.js
+++ b/src/app/world.js
@@ -35,13 +35,14 @@ var WorldContentView = GObject.registerClass(
             vexpand: false
         }, params));
 
-        this.get_accessible().accessible_name = _("World view");
+        // TODO: GTK4
+        //this.get_accessible().accessible_name = _("World view");
 
         let builder = new Gtk.Builder();
         builder.add_from_resource('/org/gnome/Weather/places-popover.ui');
 
         let grid = builder.get_object('popover-grid');
-        this.add(grid);
+        this.set_child(grid);
 
         this.model = application.model;
         this._window = window;
@@ -149,7 +150,8 @@ var WorldContentView = GObject.registerClass(
 
         let grid = new Gtk.Grid({ orientation: Gtk.Orientation.HORIZONTAL,
                                   column_spacing: 12,
-                                  margin: 12,
+                                  // TODO: GTK4
+                                  //  margin: 12,
                                   visible: true });
 
         let name = location.get_city_name();
@@ -172,30 +174,33 @@ var WorldContentView = GObject.registerClass(
         grid.attach(tempLabel, 1, 0, 1, 1);
 
         if (isCurrentLocation) {
-            let image = new Gtk.Image({ icon_size: Gtk.IconSize.LARGE_TOOLBAR,
+            let image = new Gtk.Image({ icon_size: Gtk.IconSize.LARGE,
                                         icon_name: 'mark-location-symbolic',
                                         use_fallback: true,
-                                        halign: Gtk.Align.START,
-                                        visible: true });
+                                        halign: Gtk.Align.START
+                                     });
             locationGrid.attach(image, 1, 0, 1, 1);
         }
 
-        let image = new Gtk.Image({ icon_size: Gtk.IconSize.LARGE_TOOLBAR,
+        let image = new Gtk.Image({ icon_size: Gtk.IconSize.LARGE,
                                     use_fallback: true,
-                                    halign: Gtk.Align.END,
-                                    visible: true });
+                                    halign: Gtk.Align.END
+                                 });
         grid.attach(image, 2, 0, 1, 1);
 
         let row = new Gtk.ListBoxRow({ visible: true });
-        row.add(grid);
+        row.set_child(grid);
         row._info = info;
         row._isCurrentLocation = isCurrentLocation;
 
         if (isCurrentLocation) {
             if (this._currentLocationAdded) {
                 let row0 = this._listbox.get_row_at_index(0);
-                if (row0)
-                    row0.destroy();
+                if (row0) {
+                    // TODO: GTK4
+                    delete row0._info;
+                    this._listbox.remove(row0);
+                }
             }
 
             this._currentLocationAdded = true;
@@ -219,13 +224,21 @@ var WorldContentView = GObject.registerClass(
     }
 
     _onLocationRemoved(model, info) {
-        let rows = this._listbox.get_children();
-
-        for (let row of rows) {
+        let i = 0;
+        let row = null;
+        // TODO: GTK4
+        // This seems like the correct way to iterate over rows now.
+        while (row = this._listbox.get_row_at_index(i)) {
             if (row._info == info) {
-                row.destroy();
+               // TODO: GTK4
+               // row.destroy();
+               delete row._info;
+               this._listbox.remove(row);
+               
                 break;
             }
+
+            i++;
         }
 
         if (info._updatedId) {
diff --git a/src/misc/util.js b/src/misc/util.js
index 7d16199..261687f 100644
--- a/src/misc/util.js
+++ b/src/misc/util.js
@@ -46,7 +46,7 @@ function loadUI(resourcePath, objects) {
 function loadStyleSheet(resource) {
     let provider = new Gtk.CssProvider();
     provider.load_from_file(Gio.File.new_for_uri('resource://' + resource));
-    Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
+    Gtk.StyleContext.add_provider_for_display(Gdk.Display.get_default(),
                                              provider,
                                              Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
 }
@@ -88,14 +88,6 @@ function getSettings(schemaId, path) {
                                   path: path });
 }
 
-function loadIcon(iconName, size) {
-    let theme = Gtk.IconTheme.get_default();
-
-    return theme.load_icon(iconName,
-                           size,
-                           Gtk.IconLookupFlags.GENERIC_FALLBACK);
-}
-
 function getWeatherConditions(info) {
     let conditions = info.get_conditions();
     if (conditions == '-') // Not significant
diff --git a/src/service/main.js b/src/service/main.js
index 113bf93..b28e3d3 100644
--- a/src/service/main.js
+++ b/src/service/main.js
@@ -21,7 +21,7 @@ pkg.initFormat();
 pkg.require({ 'Gio': '2.0',
               'GLib': '2.0',
               'GObject': '2.0',
-              'GWeather': '3.0' });
+              'GWeather': '4.0' });
 
 const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;


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