Merge branch 'feature-icon' of git://github.com/Gjum/dunst into pull_requests
Conflicts: dunstrc settings.c
This commit is contained in:
commit
6957ac77a0
@ -11,6 +11,7 @@ char *lowfgcolor = "#000000";
|
|||||||
char *format = "%s %b"; /* default format */
|
char *format = "%s %b"; /* default format */
|
||||||
|
|
||||||
int timeouts[] = { 10, 10, 0 }; /* low, normal, critical */
|
int timeouts[] = { 10, 10, 0 }; /* low, normal, critical */
|
||||||
|
char *icons[] = { "info", "info", "emblem-important" }; /* low, normal, critical */
|
||||||
|
|
||||||
unsigned int transparency = 0; /* transparency */
|
unsigned int transparency = 0; /* transparency */
|
||||||
char *geom = "0x0"; /* geometry */
|
char *geom = "0x0"; /* geometry */
|
||||||
@ -50,6 +51,9 @@ char *dmenu = "/usr/bin/dmenu";
|
|||||||
|
|
||||||
char *browser = "/usr/bin/firefox";
|
char *browser = "/usr/bin/firefox";
|
||||||
|
|
||||||
|
/* 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?
|
/* follow focus to different monitor and display notifications there?
|
||||||
* possible values:
|
* possible values:
|
||||||
* FOLLOW_NONE
|
* FOLLOW_NONE
|
||||||
|
1
dunst.h
1
dunst.h
@ -16,6 +16,7 @@
|
|||||||
#define ColBG 0
|
#define ColBG 0
|
||||||
|
|
||||||
enum alignment { left, center, right };
|
enum alignment { left, center, right };
|
||||||
|
enum icon_position_t { icons_left, icons_right, icons_off };
|
||||||
enum separator_color { FOREGROUND, AUTO, FRAME, CUSTOM };
|
enum separator_color { FOREGROUND, AUTO, FRAME, CUSTOM };
|
||||||
enum follow_mode { FOLLOW_NONE, FOLLOW_MOUSE, FOLLOW_KEYBOARD };
|
enum follow_mode { FOLLOW_NONE, FOLLOW_MOUSE, FOLLOW_KEYBOARD };
|
||||||
|
|
||||||
|
8
dunstrc
8
dunstrc
@ -138,6 +138,12 @@
|
|||||||
# Browser for opening urls in context menu.
|
# Browser for opening urls in context menu.
|
||||||
browser = /usr/bin/firefox -new-tab
|
browser = /usr/bin/firefox -new-tab
|
||||||
|
|
||||||
|
# Align icons left/right/off
|
||||||
|
icon_position = off
|
||||||
|
|
||||||
|
# Paths to default icons.
|
||||||
|
icon_folders = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/
|
||||||
|
|
||||||
[frame]
|
[frame]
|
||||||
width = 3
|
width = 3
|
||||||
color = "#aaaaaa"
|
color = "#aaaaaa"
|
||||||
@ -185,7 +191,7 @@
|
|||||||
# override settings for certain messages.
|
# override settings for certain messages.
|
||||||
# Messages can be matched by "appname", "summary", "body", "icon",
|
# Messages can be matched by "appname", "summary", "body", "icon",
|
||||||
# "msg_urgency" and you can override the "timeout", "urgency", "foreground",
|
# "msg_urgency" and you can override the "timeout", "urgency", "foreground",
|
||||||
# "background" and "format".
|
# "background", "new_icon" and "format".
|
||||||
# Shell-like globbing will get expanded.
|
# Shell-like globbing will get expanded.
|
||||||
#
|
#
|
||||||
# SCRIPTING
|
# SCRIPTING
|
||||||
|
@ -383,6 +383,14 @@ int notification_init(notification * n, int id)
|
|||||||
n->timeout == -1 ? settings.timeouts[n->urgency] : n->timeout;
|
n->timeout == -1 ? settings.timeouts[n->urgency] : n->timeout;
|
||||||
n->start = 0;
|
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->timestamp = time(NULL);
|
||||||
|
|
||||||
n->redisplayed = false;
|
n->redisplayed = false;
|
||||||
|
3
rules.c
3
rules.c
@ -15,6 +15,8 @@ void rule_apply(rule_t * r, notification * n)
|
|||||||
n->timeout = r->timeout;
|
n->timeout = r->timeout;
|
||||||
if (r->urgency != -1)
|
if (r->urgency != -1)
|
||||||
n->urgency = r->urgency;
|
n->urgency = r->urgency;
|
||||||
|
if (r->new_icon)
|
||||||
|
n->icon = r->new_icon;
|
||||||
if (r->fg)
|
if (r->fg)
|
||||||
n->color_strings[ColFG] = r->fg;
|
n->color_strings[ColFG] = r->fg;
|
||||||
if (r->bg)
|
if (r->bg)
|
||||||
@ -51,6 +53,7 @@ void rule_init(rule_t * r)
|
|||||||
r->msg_urgency = -1;
|
r->msg_urgency = -1;
|
||||||
r->timeout = -1;
|
r->timeout = -1;
|
||||||
r->urgency = -1;
|
r->urgency = -1;
|
||||||
|
r->new_icon = NULL;
|
||||||
r->fg = NULL;
|
r->fg = NULL;
|
||||||
r->bg = NULL;
|
r->bg = NULL;
|
||||||
r->format = NULL;
|
r->format = NULL;
|
||||||
|
1
rules.h
1
rules.h
@ -18,6 +18,7 @@ typedef struct _rule_t {
|
|||||||
/* actions */
|
/* actions */
|
||||||
int timeout;
|
int timeout;
|
||||||
int urgency;
|
int urgency;
|
||||||
|
char *new_icon;
|
||||||
char *fg;
|
char *fg;
|
||||||
char *bg;
|
char *bg;
|
||||||
const char *format;
|
const char *format;
|
||||||
|
37
settings.c
37
settings.c
@ -213,6 +213,28 @@ void load_settings(char *cmdline_config_path)
|
|||||||
option_get_string("global", "browser", "-browser", browser,
|
option_get_string("global", "browser", "-browser", browser,
|
||||||
"path to browser");
|
"path to browser");
|
||||||
|
|
||||||
|
{
|
||||||
|
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_folders =
|
||||||
|
option_get_string("global", "icon_folders", "-icon_folders", icon_folders,
|
||||||
|
"paths to default icons");
|
||||||
|
|
||||||
settings.frame_width =
|
settings.frame_width =
|
||||||
option_get_int("frame", "width", "-frame_width", frame_width,
|
option_get_int("frame", "width", "-frame_width", frame_width,
|
||||||
"Width of frame around window");
|
"Width of frame around window");
|
||||||
@ -230,6 +252,9 @@ void load_settings(char *cmdline_config_path)
|
|||||||
settings.timeouts[LOW] =
|
settings.timeouts[LOW] =
|
||||||
option_get_int("urgency_low", "timeout", "-lto", timeouts[LOW],
|
option_get_int("urgency_low", "timeout", "-lto", timeouts[LOW],
|
||||||
"Timeout for notifications with low urgency");
|
"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 =
|
settings.normbgcolor =
|
||||||
option_get_string("urgency_normal", "background", "-nb",
|
option_get_string("urgency_normal", "background", "-nb",
|
||||||
normbgcolor,
|
normbgcolor,
|
||||||
@ -241,6 +266,9 @@ void load_settings(char *cmdline_config_path)
|
|||||||
settings.timeouts[NORM] =
|
settings.timeouts[NORM] =
|
||||||
option_get_int("urgency_normal", "timeout", "-nto", timeouts[NORM],
|
option_get_int("urgency_normal", "timeout", "-nto", timeouts[NORM],
|
||||||
"Timeout for notifications with normal urgency");
|
"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 =
|
settings.critbgcolor =
|
||||||
option_get_string("urgency_critical", "background", "-cb",
|
option_get_string("urgency_critical", "background", "-cb",
|
||||||
critbgcolor,
|
critbgcolor,
|
||||||
@ -250,9 +278,11 @@ void load_settings(char *cmdline_config_path)
|
|||||||
critfgcolor,
|
critfgcolor,
|
||||||
"Foreground color for notifications with ciritical urgency");
|
"Foreground color for notifications with ciritical urgency");
|
||||||
settings.timeouts[CRIT] =
|
settings.timeouts[CRIT] =
|
||||||
option_get_int("urgency_critical", "timeout", "-cto",
|
option_get_int("urgency_critical", "timeout", "-cto", timeouts[CRIT],
|
||||||
timeouts[CRIT],
|
|
||||||
"Timeout for notifications with critical urgency");
|
"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 =
|
settings.close_ks.str =
|
||||||
option_get_string("shortcuts", "close", "-key", close_ks.str,
|
option_get_string("shortcuts", "close", "-key", close_ks.str,
|
||||||
@ -317,7 +347,8 @@ void load_settings(char *cmdline_config_path)
|
|||||||
r->fg = ini_get_string(cur_section, "foreground", r->fg);
|
r->fg = ini_get_string(cur_section, "foreground", r->fg);
|
||||||
r->bg = ini_get_string(cur_section, "background", r->bg);
|
r->bg = ini_get_string(cur_section, "background", r->bg);
|
||||||
r->format = ini_get_string(cur_section, "format", r->format);
|
r->format = ini_get_string(cur_section, "format", r->format);
|
||||||
r->script = ini_get_string(cur_section, "script", NULL);
|
r->new_icon = ini_get_string(cur_section, "new_icon", r->new_icon);
|
||||||
|
r->script = ini_get_string(cur_section, "script", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef STATIC_CONFIG
|
#ifndef STATIC_CONFIG
|
||||||
|
@ -14,6 +14,7 @@ typedef struct _settings {
|
|||||||
char *lowfgcolor;
|
char *lowfgcolor;
|
||||||
char *format;
|
char *format;
|
||||||
int timeouts[3];
|
int timeouts[3];
|
||||||
|
char *icons[3];
|
||||||
unsigned int transparency;
|
unsigned int transparency;
|
||||||
char *geom;
|
char *geom;
|
||||||
int shrink;
|
int shrink;
|
||||||
@ -42,6 +43,8 @@ typedef struct _settings {
|
|||||||
char *dmenu;
|
char *dmenu;
|
||||||
char **dmenu_cmd;
|
char **dmenu_cmd;
|
||||||
char *browser;
|
char *browser;
|
||||||
|
enum icon_position_t icon_position;
|
||||||
|
char *icon_folders;
|
||||||
enum follow_mode f_mode;
|
enum follow_mode f_mode;
|
||||||
keyboard_shortcut close_ks;
|
keyboard_shortcut close_ks;
|
||||||
keyboard_shortcut close_all_ks;
|
keyboard_shortcut close_all_ks;
|
||||||
|
84
x.c
84
x.c
@ -40,6 +40,7 @@ typedef struct _colored_layout {
|
|||||||
color_t bg;
|
color_t bg;
|
||||||
char *text;
|
char *text;
|
||||||
PangoAttrList *attr;
|
PangoAttrList *attr;
|
||||||
|
cairo_surface_t *icon;
|
||||||
} colored_layout;
|
} colored_layout;
|
||||||
|
|
||||||
cairo_ctx_t cairo_ctx;
|
cairo_ctx_t cairo_ctx;
|
||||||
@ -177,6 +178,7 @@ static void free_colored_layout(void *data)
|
|||||||
g_object_unref(cl->l);
|
g_object_unref(cl->l);
|
||||||
pango_attr_list_unref(cl->attr);
|
pango_attr_list_unref(cl->attr);
|
||||||
g_free(cl->text);
|
g_free(cl->text);
|
||||||
|
if (cl->icon) cairo_surface_destroy(cl->icon);
|
||||||
g_free(cl);
|
g_free(cl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,6 +221,10 @@ static dimension_t calculate_dimensions(GSList *layouts)
|
|||||||
colored_layout *cl = iter->data;
|
colored_layout *cl = iter->data;
|
||||||
int w=0,h=0;
|
int w=0,h=0;
|
||||||
pango_layout_get_pixel_size(cl->l, &w, &h);
|
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;
|
dim.h += h;
|
||||||
text_width = MAX(w, text_width);
|
text_width = MAX(w, text_width);
|
||||||
|
|
||||||
@ -238,13 +244,18 @@ static dimension_t calculate_dimensions(GSList *layouts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* re-setup the layout */
|
/* re-setup the layout */
|
||||||
int width = dim.w;
|
w = dim.w;
|
||||||
width -= 2 * settings.h_padding;
|
w -= 2 * settings.h_padding;
|
||||||
width -= 2 * settings.frame_width;
|
w -= 2 * settings.frame_width;
|
||||||
r_setup_pango_layout(cl->l, 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 */
|
/* re-read information */
|
||||||
pango_layout_get_pixel_size(cl->l, &w, &h);
|
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;
|
dim.h += h;
|
||||||
text_width = MAX(w, text_width);
|
text_width = MAX(w, text_width);
|
||||||
}
|
}
|
||||||
@ -258,6 +269,49 @@ static dimension_t calculate_dimensions(GSList *layouts)
|
|||||||
return dim;
|
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 icon_surface;
|
||||||
|
}
|
||||||
|
|
||||||
static colored_layout *r_init_shared(cairo_t *c, notification *n)
|
static colored_layout *r_init_shared(cairo_t *c, notification *n)
|
||||||
{
|
{
|
||||||
colored_layout *cl = malloc(sizeof(colored_layout));
|
colored_layout *cl = malloc(sizeof(colored_layout));
|
||||||
@ -267,6 +321,7 @@ static colored_layout *r_init_shared(cairo_t *c, notification *n)
|
|||||||
pango_layout_set_ellipsize(cl->l, PANGO_ELLIPSIZE_MIDDLE);
|
pango_layout_set_ellipsize(cl->l, PANGO_ELLIPSIZE_MIDDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cl->icon = get_icon_surface(n->icon);
|
||||||
|
|
||||||
cl->fg = x_string_to_color_t(n->color_strings[ColFG]);
|
cl->fg = x_string_to_color_t(n->color_strings[ColFG]);
|
||||||
cl->bg = x_string_to_color_t(n->color_strings[ColBG]);
|
cl->bg = x_string_to_color_t(n->color_strings[ColBG]);
|
||||||
@ -279,6 +334,7 @@ static colored_layout *r_init_shared(cairo_t *c, notification *n)
|
|||||||
} else {
|
} else {
|
||||||
width -= 2 * settings.h_padding;
|
width -= 2 * settings.h_padding;
|
||||||
width -= 2 * settings.frame_width;
|
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);
|
r_setup_pango_layout(cl->l, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,6 +376,7 @@ static colored_layout *r_create_layout_from_notification(cairo_t *c, notificatio
|
|||||||
|
|
||||||
|
|
||||||
pango_layout_get_pixel_size(cl->l, NULL, &(n->displayed_height));
|
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->displayed_height += 2 * settings.padding;
|
||||||
|
|
||||||
n->first_render = false;
|
n->first_render = false;
|
||||||
@ -369,6 +426,7 @@ static dimension_t x_render_layout(cairo_t *c, colored_layout *cl, dimension_t d
|
|||||||
{
|
{
|
||||||
int h;
|
int h;
|
||||||
pango_layout_get_pixel_size(cl->l, NULL, &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_x = 0;
|
||||||
int bg_y = dim.y;
|
int bg_y = dim.y;
|
||||||
@ -390,7 +448,9 @@ static dimension_t x_render_layout(cairo_t *c, colored_layout *cl, dimension_t d
|
|||||||
cairo_fill(c);
|
cairo_fill(c);
|
||||||
|
|
||||||
dim.y += settings.padding;
|
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);
|
cairo_set_source_rgb(c, cl->fg.r, cl->fg.g, cl->fg.b);
|
||||||
pango_cairo_update_layout(c, cl->l);
|
pango_cairo_update_layout(c, cl->l);
|
||||||
pango_cairo_show_layout(c, cl->l);
|
pango_cairo_show_layout(c, cl->l);
|
||||||
@ -408,6 +468,20 @@ static dimension_t x_render_layout(cairo_t *c, colored_layout *cl, dimension_t d
|
|||||||
}
|
}
|
||||||
cairo_move_to(c, settings.h_padding, dim.y);
|
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,
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
return dim;
|
return dim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user