/* copyright 2013 Sascha Kruse and contributors (see LICENSE for licensing information) */ #include "settings.h" #include #include #include #ifndef STATIC_CONFIG #include #include #endif #include "rules.h" // put before config.h to fix missing include #include "config.h" #include "dunst.h" #include "notification.h" #include "option_parser.h" #include "utils.h" settings_t settings; static void parse_follow_mode(const char *mode) { if (strcmp(mode, "mouse") == 0) settings.f_mode = FOLLOW_MOUSE; else if (strcmp(mode, "keyboard") == 0) settings.f_mode = FOLLOW_KEYBOARD; else if (strcmp(mode, "none") == 0) settings.f_mode = FOLLOW_NONE; else { fprintf(stderr, "Warning: unknown follow mode: \"%s\"\n", mode); settings.f_mode = FOLLOW_NONE; } } static enum markup_mode parse_markup_mode(const char *mode) { if (strcmp(mode, "strip") == 0) { return MARKUP_STRIP; } else if (strcmp(mode, "no") == 0) { return MARKUP_NO; } else if (strcmp(mode, "full") == 0 || strcmp(mode, "yes") == 0) { return MARKUP_FULL; } else { fprintf(stderr, "Warning: unknown markup mode: \"%s\"\n", mode); return MARKUP_NO; } } static int ini_get_urgency(char *section, char *key, int def) { int ret = def; char *urg = ini_get_string(section, key, ""); if (strlen(urg) > 0) { if (strcmp(urg, "low") == 0) ret = LOW; else if (strcmp(urg, "normal") == 0) ret = NORM; else if (strcmp(urg, "critical") == 0) ret = CRIT; else fprintf(stderr, "unknown urgency: %s, ignoring\n", urg); } if (urg) g_free(urg); return ret; } void load_settings(char *cmdline_config_path) { #ifndef STATIC_CONFIG xdgHandle xdg; FILE *config_file = NULL; xdgInitHandle(&xdg); if (cmdline_config_path != NULL) { config_file = fopen(cmdline_config_path, "r"); } if (config_file == NULL) { config_file = xdgConfigOpen("dunst/dunstrc", "r", &xdg); } if (config_file == NULL) { /* Fall back to just "dunstrc", which was used before 2013-06-23 * (before v0.2). */ config_file = xdgConfigOpen("dunstrc", "r", &xdg); if (config_file == NULL) { puts("no dunstrc found -> skipping\n"); xdgWipeHandle(&xdg); } } load_ini_file(config_file); #endif settings.font = option_get_string( "global", "font", "-fn", font, "The font dunst should use." ); { //If markup isn't set, fall back to allow_markup for backwards compatibility if (ini_is_set("global", "markup") || cmdline_is_set("-markup")) { char *c = option_get_string( "global", "markup", "-markup", markup, "Specify how markup should be handled" ); settings.markup = parse_markup_mode(c); g_free(c); } else if (ini_is_set("global", "allow_markup")) { bool allow_markup = option_get_bool( "global", "allow_markup", NULL, false, "Allow markup in notifications" ); settings.markup = (allow_markup ? MARKUP_FULL : MARKUP_STRIP); fprintf(stderr, "Warning: 'allow_markup' is deprecated, please use 'markup' instead.\n"); } else { settings.markup = parse_markup_mode(markup); // None are set, parse the default value from config.h } } settings.format = option_get_string( "global", "format", "-format", format, "The format template for the notifications" ); settings.sort = option_get_bool( "global", "sort", "-sort", sort, "Sort notifications by urgency and date?" ); settings.indicate_hidden = option_get_bool( "global", "indicate_hidden", "-indicate_hidden", indicate_hidden, "Show how many notificaitons are hidden?" ); settings.word_wrap = option_get_bool( "global", "word_wrap", "-word_wrap", word_wrap, "Truncating long lines or do word wrap" ); settings.ignore_newline = option_get_bool( "global", "ignore_newline", "-ignore_newline", ignore_newline, "Ignore newline characters in notifications" ); settings.idle_threshold = option_get_int( "global", "idle_threshold", "-idle_threshold", idle_threshold, "Don't timeout notifications if user is longer idle than threshold" ); settings.monitor = option_get_int( "global", "monitor", "-mon", monitor, "On which monitor should the notifications be displayed" ); { char *c = option_get_string( "global", "follow", "-follow", "", "Follow mouse, keyboard or none?" ); if (strlen(c) > 0) { parse_follow_mode(c); g_free(c); } } settings.title = option_get_string( "global", "title", "-t/-title", title, "Define the title of windows spawned by dunst." ); settings.class = option_get_string( "global", "class", "-c/-class", class, "Define the class of windows spawned by dunst." ); settings.geom = option_get_string( "global", "geometry", "-geom/-geometry", geom, "Geometry for the window" ); settings.shrink = option_get_bool( "global", "shrink", "-shrink", shrink, "Shrink window if it's smaller than the width" ); settings.line_height = option_get_int( "global", "line_height", "-lh/-line_height", line_height, "Add spacing between lines of text" ); settings.notification_height = option_get_int( "global", "notification_height", "-nh/-notification_height", notification_height, "Define height of the window" ); settings.bounce_freq = option_get_double( "global", "bounce_freq", "-bounce_freq", bounce_freq, "Make long text bounce from side to side" ); { char *c = option_get_string( "global", "alignment", "-align/-alignment", "", "Text alignment left/center/right" ); if (strlen(c) > 0) { if (strcmp(c, "left") == 0) settings.align = left; else if (strcmp(c, "center") == 0) settings.align = center; else if (strcmp(c, "right") == 0) settings.align = right; else fprintf(stderr, "Warning: unknown alignment\n"); g_free(c); } } settings.show_age_threshold = option_get_int( "global", "show_age_threshold", "-show_age_threshold", show_age_threshold, "When should the age of the notification be displayed?" ); settings.hide_duplicate_count = option_get_bool( "global", "hide_duplicate_count", "-hide_duplicate_count", false, "Hide the count of merged notifications with the same content" ); settings.sticky_history = option_get_bool( "global", "sticky_history", "-sticky_history", sticky_history, "Don't timeout notifications popped up from history" ); settings.history_length = option_get_int( "global", "history_length", "-history_length", history_length, "Max amount of notifications kept in history" ); settings.show_indicators = option_get_bool( "global", "show_indicators", "-show_indicators", show_indicators, "Show indicators for actions \"(A)\" and URLs \"(U)\"" ); settings.separator_height = option_get_int( "global", "separator_height", "-sep_height/-separator_height", separator_height, "height of the separator line" ); settings.padding = option_get_int( "global", "padding", "-padding", padding, "Padding between text and separator" ); settings.h_padding = option_get_int( "global", "horizontal_padding", "-horizontal_padding", h_padding, "horizontal padding" ); settings.transparency = option_get_int( "global", "transparency", "-transparency", transparency, "Transparency. range 0-100" ); { char *c = option_get_string( "global", "separator_color", "-sep_color/-separator_color", "", "Color of the separator line (or 'auto')" ); if (strlen(c) > 0) { if (strcmp(c, "auto") == 0) settings.sep_color = AUTO; else if (strcmp(c, "foreground") == 0) settings.sep_color = FOREGROUND; else if (strcmp(c, "frame") == 0) settings.sep_color = FRAME; else { settings.sep_color = CUSTOM; settings.sep_custom_color_str = g_strdup(c); } g_free(c); } } settings.stack_duplicates = option_get_bool( "global", "stack_duplicates", "-stack_duplicates", true, "Merge multiple notifications with the same content" ); settings.startup_notification = option_get_bool( "global", "startup_notification", "-startup_notification", false, "print notification on startup" ); settings.dmenu = option_get_string( "global", "dmenu", "-dmenu", dmenu, "path to dmenu" ); { GError *error = NULL; if (!g_shell_parse_argv(settings.dmenu, NULL, &settings.dmenu_cmd, &error)) { fprintf(stderr, "Unable to parse dmenu command: %s\n", error->message); fprintf(stderr, "dmenu functionality will be disabled.\n"); g_error_free(error); settings.dmenu_cmd = NULL; } } settings.browser = option_get_string( "global", "browser", "-browser", 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); g_free(c); } } settings.max_icon_size = option_get_int( "global", "max_icon_size", "-max_icon_size", max_icon_size, "Scale larger icons down to this size, set to 0 to disable" ); 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, "Width of frame around window" ); settings.frame_color = option_get_string( "frame", "color", "-frame_color", frame_color, "Color of the frame around window" ); settings.lowbgcolor = option_get_string( "urgency_low", "background", "-lb", lowbgcolor, "Background color for notifications with low urgency" ); settings.lowfgcolor = option_get_string( "urgency_low", "foreground", "-lf", lowfgcolor, "Foreground color for notifications with low urgency" ); settings.lowframecolor = option_get_string( "urgency_low", "frame_color", "-lfr", NULL, "Frame color for notifications with low urgency" ); 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, "Background color for notifications with normal urgency" ); settings.normfgcolor = option_get_string( "urgency_normal", "foreground", "-nf", normfgcolor, "Foreground color for notifications with normal urgency" ); settings.normframecolor = option_get_string( "urgency_normal", "frame_color", "-nfr", NULL, "Frame color for notifications with normal urgency" ); 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, "Background color for notifications with critical urgency" ); settings.critfgcolor = option_get_string( "urgency_critical", "foreground", "-cf", critfgcolor, "Foreground color for notifications with ciritical urgency" ); settings.critframecolor = option_get_string( "urgency_critical", "frame_color", "-cfr", NULL, "Frame color for notifications with critical urgency" ); settings.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, "Shortcut for closing one notification" ); settings.close_all_ks.str = option_get_string( "shortcuts", "close_all", "-all_key", close_all_ks.str, "Shortcut for closing all notifications" ); settings.history_ks.str = option_get_string( "shortcuts", "history", "-history_key", history_ks.str, "Shortcut to pop the last notification from history" ); settings.context_ks.str = option_get_string( "shortcuts", "context", "-context_key", context_ks.str, "Shortcut for context menu" ); settings.print_notifications = cmdline_get_bool( "-print", false, "Print notifications to cmdline (DEBUG)" ); settings.always_run_script = option_get_bool( "global", "always_run_script", "-always_run_script", true, "Always run rule-defined scripts, even if the notification is suppressed with format = \"\"." ); /* push hardcoded default rules into rules list */ for (int i = 0; i < LENGTH(default_rules); i++) { rules = g_slist_insert(rules, &(default_rules[i]), -1); } char *cur_section = NULL; for (;;) { cur_section = next_section(cur_section); if (!cur_section) break; if (strcmp(cur_section, "global") == 0 || strcmp(cur_section, "shortcuts") == 0 || strcmp(cur_section, "urgency_low") == 0 || strcmp(cur_section, "urgency_normal") == 0 || strcmp(cur_section, "urgency_critical") == 0) continue; /* check for existing rule with same name */ rule_t *r = NULL; for (GSList * iter = rules; iter; iter = iter->next) { rule_t *match = iter->data; if (match->name && strcmp(match->name, cur_section) == 0) r = match; } if (r == NULL) { r = g_malloc(sizeof(rule_t)); rule_init(r); rules = g_slist_insert(rules, r, -1); } r->name = g_strdup(cur_section); r->appname = ini_get_string(cur_section, "appname", r->appname); r->summary = ini_get_string(cur_section, "summary", r->summary); r->body = ini_get_string(cur_section, "body", r->body); r->icon = ini_get_string(cur_section, "icon", r->icon); r->category = ini_get_string(cur_section, "category", r->category); r->timeout = ini_get_int(cur_section, "timeout", r->timeout); { char *c = ini_get_string( cur_section, "markup", "" ); if (strlen(c) > 0) { r->markup = parse_markup_mode(c); g_free(c); } } r->urgency = ini_get_urgency(cur_section, "urgency", r->urgency); r->msg_urgency = ini_get_urgency(cur_section, "msg_urgency", r->msg_urgency); 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); r->new_icon = ini_get_string(cur_section, "new_icon", r->new_icon); r->history_ignore = ini_get_bool(cur_section, "history_ignore", r->history_ignore); r->script = ini_get_string(cur_section, "script", NULL); } #ifndef STATIC_CONFIG if (config_file) { fclose(config_file); free_ini(); xdgWipeHandle(&xdg); } #endif } /* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */