[gnome-shell] dateMenu: Stop accessing app settings directly



commit 3114a24d1fc495d04e8999a4f72d84dfed2b10d1
Author: Florian Müllner <fmuellner gnome org>
Date:   Thu Aug 1 01:24:13 2019 +0200

    dateMenu: Stop accessing app settings directly
    
    Clocks has exactly the same issue as Weather: Its integration currently
    relies on accessing its settings directly, which isn't possible when
    the app is sandboxed.
    
    Fix this the same way we did for Weather, by adding our own setting
    and syncing it with the app via a custom D-Bus interface.
    
    https://gitlab.gnome.org/GNOME/gnome-shell/issues/1158

 .../org.gnome.Shell.ClocksIntegration.xml          | 15 +++++
 data/gnome-shell-dbus-interfaces.gresource.xml     |  1 +
 data/org.gnome.shell.gschema.xml.in                | 11 ++++
 js/ui/dateMenu.js                                  | 64 +++++++++++++++++-----
 4 files changed, 77 insertions(+), 14 deletions(-)
---
diff --git a/data/dbus-interfaces/org.gnome.Shell.ClocksIntegration.xml 
b/data/dbus-interfaces/org.gnome.Shell.ClocksIntegration.xml
new file mode 100644
index 0000000000..0cbb132c16
--- /dev/null
+++ b/data/dbus-interfaces/org.gnome.Shell.ClocksIntegration.xml
@@ -0,0 +1,15 @@
+<node>
+
+  <!--
+      org.gnome.Shell.ClocksIntegration:
+      @short_description: Clocks integration interface
+
+      The interface used for exporting location settings to GNOME Shell's
+      world clocks integration.
+  -->
+  <interface name="org.gnome.Shell.ClocksIntegration">
+
+  <property name="Locations" type="av" access="read"/>
+
+  </interface>
+</node>
diff --git a/data/gnome-shell-dbus-interfaces.gresource.xml b/data/gnome-shell-dbus-interfaces.gresource.xml
index 21fdfa9496..db3ef4ac22 100644
--- a/data/gnome-shell-dbus-interfaces.gresource.xml
+++ b/data/gnome-shell-dbus-interfaces.gresource.xml
@@ -40,6 +40,7 @@
     <file preprocess="xml-stripblanks">org.gnome.SettingsDaemon.Wacom.xml</file>
     <file preprocess="xml-stripblanks">org.gnome.Shell.AudioDeviceSelection.xml</file>
     <file preprocess="xml-stripblanks">org.gnome.Shell.CalendarServer.xml</file>
+    <file preprocess="xml-stripblanks">org.gnome.Shell.ClocksIntegration.xml</file>
     <file preprocess="xml-stripblanks">org.gnome.Shell.Extensions.xml</file>
     <file preprocess="xml-stripblanks">org.gnome.Shell.Introspect.xml</file>
     <file preprocess="xml-stripblanks">org.gnome.Shell.HotplugSniffer.xml</file>
diff --git a/data/org.gnome.shell.gschema.xml.in b/data/org.gnome.shell.gschema.xml.in
index d5f3271831..99221a7dd2 100644
--- a/data/org.gnome.shell.gschema.xml.in
+++ b/data/org.gnome.shell.gschema.xml.in
@@ -228,6 +228,17 @@
     </key>
   </schema>
 
+  <schema id="org.gnome.shell.world-clocks" path="/org/gnome/shell/world-clocks/"
+          gettext-domain="@GETTEXT_PACKAGE@">
+    <key name="locations" type="av">
+      <summary>Locations</summary>
+      <description>
+        The locations to show in world clocks
+      </description>
+      <default>[]</default>
+    </key>
+  </schema>
+
   <schema id="org.gnome.shell.weather" path="/org/gnome/shell/weather/"
           gettext-domain="@GETTEXT_PACKAGE@">
     <key name="automatic-location" type="b">
diff --git a/js/ui/dateMenu.js b/js/ui/dateMenu.js
index ab137edf43..c78b39c6b3 100644
--- a/js/ui/dateMenu.js
+++ b/js/ui/dateMenu.js
@@ -1,7 +1,7 @@
 // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 /* exported DateMenuButton */
 
