diff --git a/installed-tests/js/testGio.js b/installed-tests/js/testGio.js
index 7feeb79..43cf596 100644
--- a/installed-tests/js/testGio.js
+++ b/installed-tests/js/testGio.js
@@ -24,4 +24,25 @@ describe('ListStore iterator', function () {
             expect(f.value).toBe(i++);
         }
     });
-});
\ No newline at end of file
+});
+
+describe('Settings connect', function () {
+    let latestValue = 0;
+    const settings = new Gio.Settings({ schema_id: 'org.gnome.shell' });
+    settings.connect('changed::development-tools', function () {
+        const newValue = settings.get_boolean('development-tools');
+        expect(newValue).not.toBeEqual(latestValue);
+        latestValue = newValue;
+    });
+    latestValue = true;  // Default value
+    settings.set_boolean('development-tools', true);
+    settings.set_boolean('development-tools', true);
+    settings.set_boolean('development-tools', false);
+    settings.set_boolean('development-tools', true);
+    settings.set_boolean('development-tools', true);
+    settings.set_boolean('development-tools', true);
+    settings.set_boolean('development-tools', false);
+    settings.set_boolean('development-tools', false);
+    settings.set_boolean('development-tools', false);
+    settings.set_boolean('development-tools', true);
+});
diff --git a/modules/overrides/Gio.js b/modules/overrides/Gio.js
index aa04712..bdfa01c 100644
--- a/modules/overrides/Gio.js
+++ b/modules/overrides/Gio.js
@@ -23,6 +23,7 @@ var GObject = imports.gi.GObject;
 var GjsPrivate = imports.gi.GjsPrivate;
 var Lang = imports.lang;
 var Signals = imports.signals;
+const System = imports.system;
 var Gio;
 
 function _signatureLength(sig) {
@@ -348,9 +349,64 @@ function* _listModelIterator() {
     }
 }
 
+const _SettingsListener = new Lang.Class({
+    Name: 'SettingsListener',
+    _init: function(settings) {
+        const self = this;
+        const values = {};
+        settings.settingsSchema.list_keys().map(function(key) {
+
+            // Listen for changes in the value
+            settings.connect('changed::' + key, function() {
+                const newValue = settings.get_value(key);
+
+                global.log('Gio.Settings: received "changed" event for ' +
+                    settings.schemaId + ':' + key + ':' + newValue.print(true));
+
+                newValue.hash();  // This is here just to make the spurious events more reproduceable.
+
+                if (!newValue.equal(values[key])) {
+                    values[key] = newValue;
+                    self.emit('changed');
+                    self.emit('changed::' + key);
+                } else {
+                    // If the value has not changed, why is the "changed" event sometimes emitted?
+                    global.log('Gio.Settings: rejecting spurious "changed" event for ' +
+                        settings.schemaId + ':' + key + ':' + newValue.print(true));
+                    System.breakpoint();
+                }
+            });
+
+            // Fetch the value initially (also necessary for the listener to work)
+            values[key] = settings.get_value(key);
+            global.log('Registered a setting of type "' + values[key].get_type_string() +
+                '" with value ' + values[key].print(true));
+
+            values[key].hash();  // This is here just to make the spurious events more reproduceable.
+        });
+    },
+});
+Signals.addSignalMethods(_SettingsListener.prototype);
+
+
 function _init() {
     Gio = this;
 
+    Gio.Settings = new Proxy(Gio.Settings, {
+        construct: function (_GioSettings, argumentsList, newTarget) {
+            const settings = new _GioSettings(...argumentsList);
+            // const schemaId? = argumentsList[0];
+            const listener = new _SettingsListener(settings);
+            const signalMethods = ['connect', 'disconnect', 'emit', 'disconnectAll'];
+            for (let method of signalMethods) {
+                // Proxy signal methods to the _SettingsListener which in turn wraps the
+                // underlying Gio.Settings object
+                settings[method] = listener[method];
+            }
+            return settings;
+        },
+    });
+
     Gio.DBus = {
         get session() {
             return Gio.bus_get_sync(Gio.BusType.SESSION, null);
