Move id assignment to separate function in queues.c
Move all id-changing functions out of notification_init and handle this in queues.c Also use stack_duplicates in combination with replacement of notifications correctly. Fixes #404 (issue not found)
This commit is contained in:
parent
af9f6b8b7d
commit
f869175d0d
@ -264,7 +264,8 @@ static void on_notify(GDBusConnection *connection,
|
|||||||
n->color_strings[ColFG] = fgcolor;
|
n->color_strings[ColFG] = fgcolor;
|
||||||
n->color_strings[ColBG] = bgcolor;
|
n->color_strings[ColBG] = bgcolor;
|
||||||
|
|
||||||
int id = notification_init(n, replaces_id);
|
notification_init(n);
|
||||||
|
int id = queues_notification_insert(n, replaces_id);
|
||||||
wake_up();
|
wake_up();
|
||||||
|
|
||||||
GVariant *reply = g_variant_new("(u)", id);
|
GVariant *reply = g_variant_new("(u)", id);
|
||||||
|
@ -261,7 +261,9 @@ int dunst_main(int argc, char *argv[])
|
|||||||
n->timeout = 10 * G_USEC_PER_SEC;
|
n->timeout = 10 * G_USEC_PER_SEC;
|
||||||
n->markup = MARKUP_NO;
|
n->markup = MARKUP_NO;
|
||||||
n->urgency = LOW;
|
n->urgency = LOW;
|
||||||
notification_init(n, 0);
|
notification_init(n);
|
||||||
|
queues_notification_insert(n, 0);
|
||||||
|
// we do not call wakeup now, wake_up does not work here yet
|
||||||
}
|
}
|
||||||
|
|
||||||
mainloop = g_main_loop_new(NULL, FALSE);
|
mainloop = g_main_loop_new(NULL, FALSE);
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "x11/x.h"
|
#include "x11/x.h"
|
||||||
|
|
||||||
int next_notification_id = 1;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* print a human readable representation
|
* print a human readable representation
|
||||||
@ -280,28 +279,28 @@ void notification_init_defaults(notification *n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the given notification and add it to
|
* Initialize the given notification
|
||||||
* the queue. Replace notification with id if id > 0.
|
|
||||||
*
|
*
|
||||||
* n should be a pointer to a notification allocated with
|
* n should be a pointer to a notification allocated with
|
||||||
* notification_create, it is undefined behaviour to pass a notification
|
* notification_create, it is undefined behaviour to pass a notification
|
||||||
* allocated some other way.
|
* allocated some other way.
|
||||||
*/
|
*/
|
||||||
int notification_init(notification *n, int id)
|
void notification_init(notification *n)
|
||||||
{
|
{
|
||||||
assert(n != NULL);
|
assert(n != NULL);
|
||||||
|
|
||||||
//Prevent undefined behaviour by initialising required fields
|
//Prevent undefined behaviour by initialising required fields
|
||||||
notification_init_defaults(n);
|
notification_init_defaults(n);
|
||||||
|
|
||||||
|
// TODO: this does not belong into notification_init
|
||||||
if (strcmp("DUNST_COMMAND_PAUSE", n->summary) == 0) {
|
if (strcmp("DUNST_COMMAND_PAUSE", n->summary) == 0) {
|
||||||
pause_display = true;
|
pause_display = true;
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp("DUNST_COMMAND_RESUME", n->summary) == 0) {
|
if (strcmp("DUNST_COMMAND_RESUME", n->summary) == 0) {
|
||||||
pause_display = false;
|
pause_display = false;
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
n->script = NULL;
|
n->script = NULL;
|
||||||
@ -423,65 +422,8 @@ int notification_init(notification *n, int id)
|
|||||||
n->msg = buffer;
|
n->msg = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id == 0) {
|
|
||||||
n->id = ++next_notification_id;
|
|
||||||
} else {
|
|
||||||
n->id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
n->dup_count = 0;
|
n->dup_count = 0;
|
||||||
|
|
||||||
/* TODO: move this to queue.c */
|
|
||||||
/* check if n is a duplicate */
|
|
||||||
if (settings.stack_duplicates) {
|
|
||||||
for (GList *iter = g_queue_peek_head_link(queue); iter;
|
|
||||||
iter = iter->next) {
|
|
||||||
notification *orig = iter->data;
|
|
||||||
if (notification_is_duplicate(orig, n)) {
|
|
||||||
/* If the progress differs this was probably intended to replace the notification
|
|
||||||
* but notify-send was used. So don't increment dup_count in this case
|
|
||||||
*/
|
|
||||||
if (orig->progress == n->progress) {
|
|
||||||
orig->dup_count++;
|
|
||||||
} else {
|
|
||||||
orig->progress = n->progress;
|
|
||||||
}
|
|
||||||
/* notifications that differ only in progress hints should be expected equal,
|
|
||||||
* but we want the latest message, with the latest hint value
|
|
||||||
*/
|
|
||||||
g_free(orig->msg);
|
|
||||||
orig->msg = g_strdup(n->msg);
|
|
||||||
notification_free(n);
|
|
||||||
wake_up();
|
|
||||||
return orig->id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (GList *iter = g_queue_peek_head_link(displayed); iter;
|
|
||||||
iter = iter->next) {
|
|
||||||
notification *orig = iter->data;
|
|
||||||
if (notification_is_duplicate(orig, n)) {
|
|
||||||
/* notifications that differ only in progress hints should be expected equal,
|
|
||||||
* but we want the latest message, with the latest hint value
|
|
||||||
*/
|
|
||||||
g_free(orig->msg);
|
|
||||||
orig->msg = g_strdup(n->msg);
|
|
||||||
/* If the progress differs this was probably intended to replace the notification
|
|
||||||
* but notify-send was used. So don't increment dup_count in this case
|
|
||||||
*/
|
|
||||||
if (orig->progress == n->progress) {
|
|
||||||
orig->dup_count++;
|
|
||||||
} else {
|
|
||||||
orig->progress = n->progress;
|
|
||||||
}
|
|
||||||
orig->start = g_get_monotonic_time();
|
|
||||||
notification_free(n);
|
|
||||||
wake_up();
|
|
||||||
return orig->id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* urgency > CRIT -> array out of range */
|
/* urgency > CRIT -> array out of range */
|
||||||
n->urgency = n->urgency > CRIT ? CRIT : n->urgency;
|
n->urgency = n->urgency > CRIT ? CRIT : n->urgency;
|
||||||
|
|
||||||
@ -507,15 +449,13 @@ int notification_init(notification *n, int id)
|
|||||||
|
|
||||||
n->first_render = true;
|
n->first_render = true;
|
||||||
|
|
||||||
|
/* TODO: this should not be part of notification_init */
|
||||||
if (strlen(n->msg) == 0) {
|
if (strlen(n->msg) == 0) {
|
||||||
notification_close(n, 2);
|
notification_close(n, 2);
|
||||||
if (settings.always_run_script) {
|
if (settings.always_run_script) {
|
||||||
notification_run_script(n);
|
notification_run_script(n);
|
||||||
}
|
}
|
||||||
printf("skipping notification: %s %s\n", n->body, n->summary);
|
printf("skipping notification: %s %s\n", n->body, n->summary);
|
||||||
} else {
|
|
||||||
if (id == 0 || !notification_replace_by_id(n))
|
|
||||||
g_queue_insert_sorted(queue, n, notification_cmp_data, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *tmp = g_strconcat(n->summary, " ", n->body, NULL);
|
char *tmp = g_strconcat(n->summary, " ", n->body, NULL);
|
||||||
@ -540,11 +480,6 @@ int notification_init(notification *n, int id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_free(tmp);
|
g_free(tmp);
|
||||||
|
|
||||||
if (settings.print_notifications)
|
|
||||||
notification_print(n);
|
|
||||||
|
|
||||||
return n->id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void notification_update_text_to_render(notification *n)
|
void notification_update_text_to_render(notification *n)
|
||||||
|
@ -62,7 +62,7 @@ typedef struct _notification {
|
|||||||
} notification;
|
} notification;
|
||||||
|
|
||||||
notification *notification_create(void);
|
notification *notification_create(void);
|
||||||
int notification_init(notification *n, int id);
|
void notification_init(notification *n);
|
||||||
void notification_free(notification *n);
|
void notification_free(notification *n);
|
||||||
int notification_cmp(const void *a, const void *b);
|
int notification_cmp(const void *a, const void *b);
|
||||||
int notification_cmp_data(const void *a, const void *b, void *data);
|
int notification_cmp_data(const void *a, const void *b, void *data);
|
||||||
|
81
src/queues.c
81
src/queues.c
@ -15,6 +15,9 @@ GQueue *displayed = NULL; /* currently displayed notifications */
|
|||||||
GQueue *history = NULL; /* history of displayed notifications */
|
GQueue *history = NULL; /* history of displayed notifications */
|
||||||
|
|
||||||
unsigned int displayed_limit = 0;
|
unsigned int displayed_limit = 0;
|
||||||
|
int next_notification_id = 1;
|
||||||
|
|
||||||
|
static int queues_stack_duplicate(notification *n);
|
||||||
|
|
||||||
void queues_init(void)
|
void queues_init(void)
|
||||||
{
|
{
|
||||||
@ -28,6 +31,84 @@ void queues_displayed_limit(unsigned int limit)
|
|||||||
displayed_limit = limit;
|
displayed_limit = limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int queues_notification_insert(notification *n, int replaces_id)
|
||||||
|
{
|
||||||
|
if (replaces_id == 0) {
|
||||||
|
|
||||||
|
n->id = ++next_notification_id;
|
||||||
|
|
||||||
|
if (settings.stack_duplicates) {
|
||||||
|
int stacked = queues_stack_duplicate(n);
|
||||||
|
if (stacked > 0) {
|
||||||
|
// notification got stacked
|
||||||
|
return stacked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_queue_insert_sorted(queue, n, notification_cmp_data, NULL);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
n->id = replaces_id;
|
||||||
|
if (!notification_replace_by_id(n))
|
||||||
|
g_queue_insert_sorted(queue, n, notification_cmp_data, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.print_notifications)
|
||||||
|
notification_print(n);
|
||||||
|
|
||||||
|
return n->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Replaces duplicate notification and stacks it
|
||||||
|
*
|
||||||
|
* Returns the notification id of the stacked notification
|
||||||
|
* Returns -1 if not notification could be stacked
|
||||||
|
*/
|
||||||
|
static int queues_stack_duplicate(notification *n)
|
||||||
|
{
|
||||||
|
for (GList *iter = g_queue_peek_head_link(displayed); iter;
|
||||||
|
iter = iter->next) {
|
||||||
|
notification *orig = iter->data;
|
||||||
|
if (notification_is_duplicate(orig, n)) {
|
||||||
|
/* If the progress differs, probably notify-send was used to update the notification
|
||||||
|
* So only count it as a duplicate, if the progress was not the same.
|
||||||
|
* */
|
||||||
|
if (orig->progress == n->progress) {
|
||||||
|
orig->dup_count++;
|
||||||
|
} else {
|
||||||
|
orig->progress = n->progress;
|
||||||
|
}
|
||||||
|
orig->start = g_get_monotonic_time();
|
||||||
|
g_free(orig->msg);
|
||||||
|
orig->msg = g_strdup(n->msg);
|
||||||
|
notification_free(n);
|
||||||
|
return orig->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (GList *iter = g_queue_peek_head_link(queue); iter;
|
||||||
|
iter = iter->next) {
|
||||||
|
notification *orig = iter->data;
|
||||||
|
if (notification_is_duplicate(orig, n)) {
|
||||||
|
/* If the progress differs, probably notify-send was used to update the notification
|
||||||
|
* So only count it as a duplicate, if the progress was not the same.
|
||||||
|
* */
|
||||||
|
if (orig->progress == n->progress) {
|
||||||
|
orig->dup_count++;
|
||||||
|
} else {
|
||||||
|
orig->progress = n->progress;
|
||||||
|
}
|
||||||
|
g_free(orig->msg);
|
||||||
|
orig->msg = g_strdup(n->msg);
|
||||||
|
notification_free(n);
|
||||||
|
return orig->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
bool notification_replace_by_id(notification *new)
|
bool notification_replace_by_id(notification *new)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
11
src/queues.h
11
src/queues.h
@ -21,6 +21,17 @@ void queues_init(void);
|
|||||||
*/
|
*/
|
||||||
void queues_displayed_limit(unsigned int limit);
|
void queues_displayed_limit(unsigned int limit);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Insert a fully initialized notification into queues
|
||||||
|
* Respects stack_duplicates, and notification replacement
|
||||||
|
*
|
||||||
|
* If replaces_id != 0, n replaces notification with id replaces_id
|
||||||
|
* If replaces_id == 0, n gets occupies a new position
|
||||||
|
*
|
||||||
|
* Returns the assigned notification id
|
||||||
|
*/
|
||||||
|
int queues_notification_insert(notification *n, int replaces_id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Replace the notification which matches the id field of
|
* Replace the notification which matches the id field of
|
||||||
* the new notification. The given notification is inserted
|
* the new notification. The given notification is inserted
|
||||||
|
Loading…
x
Reference in New Issue
Block a user