fix(astal-menu): refresh Bluetooth list on device connection changes
The device rows already render a "Disconnect" button when a device is connected, but the list only rebuilt on adapter-level notify::devices / notify::is-powered — not on per-device state changes. So a device connected (via the menu or elsewhere) while the menu was open kept its "Connect" button and offered no way to disconnect. Hook each device's notify::connected/connecting/paired (once each) to refresh the list, so a connected device flips to "Disconnect". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XUWCXM4KhjRkwheaA3X7bPfeat/astal-menu
parent
5cd880c388
commit
e79d427c2a
|
|
@ -44,6 +44,7 @@ class _BluetoothView(Gtk.Box):
|
||||||
self.full = full
|
self.full = full
|
||||||
self.bt = ctx.services.bluetooth
|
self.bt = ctx.services.bluetooth
|
||||||
self._recorded: set[str] = set()
|
self._recorded: set[str] = set()
|
||||||
|
self._hooked: set[str] = set() # devices whose state signals we've wired
|
||||||
|
|
||||||
self.append(self._build_header())
|
self.append(self._build_header())
|
||||||
|
|
||||||
|
|
@ -121,11 +122,23 @@ class _BluetoothView(Gtk.Box):
|
||||||
if not self.full:
|
if not self.full:
|
||||||
devices = [d for d in devices if d.get_connected() or d.get_paired()][:4]
|
devices = [d for d in devices if d.get_connected() or d.get_paired()][:4]
|
||||||
for dev in devices:
|
for dev in devices:
|
||||||
|
self._hook_device(dev)
|
||||||
self._list.append(self._device_row(dev))
|
self._list.append(self._device_row(dev))
|
||||||
|
|
||||||
if self.full and self.ctx.feature("history", True):
|
if self.full and self.ctx.feature("history", True):
|
||||||
self._list.append(self._history_section())
|
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:
|
def _device_row(self, dev) -> Gtk.Widget:
|
||||||
row = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
|
row = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
|
||||||
row.add_css_class("bt-row")
|
row.add_css_class("bt-row")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue