diff --git a/src/modules/bluetooth.ts b/src/modules/bluetooth.ts index b835e8d..7dd6abd 100644 --- a/src/modules/bluetooth.ts +++ b/src/modules/bluetooth.ts @@ -1,5 +1,7 @@ import { createRoot, getScope, Scope } from "ags"; -import GObject, { getter, gtype, register, setter } from "ags/gobject"; +import GObject, { getter, gtype, property, register, setter } from "ags/gobject"; +import { execAsync } from "ags/process"; + import AstalBluetooth from "gi://AstalBluetooth"; @@ -16,6 +18,8 @@ export class Bluetooth extends GObject.Object { @getter(Boolean) get isAvailable() { return this.#isAvailable; } + + @property(Boolean) saveDefaultAdapter = true; @getter(gtype(AstalBluetooth.Adapter)) get adapter() { return this.#adapter; } @@ -24,6 +28,19 @@ export class Bluetooth extends GObject.Object { set adapter(newAdapter: AstalBluetooth.Adapter|null) { this.#adapter = newAdapter; this.notify("adapter"); + + if(!newAdapter) return; + + AstalBluetooth.get_default().adapters.filter(ad => { + if(ad.address !== newAdapter.address) + return true; + + ad.set_powered(true); + return false; + }).forEach(ad => ad.set_powered(false)); + + execAsync(`bluetoothctl select ${newAdapter.address}`).catch(e => + console.error(`Bluetooth: Couldn't select adapter. Stderr: ${e}`)); } constructor() { @@ -38,38 +55,41 @@ export class Bluetooth extends GObject.Object { } this.#connections.set( - AstalBluetooth.get_default(), - AstalBluetooth.get_default().connect("adapter-added", (self, adapter) => { - if(self.adapters.length === 1) // adapter was just added - this.adapter = adapter; - }) + AstalBluetooth.get_default(), [ + AstalBluetooth.get_default().connect("adapter-added", (self, adapter) => { + if(self.adapters.length === 1) // adapter was just added + this.adapter = adapter; + }), + AstalBluetooth.get_default().connect("adapter-removed", (self, adapter) => { + if(self.adapters.length < 1) { + this.adapter = null; + this.#isAvailable = false; + this.notify("is-available"); + } + + if(this.#adapter?.address !== adapter.address) + return; + + // the removed adapter was the default + + if(self.adapters.length < 1) { + this.adapter = null; + this.#isAvailable = false; + this.notify("is-available"); + + return; + } + + this.#adapter = self.adapters[0]; + }) + ] ); - this.#connections.set( - AstalBluetooth.get_default(), - AstalBluetooth.get_default().connect("adapter-removed", (self, adapter) => { - if(self.adapters.length < 1) { - this.adapter = null; - this.#isAvailable = false; - this.notify("is-available"); - } - - if(this.#adapter?.address !== adapter.address) - return; - - // the removed adapter was the default - - if(self.adapters.length < 1) { - this.adapter = null; - this.#isAvailable = false; - this.notify("is-available"); - - return; - } - - this.#adapter = self.adapters[0]; - }) - ); + this.#scope.onCleanup(() => this.#connections.forEach((ids, gobj) => + Array.isArray(ids) ? + ids.forEach(id => gobj.disconnect(id)) + : gobj.disconnect(ids) + )); }); } diff --git a/src/modules/utils.ts b/src/modules/utils.ts index aaf5d7f..af015f9 100644 --- a/src/modules/utils.ts +++ b/src/modules/utils.ts @@ -1,6 +1,6 @@ import { createPoll } from "ags/time"; import { exec, execAsync } from "ags/process"; -import { Accessor, For, getScope, onCleanup, With } from "ags"; +import { Accessor, For, getScope, With } from "ags"; import { Astal, Gtk } from "ags/gtk4"; import { getSymbolicIcon } from "./apps"; diff --git a/src/window/control-center/widgets/pages/Bluetooth.tsx b/src/window/control-center/widgets/pages/Bluetooth.tsx index af467c9..eb9b0a0 100644 --- a/src/window/control-center/widgets/pages/Bluetooth.tsx +++ b/src/window/control-center/widgets/pages/Bluetooth.tsx @@ -4,7 +4,6 @@ import { tr } from "../../../../i18n/intl"; import { Windows } from "../../../../windows"; import { Notifications } from "../../../../modules/notifications"; import { execApp } from "../../../../modules/apps"; -import { execAsync } from "ags/process"; import { createBinding, createComputed, For, With } from "ags"; import { Bluetooth } from "../../../../modules/bluetooth"; @@ -69,10 +68,10 @@ export const BluetoothPage = new Page({ return is ? "selected" : "")} title={adapter.alias ?? "Adapter"} icon={"bluetooth-active-symbolic"} description={createBinding(adapter, "address")} - actionClicked={() => - adapter.address !== Bluetooth.getDefault().adapter?.address && - selectAdapter(adapter) - } + actionClicked={() => { + if(adapter.address !== Bluetooth.getDefault().adapter?.address) + Bluetooth.getDefault().adapter = adapter; + }} endWidget={ } @@ -212,18 +211,3 @@ function DeviceWidget({ device }: { device: AstalBluetooth.Device }): Gtk.Widget } /> as Gtk.Widget; } - -function selectAdapter(adapter: AstalBluetooth.Adapter): void { - AstalBluetooth.get_default().adapters.filter(ad => { - if(ad.alias !== adapter.alias) - return true; - - ad.set_powered(true); - return false; - }).forEach(ad => ad.set_powered(false)); - - execAsync(`bluetoothctl select ${adapter.address}`).catch(e => - console.error(`Bluetooth: Couldn't select adapter. Stderr: ${e}`)); - - Bluetooth.getDefault().adapter = adapter; -}