rework draw_win to use buffers
This makes it much easier to add additional text to the Notifications without changing the next of the notification itself. This also implements issue #27
This commit is contained in:
parent
41540c4bde
commit
7a1d758242
116
dunst.c
116
dunst.c
@ -44,6 +44,11 @@ typedef struct _screen_info {
|
|||||||
dimension_t dim;
|
dimension_t dim;
|
||||||
} screen_info;
|
} screen_info;
|
||||||
|
|
||||||
|
typedef struct _notification_buffer {
|
||||||
|
char txt[BUFSIZ];
|
||||||
|
notification *n;
|
||||||
|
} notification_buffer;
|
||||||
|
|
||||||
/* global variables */
|
/* global variables */
|
||||||
char *font = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*";
|
char *font = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*";
|
||||||
char *normbgcolor = "#1793D1";
|
char *normbgcolor = "#1793D1";
|
||||||
@ -114,7 +119,7 @@ void hide_win(void);
|
|||||||
void move_all_to_history(void);
|
void move_all_to_history(void);
|
||||||
void print_version(void);
|
void print_version(void);
|
||||||
|
|
||||||
int cmp_notification(void * a, void * b)
|
int cmp_notification(void *a, void *b)
|
||||||
{
|
{
|
||||||
notification *na = (notification *) a;
|
notification *na = (notification *) a;
|
||||||
notification *nb = (notification *) b;
|
notification *nb = (notification *) b;
|
||||||
@ -290,65 +295,72 @@ void update_lists()
|
|||||||
void draw_win(void)
|
void draw_win(void)
|
||||||
{
|
{
|
||||||
int width, x, y, height;
|
int width, x, y, height;
|
||||||
|
int i;
|
||||||
unsigned int len = l_length(displayed_notifications);
|
unsigned int len = l_length(displayed_notifications);
|
||||||
l_node *iter;
|
l_node *iter;
|
||||||
notification *data;
|
notification_buffer *n_buf;
|
||||||
char hidden[128];
|
|
||||||
ColorSet *hidden_colors = colors[NORM];
|
|
||||||
dc->x = 0;
|
dc->x = 0;
|
||||||
dc->y = 0;
|
dc->y = 0;
|
||||||
dc->h = 0;
|
dc->h = 0;
|
||||||
|
|
||||||
|
/* calculate height */
|
||||||
if (geometry.h == 0) {
|
if (geometry.h == 0) {
|
||||||
height = len;
|
height = len;
|
||||||
} else {
|
} else {
|
||||||
height = MIN(geometry.h, len);
|
height = MIN(geometry.h, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (indicate_hidden && !l_is_empty(notification_queue)) {
|
if (indicate_hidden && geometry.h != 1
|
||||||
sprintf(hidden, "(%d more)", l_length(notification_queue));
|
&& !l_is_empty(notification_queue)) {
|
||||||
height++;
|
height++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* initialize and fill buffers */
|
||||||
* calculate the width
|
n_buf = calloc(height, sizeof(notification_buffer));
|
||||||
*/
|
|
||||||
|
|
||||||
if (geometry.mask & HeightValue) {
|
for (i = 0, iter = displayed_notifications->head; i < height; i++) {
|
||||||
if (geometry.h) {
|
memset(n_buf[i].txt, '\0', BUFSIZ);
|
||||||
/* code */
|
if (iter) {
|
||||||
|
n_buf[i].n = (notification *) iter->data;
|
||||||
|
strncpy(n_buf[i].txt, n_buf[i].n->msg, BUFSIZ);
|
||||||
|
iter = iter->next;
|
||||||
|
} else {
|
||||||
|
n_buf[i].n = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* defined width */
|
|
||||||
if (geometry.mask & WidthValue) {
|
|
||||||
|
|
||||||
|
/* add "(x more)" */
|
||||||
|
if (indicate_hidden && geometry.h != 1
|
||||||
|
&& !l_is_empty(notification_queue)) {
|
||||||
|
snprintf(n_buf[height - 1].txt, BUFSIZ, "(%d more)",
|
||||||
|
l_length(notification_queue));
|
||||||
|
|
||||||
|
} else if (indicate_hidden && !l_is_empty(notification_queue)) {
|
||||||
|
/* append "(x more)" message to notification text */
|
||||||
|
char *begin;
|
||||||
|
for (begin = n_buf[0].txt; *begin != '\0'; begin++) ;
|
||||||
|
snprintf(begin, BUFSIZ - strlen(n_buf[0].txt),
|
||||||
|
" (%d more)", l_length(notification_queue));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate width */
|
||||||
|
if (geometry.mask & WidthValue && geometry.w == 0) {
|
||||||
/* dynamic width */
|
/* dynamic width */
|
||||||
if (geometry.w == 0) {
|
width = 0;
|
||||||
width = 0;
|
for (i = 0; i < height; i++) {
|
||||||
|
width = MAX(width, textw(dc, n_buf[i].txt));
|
||||||
for (iter = displayed_notifications->head;
|
|
||||||
iter; iter = iter->next) {
|
|
||||||
data = (notification *) iter->data;
|
|
||||||
width = MAX(width, textw(dc, data->msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we also have the "(x more)" message into account */
|
|
||||||
if (indicate_hidden
|
|
||||||
&& !l_is_empty(displayed_notifications)) {
|
|
||||||
width = MAX(width, textw(dc, hidden));
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
width = geometry.w;
|
|
||||||
}
|
}
|
||||||
|
} else if (geometry.mask & WidthValue) {
|
||||||
|
/* fixed width */
|
||||||
|
width = geometry.w;
|
||||||
} else {
|
} else {
|
||||||
|
/* across the screen */
|
||||||
width = scr.dim.w;
|
width = scr.dim.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* calculate window position
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
/* calculate window position */
|
||||||
if (geometry.mask & XNegative) {
|
if (geometry.mask & XNegative) {
|
||||||
x = (scr.dim.x + (scr.dim.w - width)) + geometry.x;
|
x = (scr.dim.x + (scr.dim.w - width)) + geometry.x;
|
||||||
} else {
|
} else {
|
||||||
@ -366,31 +378,29 @@ void draw_win(void)
|
|||||||
XResizeWindow(dc->dpy, win, width, height * font_h);
|
XResizeWindow(dc->dpy, win, width, height * font_h);
|
||||||
drawrect(dc, 0, 0, width, height * font_h, True, colors[NORM]->BG);
|
drawrect(dc, 0, 0, width, height * font_h, True, colors[NORM]->BG);
|
||||||
|
|
||||||
/* draw notifications */
|
/* draw buffers */
|
||||||
for (iter = displayed_notifications->head; iter; iter = iter->next) {
|
for (i = 0; i < height; i++) {
|
||||||
data = (notification *) iter->data;
|
if (strlen(n_buf[i].txt) > 0) {
|
||||||
|
notification *n;
|
||||||
|
/*
|
||||||
|
* "(x more)" hasn't got a notification assigned to it.
|
||||||
|
* Take the previous notification instead to 'clone'
|
||||||
|
* its attributes
|
||||||
|
*/
|
||||||
|
n = n_buf[i].n ? n_buf[i].n : n_buf[i - 1].n;
|
||||||
|
|
||||||
drawrect(dc, 0, dc->y, width, font_h, True, data->colors->BG);
|
drawrect(dc, 0, 0, width, font_h, True, n->colors->BG);
|
||||||
drawtext(dc, data->msg, data->colors);
|
drawtext(dc, n_buf[i].txt, n->colors);
|
||||||
dc->y += font_h;
|
dc->y += font_h;
|
||||||
|
}
|
||||||
/* the "(x more)" message should have the same BG-color as
|
|
||||||
* the last displayed_notifications
|
|
||||||
*/
|
|
||||||
hidden_colors = data->colors;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* actually draw the "(x more)" message */
|
|
||||||
if (indicate_hidden && !l_is_empty(notification_queue)) {
|
|
||||||
drawrect(dc, 0, dc->y, width, font_h, True, hidden_colors->BG);
|
|
||||||
|
|
||||||
drawtext(dc, hidden, hidden_colors);
|
|
||||||
dc->y += font_h;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* move and map window */
|
/* move and map window */
|
||||||
XMoveWindow(dc->dpy, win, x, y);
|
XMoveWindow(dc->dpy, win, x, y);
|
||||||
mapdc(dc, win, width, height * font_h);
|
mapdc(dc, win, width, height * font_h);
|
||||||
|
|
||||||
|
/* cleanup */
|
||||||
|
free(n_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dunst_printf(int level, const char *fmt, ...)
|
void dunst_printf(int level, const char *fmt, ...)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user