diff --git a/desktopenvs/hyprlua/astal-menu/modules/bluetooth.py b/desktopenvs/hyprlua/astal-menu/modules/bluetooth.py index b834ebd..4519c72 100644 --- a/desktopenvs/hyprlua/astal-menu/modules/bluetooth.py +++ b/desktopenvs/hyprlua/astal-menu/modules/bluetooth.py @@ -44,6 +44,7 @@ class _BluetoothView(Gtk.Box): self.full = full self.bt = ctx.services.bluetooth self._recorded: set[str] = set() + self._hooked: set[str] = set() # devices whose state signals we've wired self.append(self._build_header()) @@ -121,11 +122,23 @@ class _BluetoothView(Gtk.Box): if not self.full: devices = [d for d in devices if d.get_connected() or d.get_paired()][:4] for dev in devices: + self._hook_device(dev) self._list.append(self._device_row(dev)) if self.full and self.ctx.feature("history", True): self._list.append(self._history_section()) + def _hook_device(self, dev) -> None: + # Rebuild the list when a device's connection state changes, so a freshly + # connected device flips its button to "Disconnect" (adapter-level + # notify::devices doesn't fire for per-device state changes). Hook once each. + key = dev.get_address() or "" + if key in self._hooked: + return + self._hooked.add(key) + for sig in ("notify::connected", "notify::connecting", "notify::paired"): + dev.connect(sig, lambda *_a: self._refresh()) + def _device_row(self, dev) -> Gtk.Widget: row = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) row.add_css_class("bt-row")