use queue for notification queue

This commit is contained in:
Sascha Kruse 2012-12-12 12:06:04 +01:00
parent 557a8e29fa
commit 1dd6e2587e
3 changed files with 139 additions and 72 deletions

View File

@ -265,7 +265,7 @@ void l_sort(list * l, int (*f) (void *, void *))
void n_stack_push(n_stack **s, notification *n) void n_stack_push(n_stack **s, notification *n)
{ {
if (!n) if (!n || !s)
return; return;
n_stack *new = malloc(sizeof(n_stack)); n_stack *new = malloc(sizeof(n_stack));
@ -288,4 +288,86 @@ notification *n_stack_pop(n_stack **s)
return n; return n;
} }
int n_stack_len(n_stack **s)
{
if (!s || !*s)
return 0;
n_stack *cur = *s;
int count = 0;
while (cur) {
cur = cur->next;
count++;
}
return count;
}
int cmp_notification(notification *a, notification *b)
{
if (a == NULL && b == NULL)
return 0;
else if (a == NULL)
return -1;
else if (b == NULL)
return 1;
if (a->urgency != b->urgency) {
return a->urgency - b->urgency;
} else {
return b->timestamp - a->timestamp;
}
}
void n_queue_enqueue(n_queue **q, notification *n)
{
if (!n || !q)
return;
n_queue *new = malloc(sizeof(n_queue));
new->n = n;
new->next = NULL;
if (!(*q)) {
/* queue was empty */
*q = new;
return;
}
/* new head */
if (cmp_notification(new->n, (*q)->n) > 0) {
new->next = *q;
*q = new;
return;
}
/* in between */
n_queue *cur = *q;
while (cur->next) {
if (cmp_notification(new->n, cur->next->n) > 0) {
new->next = cur->next;
cur->next = new;
return;
}
cur = cur->next;
}
/* last */
cur->next = new;
}
notification *n_queue_dequeue(n_queue **q)
{
return n_stack_pop(q);
}
int n_queue_len(n_queue **q)
{
return n_stack_len(q);
}
/* vim: set ts=8 sw=8 tw=0: */ /* vim: set ts=8 sw=8 tw=0: */

View File

@ -17,6 +17,10 @@ typedef struct _n_stack {
struct _n_stack *next; struct _n_stack *next;
} n_stack; } n_stack;
typedef n_stack n_queue;
int cmp_notification(notification *a, notification *b);
/* append to end of list */ /* append to end of list */
int l_push(list * l, void *data); int l_push(list * l, void *data);
@ -79,6 +83,35 @@ void n_stack_push(n_stack **s, notification *n);
*/ */
notification *n_stack_pop(n_stack **s); notification *n_stack_pop(n_stack **s);
/**
* return length of stack
*/
int n_stack_len(n_stack **s);
/***************
* queue
*/
/**
* enqueue notification into queue
* creates a new queue if *q == NULL
*/
void n_queue_enqueue(n_queue **q, notification *n);
/**
* dequeues the next element from the queue.
* returns NULL if queue is empty
*/
notification *n_queue_dequeue(n_queue **q);
/**
* return length of queue
*/
int n_queue_len(n_queue **q);
#endif #endif
/* vim: set ts=8 sw=8 tw=0: */ /* vim: set ts=8 sw=8 tw=0: */

94
dunst.c
View File

