diff --git a/desktopenvs/hyprdrive/station-bar/tray.py b/desktopenvs/hyprdrive/station-bar/tray.py index c6d3b1f..a14dcd4 100644 --- a/desktopenvs/hyprdrive/station-bar/tray.py +++ b/desktopenvs/hyprdrive/station-bar/tray.py @@ -35,11 +35,20 @@ class TrayHost: self._on_watcher_appeared, self._on_watcher_vanished) def _on_watcher_appeared(self, _conn, _name, _owner) -> None: + # MUST be async: this bar hosts the StatusNotifierWatcher itself (see + # sni_watcher.py), so a *_sync proxy here would block the main loop + # waiting on a reply only that same loop can produce — a self-deadlock + # that freezes the whole bar (its clock, its holo intro — everything) + # until the 25s D-Bus timeout finally lets it go. + Gio.DBusProxy.new_for_bus( + Gio.BusType.SESSION, Gio.DBusProxyFlags.NONE, None, + _WATCHER_BUS, _WATCHER_PATH, _WATCHER_IFACE, None, + self._on_watcher_ready, None, + ) + + def _on_watcher_ready(self, _source, result, _user_data) -> None: try: - self._watcher = Gio.DBusProxy.new_for_bus_sync( - Gio.BusType.SESSION, Gio.DBusProxyFlags.NONE, None, - _WATCHER_BUS, _WATCHER_PATH, _WATCHER_IFACE, None, - ) + self._watcher = Gio.DBusProxy.new_for_bus_finish(result) except GLib.Error: self._watcher = None return @@ -56,14 +65,13 @@ class TrayHost: def _ensure_host_registered(self) -> None: if self._registered_host or self._watcher is None: return - try: - self._watcher.call_sync( - "RegisterStatusNotifierHost", GLib.Variant("(s)", (_HOST_NAME,)), - Gio.DBusCallFlags.NONE, 500, None, - ) - except GLib.Error: - pass + # Async for the same self-deadlock reason as _on_watcher_appeared: this + # call targets our own in-process watcher. Fire-and-forget. self._registered_host = True + self._watcher.call( + "RegisterStatusNotifierHost", GLib.Variant("(s)", (_HOST_NAME,)), + Gio.DBusCallFlags.NONE, 2000, None, None, + ) def available(self) -> bool: return self._watcher is not None