Description: Autogenerated patch header for a single-debian-patch file.
 The delta against upstream is either kept as a single patch, or maintained
 in some VCS, and exported as a single patch instead of more manageable
 atomic patches.
Forwarded: not-needed

---
--- pqmarble-1.3.0.orig/.editorconfig
+++ pqmarble-1.3.0/.editorconfig
@@ -2,13 +2,10 @@ root = true
 
 [*]
 indent_style = space
-indent_size = 4
+indent_size = 2
 charset = utf-8
 trim_trailing_whitespace = true
 insert_final_newline = true
 
-[*.{ui,build}]
-indent_size = 2
-
 [Makefile]
 indent_style = tab
--- /dev/null
+++ pqmarble-1.3.0/.gitlab-ci.yml.DISABLE
@@ -0,0 +1,16 @@
+image: 'fedora:latest'
+
+stages:
+    - build
+
+variables:
+    DEPS: gcc vala meson git gtk4-devel
+
+before_script:
+    - dnf install -y $DEPS
+
+build:
+    stage: build
+    script:
+        - meson _build --prefix=/usr
+        - ninja -C _build
--- pqmarble-1.3.0.orig/CHANGELOG.md
+++ pqmarble-1.3.0/CHANGELOG.md
@@ -1,5 +1,15 @@
 # Changelog
 
+## Release 42.alpha0 - 2022.04.07
+
+### Removed:
+
+All widgets have been removed for now.
+
+### Updated:
+
+Marble is now compiled against Gtk 4.
+
 ## Release 1.3.0 - 2020.07.06
 
 ### Removed:
--- pqmarble-1.3.0.orig/README.md
+++ pqmarble-1.3.0/README.md
@@ -1,30 +1,17 @@
 <div align="center">
-    <h1>
-        <img src="https://gitlab.com/raggesilver/marble/raw/master/resources/com.raggesilver.Marble.svg" /> Marble
-    </h1>
-    <h4>My GTK library</h4>
-    <p>
-        <a href="https://gitlab.com/raggesilver/marble/pipelines">
-            <img src="https://gitlab.com/raggesilver/marble/badges/master/pipeline.svg" alt="Build Status" />
-        </a>
-        <a href="https://www.patreon.com/raggesilver">
-            <img src="https://img.shields.io/badge/patreon-donate-orange.svg?logo=patreon" alt="Marble on Patreon" />
-        </a>
-    </p>
-    <p>
-        <a href="#install">Install</a> •
-        <a href="#features">Features</a> •
-        <a href="https://gitlab.com/raggesilver/marble/blob/master/COPYING">License</a>
-    </p>
+  <h1><img src="./resources/com.raggesilver.PQMarble.svg" height="64"/>PQMarble</h1>
+  <h4>Utility library for GNOME apps.</h4>
+  <p>
+    <a href="#install">Install</a> •
+    <a href="./CHANGELOG.md">Changelog</a> •
+    <a href="./COPYING">License</a>
+  </p>
 </div>
 
-Just as Elementary has Granite I have Marble, my collection of useful functions
-and reusable widgets.
-
 # Install
 
 ```bash
-git clone https://gitlab.com/raggesilver/marble
+git clone https://gitlab.gnome.org/raggesilver/marble
 cd marble
 meson _build --prefix=/usr
 ninja -C _build
@@ -32,31 +19,12 @@ sudo ninja -C _build install
 ```
 
 If you ever want to remove it just
+
 ```bash
 sudo ninja -C _build uninstall
 ```
 
 **Dependencies**
 
-- `meson` (>= 0.50.0) | `sudo dnf install meson` on Fedora
-
-# Features
-
-## `SideWindow`
-
-`SideWindow` is a `Gtk.ApplicationWindow` implementation that divides it's
-layout in "two" boxes, making it a pretty application window with space for a
-side menu (such as GNOME Settings, Tweaks, etc).
-
-> This is a screenshot of a test window shipped with Marble
-
-![SideWindow preview](https://imgur.com/qZGwSxk.png)
-
-# Todo
-
-- Write docs
-- Create examples
-
-# Credits
-
-Code derived from other sources is properly attributed on each file.
+- meson
+- gtk4
--- pqmarble-1.3.0.orig/build-aux/meson/postinstall.py
+++ pqmarble-1.3.0/build-aux/meson/postinstall.py
@@ -20,21 +20,3 @@ if not destdir:
 
     print('Compiling GSettings schemas...')
     call(['glib-compile-schemas', path.join(datadir, 'glib-2.0', 'schemas')])
-
-# Valac doesn't set namespace headers for whatever reason, so we do it manually
-s = "[CCode (cprefix = \"Marble\", gir_namespace = \"Marble\", gir_version = \"%s\", lower_case_cprefix = \"marble_\")]\n" % version
-
-fp = path.join(destdir + datadir, 'vala', 'vapi', 'marble.vapi')
-
-f = open(fp, 'r')
-contents = f.readlines()
-f.close()
-
-contents.insert(2, s)
-
-f = open(fp, 'w')
-contents = ''.join(contents)
-f.write(contents)
-f.close()
-
-print('Wrote marble.vapi header\n%s' % s)
--- pqmarble-1.3.0.orig/meson.build
+++ pqmarble-1.3.0/meson.build
@@ -1,5 +1,5 @@
-project('marble', ['c', 'vala'],
-          version: '1.3.0',
+project('pqmarble', ['c', 'vala'],
+          version: '2.0.0',
     meson_version: '>= 0.50.0',
   default_options: [ 'warning_level=2',
                    ],
--- pqmarble-1.3.0.orig/po/POTFILES
+++ pqmarble-1.3.0/po/POTFILES
@@ -1,6 +1,6 @@
-data/com.raggesilver.Marble.desktop.in
-data/com.raggesilver.Marble.appdata.xml.in
-data/com.raggesilver.Marble.gschema.xml
+data/com.raggesilver.PQMarble.desktop.in
+data/com.raggesilver.PQMarble.appdata.xml.in
+data/com.raggesilver.PQMarble.gschema.xml
 src/window.ui
 src/main.vala
 src/window.vala
--- pqmarble-1.3.0.orig/po/meson.build
+++ pqmarble-1.3.0/po/meson.build
@@ -1 +1 @@
-i18n.gettext('marble', preset: 'glib')
+i18n.gettext('pqmarble', preset: 'glib')
--- /dev/null
+++ pqmarble-1.3.0/resources/com.raggesilver.PQMarble.svg
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="128"
+   height="128"
+   viewBox="0 0 33.86624 33.86624"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.4 5da689c313, 2019-01-14"
+   sodipodi:docname="com.raggesilver.PQMarble.svg"
+   inkscape:export-filename="/home/pqueiroz/Projects/writer/data/icons/hicolor/scalable/apps/com.raggesilver.Writer.svg.png"
+   inkscape:export-xdpi="191.9976"
+   inkscape:export-ydpi="191.9976">
+  <defs
+     id="defs2">
+    <linearGradient
+       id="grad"
+       inkscape:collect="always">
+      <stop
+         id="stop4557"
+         offset="0"
+         style="stop-color:#da305e;stop-opacity:1" />
+      <stop
+         id="stop4559"
+         offset="1"
+         style="stop-color:#a11d40;stop-opacity:1" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#grad"
+       id="linearGradient4555"
+       gradientUnits="userSpaceOnUse"
+       x1="16.914434"
+       y1="266.12402"
+       x2="17.008928"
+       y2="295.93692" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#232323"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="5.6"
+     inkscape:cx="42.793615"
+     inkscape:cy="65.465562"
+     inkscape:document-units="px"
+     inkscape:current-layer="text4536"
+     showgrid="false"
+     units="px"
+     inkscape:window-width="1920"
+     inkscape:window-height="1016"
+     inkscape:window-x="0"
+     inkscape:window-y="27"
+     inkscape:window-maximized="1"
+     inkscape:snap-others="true"
+     scale-x="0.26458"
+     inkscape:showpageshadow="false" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-263.1333)">
+    <circle
+       id="path3718"
+       cx="16.933332"
+       cy="280.06662"
+       style="fill:#ffffff;stroke-width:0.26458332"
+       r="16.933332"
+       inkscape:export-xdpi="191.9976"
+       inkscape:export-ydpi="191.9976" />
+    <circle
+       style="fill:url(#linearGradient4555);fill-opacity:1;stroke-width:0.26458332"
+       id="path3738"
+       cx="16.933334"
+       cy="280.06662"
+       r="14.2875"
+       inkscape:export-xdpi="191.9976"
+       inkscape:export-ydpi="191.9976" />
+    <g
+       aria-label="M"
+       style="font-style:normal;font-weight:normal;font-size:21.49619293px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.53740484"
+       id="text4536">
+      <path
+         d="m 9.7642238,272.23102 h 3.1593522 l 3.999048,10.66412 4.02004,-10.66412 h 3.159353 v 15.6708 h -2.06775 v -13.7605 l -4.041032,10.7481 h -2.130726 l -4.041032,-10.7481 v 13.7605 H 9.7642238 Z"
+         style="fill:#ffffff;stroke-width:0.53740484"
+         id="path4538" />
+    </g>
+  </g>
+</svg>
--- pqmarble-1.3.0.orig/src/meson.build
+++ pqmarble-1.3.0/src/meson.build
@@ -1,75 +1,71 @@
-marble_sources = []
+pqmarble_sources = []
 
 subdir('services')
 subdir('utils')
-subdir('widgets')
+# subdir('widgets')
 
-marble_deps = [
+pqmarble_deps = [
   dependency('gio-2.0', version: '>= 2.50'),
-  dependency('gtk+-3.0', version: '>= 3.24'),
+  dependency('gtk4', version: '>= 4.6'),
 ]
 
 gnome = import('gnome')
 
-marble_sources += gnome.compile_resources('marble-resources',
-  'marble.gresource.xml',
-  c_name: 'marble'
+pqmarble_sources += gnome.compile_resources('pqmarble-resources',
+  'pqmarble.gresource.xml',
+  c_name: 'pqmarble'
 )
 
-marble_gi = 'Marble-' + meson.project_version()
-marble_gir = marble_gi + '.gir'
-marble_typelib = marble_gi + '.typelib'
-
-marble_lib = library('marble', marble_sources,
-    dependencies: marble_deps,
-
-     vala_header: 'marble.h',
-       vala_vapi: 'marble.vapi',
-        vala_gir: marble_gir,
+version_parts = meson.project_version().split('.')
+MAJOR_VERSION = version_parts[0]
+
+pqmarble_gi = 'PQMarble-' + MAJOR_VERSION
+pqmarble_gir = pqmarble_gi + '.gir'
+pqmarble_typelib = pqmarble_gi + '.typelib'
+
+pqmarble_lib = library('pqmarble', pqmarble_sources,
+    dependencies: pqmarble_deps,
+     vala_header: 'pqmarble.h',
+       vala_vapi: 'pqmarble.vapi',
+        vala_gir: pqmarble_gir,
          install: true,
      install_dir: [ true, true, true, true ],
          version: meson.project_version(),
 )
 
-install_data('marble.deps',
+install_data('pqmarble.deps',
              install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'vala', 'vapi'))
 
 g_ir_compiler = find_program('g-ir-compiler')
 
-custom_target(marble_typelib,
+custom_target(pqmarble_typelib,
   command: [
     g_ir_compiler,
-    '--shared-library', marble_lib.full_path(),
+    '--shared-library', pqmarble_lib.full_path(),
     '--output', '@OUTPUT@',
-    join_paths(meson.current_build_dir(), marble_gir)
+    join_paths(meson.current_build_dir(), pqmarble_gir)
   ],
-  output: marble_typelib,
-  depends: marble_lib,
+  output: pqmarble_typelib,
+  depends: pqmarble_lib,
   install: true,
   install_dir: get_option('libdir') / 'girepository-1.0')
 
-marble_lib_dep = declare_dependency(
-    link_with: marble_lib,
-    dependencies: marble_deps,
+pqmarble_lib_dep = declare_dependency(
+    link_with: pqmarble_lib,
+    dependencies: pqmarble_deps,
     include_directories: [include_directories('.')])
 
 pkg = import('pkgconfig')
 
 pkg.generate(
     version: meson.project_version(),
-    requires: marble_deps,
-    libraries: marble_lib,
-    description: 'Marble library',
-    name: 'marble',
-    filebase: 'marble'
+    requires: pqmarble_deps,
+    libraries: pqmarble_lib,
+    description: 'PQMarble library',
+    name: 'pqmarble',
+    filebase: 'pqmarble'
 )
 
 if get_option('tests')
-    # executable('sidewindowtest', 'tests/SideWindowTest.vala',
-    #        link_with: marble_lib,
-    #        vala_args: '--target-glib=2.50',
-    #     dependencies: marble_lib_dep,
-    #          install: true,
-    # )
-    subdir('tests')
+  # subdir('tests')
 endif
--- /dev/null
+++ pqmarble-1.3.0/src/pqmarble.deps
@@ -0,0 +1,2 @@
+gio-2.0
+gtk4
--- /dev/null
+++ pqmarble-1.3.0/src/pqmarble.gresource.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+  <gresource prefix="/com/raggesilver/PQMarble">
+    <file>resources/style.css</file>
+  </gresource>
+</gresources>
--- pqmarble-1.3.0.orig/src/resources/style.css
+++ pqmarble-1.3.0/src/resources/style.css
@@ -1,6 +1,6 @@
 /* style.css
  *
- * Copyright 2020 Paulo Queiroz <pvaqueiroz@gmail.com>
+ * Copyright 2020-2022 Paulo Queiroz <pvaqueiroz@gmail.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
--- pqmarble-1.3.0.orig/src/services/Settings.vala
+++ pqmarble-1.3.0/src/services/Settings.vala
@@ -5,7 +5,7 @@
  * which is licensed under GNU Lesser General Public version 3 of the License,
  * or (at your option) any later version.
  *
- * Copyright 2020 Paulo Queiroz <pvaqueiroz@gmail.com>
+ * Copyright 2020-2022 Paulo Queiroz <pvaqueiroz@gmail.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -23,167 +23,190 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
-public abstract class Marble.Settings : Object
-{
-    public GLib.Settings schema { get; construct set; }
-
-    private bool updating = false;
-    private bool doing_setup = true;
-
-    protected Settings(string path)
-    {
-        Object(schema: new GLib.Settings(path));
-    }
-
-    // Runs after Settings()
-    construct
-    {
-        debug("Started settings from '%s'", this.schema.schema_id);
-
-        var obj_class = (ObjectClass) this.get_type().class_ref();
-        var properties = obj_class.list_properties();
-            foreach (var prop in properties)
-                this.load_key(prop.name);
-
-        this.doing_setup = false;
-        this.schema.changed.connect(this.load_key);
-    }
-
-    private void load_key(string key)
-    {
-        if (key == "schema")
-            return;
-
-        var obj_class = (ObjectClass) this.get_type().class_ref();
-        var prop = obj_class.find_property(key);
-
-        if (prop == null)
-            return;
-
-        this.notify.disconnect(this.on_notify);
-
-        var type = prop.value_type;
-        var val = Value(type);
-        this.get_property(key, ref val);
-
-        if (val.type() == prop.value_type)
-        {
-            if (type == typeof(int))
-                this.set_property(prop.name, schema.get_int(key));
-            else if (type == typeof(uint))
-                this.set_property(prop.name, schema.get_uint(key));
-            else if (type == typeof(double))
-                this.set_property(prop.name, schema.get_double(key));
-            else if (type == typeof(bool))
-                this.set_property(prop.name, schema.get_boolean(key));
-            else if (type == typeof(string))
-                this.set_property(prop.name, schema.get_string(key));
-            else if (type == typeof(string[]))
-                this.set_property(prop.name, schema.get_strv(key));
-            else if (type == typeof(int64))
-                this.set_property(prop.name, schema.get_value(key).get_int64());
-            else if (type == typeof(uint64))
-                this.set_property(prop.name,
-                                  schema.get_value(key).get_uint64());
-            else if (type.is_enum())
-                this.set_property(prop.name, schema.get_enum(key));
-        }
-        else
-        {
-            warning("Unsuported type %s for key %s", type.to_string(), key);
-        }
-
-        this.notify.connect(this.on_notify);
-    }
-
-    private void save_key(string key)
-    {
-        if (key == "schema" || this.updating)
-            return;
-
-        var obj_class = (ObjectClass) this.get_type().class_ref();
-        var prop = obj_class.find_property(key);
-
-        if (prop == null)
-            return;
-
-        this.notify.disconnect(this.on_notify);
-
-        bool res = true;
-        this.updating = true;
-
-        var type = prop.value_type;
-        var val = Value(type);
-        this.get_property(prop.name, ref val);
-
-        if (val.type() == prop.value_type)
-        {
-            if (type == typeof(int) &&
-                val.get_int() != schema.get_int(key))
-            {
-                res = this.schema.set_int(key, val.get_int());
-            }
-            else if (type == typeof(uint) &&
-                     val.get_uint() != schema.get_uint(key))
-            {
-                res = this.schema.set_uint(key, val.get_uint());
-            }
-            else if (type == typeof(double) &&
-                     val.get_double() != schema.get_double(key))
-            {
-                res = this.schema.set_double(key, val.get_double());
-            }
-            else if (type == typeof(bool) &&
-                     val.get_boolean() != schema.get_boolean(key))
-            {
-                res = this.schema.set_boolean(key, val.get_boolean());
-            }
-            else if (type == typeof(string) &&
-                     val.get_string() != schema.get_string(key))
-            {
-                res = this.schema.set_string(key, val.get_string());
-            }
-            else if (type == typeof(string[]))
-            {
-                string[] strv = null;
-                this.get(key, &strv);
-                if (strv != this.schema.get_strv(key))
-                {
-                    res = this.schema.set_strv(key, strv);
-                }
-            }
-            else if (type == typeof(int64) &&
-                     val.get_int64() != schema.get_value(key).get_int64())
-            {
-                res = this.schema.set_value(key,
-                        new Variant.int64(val.get_int64()));
-            }
-            else if (type == typeof(uint64) &&
-                     val.get_uint64() != schema.get_value(key).get_uint64())
-            {
-                res = this.schema.set_value(key,
-                        new Variant.uint64(val.get_uint64()));
-            }
-            else if (type.is_enum() &&
-                     val.get_enum() != this.schema.get_enum(key))
-            {
-                res = this.schema.set_enum(key, val.get_enum());
-            }
-        }
-        else
-        {
-            warning("Unsuported type %s for key %s", type.to_string(), key);
-        }
-
-        if (!res)
-            warning("Could not update %s", key);
-
-        this.updating = false;
-        this.notify.connect(this.on_notify);
-    }
-
-    private void on_notify(Object sender, ParamSpec prop)
-    {
-        this.save_key(prop.name);
+public abstract class PQMarble.Settings : Object {
+  public GLib.Settings schema { get; construct set; }
+
+  private bool updating = false;
+  private bool doing_setup = true;
+
+  protected Settings (string path) {
+    Object(schema: new GLib.Settings(path));
+  }
+
+  // Runs after Settings()
+  construct {
+    debug("Started settings from '%s'", this.schema.schema_id);
+
+    var obj_class = (ObjectClass) this.get_type().class_ref();
+    var properties = obj_class.list_properties();
+
+    foreach (var prop in properties) {
+      this.load_key(prop.name);
+    }
+
+    this.doing_setup = false;
+    this.schema.changed.connect(this.load_key);
+  }
+
+  private void load_key (string key) {
+    if (key == "schema") {
+      return;
+    }
+
+    var obj_class = (ObjectClass) this.get_type().class_ref();
+    var prop = obj_class.find_property(key);
+
+    if (prop == null) {
+      return;
+    }
+
+    this.notify.disconnect(this.on_notify);
+
+    var type = prop.value_type;
+    var val = Value(type);
+    this.get_property(key, ref val);
+
+    // Unsupported type
+    if (val.type() != prop.value_type) {
+      warning("Unsupported type %s for key %s", type.to_string(), key);
+      this.notify.connect(this.on_notify);
+      return;
+    }
+
+    if (type == typeof(int)) {
+      this.set_property(prop.name, schema.get_int(key));
+    }
+    else if (type == typeof(uint)) {
+      this.set_property(prop.name, schema.get_uint(key));
+    }
+    else if (type == typeof(double)) {
+      this.set_property(prop.name, schema.get_double(key));
+    }
+    else if (type == typeof(bool)) {
+      this.set_property(prop.name, schema.get_boolean(key));
+    }
+    else if (type == typeof(string)) {
+      this.set_property(prop.name, schema.get_string(key));
+    }
+    else if (type == typeof(string[])) {
+      this.set_property(prop.name, schema.get_strv(key));
+    }
+    else if (type == typeof(int64)) {
+      this.set_property(prop.name, schema.get_value(key).get_int64());
+    }
+    else if (type == typeof(uint64)) {
+      this.set_property(
+        prop.name,
+        schema.get_value(key).get_uint64()
+      );
+    }
+    else if (type.is_enum()) {
+      this.set_property(prop.name, schema.get_enum(key));
+    }
+    else if (type == typeof(Variant)) {
+      this.set_property (prop.name, schema.get_value (key));
     }
+
+    this.notify.connect(this.on_notify);
+  }
+
+  private void save_key (string key) {
+    if (key == "schema" || this.updating) {
+      return;
+    }
+
+    var obj_class = (ObjectClass) this.get_type().class_ref();
+    var prop = obj_class.find_property(key);
+
+    if (prop == null) {
+      return;
+    }
+
+    this.notify.disconnect(this.on_notify);
+
+    bool res = true;
+    this.updating = true;
+
+    var type = prop.value_type;
+    var val = Value(type);
+    this.get_property(prop.name, ref val);
+
+    // Unsupported type
+    if (val.type() != prop.value_type) {
+      warning("Unsupported type %s for key %s", type.to_string(), key);
+    }
+
+    if (
+      type == typeof(int) && val.get_int() != schema.get_int(key)
+    ) {
+      res = this.schema.set_int(key, val.get_int());
+    }
+    else if (
+      type == typeof(uint) && val.get_uint() != schema.get_uint(key)
+    ) {
+      res = this.schema.set_uint(key, val.get_uint());
+    }
+    else if (
+      type == typeof(double) &&
+      val.get_double() != schema.get_double(key)
+    ) {
+      res = this.schema.set_double(key, val.get_double());
+    }
+    else if (
+      type == typeof(bool) &&
+      val.get_boolean() != schema.get_boolean(key)
+    ) {
+      res = this.schema.set_boolean(key, val.get_boolean());
+    }
+    else if (
+      type == typeof(string) &&
+      val.get_string() != schema.get_string(key)
+    ) {
+      res = this.schema.set_string(key, val.get_string());
+    }
+    else if (type == typeof(string[])) {
+      string[] strv = null;
+      this.get(key, &strv);
+      if (strv != this.schema.get_strv(key)) {
+        res = this.schema.set_strv(key, strv);
+      }
+    }
+    else if (
+      type == typeof(int64) &&
+      val.get_int64() != schema.get_value(key).get_int64()
+    ) {
+      res = this.schema.set_value(
+        key,
+        new Variant.int64(val.get_int64())
+      );
+    }
+    else if (
+      type == typeof(uint64) &&
+      val.get_uint64() != schema.get_value(key).get_uint64()
+    ) {
+      res = this.schema.set_value(
+        key,
+        new Variant.uint64(val.get_uint64())
+      );
+    }
+    else if (
+      type.is_enum() && val.get_enum() != this.schema.get_enum(key)
+    ) {
+      res = this.schema.set_enum(key, val.get_enum());
+    }
+    else if (type == typeof(Variant)) {
+      res = this.schema.set_value (key, val.get_variant ());
+    }
+
+    if (!res) {
+      warning("Could not update %s", key);
+    }
+
+    this.updating = false;
+    this.notify.connect(this.on_notify);
+  }
+
+  private void on_notify (Object sender, ParamSpec prop) {
+    this.save_key(prop.name);
+  }
 }
--- pqmarble-1.3.0.orig/src/services/meson.build
+++ pqmarble-1.3.0/src/services/meson.build
@@ -1,3 +1,3 @@
-marble_sources += files([
+pqmarble_sources += files([
   'Settings.vala',
 ])
--- /dev/null
+++ pqmarble-1.3.0/src/tests/pqmarbletest.gresource.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+  <gresource prefix="/com/raggesilver/PQMarble/tests">
+    <file>layouts/pqmarbletest.ui</file>
+  </gresource>
+</gresources>
--- pqmarble-1.3.0.orig/src/utils/Utils.vala
+++ pqmarble-1.3.0/src/utils/Utils.vala
@@ -18,7 +18,7 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
-namespace Marble
+namespace PQMarble
 {
     /*
      * Copyright (C) 2012-2017 Granite Developers
@@ -26,51 +26,51 @@ namespace Marble
      * Adapted from https://github.com/elementary/granite which is licensed
      * under GPL-3.0-or-later.
      */
-    public Gtk.CssProvider? get_css_provider_for_data(string data)
-    {
-        var provider = new Gtk.CssProvider();
-
-        try
-        {
-            provider.load_from_data(data, -1);
-        }
-        catch(Error e)
-        {
-            warning(e.message);
-            return (null);
-        }
+    public Gtk.CssProvider? get_css_provider_for_data(string data) {
+      var provider = new Gtk.CssProvider();
 
-        return (provider);
-    }
+#if VALA_0_58
+    provider.load_from_data (data);
+#else
+    provider.load_from_data (data.data);
+#endif
+
+    return provider;
+  }
+
+  /*
+   * Copyright (C) 2012-2017 Granite Developers
+   *
+   * Adapted from https://github.com/elementary/granite which is licensed
+   * under GPL-3.0-or-later.
+   */
+  public void set_theming_for_data (
+    Gtk.Widget widget,
+    string data,
+    string? class_name = null,
+    int priority = Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
+  ) {
+    var provider = get_css_provider_for_data(data);
 
-    /*
-     * Copyright (C) 2012-2017 Granite Developers
-     *
-     * Adapted from https://github.com/elementary/granite which is licensed
-     * under GPL-3.0-or-later.
-     */
-    public void set_theming_for_data(Gtk.Widget widget, string data,
-        string? class_name = null,
-        int priority = Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
-    {
-        var provider = get_css_provider_for_data(data);
-
-        var ctx = widget.get_style_context();
-
-        if (provider != null)
-            ctx.add_provider(provider, priority);
+    var ctx = widget.get_style_context();
 
-        if (class_name != null)
-            ctx.add_class(class_name);
+    if (provider != null) {
+      ctx.add_provider(provider, priority);
     }
 
-    public void add_css_provider_from_resource(string resource,
-        int priority = Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION,
-        Gdk.Screen screen = Gdk.Screen.get_default())
-    {
-        var provider = new Gtk.CssProvider();
-
-        provider.load_from_resource(resource);
-        Gtk.StyleContext.add_provider_for_screen(screen, provider, priority);
+    if (class_name != null) {
+      ctx.add_class(class_name);
     }
+  }
+
+  public void add_css_provider_from_resource (
+    string resource,
+    int priority = Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION,
+    Gdk.Display display = Gdk.Display.get_default()
+  ) {
+    var provider = new Gtk.CssProvider();
+
+    provider.load_from_resource(resource);
+    Gtk.StyleContext.add_provider_for_display(display, provider, priority);
+  }
 }
--- pqmarble-1.3.0.orig/src/utils/meson.build
+++ pqmarble-1.3.0/src/utils/meson.build
@@ -1,3 +1,3 @@
-marble_sources += files([
+pqmarble_sources += files([
   'Utils.vala',
 ])
--- /dev/null
+++ pqmarble-1.3.0/src/widgets-disabled/Loadable.vala
@@ -0,0 +1,67 @@
+/* Loadable.vala
+ *
+ * Copyright 2019 Paulo Queiroz <pvaqueiroz@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Loadable is a {@link Gtk.Overlay} that allows you to quickly toggle an
+ * overlayed {@link Gtk.Spinner} on top of it's content. Useful when you run
+ * async operations and need to let the user know something is being done in the
+ * background.
+ */
+public class PQMarble.Loadable : Gtk.Overlay
+{
+  /**
+   * Whether or not the widget is working. ``False`` by default.
+   */
+  public bool      loading { get; set; default = false; }
+
+  private Gtk.Spinner  spinner;
+
+  private const string DEFAULT_STYLE = """
+    .loadable > spinner {
+      background: alpha(darker(@theme_bg_color), .6);
+    }
+  """;
+
+  /**
+   * Creates a new {@link Marble.Loadable}.
+   */
+  public Loadable()
+  {
+    this.spinner = new Gtk.Spinner();
+    this.spinner.start();
+
+    this.add_overlay(this.spinner);
+    this.set_overlay_pass_through(this.spinner, false);
+
+    this.notify["loading"].connect(this.loading_changed);
+
+    this.get_style_context().add_class("loadable");
+    PQMarble.set_theming_for_data(this.spinner, DEFAULT_STYLE, null,
+      Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
+  }
+
+  private void loading_changed()
+  {
+    if (this.loading)
+      this.spinner.show();
+    else
+      this.spinner.hide();
+  }
+}
--- /dev/null
+++ pqmarble-1.3.0/src/widgets-disabled/Progressable.vala
@@ -0,0 +1,81 @@
+/* Progressable.vala
+ *
+ * Copyright 2019 Paulo Queiroz <pvaqueiroz@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Progressable is a {@link Gtk.Overlay} that allows you to quickly toggle an
+ * overlayed {@link Gtk.ProgressBar} on top of it's content. Useful when you run
+ * async operations and need to let the user know something is being done in the
+ * background.
+ */
+public class Marble.Progressable : Gtk.Overlay
+{
+  /**
+   * Whether or not the widget is working. ``False`` by default.
+   */
+  public bool      loading    { get; set; default = false; }
+
+  public Gtk.ProgressBar progress_bar { get; construct set; }
+
+  private const string   DEFAULT_STYLE = """
+    .loadable > progressbar {
+      background: alpha(darker(@theme_bg_color), .6);
+    }
+  """;
+
+  /**
+   * Creates a new {@link Marble.Progressable}.
+   */
+  public Progressable()
+  {
+    this.progress_bar = new Gtk.ProgressBar();
+    this.progress_bar.set_pulse_step(0.5);
+
+    this.add_overlay(this.progress_bar);
+    this.set_overlay_pass_through(this.progress_bar, false);
+
+    this.notify["loading"].connect(this.loading_changed);
+
+    this.get_style_context().add_class("loadable");
+    Marble.set_theming_for_data(this.progress_bar, DEFAULT_STYLE, null,
+      Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
+  }
+
+  private void loading_changed()
+  {
+    if (this.loading)
+      this.progress_bar.show();
+    else
+      this.progress_bar.hide();
+  }
+
+  /**
+   * Make ``this.progress_bar`` start pulsating in an infinite loop.
+   *
+   * @return always return false
+   */
+  public bool pulse()
+  {
+    this.progress_bar.pulse();
+
+    Timeout.add(1500, () => { return (this.pulse()); });
+
+    return (false);
+  }
+}
--- /dev/null
+++ pqmarble-1.3.0/src/widgets-disabled/meson.build
@@ -0,0 +1,4 @@
+pqmarble_sources += files([
+  'Loadable.vala',
+  'Progressable.vala',
+])
