Skip to content

Commit a63dbc3

Browse files
committed
trayicon: fix removing trayicon when plugin is disabled
1 parent 603a642 commit a63dbc3

File tree

1 file changed

+35
-3
lines changed

1 file changed

+35
-3
lines changed

safeeyes/plugins/trayicon/plugin.py

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
Safe Eyes tray icon plugin
3333
"""
3434

35-
tray_icon = None
35+
tray_icon: typing.Optional["TrayIcon"] = None
3636
safeeyes_config = None
3737

3838
SNI_NODE_INFO = Gio.DBusNodeInfo.new_for_xml(
@@ -405,6 +405,14 @@ def register(self):
405405
cancellable=None,
406406
)
407407

408+
# Note that according to the (freedesktop) spec, we should own the name
409+
# org.freedesktop.StatusNotifierItem-PID-ID and pass that to the watcher
410+
# instead
411+
# with the path being hardcoded at /StatusNotifierItem
412+
# The spec behaviour is worse for flatpak, however, as it requires owning a
413+
# pretty generic name.
414+
# Note that libappindicator/ayatana also used this non-standard behaviour -
415+
# this must be pretty well supported then.
408416
watcher.RegisterStatusNotifierItem("(s)", self.DBUS_SERVICE_PATH)
409417

410418
def unregister(self):
@@ -441,6 +449,8 @@ class TrayIcon:
441449

442450
_resume_timeout_id: typing.Optional[int] = None
443451

452+
_session_bus: Gio.DBusConnection
453+
444454
def __init__(self, context: Context, plugin_config):
445455
self.context = context
446456
self.on_show_settings = context.api.show_settings
@@ -458,10 +468,19 @@ def __init__(self, context: Context, plugin_config):
458468
self.allow_disabling = plugin_config["allow_disabling"]
459469
self.menu_locked = False
460470

461-
session_bus = Gio.bus_get_sync(Gio.BusType.SESSION)
471+
# This is using a separate dbus connection on purpose
472+
# StatusNotifierWatcher does not have an unregister method - the spec instead
473+
# says that the watcher should detect the item "going away from the bus"
474+
# in practice, this means that the connection closing is detected by the watcher
475+
# which can only happen if we use our own connection, and close it manually
476+
self._session_bus = Gio.DBusConnection.new_for_address_sync(
477+
Gio.dbus_address_get_for_bus_sync(Gio.BusType.SESSION),
478+
Gio.DBusConnectionFlags.AUTHENTICATION_CLIENT
479+
| Gio.DBusConnectionFlags.MESSAGE_BUS_CONNECTION,
480+
)
462481

463482
self.sni_service = StatusNotifierItemService(
464-
session_bus, menu_items=self.get_items()
483+
self._session_bus, menu_items=self.get_items()
465484
)
466485
self.sni_service.register()
467486

@@ -475,6 +494,10 @@ def initialize(self, plugin_config):
475494
self.update_menu()
476495
self.update_tooltip()
477496

497+
def unregister(self) -> None:
498+
self.sni_service.unregister()
499+
self._session_bus.close_sync()
500+
478501
def get_items(self):
479502
breaks_found = self.has_breaks()
480503

@@ -864,3 +887,12 @@ def on_start():
864887
def on_stop():
865888
"""Disable the tray icon."""
866889
tray_icon.disable_ui()
890+
891+
892+
def disable() -> None:
893+
"""Disable the tray icon plugin."""
894+
global tray_icon
895+
896+
if tray_icon:
897+
tray_icon.unregister()
898+
tray_icon = None

0 commit comments

Comments
 (0)