@ -79,7 +79,7 @@ bool dunst_grab_errored = false;
int next_notification_id = 1; int next_notification_id = 1;
/* notification lists */ /* notification lists */
list *notification_queue = NULL; /* all new notifications get into here */ n_queue *queue = NULL; /* all new notifications get into here */
list *displayed_notifications = NULL; /* currently displayed notifications */ list *displayed_notifications = NULL; /* currently displayed notifications */
n_stack *n_history = NULL; /* history of displayed notifications */ n_stack *n_history = NULL; /* history of displayed notifications */
@ -194,51 +194,6 @@ void ungrab_key(keyboard_shortcut * ks)
XUngrabKey(dc->dpy, ks->code, ks->mask, root); XUngrabKey(dc->dpy, ks->code, ks->mask, root);
} }
int cmp_notification(void *a, void *b)
{
if (a == NULL && b == NULL)
return 0;
else if (a == NULL)
return -1;
else if (b == NULL)
return 1;
notification *na = (notification *) a;
notification *nb = (notification *) b;
if (na->urgency != nb->urgency) {
return na->urgency - nb->urgency;
} else {
return nb->timestamp - na->timestamp;
}
}
l_node *most_important(list * l)
{
if (l == NULL || l_is_empty(l)) {
return NULL;
}
if (sort) {
notification *max;
l_node *node_max;
notification *data;
max = l->head->data;
node_max = l->head;
for (l_node * iter = l->head; iter; iter = iter->next) {
data = (notification *) iter->data;
if (cmp_notification(max, data) < 0) {
max = data;
node_max = iter;
}
}
return node_max;
} else {
return l->head;
}
}
void apply_rules(notification * n) void apply_rules(notification * n)
{ {
@ -303,15 +258,14 @@ void check_timeouts(void)
void update_lists() void update_lists()
{ {
l_node *to_move;
notification *n;
int limit; int limit;
check_timeouts(); check_timeouts();
if (pause_display) { if (pause_display) {
while (!l_is_empty(displayed_notifications)) { while (!l_is_empty(displayed_notifications)) {
l_move(displayed_notifications, notification_queue, displayed_notifications->head); notification *n = (notification *) l_remove(displayed_notifications, displayed_notifications->head);
n_queue_enqueue(&queue, n);
} }
return; return;
} }
@ -328,23 +282,20 @@ void update_lists()
/* move notifications from queue to displayed */ /* move notifications from queue to displayed */
while (!l_is_empty(notification_queue)) { while (queue) {
if (limit > 0 && l_length(displayed_notifications) >= limit) { if (limit > 0 && l_length(displayed_notifications) >= limit) {
/* the list is full */ /* the list is full */
break; break;
} }
to_move = most_important(notification_queue); notification *n = n_queue_dequeue(&queue);
if (!to_move) {
return;
}
n = (notification *) to_move->data;
if (!n) if (!n)
return; return;
n->start = now; n->start = now;
l_move(notification_queue, displayed_notifications, to_move); l_push(displayed_notifications, n);
l_sort(displayed_notifications, cmp_notification); l_sort(displayed_notifications, cmp_notification);
@ -629,7 +580,7 @@ void fill_line_cache(int width)
assert(line_cache.count > 0); assert(line_cache.count > 0);
/* add (x more) */ /* add (x more) */
int queue_cnt = l_length(notification_queue); int queue_cnt = n_queue_len(&queue);
if (indicate_hidden && queue_cnt > 0) { if (indicate_hidden && queue_cnt > 0) {
if (geometry.h != 1) { if (geometry.h != 1) {
char *tmp; char *tmp;
@ -846,10 +797,11 @@ void move_all_to_history()
n = (notification *) node->data; n = (notification *) node->data;
close_notification(n, 2); close_notification(n, 2);
} }
while (!l_is_empty(notification_queue)) {
node = notification_queue->head; n = n_queue_dequeue(&queue);
n = (notification *) node->data; while (n) {
close_notification(n, 2); n_stack_push(&n_history, n);
n = n_queue_dequeue(&queue);
} }
} }
@ -863,7 +815,7 @@ void history_pop(void)
n->redisplayed = true; n->redisplayed = true;
n->start = 0; n->start = 0;
n->timeout = sticky_history ? 0 : n->timeout; n->timeout = sticky_history ? 0 : n->timeout;
l_push(notification_queue, n); n_queue_enqueue(&queue, n);
if (!visible) { if (!visible) {
map_win(); map_win();
@ -923,8 +875,8 @@ int init_notification(notification * n, int id)
n->dup_count = 0; n->dup_count = 0;
/* check if n is a duplicate */ /* check if n is a duplicate */
for (l_node * iter = notification_queue->head; iter; iter = iter->next) { for (n_queue *iter = queue; iter; iter = iter->next) {
notification *orig = (notification *) iter->data; notification *orig = iter->n;
if (strcmp(orig->appname, n->appname) == 0 if (strcmp(orig->appname, n->appname) == 0
&& strcmp(orig->msg, n->msg) == 0) { && strcmp(orig->msg, n->msg) == 0) {
orig->dup_count++; orig->dup_count++;
@ -980,7 +932,7 @@ int init_notification(notification * n, int id)
close_notification(n, 2); close_notification(n, 2);
printf("skipping notification: %s %s\n", n->body, n->summary); printf("skipping notification: %s %s\n", n->body, n->summary);
} else { } else {
l_push(notification_queue, n); n_queue_enqueue(&queue, n);
} }
if (print_notifications) if (print_notifications)
@ -998,10 +950,9 @@ int init_notification(notification * n, int id)
*/ */
int close_notification_by_id(int id, int reason) int close_notification_by_id(int id, int reason)
{ {
l_node *iter;
notification *target = NULL; notification *target = NULL;
for (iter = displayed_notifications->head; iter; iter = iter->next) { for (l_node *iter = displayed_notifications->head; iter; iter = iter->next) {
notification *n = (notification *) iter->data; notification *n = (notification *) iter->data;
if (n->id == id) { if (n->id == id) {
l_remove(displayed_notifications, iter); l_remove(displayed_notifications, iter);
@ -1011,10 +962,12 @@ int close_notification_by_id(int id, int reason)
} }
} }
for (iter = notification_queue->head; iter; iter = iter->next) { for (n_queue *iter = queue; iter && iter->next; iter = iter->next) {
notification *n = (notification *) iter->data; notification *n = iter->next->n;
if (n->id == id) { if (n->id == id) {
l_remove(notification_queue, iter); n_queue *tmp = iter->next;
iter->next = iter->next->next;
free(tmp);
n_stack_push(&n_history, n); n_stack_push(&n_history, n);
target = n; target = n;
break; break;
@ -1623,7 +1576,6 @@ int main(int argc, char *argv[])
{ {
now = time(&now); now = time(&now);
notification_queue = l_init();
displayed_notifications = l_init(); displayed_notifications = l_init();
r_line_cache_init(&line_cache); r_line_cache_init(&line_cache);