Skip to content

Commit edb41be

Browse files
committed
Re-factor notifier.
* Add an internal `_notifier_uninit()` function. * Instead of `#ifdef` inside `notify()`, provide different target-specific static implementations. This also introduces `log_error_once()`. Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
1 parent 00d50d4 commit edb41be

File tree

2 files changed

+148
-104
lines changed

2 files changed

+148
-104
lines changed

src/log.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838

3939
#include <glib.h>
4040

41+
#define PROF_TMPVAR__(n, l) n##l
42+
#define PROF_TMPVAR_(n, l) PROF_TMPVAR__(n, l)
43+
#define PROF_TMPVAR(n) PROF_TMPVAR_(PROF_##n##_, __LINE__)
44+
4145
// log levels
4246
typedef enum {
4347
PROF_LEVEL_DEBUG,
@@ -58,6 +62,17 @@ void log_msg(log_level_t level, const char* const area, const char* const msg);
5862
int log_level_from_string(char* log_level, log_level_t* level);
5963
const char* log_string_from_level(log_level_t level);
6064

65+
#define _log_Xtype_once(type, ...) \
66+
do { \
67+
static gboolean PROF_TMPVAR(once) = FALSE; \
68+
if (!PROF_TMPVAR(once)) { \
69+
log_##type(__VA_ARGS__); \
70+
PROF_TMPVAR(once) = TRUE; \
71+
} \
72+
} while (0)
73+
74+
#define log_error_once(...) _log_Xtype_once(error, __VA_ARGS__)
75+
6176
void log_stderr_init(log_level_t level);
6277
void log_stderr_handler(void);
6378

src/ui/notifier.c

Lines changed: 133 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,139 @@
5656
#include "xmpp/muc.h"
5757

5858
static GTimer* remind_timer;
59+
5960
#ifdef HAVE_LIBNOTIFY
6061
static NotifyNotification* notification;
62+
63+
static void
64+
_notifier_uninit(void)
65+
{
66+
if (notify_is_initted()) {
67+
g_object_unref(G_OBJECT(notification));
68+
notification = NULL;
69+
notify_uninit();
70+
}
71+
}
72+
#else
73+
static void
74+
_notifier_uninit(void)
75+
{
76+
}
77+
#endif
78+
79+
#ifdef HAVE_LIBNOTIFY
80+
static void
81+
_notify(const char* const message, int timeout, const char* const category)
82+
{
83+
log_debug("Attempting notification: %s", message);
84+
if (notify_is_initted()) {
85+
log_debug("Reinitialising libnotify");
86+
notify_uninit();
87+
} else {
88+
log_debug("Initialising libnotify");
89+
}
90+
notify_init("Profanity");
91+
92+
if (notify_is_initted()) {
93+
if (notification)
94+
g_object_unref(G_OBJECT(notification));
95+
notification = notify_notification_new("Profanity", message, NULL);
96+
notify_notification_set_timeout(notification, timeout);
97+
notify_notification_set_category(notification, category);
98+
notify_notification_set_urgency(notification, NOTIFY_URGENCY_NORMAL);
99+
100+
GError* error = NULL;
101+
gboolean notify_success = notify_notification_show(notification, &error);
102+
103+
if (!notify_success) {
104+
log_error("Error sending desktop notification:");
105+
log_error(" -> Message : %s", message);
106+
log_error(" -> Error : %s", error->message);
107+
g_error_free(error);
108+
} else {
109+
log_debug("Notification sent.");
110+
}
111+
} else {
112+
log_error("Libnotify not initialised.");
113+
}
114+
}
115+
#elif defined(PLATFORM_CYGWIN)
116+
static void
117+
_notify(const char* const message, int timeout, const char* const category)
118+
{
119+
NOTIFYICONDATA nid;
120+
memset(&nid, 0, sizeof(nid));
121+
nid.cbSize = sizeof(NOTIFYICONDATA);
122+
// nid.hWnd = hWnd;
123+
nid.uID = 100;
124+
nid.uVersion = NOTIFYICON_VERSION;
125+
// nid.uCallbackMessage = WM_MYMESSAGE;
126+
nid.hIcon = LoadIcon(NULL, IDI_APPLICATION);
127+
strcpy(nid.szTip, "Tray Icon");
128+
nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
129+
Shell_NotifyIcon(NIM_ADD, &nid);
130+
131+
// For a Ballon Tip
132+
nid.uFlags = NIF_INFO;
133+
strcpy(nid.szInfoTitle, "Profanity"); // Title
134+
strncpy(nid.szInfo, message, sizeof(nid.szInfo) - 1); // Copy Tip
135+
nid.uTimeout = timeout; // 3 Seconds
136+
nid.dwInfoFlags = NIIF_INFO;
137+
138+
Shell_NotifyIcon(NIM_MODIFY, &nid);
139+
}
140+
#elif defined(HAVE_OSXNOTIFY)
141+
static void
142+
_notify(const char* const message, int timeout, const char* const category)
143+
{
144+
GString* notify_command = g_string_new("terminal-notifier -title \"Profanity\" -message '");
145+
146+
auto_char char* escaped_single = str_replace(message, "'", "'\\''");
147+
148+
if (escaped_single[0] == '<') {
149+
g_string_append(notify_command, "\\<");
150+
g_string_append(notify_command, &escaped_single[1]);
151+
} else if (escaped_single[0] == '[') {
152+
g_string_append(notify_command, "\\[");
153+
g_string_append(notify_command, &escaped_single[1]);
154+
} else if (escaped_single[0] == '(') {
155+
g_string_append(notify_command, "\\(");
156+
g_string_append(notify_command, &escaped_single[1]);
157+
} else if (escaped_single[0] == '{') {
158+
g_string_append(notify_command, "\\{");
159+
g_string_append(notify_command, &escaped_single[1]);
160+
} else {
161+
g_string_append(notify_command, escaped_single);
162+
}
163+
164+
g_string_append(notify_command, "'");
165+
166+
char* term_name = getenv("TERM_PROGRAM");
167+
char* app_id = NULL;
168+
if (g_strcmp0(term_name, "Apple_Terminal") == 0) {
169+
app_id = "com.apple.Terminal";
170+
} else if (g_strcmp0(term_name, "iTerm.app") == 0) {
171+
app_id = "com.googlecode.iterm2";
172+
}
173+
174+
if (app_id) {
175+
g_string_append(notify_command, " -sender ");
176+
g_string_append(notify_command, app_id);
177+
}
178+
179+
int res = system(notify_command->str);
180+
if (res == -1) {
181+
log_error("Could not send desktop notification.");
182+
}
183+
184+
g_string_free(notify_command, TRUE);
185+
}
186+
#else
187+
static void
188+
_notify(const char* const message, int timeout, const char* const category)
189+
{
190+
log_error_once("Notification backend missing");
191+
}
61192
#endif
62193

63194
void
@@ -69,13 +200,7 @@ notifier_initialise(void)
69200
void
70201
notifier_uninit(void)
71202
{
72-
#ifdef HAVE_LIBNOTIFY
73-
g_object_unref(G_OBJECT(notification));
74-
notification = NULL;
75-
if (notify_is_initted()) {
76-
notify_uninit();
77-
}
78-
#endif
203+
_notifier_uninit();
79204
g_timer_destroy(remind_timer);
80205
}
81206

@@ -202,102 +327,6 @@ notify_remind(void)
202327
void
203328
notify(const char* const message, int timeout, const char* const category)
204329
{
205-
#ifdef HAVE_LIBNOTIFY
206330
log_debug("Attempting notification: %s", message);
207-
if (notify_is_initted()) {
208-
log_debug("Reinitialising libnotify");
209-
notify_uninit();
210-
} else {
211-
log_debug("Initialising libnotify");
212-
}
213-
notify_init("Profanity");
214-
215-
if (notify_is_initted()) {
216-
if (notification)
217-
g_object_unref(G_OBJECT(notification));
218-
notification = notify_notification_new("Profanity", message, NULL);
219-
notify_notification_set_timeout(notification, timeout);
220-
notify_notification_set_category(notification, category);
221-
notify_notification_set_urgency(notification, NOTIFY_URGENCY_NORMAL);
222-
223-
GError* error = NULL;
224-
gboolean notify_success = notify_notification_show(notification, &error);
225-
226-
if (!notify_success) {
227-
log_error("Error sending desktop notification:");
228-
log_error(" -> Message : %s", message);
229-
log_error(" -> Error : %s", error->message);
230-
g_error_free(error);
231-
} else {
232-
log_debug("Notification sent.");
233-
}
234-
} else {
235-
log_error("Libnotify not initialised.");
236-
}
237-
#endif
238-
#ifdef PLATFORM_CYGWIN
239-
NOTIFYICONDATA nid;
240-
memset(&nid, 0, sizeof(nid));
241-
nid.cbSize = sizeof(NOTIFYICONDATA);
242-
// nid.hWnd = hWnd;
243-
nid.uID = 100;
244-
nid.uVersion = NOTIFYICON_VERSION;
245-
// nid.uCallbackMessage = WM_MYMESSAGE;
246-
nid.hIcon = LoadIcon(NULL, IDI_APPLICATION);
247-
strcpy(nid.szTip, "Tray Icon");
248-
nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
249-
Shell_NotifyIcon(NIM_ADD, &nid);
250-
251-
// For a Ballon Tip
252-
nid.uFlags = NIF_INFO;
253-
strcpy(nid.szInfoTitle, "Profanity"); // Title
254-
strncpy(nid.szInfo, message, sizeof(nid.szInfo) - 1); // Copy Tip
255-
nid.uTimeout = timeout; // 3 Seconds
256-
nid.dwInfoFlags = NIIF_INFO;
257-
258-
Shell_NotifyIcon(NIM_MODIFY, &nid);
259-
#endif
260-
#ifdef HAVE_OSXNOTIFY
261-
GString* notify_command = g_string_new("terminal-notifier -title \"Profanity\" -message '");
262-
263-
auto_char char* escaped_single = str_replace(message, "'", "'\\''");
264-
265-
if (escaped_single[0] == '<') {
266-
g_string_append(notify_command, "\\<");
267-
g_string_append(notify_command, &escaped_single[1]);
268-
} else if (escaped_single[0] == '[') {
269-
g_string_append(notify_command, "\\[");
270-
g_string_append(notify_command, &escaped_single[1]);
271-
} else if (escaped_single[0] == '(') {
272-
g_string_append(notify_command, "\\(");
273-
g_string_append(notify_command, &escaped_single[1]);
274-
} else if (escaped_single[0] == '{') {
275-
g_string_append(notify_command, "\\{");
276-
g_string_append(notify_command, &escaped_single[1]);
277-
} else {
278-
g_string_append(notify_command, escaped_single);
279-
}
280-
281-
g_string_append(notify_command, "'");
282-
283-
char* term_name = getenv("TERM_PROGRAM");
284-
char* app_id = NULL;
285-
if (g_strcmp0(term_name, "Apple_Terminal") == 0) {
286-
app_id = "com.apple.Terminal";
287-
} else if (g_strcmp0(term_name, "iTerm.app") == 0) {
288-
app_id = "com.googlecode.iterm2";
289-
}
290-
291-
if (app_id) {
292-
g_string_append(notify_command, " -sender ");
293-
g_string_append(notify_command, app_id);
294-
}
295-
296-
int res = system(notify_command->str);
297-
if (res == -1) {
298-
log_error("Could not send desktop notification.");
299-
}
300-
301-
g_string_free(notify_command, TRUE);
302-
#endif
331+
_notify(message, timeout, category);
303332
}

0 commit comments

Comments
 (0)