3232Safe Eyes tray icon plugin
3333"""
3434
35- tray_icon = None
35+ tray_icon : typing . Optional [ "TrayIcon" ] = None
3636safeeyes_config = None
3737
3838SNI_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():
864887def 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