@@ -57,16 +57,26 @@ namespace tray_linux {
5757 /* *
5858 * @brief Acknowledge/click current notification
5959 * @param run_callback - Run notification callback when acknowledging
60+ * @param async - Acknowledge asynchronously in the event loop (default: true)
6061 */
61- void acknowledge_notification (const bool run_callback = false ) {
62+ void acknowledge_notification (const bool run_callback = false , const bool async = true ) {
6263 if (notify_is_initted ()) {
6364 std::scoped_lock lock (notification_mutex);
6465 if (notification_current != nullptr && NOTIFY_IS_NOTIFICATION (notification_current)) {
6566 if (run_callback && notification_current_callback != nullptr ) {
6667 notification_current_callback ();
6768 }
68- notify_notification_close (notification_current, nullptr );
69- g_object_unref (G_OBJECT (notification_current));
69+ GSourceFunc f = [](gpointer data) -> gboolean {
70+ auto n = static_cast <NotifyNotification *>(data);
71+ notify_notification_close (n, nullptr );
72+ g_object_unref (G_OBJECT (n));
73+ return false ; // Run once then remove from queue
74+ };
75+ if (async) {
76+ g_idle_add (f, notification_current);
77+ } else {
78+ f (notification_current);
79+ }
7080 notification_current = nullptr ;
7181 notification_current_callback = nullptr ;
7282 }
@@ -75,6 +85,36 @@ namespace tray_linux {
7585 }
7686 }
7787
88+ /* *
89+ * @brief Show tray notification via desktop-independent interface async via g_idle_add
90+ * @param data Tray structure containing notification information as a gpointer
91+ * @return false to run just once
92+ */
93+ gboolean async_notify_ (const gpointer data) {
94+ auto tray = static_cast <struct tray *>(data);
95+ if (notification_current != nullptr ) {
96+ acknowledge_notification (false , false );
97+ }
98+ std::scoped_lock lock (notification_mutex);
99+ std::filesystem::path notification_icon = tray->notification_icon != nullptr ? tray->notification_icon : tray->icon ;
100+ if (std::filesystem::exists (notification_icon)) {
101+ // Use absolute path for filesystem icon files, not a relative one
102+ notification_icon = std::filesystem::absolute (notification_icon);
103+ }
104+ notification_current = notify_notification_new (tray->notification_title , tray->notification_text , notification_icon.c_str ());
105+ if (notification_current != nullptr && NOTIFY_IS_NOTIFICATION (notification_current)) {
106+ if (tray->notification_cb != nullptr ) {
107+ notification_current_callback = tray->notification_cb ;
108+ notify_notification_add_action (notification_current, " default" , " Default" , NOTIFY_ACTION_CALLBACK (tray->notification_cb ), nullptr , nullptr );
109+ }
110+ // Fallback to QtTrayMenu notification if notificaton_show fails
111+ if (!notify_notification_show (notification_current, nullptr ) && qt_tray_menu != nullptr && QtTrayMenu::supportsMessages ()) {
112+ qt_tray_menu->showMessage (tray->notification_title , tray->notification_text , tray->notification_icon , tray->notification_cb );
113+ }
114+ }
115+ return false ; // Run once then remove from queue
116+ }
117+
78118 /* *
79119 * @brief Show tray notification via desktop-independent interface
80120 * @param tray Tray structure containing notification information
@@ -85,25 +125,10 @@ namespace tray_linux {
85125 }
86126 // Try to notify using libnotify
87127 if (notify_is_initted ()) {
88- if (notification_current != nullptr ) {
89- acknowledge_notification ();
90- }
91- std::scoped_lock lock (notification_mutex);
92- std::filesystem::path notification_icon = tray->notification_icon != nullptr ? tray->notification_icon : tray->icon ;
93- if (std::filesystem::exists (notification_icon)) {
94- // Use absolute path for filesystem icon files, not a relative one
95- notification_icon = std::filesystem::absolute (notification_icon);
96- }
97- notification_current = notify_notification_new (tray->notification_title , tray->notification_text , notification_icon.c_str ());
98- if (notification_current != nullptr && NOTIFY_IS_NOTIFICATION (notification_current)) {
99- if (tray->notification_cb != nullptr ) {
100- notification_current_callback = tray->notification_cb ;
101- notify_notification_add_action (notification_current, " default" , " Default" , NOTIFY_ACTION_CALLBACK (tray->notification_cb ), nullptr , nullptr );
102- }
103- if (notify_notification_show (notification_current, nullptr )) {
104- return ;
105- }
106- }
128+ // Fix tray icon path
129+
130+ // Show tray icon aync via event loop
131+ g_idle_add (async_notify_, tray);
107132 }
108133 // Fallback to QtTrayMenu notification
109134 if (qt_tray_menu != nullptr && QtTrayMenu::supportsMessages ()) {
0 commit comments