From 51a8bbddd569bf7782d70e01e8a21474873594f3 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Fri, 16 Jul 2021 09:21:22 -0700 Subject: [PATCH] location: Add GObject properties to `Location.Indicator` Makes `enabled`, `in-use`, and `max-accuracy-level` GObject properties that can be used for property binding, etc. Part-of: --- js/ui/status/location.js | 93 ++++++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 38 deletions(-) diff --git a/js/ui/status/location.js b/js/ui/status/location.js index 4250ed0fe..d0478b19c 100644 --- a/js/ui/status/location.js +++ b/js/ui/status/location.js @@ -42,22 +42,38 @@ const GeoclueManager = Gio.DBusProxy.makeProxyWrapper(GeoclueIface); var AgentIface = loadInterfaceXML('org.freedesktop.GeoClue2.Agent'); -var Indicator = GObject.registerClass( -class Indicator extends PanelMenu.SystemIndicator { +var Indicator = GObject.registerClass({ + Properties: { + 'enabled': GObject.ParamSpec.boolean( + 'enabled', 'Enabled', 'Enabled', + GObject.ParamFlags.READWRITE, + false), + 'in-use': GObject.ParamSpec.boolean( + 'in-use', 'In use', 'In use', + GObject.ParamFlags.READABLE, + false), + 'max-accuracy-level': GObject.ParamSpec.int( + 'max-accuracy-level', 'Max accuracy level', 'Max accuracy level', + GObject.ParamFlags.READABLE, + 0, 8, 0), + }, +}, class Indicator extends PanelMenu.SystemIndicator { _init() { super._init(); this._settings = new Gio.Settings({ schema_id: LOCATION_SCHEMA }); this._settings.connect('changed::%s'.format(ENABLED), - this._onMaxAccuracyLevelChanged.bind(this)); + () => this.notify('enabled')); this._settings.connect('changed::%s'.format(MAX_ACCURACY_LEVEL), - this._onMaxAccuracyLevelChanged.bind(this)); + this._onMaxAccuracyLevelChanged.bind(this)); this._indicator = this._addIndicator(); this._indicator.icon_name = 'find-location-symbolic'; + this.bind_property('in-use', this._indicator, 'visible', GObject.BindingFlags.SYNC_CREATE); this._item = new PopupMenu.PopupSubMenuMenuItem('', true); this._item.icon.icon_name = 'find-location-symbolic'; + this.bind_property('in-use', this._item, 'visible', GObject.BindingFlags.SYNC_CREATE); this._agent = Gio.DBusExportedObject.wrapJSObject(AgentIface, this); this._agent.export(Gio.DBus.system, '/org/freedesktop/GeoClue2/Agent'); @@ -68,6 +84,10 @@ class Indicator extends PanelMenu.SystemIndicator { this.menu.addMenuItem(this._item); + this.connect('notify::enabled', this._onMaxAccuracyLevelChanged.bind(this)); + this.connect('notify::in-use', this._updateMenuLabels.bind(this)); + this.connect('notify::max-accuracy-level', this._updateMenuLabels.bind(this)); + this._watchId = Gio.bus_watch_name(Gio.BusType.SYSTEM, 'org.freedesktop.GeoClue2', 0, @@ -80,17 +100,34 @@ class Indicator extends PanelMenu.SystemIndicator { this._connectToPermissionStore(); } - get MaxAccuracyLevel() { - return this._getMaxAccuracyLevel(); + get enabled() { + return this._settings.get_boolean(ENABLED); + } + + set enabled(value) { + this._settings.set_boolean(ENABLED, value); + } + + get inUse() { + return this._managerProxy?.InUse ?? false; + } + + get maxAccuracyLevel() { + if (this.enabled) { + let level = this._settings.get_string(MAX_ACCURACY_LEVEL); + + return GeoclueAccuracyLevel[level.toUpperCase()] || + GeoclueAccuracyLevel.NONE; + } else { + return GeoclueAccuracyLevel.NONE; + } } AuthorizeAppAsync(params, invocation) { let [desktopId, reqAccuracyLevel] = params; let authorizer = new AppAuthorizer(desktopId, - reqAccuracyLevel, - this._permStoreProxy, - this._getMaxAccuracyLevel()); + reqAccuracyLevel, this._permStoreProxy, this.maxAccuracyLevel); authorizer.authorize(accuracyLevel => { let ret = accuracyLevel != GeoclueAccuracyLevel.NONE; @@ -99,16 +136,8 @@ class Indicator extends PanelMenu.SystemIndicator { }); } - _syncIndicator() { - if (this._managerProxy == null) { - this._indicator.visible = false; - this._item.visible = false; - return; - } - - this._indicator.visible = this._managerProxy.InUse; - this._item.visible = this._indicator.visible; - this._updateMenuLabels(); + get MaxAccuracyLevel() { + return this.maxAccuracyLevel; } _connectToGeoclue() { @@ -134,7 +163,7 @@ class Indicator extends PanelMenu.SystemIndicator { this._propertiesChangedId = this._managerProxy.connect('g-properties-changed', this._onGeocluePropsChanged.bind(this)); - this._syncIndicator(); + this.notify('in-use'); this._managerProxy.AddAgentRemote('gnome-shell', this._onAgentRegistered.bind(this)); } @@ -154,12 +183,11 @@ class Indicator extends PanelMenu.SystemIndicator { } this._managerProxy = null; - this._syncIndicator(); + this.notify('in-use'); } _onOnOffAction() { - let enabled = this._settings.get_boolean(ENABLED); - this._settings.set_boolean(ENABLED, !enabled); + this.enabled = !this.enabled; } _onSessionUpdated() { @@ -168,7 +196,7 @@ class Indicator extends PanelMenu.SystemIndicator { } _updateMenuLabels() { - if (this._settings.get_boolean(ENABLED)) { + if (this.enabled) { this._item.label.text = this._indicator.visible ? _("Location In Use") : _("Location Enabled"); @@ -180,7 +208,7 @@ class Indicator extends PanelMenu.SystemIndicator { } _onMaxAccuracyLevelChanged() { - this._updateMenuLabels(); + this.notify('max-accuracy-level'); // Gotta ensure geoclue is up and we are registered as agent to it // before we emit the notify for this property change. @@ -188,26 +216,15 @@ class Indicator extends PanelMenu.SystemIndicator { this._notifyMaxAccuracyLevel(); } - _getMaxAccuracyLevel() { - if (this._settings.get_boolean(ENABLED)) { - let level = this._settings.get_string(MAX_ACCURACY_LEVEL); - - return GeoclueAccuracyLevel[level.toUpperCase()] || - GeoclueAccuracyLevel.NONE; - } else { - return GeoclueAccuracyLevel.NONE; - } - } - _notifyMaxAccuracyLevel() { - let variant = new GLib.Variant('u', this._getMaxAccuracyLevel()); + let variant = new GLib.Variant('u', this.maxAccuracyLevel); this._agent.emit_property_changed('MaxAccuracyLevel', variant); } _onGeocluePropsChanged(proxy, properties) { let unpacked = properties.deep_unpack(); if ("InUse" in unpacked) - this._syncIndicator(); + this.notify('in-use'); } _connectToPermissionStore() {