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
This commit is contained in:
parent
2638178e5a
commit
c2801181f8
6
dunstrc
6
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"
|
||||
|
@ -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) {
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
40
x.c
40
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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user