From c2801181f8ca05c026f1d045a377b7e5410e31c5 Mon Sep 17 00:00:00 2001 From: Gjum Date: Tue, 25 Feb 2014 23:07:02 +0100 Subject: [PATCH 1/8] Add icon support - icons are displayed at the top left corner - disabed by default, fully backwards-compatible - no additional dependencies, only cairo used - TODO: only supports png (but all default images are png) - TODO: message formatting is sometimes buggy --- dunstrc | 6 ++++++ notification.c | 5 +++++ settings.c | 9 +++++++++ settings.h | 2 ++ x.c | 40 ++++++++++++++++++++++++++++++++++++---- 5 files changed, 58 insertions(+), 4 deletions(-) diff --git a/dunstrc b/dunstrc index c0a629d..f50618e 100644 --- a/dunstrc +++ b/dunstrc @@ -138,6 +138,12 @@ # Browser for opening urls in context menu. browser = /usr/bin/firefox -new-tab + # Show icons in notifications. + show_icons = no + + # Path to default icons. + icon_path = /usr/share/icons/gnome/32x32/status/%s.png + [frame] width = 3 color = "#aaaaaa" diff --git a/notification.c b/notification.c index 42242d6..286f407 100644 --- a/notification.c +++ b/notification.c @@ -281,6 +281,11 @@ int notification_init(notification * n, int id) n->urls = notification_extract_markup_urls(&(n->body)); + /* Add icon path if relative */ + if (strlen(n->icon) > 0 && n->icon[0] != '/' && n->icon[0] != '~') { + n->icon = string_replace("%s", n->icon, settings.icon_path); + } + n->msg = string_replace("%a", n->appname, g_strdup(n->format)); n->msg = string_replace("%s", n->summary, n->msg); if (n->icon) { diff --git a/settings.c b/settings.c index 7b87d7a..a52a948 100644 --- a/settings.c +++ b/settings.c @@ -192,6 +192,15 @@ void load_settings(char *cmdline_config_path) option_get_string("global", "browser", "-browser", browser, "path to browser"); + settings.show_icons = + option_get_bool("global", "show_icons", + "-show_icons", false, + "show icons in notifications"); + + settings.icon_path = + option_get_string("global", "icon_path", "-icon_path", icon_path, + "path to default icons"); + settings.frame_width = option_get_int("frame", "width", "-frame_width", frame_width, "Width of frame around window"); diff --git a/settings.h b/settings.h index 9481cce..dc368a8 100644 --- a/settings.h +++ b/settings.h @@ -42,6 +42,8 @@ typedef struct _settings { char *dmenu; char **dmenu_cmd; char *browser; + bool show_icons; + char *icon_path; enum follow_mode f_mode; keyboard_shortcut close_ks; keyboard_shortcut close_all_ks; diff --git a/x.c b/x.c index a4e877f..b3edf93 100644 --- a/x.c +++ b/x.c @@ -40,6 +40,7 @@ typedef struct _colored_layout { color_t bg; char *text; PangoAttrList *attr; + cairo_surface_t *icon; } colored_layout; cairo_ctx_t cairo_ctx; @@ -166,6 +167,7 @@ static void free_colored_layout(void *data) g_object_unref(cl->l); pango_attr_list_unref(cl->attr); g_free(cl->text); + if (cl->icon) cairo_surface_destroy(cl->icon); g_free(cl); } @@ -203,11 +205,20 @@ static dimension_t calculate_dimensions(GSList *layouts) dim.h += (g_slist_length(layouts) - 1) * settings.separator_height; dim.h += g_slist_length(layouts) * settings.padding * 2; + /* text_width: width of the widest content so far + * total_width: width of the widest notification so far, with padding + * dim.w: width of the window, with frame + * Also call r_setup_pango_layout() when changing text_width. + */ int text_width = 0, total_width = 0; for (GSList *iter = layouts; iter; iter = iter->next) { colored_layout *cl = iter->data; int w=0,h=0; pango_layout_get_pixel_size(cl->l, &w, &h); + if (cl->icon) { + h = MAX(cairo_image_surface_get_height(cl->icon), h); + w += cairo_image_surface_get_width(cl->icon) + settings.h_padding; + } dim.h += h; text_width = MAX(w, text_width); @@ -227,13 +238,18 @@ static dimension_t calculate_dimensions(GSList *layouts) } /* re-setup the layout */ - int width = dim.w; - width -= 2 * settings.h_padding; - width -= 2 * settings.frame_width; - r_setup_pango_layout(cl->l, width); + w = dim.w; + w -= 2 * settings.h_padding; + w -= 2 * settings.frame_width; + if (cl->icon) w -= cairo_image_surface_get_width(cl->icon) + settings.h_padding; + r_setup_pango_layout(cl->l, w); /* re-read information */ pango_layout_get_pixel_size(cl->l, &w, &h); + if (cl->icon) { + h = MAX(cairo_image_surface_get_height(cl->icon), h); + w += cairo_image_surface_get_width(cl->icon) + settings.h_padding; + } dim.h += h; text_width = MAX(w, text_width); } @@ -256,6 +272,9 @@ static colored_layout *r_init_shared(cairo_t *c, notification *n) pango_layout_set_ellipsize(cl->l, PANGO_ELLIPSIZE_MIDDLE); } + cl->icon = NULL; + if (strlen(n->icon) > 0 && settings.show_icons) + cl->icon = cairo_image_surface_create_from_png(n->icon); cl->fg = x_string_to_color_t(n->color_strings[ColFG]); cl->bg = x_string_to_color_t(n->color_strings[ColBG]); @@ -268,6 +287,7 @@ static colored_layout *r_init_shared(cairo_t *c, notification *n) } else { width -= 2 * settings.h_padding; width -= 2 * settings.frame_width; + if (cl->icon) width -= cairo_image_surface_get_width(cl->icon) + settings.h_padding; r_setup_pango_layout(cl->l, width); } @@ -309,6 +329,7 @@ static colored_layout *r_create_layout_from_notification(cairo_t *c, notificatio pango_layout_get_pixel_size(cl->l, NULL, &(n->displayed_height)); + if (cl->icon) n->displayed_height = MAX(cairo_image_surface_get_height(cl->icon), n->displayed_height); n->displayed_height += 2 * settings.padding; n->first_render = false; @@ -358,6 +379,7 @@ static dimension_t x_render_layout(cairo_t *c, colored_layout *cl, dimension_t d { int h; pango_layout_get_pixel_size(cl->l, NULL, &h); + if (cl->icon) h = MAX(cairo_image_surface_get_height(cl->icon), h); int bg_x = 0; int bg_y = dim.y; @@ -397,6 +419,16 @@ static dimension_t x_render_layout(cairo_t *c, colored_layout *cl, dimension_t d } cairo_move_to(c, settings.h_padding, dim.y); + if (cl->icon) { + unsigned int image_width = cairo_image_surface_get_width(cl->icon), + image_height = cairo_image_surface_get_height(cl->icon), + image_x = bg_width - settings.h_padding - image_width, + image_y = bg_y + settings.padding; + cairo_set_source_surface (c, cl->icon, image_x, image_y); + cairo_rectangle (c, image_x, image_y, image_width, image_height); + cairo_fill (c); + } + return dim; } From d9e68803dcc0bf11d18c3531178cc492155773d7 Mon Sep 17 00:00:00 2001 From: Gjum Date: Wed, 26 Feb 2014 18:52:36 +0100 Subject: [PATCH 2/8] Fix stuff regarding icons - fix icon_path string calculations - add default settings to config.def.h --- config.def.h | 3 +++ dunstrc | 2 +- notification.c | 4 +++- x.c | 5 ----- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/config.def.h b/config.def.h index 169683f..45d0c19 100644 --- a/config.def.h +++ b/config.def.h @@ -50,6 +50,9 @@ char *dmenu = "/usr/bin/dmenu"; char *browser = "/usr/bin/firefox"; +/* path to default icons */ +char *icon_path = "/usr/share/icons/gnome/32x32/status/"; + /* follow focus to different monitor and display notifications there? * possible values: * FOLLOW_NONE diff --git a/dunstrc b/dunstrc index f50618e..e9f78bf 100644 --- a/dunstrc +++ b/dunstrc @@ -142,7 +142,7 @@ show_icons = no # Path to default icons. - icon_path = /usr/share/icons/gnome/32x32/status/%s.png + icon_path = /usr/share/icons/gnome/32x32/status/ [frame] width = 3 diff --git a/notification.c b/notification.c index 286f407..d806f25 100644 --- a/notification.c +++ b/notification.c @@ -283,7 +283,9 @@ int notification_init(notification * n, int id) /* Add icon path if relative */ if (strlen(n->icon) > 0 && n->icon[0] != '/' && n->icon[0] != '~') { - n->icon = string_replace("%s", n->icon, settings.icon_path); + char *new = g_strconcat(settings.icon_path, n->icon, ".png", NULL); + free(n->icon); + n->icon = new; } n->msg = string_replace("%a", n->appname, g_strdup(n->format)); diff --git a/x.c b/x.c index b3edf93..88c2504 100644 --- a/x.c +++ b/x.c @@ -205,11 +205,6 @@ static dimension_t calculate_dimensions(GSList *layouts) dim.h += (g_slist_length(layouts) - 1) * settings.separator_height; dim.h += g_slist_length(layouts) * settings.padding * 2; - /* text_width: width of the widest content so far - * total_width: width of the widest notification so far, with padding - * dim.w: width of the window, with frame - * Also call r_setup_pango_layout() when changing text_width. - */ int text_width = 0, total_width = 0; for (GSList *iter = layouts; iter; iter = iter->next) { colored_layout *cl = iter->data; From 01327a6bc4d9d2a99b0ce9804436ebdc4e84cf0d Mon Sep 17 00:00:00 2001 From: Gjum Date: Wed, 26 Feb 2014 22:42:05 +0100 Subject: [PATCH 3/8] Add option to align icons left or right --- dunst.h | 1 + dunstrc | 4 ++-- settings.c | 21 +++++++++++++++++---- settings.h | 2 +- x.c | 12 +++++++++--- 5 files changed, 30 insertions(+), 10 deletions(-) diff --git a/dunst.h b/dunst.h index 97d67a7..ad17b19 100644 --- a/dunst.h +++ b/dunst.h @@ -16,6 +16,7 @@ #define ColBG 0 enum alignment { left, center, right }; +enum icon_position_t { icons_left, icons_right, icons_off }; enum separator_color { FOREGROUND, AUTO, FRAME, CUSTOM }; enum follow_mode { FOLLOW_NONE, FOLLOW_MOUSE, FOLLOW_KEYBOARD }; diff --git a/dunstrc b/dunstrc index e9f78bf..21bf6f8 100644 --- a/dunstrc +++ b/dunstrc @@ -138,8 +138,8 @@ # Browser for opening urls in context menu. browser = /usr/bin/firefox -new-tab - # Show icons in notifications. - show_icons = no + # Align icons left/right/off + icon_position = off # Path to default icons. icon_path = /usr/share/icons/gnome/32x32/status/ diff --git a/settings.c b/settings.c index a52a948..1eaeb44 100644 --- a/settings.c +++ b/settings.c @@ -192,10 +192,23 @@ void load_settings(char *cmdline_config_path) option_get_string("global", "browser", "-browser", browser, "path to browser"); - settings.show_icons = - option_get_bool("global", "show_icons", - "-show_icons", false, - "show icons in notifications"); + { + char *c = option_get_string("global", "icon_position", + "-icon_position", "off", + "Align icons left/right/off"); + if (strlen(c) > 0) { + if (strcmp(c, "left") == 0) + settings.icon_position = icons_left; + else if (strcmp(c, "right") == 0) + settings.icon_position = icons_right; + else if (strcmp(c, "off") == 0) + settings.icon_position = icons_off; + else + fprintf(stderr, + "Warning: unknown icon position: %s\n", c); + free(c); + } + } settings.icon_path = option_get_string("global", "icon_path", "-icon_path", icon_path, diff --git a/settings.h b/settings.h index dc368a8..6f6e3c2 100644 --- a/settings.h +++ b/settings.h @@ -42,7 +42,7 @@ typedef struct _settings { char *dmenu; char **dmenu_cmd; char *browser; - bool show_icons; + enum icon_position_t icon_position; char *icon_path; enum follow_mode f_mode; keyboard_shortcut close_ks; diff --git a/x.c b/x.c index 88c2504..4b835e7 100644 --- a/x.c +++ b/x.c @@ -268,7 +268,7 @@ static colored_layout *r_init_shared(cairo_t *c, notification *n) } cl->icon = NULL; - if (strlen(n->icon) > 0 && settings.show_icons) + if (strlen(n->icon) > 0 && settings.icon_position != icons_off) cl->icon = cairo_image_surface_create_from_png(n->icon); cl->fg = x_string_to_color_t(n->color_strings[ColFG]); @@ -396,7 +396,9 @@ static dimension_t x_render_layout(cairo_t *c, colored_layout *cl, dimension_t d cairo_fill(c); dim.y += settings.padding; - cairo_move_to(c, settings.h_padding, dim.y); + if (cl->icon && settings.icon_position == icons_left) + cairo_move_to(c, cairo_image_surface_get_width(cl->icon) + 2 * settings.h_padding, dim.y); + else cairo_move_to(c, settings.h_padding, dim.y); cairo_set_source_rgb(c, cl->fg.r, cl->fg.g, cl->fg.b); pango_cairo_update_layout(c, cl->l); pango_cairo_show_layout(c, cl->l); @@ -417,8 +419,12 @@ static dimension_t x_render_layout(cairo_t *c, colored_layout *cl, dimension_t d if (cl->icon) { unsigned int image_width = cairo_image_surface_get_width(cl->icon), image_height = cairo_image_surface_get_height(cl->icon), - image_x = bg_width - settings.h_padding - image_width, + image_x, image_y = bg_y + settings.padding; + + if (settings.icon_position == icons_left) image_x = settings.h_padding; + else image_x = bg_width - settings.h_padding - image_width; + cairo_set_source_surface (c, cl->icon, image_x, image_y); cairo_rectangle (c, image_x, image_y, image_width, image_height); cairo_fill (c); From 687a69a99f799c13485b2b7e4f7b0574757e9277 Mon Sep 17 00:00:00 2001 From: Gjum Date: Wed, 26 Feb 2014 23:27:07 +0100 Subject: [PATCH 4/8] Change default icon size to 16x16 (was 32x32) might fit better to dunst's minimalistic style --- config.def.h | 2 +- dunstrc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config.def.h b/config.def.h index 45d0c19..42a3f9b 100644 --- a/config.def.h +++ b/config.def.h @@ -51,7 +51,7 @@ char *dmenu = "/usr/bin/dmenu"; char *browser = "/usr/bin/firefox"; /* path to default icons */ -char *icon_path = "/usr/share/icons/gnome/32x32/status/"; +char *icon_path = "/usr/share/icons/gnome/16x16/status/"; /* follow focus to different monitor and display notifications there? * possible values: diff --git a/dunstrc b/dunstrc index 21bf6f8..4901086 100644 --- a/dunstrc +++ b/dunstrc @@ -142,7 +142,7 @@ icon_position = off # Path to default icons. - icon_path = /usr/share/icons/gnome/32x32/status/ + icon_path = /usr/share/icons/gnome/16x16/status/ [frame] width = 3 From c6ef8ecaedf57728ad7f89c0d05550bc7b84a683 Mon Sep 17 00:00:00 2001 From: Gjum Date: Thu, 27 Feb 2014 00:33:55 +0100 Subject: [PATCH 5/8] Fix error on non-existent icon names --- x.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/x.c b/x.c index 4b835e7..5923e9d 100644 --- a/x.c +++ b/x.c @@ -268,8 +268,15 @@ static colored_layout *r_init_shared(cairo_t *c, notification *n) } cl->icon = NULL; - if (strlen(n->icon) > 0 && settings.icon_position != icons_off) + if (strlen(n->icon) > 0 && settings.icon_position != icons_off) { cl->icon = cairo_image_surface_create_from_png(n->icon); + if (cairo_surface_status(cl->icon) != CAIRO_STATUS_SUCCESS) { + cairo_surface_destroy(cl->icon); + cl->icon = NULL; + fprintf(stderr, + "Could not load icon: %s\n", n->icon); + } + } cl->fg = x_string_to_color_t(n->color_strings[ColFG]); cl->bg = x_string_to_color_t(n->color_strings[ColBG]); From a02ab4cf701e9ba54c8235785f2084f17905051a Mon Sep 17 00:00:00 2001 From: Gjum Date: Thu, 27 Feb 2014 14:37:03 +0100 Subject: [PATCH 6/8] Change how icons are loaded - use several icon_folders instead of a single icon_path - check all paths for the icon --- config.def.h | 4 ++-- dunstrc | 4 ++-- notification.c | 7 ------- settings.c | 6 +++--- settings.h | 2 +- x.c | 54 ++++++++++++++++++++++++++++++++++++++++---------- 6 files changed, 52 insertions(+), 25 deletions(-) diff --git a/config.def.h b/config.def.h index 42a3f9b..8fdc144 100644 --- a/config.def.h +++ b/config.def.h @@ -50,8 +50,8 @@ char *dmenu = "/usr/bin/dmenu"; char *browser = "/usr/bin/firefox"; -/* path to default icons */ -char *icon_path = "/usr/share/icons/gnome/16x16/status/"; +/* paths to default icons */ +char *icon_folders = "/usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/"; /* follow focus to different monitor and display notifications there? * possible values: diff --git a/dunstrc b/dunstrc index 4901086..28a28fb 100644 --- a/dunstrc +++ b/dunstrc @@ -141,8 +141,8 @@ # Align icons left/right/off icon_position = off - # Path to default icons. - icon_path = /usr/share/icons/gnome/16x16/status/ + # Paths to default icons. + icon_folders = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/ [frame] width = 3 diff --git a/notification.c b/notification.c index d806f25..42242d6 100644 --- a/notification.c +++ b/notification.c @@ -281,13 +281,6 @@ int notification_init(notification * n, int id) n->urls = notification_extract_markup_urls(&(n->body)); - /* Add icon path if relative */ - if (strlen(n->icon) > 0 && n->icon[0] != '/' && n->icon[0] != '~') { - char *new = g_strconcat(settings.icon_path, n->icon, ".png", NULL); - free(n->icon); - n->icon = new; - } - n->msg = string_replace("%a", n->appname, g_strdup(n->format)); n->msg = string_replace("%s", n->summary, n->msg); if (n->icon) { diff --git a/settings.c b/settings.c index 1eaeb44..63ffcf1 100644 --- a/settings.c +++ b/settings.c @@ -210,9 +210,9 @@ void load_settings(char *cmdline_config_path) } } - settings.icon_path = - option_get_string("global", "icon_path", "-icon_path", icon_path, - "path to default icons"); + settings.icon_folders = + option_get_string("global", "icon_folders", "-icon_folders", icon_folders, + "paths to default icons"); settings.frame_width = option_get_int("frame", "width", "-frame_width", frame_width, diff --git a/settings.h b/settings.h index 6f6e3c2..8f3726b 100644 --- a/settings.h +++ b/settings.h @@ -43,7 +43,7 @@ typedef struct _settings { char **dmenu_cmd; char *browser; enum icon_position_t icon_position; - char *icon_path; + char *icon_folders; enum follow_mode f_mode; keyboard_shortcut close_ks; keyboard_shortcut close_all_ks; diff --git a/x.c b/x.c index 5923e9d..3aff9e0 100644 --- a/x.c +++ b/x.c @@ -258,6 +258,49 @@ static dimension_t calculate_dimensions(GSList *layouts) return dim; } +static cairo_t *get_icon_surface(char *icon_path) +{ + cairo_t *icon_surface = NULL; + if (strlen(icon_path) > 0 && settings.icon_position != icons_off) { + /* absolute path? */ + if (icon_path[0] == '/' || icon_path[0] == '~') { + icon_surface = cairo_image_surface_create_from_png(icon_path); + if (cairo_surface_status(icon_surface) != CAIRO_STATUS_SUCCESS) { + cairo_surface_destroy(icon_surface); + icon_surface = NULL; + } + } + /* search in icon_folders */ + if (icon_surface == NULL) { + char *start = settings.icon_folders, + *end, *current_folder, *maybe_icon_path; + do { + end = strchr(start, ':'); + if (end == NULL) end = strchr(settings.icon_folders, '\0'); /* end = end of string */ + + current_folder = strndup(start, end - start); + maybe_icon_path = g_strconcat(current_folder, "/", icon_path, ".png", NULL); + free(current_folder); + + icon_surface = cairo_image_surface_create_from_png(maybe_icon_path); + free(maybe_icon_path); + if (cairo_surface_status(icon_surface) == CAIRO_STATUS_SUCCESS) { + return icon_surface; + } else { + cairo_surface_destroy(icon_surface); + icon_surface = NULL; + } + + start = end + 1; + } while (*(end) != '\0'); + } + if (icon_surface == NULL) + fprintf(stderr, + "Could not load icon: '%s'\n", icon_path); + } + return NULL; +} + static colored_layout *r_init_shared(cairo_t *c, notification *n) { colored_layout *cl = malloc(sizeof(colored_layout)); @@ -267,16 +310,7 @@ static colored_layout *r_init_shared(cairo_t *c, notification *n) pango_layout_set_ellipsize(cl->l, PANGO_ELLIPSIZE_MIDDLE); } - cl->icon = NULL; - if (strlen(n->icon) > 0 && settings.icon_position != icons_off) { - cl->icon = cairo_image_surface_create_from_png(n->icon); - if (cairo_surface_status(cl->icon) != CAIRO_STATUS_SUCCESS) { - cairo_surface_destroy(cl->icon); - cl->icon = NULL; - fprintf(stderr, - "Could not load icon: %s\n", n->icon); - } - } + cl->icon = get_icon_surface(n->icon); cl->fg = x_string_to_color_t(n->color_strings[ColFG]); cl->bg = x_string_to_color_t(n->color_strings[ColBG]); From d0662e78ec7e3f0b9386970347f088e24a264310 Mon Sep 17 00:00:00 2001 From: Gjum Date: Fri, 28 Feb 2014 21:48:42 +0100 Subject: [PATCH 7/8] Introduce default icon setting --- config.def.h | 1 + notification.c | 8 ++++++++ settings.c | 12 ++++++++++-- settings.h | 1 + 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/config.def.h b/config.def.h index 8fdc144..e811a75 100644 --- a/config.def.h +++ b/config.def.h @@ -11,6 +11,7 @@ char *lowfgcolor = "#000000"; char *format = "%s %b"; /* default format */ int timeouts[] = { 10, 10, 0 }; /* low, normal, critical */ +char *icons[] = { "info", "info", "emblem-important" }; /* low, normal, critical */ unsigned int transparency = 0; /* transparency */ char *geom = "0x0"; /* geometry */ diff --git a/notification.c b/notification.c index 42242d6..3510851 100644 --- a/notification.c +++ b/notification.c @@ -383,6 +383,14 @@ int notification_init(notification * n, int id) n->timeout == -1 ? settings.timeouts[n->urgency] : n->timeout; n->start = 0; + if (n->icon == NULL) { + n->icon = settings.icons[n->urgency]; + } + else if (strlen(n->icon) <= 0) { + free(n->icon); + n->icon = settings.icons[n->urgency]; + } + n->timestamp = time(NULL); n->redisplayed = false; diff --git a/settings.c b/settings.c index 63ffcf1..4c4eb2e 100644 --- a/settings.c +++ b/settings.c @@ -231,6 +231,9 @@ void load_settings(char *cmdline_config_path) settings.timeouts[LOW] = option_get_int("urgency_low", "timeout", "-lto", timeouts[LOW], "Timeout for notifications with low urgency"); + settings.icons[LOW] = + option_get_string("urgency_low", "icon", "-li", icons[LOW], + "Icon for notifications with low urgency"); settings.normbgcolor = option_get_string("urgency_normal", "background", "-nb", normbgcolor, @@ -242,6 +245,9 @@ void load_settings(char *cmdline_config_path) settings.timeouts[NORM] = option_get_int("urgency_normal", "timeout", "-nto", timeouts[NORM], "Timeout for notifications with normal urgency"); + settings.icons[NORM] = + option_get_string("urgency_normal", "icon", "-ni", icons[NORM], + "Icon for notifications with normal urgency"); settings.critbgcolor = option_get_string("urgency_critical", "background", "-cb", critbgcolor, @@ -251,9 +257,11 @@ void load_settings(char *cmdline_config_path) critfgcolor, "Foreground color for notifications with ciritical urgency"); settings.timeouts[CRIT] = - option_get_int("urgency_critical", "timeout", "-cto", - timeouts[CRIT], + option_get_int("urgency_critical", "timeout", "-cto", timeouts[CRIT], "Timeout for notifications with critical urgency"); + settings.icons[CRIT] = + option_get_string("urgency_critical", "icon", "-ci", icons[CRIT], + "Icon for notifications with critical urgency"); settings.close_ks.str = option_get_string("shortcuts", "close", "-key", close_ks.str, diff --git a/settings.h b/settings.h index 8f3726b..55d08f4 100644 --- a/settings.h +++ b/settings.h @@ -14,6 +14,7 @@ typedef struct _settings { char *lowfgcolor; char *format; int timeouts[3]; + char *icons[3]; unsigned int transparency; char *geom; int shrink; From 5a5dab2ff351cfc3f818e2a26755a9ee2006b298 Mon Sep 17 00:00:00 2001 From: Gjum Date: Sat, 1 Mar 2014 14:53:30 +0100 Subject: [PATCH 8/8] Add script option to override shown icon --- dunstrc | 6 ++++-- rules.c | 3 +++ rules.h | 1 + settings.c | 1 + x.c | 2 +- 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/dunstrc b/dunstrc index 28a28fb..728e7cc 100644 --- a/dunstrc +++ b/dunstrc @@ -190,8 +190,8 @@ # Every section that isn't one of the above is interpreted as a rules to # override settings for certain messages. # Messages can be matched by "appname", "summary", "body" or "icon" and -# you can override the "timeout", "urgency", "foreground", "background" -# and "format". +# you can override the "timeout", "urgency", "foreground", "background", +# "new_icon", and "format". # Shell-like globbing will get expanded. # # SCRIPTING @@ -223,11 +223,13 @@ # appname = Pidgin # summary = "*signed on*" # urgency = low +# new_icon = "/usr/share/pixmaps/pidgin/status/16/log-in.png" # #[signed_off] # appname = Pidgin # summary = *signed off* # urgency = low +# new_icon = "/usr/share/pixmaps/pidgin/status/16/log-out.png" # #[says] # appname = Pidgin diff --git a/rules.c b/rules.c index 2b2478e..393f24c 100644 --- a/rules.c +++ b/rules.c @@ -15,6 +15,8 @@ void rule_apply(rule_t * r, notification * n) n->timeout = r->timeout; if (r->urgency != -1) n->urgency = r->urgency; + if (r->new_icon) + n->icon = r->new_icon; if (r->fg) n->color_strings[ColFG] = r->fg; if (r->bg) @@ -50,6 +52,7 @@ void rule_init(rule_t * r) r->icon = NULL; r->timeout = -1; r->urgency = -1; + r->new_icon = NULL; r->fg = NULL; r->bg = NULL; r->format = NULL; diff --git a/rules.h b/rules.h index 92a46de..c88ac17 100644 --- a/rules.h +++ b/rules.h @@ -17,6 +17,7 @@ typedef struct _rule_t { /* actions */ int timeout; int urgency; + char *new_icon; char *fg; char *bg; const char *format; diff --git a/settings.c b/settings.c index 4c4eb2e..fe3ed21 100644 --- a/settings.c +++ b/settings.c @@ -337,6 +337,7 @@ void load_settings(char *cmdline_config_path) free(urg); } } + r->new_icon = ini_get_string(cur_section, "new_icon", r->new_icon); r->fg = ini_get_string(cur_section, "foreground", r->fg); r->bg = ini_get_string(cur_section, "background", r->bg); r->format = ini_get_string(cur_section, "format", r->format); diff --git a/x.c b/x.c index 3aff9e0..6732d2e 100644 --- a/x.c +++ b/x.c @@ -298,7 +298,7 @@ static cairo_t *get_icon_surface(char *icon_path) fprintf(stderr, "Could not load icon: '%s'\n", icon_path); } - return NULL; + return icon_surface; } static colored_layout *r_init_shared(cairo_t *c, notification *n)