Skip to content

Commit 6332649

Browse files
authored
fix: revert running libnotify actions asynchronously (#135)
1 parent 35a6c4e commit 6332649

1 file changed

Lines changed: 35 additions & 101 deletions

File tree

src/tray_linux.cpp

Lines changed: 35 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include <memory>
1111
#include <mutex>
1212
#include <string>
13-
#include <thread>
1413
#include <utility>
1514

1615
// lib includes
@@ -22,36 +21,17 @@
2221

2322
namespace tray_linux {
2423
/**
25-
* Notification element struct
24+
* Currently shown notification object
2625
*/
27-
struct notification_data {
28-
/**
29-
* @brief Notification object
30-
*/
31-
NotifyNotification *obj = nullptr;
32-
/**
33-
* @brief Notification callback
34-
*/
35-
void (*cb)() = nullptr;
36-
/**
37-
* @brief Notification shown indicator
38-
*/
39-
bool shown = false;
40-
/**
41-
* @brief Notification mutex for async thread synchronization
42-
*/
43-
std::mutex mutex;
44-
};
45-
26+
NotifyNotification *notification_current = nullptr; // NOSONAR(cpp:S5421) - mutable state, not const
4627
/**
47-
* Currently shown notifications
28+
* Currently shown notification callback
4829
*/
49-
std::vector<std::shared_ptr<notification_data>> notifications; // NOSONAR(cpp:S5421) - mutable state, not const
30+
void (*notification_current_callback)() = nullptr; // NOSONAR(cpp:S5421) - mutable state, not const
5031
/**
51-
* Lock for currently shown notifications vector
32+
* Lock for currently shown notification/callback
5233
*/
53-
std::mutex notifications_mutex; // NOSONAR(cpp:S5421) - mutable state, not const
54-
34+
std::mutex notification_mutex; // NOSONAR(cpp:S5421) - mutable state, not const
5535
/**
5636
* QtTrayMenu instance
5737
*/
@@ -62,64 +42,34 @@ namespace tray_linux {
6242
void (*log_callback)(int, const char *) = nullptr; // NOSONAR(cpp:S5421) - mutable state, not const
6343

6444
/**
65-
* @brief Show notification asynchronously with timeout to avoid Dbus lockups
66-
* @param notification - Tray notification to show
67-
* @param timeout - optional timeout for async run in ms (default: 1000)
68-
* @return true if notification was successfully shown
69-
*/
70-
bool async_tray_notification_show_(const std::shared_ptr<notification_data> &notification, int timeout = 1000) {
71-
std::thread t([notification]() { // NOSONAR(cpp:S6168) - jthread is only available on C++20 onwards
72-
std::scoped_lock lock(notification->mutex);
73-
if (notification->obj != nullptr && NOTIFY_IS_NOTIFICATION(notification->obj) && notify_notification_show(notification->obj, nullptr)) {
74-
notification->shown = true;
75-
}
76-
});
77-
t.detach(); // NOSONAR(cpp:S5962)
78-
while (!notification->shown && timeout > 0) {
79-
std::this_thread::sleep_for(std::chrono::milliseconds(10));
80-
timeout -= 10;
81-
}
82-
return notification->shown;
83-
}
84-
85-
/**
86-
* @brief Acknowledge notification asynchronously with timeout to avoid Dbus lockups
87-
* @param notification - Tray notification to close
88-
* @param timeout - optional timeout for async run in ms (default: 1000)
89-
* @return true if notification was successfully closed
45+
* @brief Initialize notifications
46+
* @param app_name application name for notifications
47+
* @return true if successful
9048
*/
91-
bool async_tray_notification_acknowledge_(const std::shared_ptr<notification_data> &notification, int timeout = 1000) {
92-
std::thread t([notification]() { // NOSONAR(cpp:S6168) - jthread is only available on C++20 onwards
93-
std::scoped_lock lock(notification->mutex);
94-
if (notification->obj != nullptr && NOTIFY_IS_NOTIFICATION(notification->obj) && notify_notification_close(notification->obj, nullptr)) {
95-
notification->shown = false;
96-
g_object_unref(G_OBJECT(notification->obj));
97-
notification->obj = nullptr;
98-
notification->cb = nullptr;
99-
}
100-
});
101-
t.detach(); // NOSONAR(cpp:S5962)
102-
while (notification->obj != nullptr && timeout > 0) {
103-
std::this_thread::sleep_for(std::chrono::milliseconds(10));
104-
timeout -= 10;
49+
bool init_notify(const char *app_name) {
50+
if (!notify_is_initted()) {
51+
std::scoped_lock lock(notification_mutex);
52+
return notify_init(app_name);
10553
}
106-
return notification->obj == nullptr;
54+
return true; // Already initialized, so init was successful
10755
}
10856

10957
/**
110-
* @brief Acknowledge/click current notifications
58+
* @brief Acknowledge/click current notification
11159
* @param run_callback - Run notification callback when acknowledging
11260
*/
113-
void acknowledge_notifications(bool run_callback = false) {
61+
void acknowledge_notification(const bool run_callback = false) {
11462
if (notify_is_initted()) {
115-
std::scoped_lock lock(notifications_mutex);
116-
for (auto notification : notifications) {
117-
if (run_callback && notification->cb != nullptr) {
118-
notification->cb();
63+
std::scoped_lock lock(notification_mutex);
64+
if (notification_current != nullptr && NOTIFY_IS_NOTIFICATION(notification_current)) {
65+
if (run_callback && notification_current_callback != nullptr) {
66+
notification_current_callback();
11967
}
120-
async_tray_notification_acknowledge_(notification);
68+
notify_notification_close(notification_current, nullptr);
69+
g_object_unref(G_OBJECT(notification_current));
70+
notification_current = nullptr;
71+
notification_current_callback = nullptr;
12172
}
122-
notifications.clear();
12373
} else if (qt_tray_menu != nullptr && QtTrayMenu::supportsMessages()) {
12474
qt_tray_menu->clickMessage();
12575
}
@@ -135,24 +85,22 @@ namespace tray_linux {
13585
}
13686
// Try to notify using libnotify
13787
if (notify_is_initted()) {
138-
std::scoped_lock lock(notifications_mutex);
139-
if (!notifications.empty()) {
140-
acknowledge_notifications();
88+
if (notification_current != nullptr) {
89+
acknowledge_notification();
14190
}
91+
std::scoped_lock lock(notification_mutex);
14292
std::filesystem::path notification_icon = tray->notification_icon != nullptr ? tray->notification_icon : tray->icon;
14393
if (std::filesystem::exists(notification_icon)) {
14494
// Use absolute path for filesystem icon files, not a relative one
14595
notification_icon = std::filesystem::absolute(notification_icon);
14696
}
147-
auto notification = std::make_shared<struct notification_data>();
148-
notification->obj = notify_notification_new(tray->notification_title, tray->notification_text, notification_icon.c_str());
149-
if (notification->obj != nullptr && NOTIFY_IS_NOTIFICATION(notification->obj)) {
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)) {
15099
if (tray->notification_cb != nullptr) {
151-
notification->cb = tray->notification_cb;
152-
notify_notification_add_action(notification->obj, "default", "Default", NOTIFY_ACTION_CALLBACK(tray->notification_cb), nullptr, 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);
153102
}
154-
notifications.emplace_back(notification);
155-
if (async_tray_notification_show_(notification)) {
103+
if (notify_notification_show(notification_current, nullptr)) {
156104
return;
157105
}
158106
}
@@ -163,27 +111,13 @@ namespace tray_linux {
163111
}
164112
}
165113

166-
/**
167-
* @brief Initialize notifications
168-
* @param app_name application name for notifications
169-
* @return true if successful
170-
*/
171-
bool init_notify(const char *app_name) {
172-
if (!notify_is_initted()) {
173-
if (!notifications.empty()) {
174-
acknowledge_notifications();
175-
}
176-
return notify_init(app_name);
177-
}
178-
return true; // Already initialized, so init was successful
179-
}
180-
181114
/**
182115
* @brief Uninitialize notifications
183116
*/
184117
void uninit_notify() {
185118
if (notify_is_initted()) {
186-
acknowledge_notifications();
119+
acknowledge_notification();
120+
std::scoped_lock lock(notification_mutex);
187121
notify_uninit();
188122
}
189123
}
@@ -311,6 +245,6 @@ extern "C" {
311245
}
312246

313247
void tray_simulate_notification_click(void) {
314-
tray_linux::acknowledge_notifications(true);
248+
tray_linux::acknowledge_notification(true);
315249
}
316250
} // extern "C"

0 commit comments

Comments
 (0)