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 000000000..0cbb132c1 --- /dev/null +++ b/data/dbus-interfaces/org.gnome.Shell.ClocksIntegration.xml @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/data/gnome-shell-dbus-interfaces.gresource.xml b/data/gnome-shell-dbus-interfaces.gresource.xml index 21fdfa949..db3ef4ac2 100644 --- a/data/gnome-shell-dbus-interfaces.gresource.xml +++ b/data/gnome-shell-dbus-interfaces.gresource.xml @@ -40,6 +40,7 @@ org.gnome.SettingsDaemon.Wacom.xml org.gnome.Shell.AudioDeviceSelection.xml org.gnome.Shell.CalendarServer.xml + org.gnome.Shell.ClocksIntegration.xml org.gnome.Shell.Extensions.xml org.gnome.Shell.Introspect.xml org.gnome.Shell.HotplugSniffer.xml diff --git a/data/org.gnome.shell.gschema.xml.in b/data/org.gnome.shell.gschema.xml.in index d5f327183..99221a7dd 100644 --- a/data/org.gnome.shell.gschema.xml.in +++ b/data/org.gnome.shell.gschema.xml.in @@ -228,6 +228,17 @@ + + + Locations + + The locations to show in world clocks + + [] + + + diff --git a/js/ui/dateMenu.js b/js/ui/dateMenu.js index ab137edf4..c78b39c6b 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 {