-const { Clutter, GLib, GnomeDesktop,
+const { Clutter, Gio, GLib, GnomeDesktop,
         GObject, GWeather, Shell, St } = imports.gi;
 
 const Util = imports.misc.util;
@@ -11,8 +11,13 @@ const Calendar = imports.ui.calendar;
 const Weather = imports.misc.weather;
 const System = imports.system;
 
+const { loadInterfaceXML } = imports.misc.fileUtils;
+
 const MAX_FORECASTS = 5;
 
+const ClocksIntegrationIface = loadInterfaceXML('org.gnome.Shell.ClocksIntegration');
+const ClocksProxy = Gio.DBusProxy.makeProxyWrapper(ClocksIntegrationIface);
+
 function _isToday(date) {
     let now = new Date();
     return now.getYear() == date.getYear() &&
@@ -83,7 +88,8 @@ var WorldClocksSection = class WorldClocksSection {
                                      x_fill: true,
                                      can_focus: true });
         this.actor.connect('clicked', () => {
-            this._clockAppMon.activateApp();
+            if (this._clocksApp)
+                this._clocksApp.activate();
 
             Main.overview.hide();
             Main.panel.closeCalendar();
@@ -96,29 +102,40 @@ var WorldClocksSection = class WorldClocksSection {
 
         this.actor.child = this._grid;
 
-        this._clockAppMon = new Util.AppSettingsMonitor('org.gnome.clocks.desktop',
-                                                        'org.gnome.clocks');
-        this._clockAppMon.connect('available-changed',
-                                  this._sync.bind(this));
-        this._clockAppMon.watchSetting('world-clocks',
-                                       this._clocksChanged.bind(this));
+        this._clocksApp = null;
+        this._clocksProxy = new ClocksProxy(
+            Gio.DBus.session,
+            'org.gnome.clocks',
+            '/org/gnome/clocks',
+            this._onProxyReady.bind(this),
+            null /* cancellable */,
+            Gio.DBusProxyFlags.DO_NOT_AUTO_START | Gio.DBusProxyFlags.GET_INVALIDATED_PROPERTIES);
+
+        this._settings = new Gio.Settings({
+            schema_id: 'org.gnome.shell.world-clocks'
+        });
+        this._settings.connect('changed', this._clocksChanged.bind(this));
+        this._clocksChanged();
+
+        this._appSystem = Shell.AppSystem.get_default();
+        this._appSystem.connect('installed-changed',
+            this._sync.bind(this));
         this._sync();
     }
 
     _sync() {
-        this.actor.visible = this._clockAppMon.available;
+        this._clocksApp = this._appSystem.lookup_app('org.gnome.clocks.desktop');
+        this.actor.visible = this._clocksApp != null;
     }
 
-    _clocksChanged(settings) {
+    _clocksChanged() {
         this._grid.destroy_all_children();
         this._locations = [];
 
         let world = GWeather.Location.get_world();
-        let clocks = settings.get_value('world-clocks').deep_unpack();
+        let clocks = this._settings.get_value('locations').deep_unpack();
         for (let i = 0; i < clocks.length; i++) {
-            if (!clocks[i].location)
-                continue;
-            let l = world.deserialize(clocks[i].location);
+            let l = world.deserialize(clocks[i]);
             if (l && l.get_timezone() != null)
                 this._locations.push({ location: l });
         }
@@ -197,6 +214,25 @@ var WorldClocksSection = class WorldClocksSection {
             l.actor.text = Util.formatTime(now, { timeOnly: true });
         }
     }
+
+    _onProxyReady(proxy, error) {
+        if (error) {
+            log(`Failed to create GNOME Clocks proxy: ${error}`);
+            return;
+        }
+
+        this._clocksProxy.connect('g-properties-changed',
+            this._onClocksPropertiesChanged.bind(this));
+        this._onClocksPropertiesChanged();
+    }
+
+    _onClocksPropertiesChanged() {
+        if (this._clocksProxy.g_name_owner == null)
+            return;
+
+        this._settings.set_value('locations',
+            new GLib.Variant('av', this._clocksProxy.Locations));
+    }
 };
 
 var WeatherSection = class WeatherSection {


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