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: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1919>
This commit is contained in:
Ian Douglas Scott 2021-07-16 09:21:22 -07:00
parent 81a1e294f8
commit 51a8bbddd5

View File

@ -42,22 +42,38 @@ const GeoclueManager = Gio.DBusProxy.makeProxyWrapper(GeoclueIface);
var AgentIface = loadInterfaceXML('org.freedesktop.GeoClue2.Agent'); var AgentIface = loadInterfaceXML('org.freedesktop.GeoClue2.Agent');
var Indicator = GObject.registerClass( var Indicator = GObject.registerClass({
class Indicator extends PanelMenu.SystemIndicator { 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() { _init() {
super._init(); super._init();
this._settings = new Gio.Settings({ schema_id: LOCATION_SCHEMA }); this._settings = new Gio.Settings({ schema_id: LOCATION_SCHEMA });
this._settings.connect('changed::%s'.format(ENABLED), this._settings.connect('changed::%s'.format(ENABLED),
this._onMaxAccuracyLevelChanged.bind(this)); () => this.notify('enabled'));
this._settings.connect('changed::%s'.format(MAX_ACCURACY_LEVEL), this._settings.connect('changed::%s'.format(MAX_ACCURACY_LEVEL),
this._onMaxAccuracyLevelChanged.bind(this)); this._onMaxAccuracyLevelChanged.bind(this));
this._indicator = this._addIndicator(); this._indicator = this._addIndicator();
this._indicator.icon_name = 'find-location-symbolic'; 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 = new PopupMenu.PopupSubMenuMenuItem('', true);
this._item.icon.icon_name = 'find-location-symbolic'; 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 = Gio.DBusExportedObject.wrapJSObject(AgentIface, this);
this._agent.export(Gio.DBus.system, '/org/freedesktop/GeoClue2/Agent'); 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.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, this._watchId = Gio.bus_watch_name(Gio.BusType.SYSTEM,
'org.freedesktop.GeoClue2', 'org.freedesktop.GeoClue2',
0, 0,
@ -80,17 +100,34 @@ class Indicator extends PanelMenu.SystemIndicator {
this._connectToPermissionStore(); this._connectToPermissionStore();
} }
get MaxAccuracyLevel() { get enabled() {
return this._getMaxAccuracyLevel(); 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) { AuthorizeAppAsync(params, invocation) {
let [desktopId, reqAccuracyLevel] = params; let [desktopId, reqAccuracyLevel] = params;
let authorizer = new AppAuthorizer(desktopId, let authorizer = new AppAuthorizer(desktopId,
reqAccuracyLevel, reqAccuracyLevel, this._permStoreProxy, this.maxAccuracyLevel);
this._permStoreProxy,
this._getMaxAccuracyLevel());
authorizer.authorize(accuracyLevel => { authorizer.authorize(accuracyLevel => {
let ret = accuracyLevel != GeoclueAccuracyLevel.NONE; let ret = accuracyLevel != GeoclueAccuracyLevel.NONE;
@ -99,16 +136,8 @@ class Indicator extends PanelMenu.SystemIndicator {
}); });
} }
_syncIndicator() { get MaxAccuracyLevel() {
if (this._managerProxy == null) { return this.maxAccuracyLevel;
this._indicator.visible = false;
this._item.visible = false;
return;
}
this._indicator.visible = this._managerProxy.InUse;
this._item.visible = this._indicator.visible;
this._updateMenuLabels();
} }
_connectToGeoclue() { _connectToGeoclue() {
@ -134,7 +163,7 @@ class Indicator extends PanelMenu.SystemIndicator {
this._propertiesChangedId = this._managerProxy.connect('g-properties-changed', this._propertiesChangedId = this._managerProxy.connect('g-properties-changed',
this._onGeocluePropsChanged.bind(this)); this._onGeocluePropsChanged.bind(this));
this._syncIndicator(); this.notify('in-use');
this._managerProxy.AddAgentRemote('gnome-shell', this._onAgentRegistered.bind(this)); this._managerProxy.AddAgentRemote('gnome-shell', this._onAgentRegistered.bind(this));
} }
@ -154,12 +183,11 @@ class Indicator extends PanelMenu.SystemIndicator {
} }
this._managerProxy = null; this._managerProxy = null;
this._syncIndicator(); this.notify('in-use');
} }
_onOnOffAction() { _onOnOffAction() {
let enabled = this._settings.get_boolean(ENABLED); this.enabled = !this.enabled;
this._settings.set_boolean(ENABLED, !enabled);
} }
_onSessionUpdated() { _onSessionUpdated() {
@ -168,7 +196,7 @@ class Indicator extends PanelMenu.SystemIndicator {
} }
_updateMenuLabels() { _updateMenuLabels() {
if (this._settings.get_boolean(ENABLED)) { if (this.enabled) {
this._item.label.text = this._indicator.visible this._item.label.text = this._indicator.visible
? _("Location In Use") ? _("Location In Use")
: _("Location Enabled"); : _("Location Enabled");
@ -180,7 +208,7 @@ class Indicator extends PanelMenu.SystemIndicator {
} }
_onMaxAccuracyLevelChanged() { _onMaxAccuracyLevelChanged() {
this._updateMenuLabels(); this.notify('max-accuracy-level');
// Gotta ensure geoclue is up and we are registered as agent to it // Gotta ensure geoclue is up and we are registered as agent to it
// before we emit the notify for this property change. // before we emit the notify for this property change.
@ -188,26 +216,15 @@ class Indicator extends PanelMenu.SystemIndicator {
this._notifyMaxAccuracyLevel(); 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() { _notifyMaxAccuracyLevel() {
let variant = new GLib.Variant('u', this._getMaxAccuracyLevel()); let variant = new GLib.Variant('u', this.maxAccuracyLevel);
this._agent.emit_property_changed('MaxAccuracyLevel', variant); this._agent.emit_property_changed('MaxAccuracyLevel', variant);
} }
_onGeocluePropsChanged(proxy, properties) { _onGeocluePropsChanged(proxy, properties) {
let unpacked = properties.deep_unpack(); let unpacked = properties.deep_unpack();
if ("InUse" in unpacked) if ("InUse" in unpacked)
this._syncIndicator(); this.notify('in-use');
} }
_connectToPermissionStore() { _connectToPermissionStore() {