@@ -61,39 +61,29 @@ def init(app_name):
6161 path = "/org/freedesktop/Notifications"
6262 interface = "org.freedesktop.Notifications"
6363
64- mainloop = None
65- bus = None
6664 try :
67- if DBusQtMainLoop is not None :
68- mainloop = DBusQtMainLoop (set_as_default = True )
69-
70- bus = dbus .SessionBus (mainloop )
65+ # Probe on a throwaway no-mainloop connection first. Wiring the
66+ # Qt dbus mainloop before a daemon is confirmed leaves a dangling
67+ # QSocketNotifier that segfaults on its next dispatch.
68+ probe = dbus .SessionBus (private = True )
69+ try :
70+ present = probe .name_has_owner (name )
71+ finally :
72+ probe .close ()
73+ if not present :
74+ raise RuntimeError ('no notification daemon' )
75+
76+ mainloop = DBusQtMainLoop (set_as_default = True ) if DBusQtMainLoop else None
77+ bus = dbus .SessionBus (mainloop = mainloop )
7178 proxy = bus .get_object (name , path )
7279 DBUS_IFACE = dbus .Interface (proxy , interface )
7380
7481 if mainloop is not None :
75- # We have a mainloop, so connect callbacks
7682 DBUS_IFACE .connect_to_signal ('ActionInvoked' , _onActionInvoked )
7783 DBUS_IFACE .connect_to_signal ('NotificationClosed' , _onNotificationClosed )
7884 except Exception as e :
7985 LOG .warning ('Desktop Notify not available:: {}' .format (e ))
80- # When the SessionBus is constructed with a PyQt5/PyQt6 mainloop
81- # integration, dbus-python installs a QSocketNotifier on the
82- # connection fd. If the subsequent get_object/Interface setup
83- # raises (e.g. ServiceUnknown when no notification daemon owns
84- # org.freedesktop.Notifications), the Python-side bus reference
85- # is dropped on exception but the QSocketNotifier keeps the
86- # underlying C connection alive in a half-initialized state.
87- # The next QEventLoop tick dispatches a queued message via
88- # dbus_connection_dispatch() and segfaults inside
89- # _dbus_list_unlink. Close the bus explicitly so the notifier
90- # detaches and the connection is fully released.
9186 DBUS_IFACE = None
92- if bus is not None :
93- try :
94- bus .close ()
95- except Exception :
96- pass
9787
9888
9989def _onActionInvoked (nid , action ):
0 commit comments