status/bluetooth: Show immediate feedback on toggle
Since commit 6a23e8ee0f
, we use the adapter state (that includes
transitional state) to indicate progress when a state change takes
a long time.
However on many systems, the delay happens on the rfkill side,
before a change request even reaches the adapter.
Address this by temporarily overriding the adapter-state with the
expected transitional state, until an actual adapter state change
occurs.
https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5773
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2815>
This commit is contained in:
parent
8c57eab5e6
commit
56103edc0e
@ -24,6 +24,8 @@ const rfkillManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(RfkillManagerInterfa
|
||||
|
||||
Gio._promisify(GnomeBluetooth.Client.prototype, 'connect_service');
|
||||
|
||||
const STATE_CHANGE_FAILED_TIMEOUT_MS = 30 * 1000;
|
||||
|
||||
const BtClient = GObject.registerClass({
|
||||
Properties: {
|
||||
'available': GObject.ParamSpec.boolean('available', '', '',
|
||||
@ -48,8 +50,10 @@ const BtClient = GObject.registerClass({
|
||||
this._client.connect('notify::default-adapter-powered', () => {
|
||||
this.notify('active');
|
||||
});
|
||||
this._client.connect('notify::default-adapter-state',
|
||||
() => this.notify('adapter-state'));
|
||||
this._client.connect('notify::default-adapter-state', () => {
|
||||
delete this._predictedState;
|
||||
this.notify('adapter-state');
|
||||
});
|
||||
this._client.connect('notify::default-adapter', () => {
|
||||
const newAdapter = this._client.default_adapter ?? null;
|
||||
|
||||
@ -108,11 +112,30 @@ const BtClient = GObject.registerClass({
|
||||
}
|
||||
|
||||
get adapter_state() {
|
||||
if (this._predictedState !== undefined)
|
||||
return this._predictedState;
|
||||
return this._client.default_adapter_state;
|
||||
}
|
||||
|
||||
toggleActive() {
|
||||
this._proxy.BluetoothAirplaneMode = this.active;
|
||||
const {active} = this;
|
||||
|
||||
// on many systems, there's a significant delay until the rfkill
|
||||
// state results in an adapter state change; work around that by
|
||||
// overriding the current state with the expected transition
|
||||
this._predictedState = active
|
||||
? AdapterState.TURNING_OFF
|
||||
: AdapterState.TURNING_ON;
|
||||
this.notify('adapter-state');
|
||||
|
||||
// toggling the state *really* should result in an adapter-state
|
||||
// change eventually (even on error), but just to be sure to not
|
||||
// be stuck with the overriden state, force a notify signal after
|
||||
// a timeout
|
||||
setTimeout(() => this._client.notify('default-adapter-state'),
|
||||
STATE_CHANGE_FAILED_TIMEOUT_MS);
|
||||
|
||||
this._proxy.BluetoothAirplaneMode = active;
|
||||
if (!this._client.default_adapter_powered)
|
||||
this._client.default_adapter_powered = true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user