diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index ea22ec0..ba4066f 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -7,7 +7,7 @@ These program calls might help: While the notification gets sent: `dbus-monitor path=/org/freedesktop/Notifications` -If dunst segfaults (please install the debug symbols or install dunst manually again): +If dunst segfaults (please install the debug symbols or install dunst manually again): `gdb -ex run dunst -ex bt` * ISSUE DESCRIPTION GOES BELOW THIS LINE * --> diff --git a/.travis.yml b/.travis.yml index 101fd93..726ae4c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,6 @@ addons: - libxrandr-dev - libxinerama-dev - libxss-dev - - libxdg-basedir-dev - libglib2.0-dev - libpango1.0-dev - libcairo2-dev diff --git a/.valgrind.suppressions b/.valgrind.suppressions index 2b694ff..2d0e661 100644 --- a/.valgrind.suppressions +++ b/.valgrind.suppressions @@ -1,14 +1,3 @@ -{ - xdgBaseDir_leak - # see https://github.com/devnev/libxdg-basedir/pull/6 - Memcheck:Leak - fun:malloc - ... - fun:xdgInitHandle - ... - fun:main -} - # librsvg leaks some memory, when an invalid svg file is read # TODO: find the memory leak and fix it upstream { diff --git a/CHANGELOG.md b/CHANGELOG.md index 14b684b..15e555e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Added +- Remove libxdg-basedir dependency (GLib's function is used instead) - `fullscreen` rule to hide notifications when a fullscreen window is active - When new notifications arrive, but display is full, important notifications don't have to wait for a timeout in a displayed notification (#541) diff --git a/Makefile b/Makefile index 3edd1e7..5261b17 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ endif ifeq (,${SYSTEMD}) # Check for systemctl to avoid discrepancies on systems, where -# systemd is installed, but systemd.pc is in another package +# systemd is installed, but systemd.pc is in another package systemctl := $(shell command -v systemctl >/dev/null && echo systemctl) ifeq (systemctl,${systemctl}) SYSTEMD := 1 @@ -64,10 +64,10 @@ debug: all ${OBJ}: config.mk dunst: ${OBJ} main.o - ${CC} ${CFLAGS} -o $@ ${OBJ} main.o ${LDFLAGS} + ${CC} -o ${@} ${OBJ} main.o ${CFLAGS} ${LDFLAGS} dunstify: dunstify.o - ${CC} ${CFLAGS} -o $@ dunstify.o ${LDFLAGS} + ${CC} -o ${@} dunstify.o ${CFLAGS} ${LDFLAGS} .PHONY: test test-valgrind test: test/test @@ -85,7 +85,7 @@ test-valgrind: test/test ./test test/test: ${OBJ} ${TEST_OBJ} - ${CC} ${CFLAGS} -o $@ ${TEST_OBJ} ${OBJ} ${LDFLAGS} + ${CC} -o ${@} ${TEST_OBJ} ${OBJ} ${CFLAGS} ${LDFLAGS} .PHONY: doc doc-doxygen doc: docs/dunst.1 diff --git a/README.md b/README.md index eb8b84c..ea7fe6f 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,6 @@ Dunst has a number of build dependencies that must be present before attempting - libxinerama - libxrandr - libxss -- libxdg-basedir - glib - pango/cairo - libgtk-3-dev diff --git a/config.mk b/config.mk index 3d57c92..3507f09 100644 --- a/config.mk +++ b/config.mk @@ -32,10 +32,7 @@ pkg_config_packs := dbus-1 \ "xrandr >= 1.5" \ xscrnsaver -# check if we need libxdg-basedir -ifeq (,$(findstring STATIC_CONFIG,$(CFLAGS))) - pkg_config_packs += libxdg-basedir -else +ifneq (,$(findstring STATIC_CONFIG,$(CFLAGS))) $(warning STATIC_CONFIG is deprecated behavior. It will get removed in future releases) endif diff --git a/src/dbus.c b/src/dbus.c index c485a57..7785853 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -92,13 +92,13 @@ void handle_method_call(GDBusConnection *connection, GDBusMethodInvocation *invocation, gpointer user_data) { - if (g_strcmp0(method_name, "GetCapabilities") == 0) { + if (STR_EQ(method_name, "GetCapabilities")) { on_get_capabilities(connection, sender, parameters, invocation); - } else if (g_strcmp0(method_name, "Notify") == 0) { + } else if (STR_EQ(method_name, "Notify")) { on_notify(connection, sender, parameters, invocation); - } else if (g_strcmp0(method_name, "CloseNotification") == 0) { + } else if (STR_EQ(method_name, "CloseNotification")) { on_close_notification(connection, sender, parameters, invocation); - } else if (g_strcmp0(method_name, "GetServerInformation") == 0) { + } else if (STR_EQ(method_name, "GetServerInformation")) { on_get_server_information(connection, sender, parameters, invocation); } else { LOG_M("Unknown method name: '%s' (sender: '%s').", @@ -259,8 +259,6 @@ static struct notification *dbus_message_to_notification(const gchar *sender, GV g_variant_iter_free(iter); } - fflush(stdout); - if (n->actions->count < 1) g_clear_pointer(&n->actions, actions_free); diff --git a/src/draw.c b/src/draw.c index 96c4a94..6f56573 100644 --- a/src/draw.c +++ b/src/draw.c @@ -376,10 +376,6 @@ static GSList *create_layouts(cairo_t *c) return layouts; } -static void free_layouts(GSList *layouts) -{ - g_slist_free_full(layouts, free_colored_layout); -} static int layout_get_height(struct colored_layout *cl) { @@ -637,7 +633,7 @@ void draw(void) x_display_surface(image_surface, win, &dim); cairo_surface_destroy(image_surface); - free_layouts(layouts); + g_slist_free_full(layouts, free_colored_layout); } void draw_deinit(void) diff --git a/src/icon.c b/src/icon.c index 8755585..ab43e19 100644 --- a/src/icon.c +++ b/src/icon.c @@ -76,7 +76,7 @@ GdkPixbuf *get_pixbuf_from_file(const char *filename) GdkPixbuf *get_pixbuf_from_icon(const char *iconname) { - if (!iconname || iconname[0] == '\0') + if (STR_EMPTY(iconname)) return NULL; const char *suffixes[] = { ".svg", ".png", ".xpm", NULL }; @@ -117,7 +117,7 @@ GdkPixbuf *get_pixbuf_from_icon(const char *iconname) break; start = end + 1; - } while (*(end) != '\0'); + } while (STR_FULL(end)); if (!pixbuf) LOG_W("No icon found in path: '%s'", iconname); } @@ -161,18 +161,18 @@ cairo_surface_t *icon_get_for_notification(const struct notification *n) int h = gdk_pixbuf_get_height(pixbuf); int larger = w > h ? w : h; if (settings.max_icon_size && larger > settings.max_icon_size) { - GdkPixbuf *scaled; - if (w >= h) { - scaled = gdk_pixbuf_scale_simple(pixbuf, - settings.max_icon_size, - (settings.max_icon_size * h) / w, - GDK_INTERP_BILINEAR); - } else { - scaled = gdk_pixbuf_scale_simple(pixbuf, - (settings.max_icon_size * w) / h, - settings.max_icon_size, - GDK_INTERP_BILINEAR); - } + int scaled_w = settings.max_icon_size; + int scaled_h = settings.max_icon_size; + if (w >= h) + scaled_h = (settings.max_icon_size * h) / w; + else + scaled_w = (settings.max_icon_size * w) / h; + + GdkPixbuf *scaled = gdk_pixbuf_scale_simple( + pixbuf, + scaled_w, + scaled_h, + GDK_INTERP_BILINEAR); g_object_unref(pixbuf); pixbuf = scaled; } diff --git a/src/log.c b/src/log.c index 3f41c0c..3e51fb0 100644 --- a/src/log.c +++ b/src/log.c @@ -8,6 +8,8 @@ #include +#include "utils.h" + static GLogLevelFlags log_level = G_LOG_LEVEL_WARNING; /* see log.h */ @@ -30,23 +32,23 @@ void log_set_level_from_string(const char *level) if (!level) return; - if (g_ascii_strcasecmp(level, "critical") == 0) + if (STR_CASEQ(level, "critical")) log_level = G_LOG_LEVEL_CRITICAL; - else if (g_ascii_strcasecmp(level, "crit") == 0) + else if (STR_CASEQ(level, "crit")) log_level = G_LOG_LEVEL_CRITICAL; - else if (g_ascii_strcasecmp(level, "warning") == 0) + else if (STR_CASEQ(level, "warning")) log_level = G_LOG_LEVEL_WARNING; - else if (g_ascii_strcasecmp(level, "warn") == 0) + else if (STR_CASEQ(level, "warn")) log_level = G_LOG_LEVEL_WARNING; - else if (g_ascii_strcasecmp(level, "message") == 0) + else if (STR_CASEQ(level, "message")) log_level = G_LOG_LEVEL_MESSAGE; - else if (g_ascii_strcasecmp(level, "mesg") == 0) + else if (STR_CASEQ(level, "mesg")) log_level = G_LOG_LEVEL_MESSAGE; - else if (g_ascii_strcasecmp(level, "info") == 0) + else if (STR_CASEQ(level, "info")) log_level = G_LOG_LEVEL_INFO; - else if (g_ascii_strcasecmp(level, "debug") == 0) + else if (STR_CASEQ(level, "debug")) log_level = G_LOG_LEVEL_DEBUG; - else if (g_ascii_strcasecmp(level, "deb") == 0) + else if (STR_CASEQ(level, "deb")) log_level = G_LOG_LEVEL_DEBUG; else LOG_W("Unknown log level: '%s'", level); diff --git a/src/notification.c b/src/notification.c index f4c6abf..e8699c8 100644 --- a/src/notification.c +++ b/src/notification.c @@ -93,7 +93,7 @@ void notification_print(const struct notification *n) /* see notification.h */ void notification_run_script(struct notification *n) { - if (!n->script || strlen(n->script) < 1) + if (STR_EMPTY(n->script)) return; if (n->script_run && !settings.always_run_script) @@ -182,10 +182,10 @@ int notification_is_duplicate(const struct notification *a, const struct notific && (a->raw_icon || b->raw_icon)) return false; - return strcmp(a->appname, b->appname) == 0 - && strcmp(a->summary, b->summary) == 0 - && strcmp(a->body, b->body) == 0 - && (settings.icon_position != ICON_OFF ? strcmp(a->icon, b->icon) == 0 : 1) + return STR_EQ(a->appname, b->appname) + && STR_EQ(a->summary, b->summary) + && STR_EQ(a->body, b->body) + && (settings.icon_position != ICON_OFF ? STR_EQ(a->icon, b->icon) : 1) && a->urgency == b->urgency; } @@ -340,7 +340,7 @@ void notification_init(struct notification *n) n->timeout = settings.timeouts[n->urgency]; /* Icon handling */ - if (n->icon && strlen(n->icon) <= 0) + if (STR_EMPTY(n->icon)) g_clear_pointer(&n->icon, g_free); if (!n->raw_icon && !n->icon) n->icon = g_strdup(settings.icons[n->urgency]); @@ -461,11 +461,8 @@ static void notification_format_message(struct notification *n) n->msg = g_strchomp(n->msg); /* truncate overlong messages */ - if (strlen(n->msg) > DUNST_NOTIF_MAX_CHARS) { - char *buffer = g_malloc(DUNST_NOTIF_MAX_CHARS); - strncpy(buffer, n->msg, DUNST_NOTIF_MAX_CHARS); - buffer[DUNST_NOTIF_MAX_CHARS-1] = '\0'; - + if (strnlen(n->msg, DUNST_NOTIF_MAX_CHARS + 1) > DUNST_NOTIF_MAX_CHARS) { + char * buffer = g_strndup(n->msg, DUNST_NOTIF_MAX_CHARS); g_free(n->msg); n->msg = buffer; } @@ -577,7 +574,7 @@ void notification_do_action(const struct notification *n) return; } for (int i = 0; i < n->actions->count; i += 2) { - if (strcmp(n->actions->actions[i], "default") == 0) { + if (STR_EQ(n->actions->actions[i], "default")) { signal_action_invoked(n, n->actions->actions[i]); return; } diff --git a/src/option_parser.c b/src/option_parser.c index 849a2ba..0bd78bb 100644 --- a/src/option_parser.c +++ b/src/option_parser.c @@ -42,7 +42,7 @@ static int cmdline_find_option(const char *key); struct section *new_section(const char *name) { for (int i = 0; i < section_count; i++) { - if (!strcmp(name, sections[i].name)) { + if (STR_EQ(name, sections[i].name)) { DIE("Duplicated section in dunstrc detected."); } } @@ -72,7 +72,7 @@ void free_ini(void) struct section *get_section(const char *name) { for (int i = 0; i < section_count; i++) { - if (strcmp(sections[i].name, name) == 0) + if (STR_EQ(sections[i].name, name)) return §ions[i]; } @@ -100,7 +100,7 @@ const char *get_value(const char *section, const char *key) } for (int i = 0; i < s->entry_count; i++) { - if (strcmp(s->entries[i].key, key) == 0) { + if (STR_EQ(s->entries[i].key, key)) { return s->entries[i].value; } } @@ -165,7 +165,7 @@ const char *next_section(const char *section) return sections[0].name; for (int i = 0; i < section_count; i++) { - if (strcmp(section, sections[i].name) == 0) { + if (STR_EQ(section, sections[i].name)) { if (i + 1 >= section_count) return NULL; else @@ -215,7 +215,7 @@ int load_ini_file(FILE *fp) char *start = g_strstrip(line); - if (*start == ';' || *start == '#' || strlen(start) == 0) + if (*start == ';' || *start == '#' || STR_EMPTY(start)) continue; if (*start == '[') { @@ -290,7 +290,7 @@ int cmdline_find_option(const char *key) /* look for first key */ for (int i = 0; i < cmdline_argc; i++) { - if (strcmp(key1, cmdline_argv[i]) == 0) { + if (STR_EQ(key1, cmdline_argv[i])) { g_free(key1); return i; } @@ -299,7 +299,7 @@ int cmdline_find_option(const char *key) /* look for second key if one was specified */ if (key2) { for (int i = 0; i < cmdline_argc; i++) { - if (strcmp(key2, cmdline_argv[i]) == 0) { + if (STR_EQ(key2, cmdline_argv[i])) { g_free(key1); return i; } @@ -505,7 +505,7 @@ int option_get_bool(const char *ini_section, void cmdline_usage_append(const char *key, const char *type, const char *description) { char *key_type; - if (type && strlen(type) > 0) + if (STR_FULL(type)) key_type = g_strdup_printf("%s (%s)", key, type); else key_type = g_strdup(key); @@ -538,11 +538,11 @@ enum behavior_fullscreen parse_enum_fullscreen(const char *string, enum behavior if (!string) return def; - if (strcmp(string, "show") == 0) + if (STR_EQ(string, "show")) return FS_SHOW; - else if (strcmp(string, "delay") == 0) + else if (STR_EQ(string, "delay")) return FS_DELAY; - else if (strcmp(string, "pushback") == 0) + else if (STR_EQ(string, "pushback")) return FS_PUSHBACK; else { LOG_W("Unknown fullscreen value: '%s'\n", string); diff --git a/src/queues.c b/src/queues.c index 06efc50..efa28af 100644 --- a/src/queues.c +++ b/src/queues.c @@ -125,7 +125,7 @@ int queues_notification_insert(struct notification *n) { /* do not display the message, if the message is empty */ - if (strlen(n->msg) == 0) { + if (STR_EMPTY(n->msg)) { if (settings.always_run_script) { notification_run_script(n); } @@ -133,15 +133,15 @@ int queues_notification_insert(struct notification *n) return 0; } /* Do not insert the message if it's a command */ - if (strcmp("DUNST_COMMAND_PAUSE", n->summary) == 0) { + if (STR_EQ("DUNST_COMMAND_PAUSE", n->summary)) { pause_displayed = true; return 0; } - if (strcmp("DUNST_COMMAND_RESUME", n->summary) == 0) { + if (STR_EQ("DUNST_COMMAND_RESUME", n->summary)) { pause_displayed = false; return 0; } - if (strcmp("DUNST_COMMAND_TOGGLE", n->summary) == 0) { + if (STR_EQ("DUNST_COMMAND_TOGGLE", n->summary)) { pause_displayed = !pause_displayed; return 0; } diff --git a/src/settings.c b/src/settings.c index 411f85e..a71978f 100644 --- a/src/settings.c +++ b/src/settings.c @@ -5,10 +5,6 @@ #include #include #include -#ifndef STATIC_CONFIG -#include -#include -#endif #include "rules.h" // put before config.h to fix missing include #include "config.h" @@ -21,27 +17,40 @@ struct settings settings; -static void parse_follow_mode(const char *mode) +static const char *follow_mode_to_string(enum follow_mode f_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; + switch(f_mode) { + case FOLLOW_NONE: return "none"; + case FOLLOW_MOUSE: return "mouse"; + case FOLLOW_KEYBOARD: return "keyboard"; + default: return ""; + } +} + +static enum follow_mode parse_follow_mode(const char *mode) +{ + if (!mode) + return FOLLOW_NONE; + + if (STR_EQ(mode, "mouse")) + return FOLLOW_MOUSE; + else if (STR_EQ(mode, "keyboard")) + return FOLLOW_KEYBOARD; + else if (STR_EQ(mode, "none")) + return FOLLOW_NONE; else { LOG_W("Unknown follow mode: '%s'", mode); - settings.f_mode = FOLLOW_NONE; + return FOLLOW_NONE; } } static enum markup_mode parse_markup_mode(const char *mode) { - if (strcmp(mode, "strip") == 0) { + if (STR_EQ(mode, "strip")) { return MARKUP_STRIP; - } else if (strcmp(mode, "no") == 0) { + } else if (STR_EQ(mode, "no")) { return MARKUP_NO; - } else if (strcmp(mode, "full") == 0 || strcmp(mode, "yes") == 0) { + } else if (STR_EQ(mode, "full") || STR_EQ(mode, "yes")) { return MARKUP_FULL; } else { LOG_W("Unknown markup mode: '%s'", mode); @@ -51,13 +60,13 @@ static enum markup_mode parse_markup_mode(const char *mode) static enum mouse_action parse_mouse_action(const char *action) { - if (strcmp(action, "none") == 0) + if (STR_EQ(action, "none")) return MOUSE_NONE; - else if (strcmp(action, "do_action") == 0) + else if (STR_EQ(action, "do_action")) return MOUSE_DO_ACTION; - else if (strcmp(action, "close_current") == 0) + else if (STR_EQ(action, "close_current")) return MOUSE_CLOSE_CURRENT; - else if (strcmp(action, "close_all") == 0) + else if (STR_EQ(action, "close_all")) return MOUSE_CLOSE_ALL; else { LOG_W("Unknown mouse action: '%s'", action); @@ -71,12 +80,12 @@ static enum urgency ini_get_urgency(const char *section, const char *key, const int ret = def; char *urg = ini_get_string(section, key, ""); - if (strlen(urg) > 0) { - if (strcmp(urg, "low") == 0) + if (STR_FULL(urg)) { + if (STR_EQ(urg, "low")) ret = URG_LOW; - else if (strcmp(urg, "normal") == 0) + else if (STR_EQ(urg, "normal")) ret = URG_NORM; - else if (strcmp(urg, "critical") == 0) + else if (STR_EQ(urg, "critical")) ret = URG_CRIT; else LOG_W("Unknown urgency: '%s'", urg); @@ -85,37 +94,59 @@ static enum urgency ini_get_urgency(const char *section, const char *key, const return ret; } +static FILE *xdg_config(const char *filename) +{ + const gchar * const * systemdirs = g_get_system_config_dirs(); + const gchar * userdir = g_get_user_config_dir(); + + FILE *f; + char *path; + + path = g_strconcat(userdir, filename, NULL); + f = fopen(path, "r"); + g_free(path); + + for (const gchar * const *d = systemdirs; + !f && *d; + d++) { + path = g_strconcat(*d, filename, NULL); + f = fopen(path, "r"); + g_free(path); + } + + return f; +} + void load_settings(char *cmdline_config_path) { #ifndef STATIC_CONFIG - xdgHandle xdg; FILE *config_file = NULL; - xdgInitHandle(&xdg); - if (cmdline_config_path) { - if (0 == strcmp(cmdline_config_path, "-")) { + if (STR_EQ(cmdline_config_path, "-")) { config_file = stdin; } else { config_file = fopen(cmdline_config_path, "r"); } - if(!config_file) { + if (!config_file) { DIE("Cannot find config file: '%s'", cmdline_config_path); } } + if (!config_file) { - config_file = xdgConfigOpen("dunst/dunstrc", "r", &xdg); + config_file = xdg_config("/dunst/dunstrc"); } + if (!config_file) { /* Fall back to just "dunstrc", which was used before 2013-06-23 * (before v0.2). */ - config_file = xdgConfigOpen("dunstrc", "r", &xdg); - if (!config_file) { - LOG_W("No dunstrc found."); - xdgWipeHandle(&xdg); - } + config_file = xdg_config("/dunstrc"); + } + + if (!config_file) { + LOG_W("No dunstrc found."); } load_ini_file(config_file); @@ -216,13 +247,13 @@ void load_settings(char *cmdline_config_path) "Ellipsize truncated lines on the start/middle/end" ); - if (strlen(c) == 0) { + if (STR_EMPTY(c)) { settings.ellipsize = defaults.ellipsize; - } else if (strcmp(c, "start") == 0) { + } else if (STR_EQ(c, "start")) { settings.ellipsize = ELLIPSE_START; - } else if (strcmp(c, "middle") == 0) { + } else if (STR_EQ(c, "middle")) { settings.ellipsize = ELLIPSE_MIDDLE; - } else if (strcmp(c, "end") == 0) { + } else if (STR_EQ(c, "end")) { settings.ellipsize = ELLIPSE_END; } else { LOG_W("Unknown ellipsize value: '%s'", c); @@ -252,14 +283,12 @@ void load_settings(char *cmdline_config_path) { char *c = option_get_string( "global", - "follow", "-follow", "", + "follow", "-follow", follow_mode_to_string(defaults.f_mode), "Follow mouse, keyboard or none?" ); - if (strlen(c) > 0) { - parse_follow_mode(c); - g_free(c); - } + settings.f_mode = parse_follow_mode(c); + g_free(c); } settings.title = option_get_string( @@ -317,13 +346,12 @@ void load_settings(char *cmdline_config_path) "alignment", "-align/-alignment", "", "Text alignment left/center/right" ); - - if (strlen(c) > 0) { - if (strcmp(c, "left") == 0) + if (STR_FULL(c)) { + if (STR_EQ(c, "left")) settings.align = ALIGN_LEFT; - else if (strcmp(c, "center") == 0) + else if (STR_EQ(c, "center")) settings.align = ALIGN_CENTER; - else if (strcmp(c, "right") == 0) + else if (STR_EQ(c, "right")) settings.align = ALIGN_RIGHT; else LOG_W("Unknown alignment value: '%s'", c); @@ -398,12 +426,12 @@ void load_settings(char *cmdline_config_path) "Color of the separator line (or 'auto')" ); - if (strlen(c) > 0) { - if (strcmp(c, "auto") == 0) + if (STR_FULL(c)) { + if (STR_EQ(c, "auto")) settings.sep_color = SEP_AUTO; - else if (strcmp(c, "foreground") == 0) + else if (STR_EQ(c, "foreground")) settings.sep_color = SEP_FOREGROUND; - else if (strcmp(c, "frame") == 0) + else if (STR_EQ(c, "frame")) settings.sep_color = SEP_FRAME; else { settings.sep_color = SEP_CUSTOM; @@ -465,12 +493,12 @@ void load_settings(char *cmdline_config_path) "Align icons left/right/off" ); - if (strlen(c) > 0) { - if (strcmp(c, "left") == 0) + if (STR_FULL(c)) { + if (STR_EQ(c, "left")) settings.icon_position = ICON_LEFT; - else if (strcmp(c, "right") == 0) + else if (STR_EQ(c, "right")) settings.icon_position = ICON_RIGHT; - else if (strcmp(c, "off") == 0) + else if (STR_EQ(c, "off")) settings.icon_position = ICON_OFF; else LOG_W("Unknown icon position: '%s'", c); @@ -727,13 +755,13 @@ void load_settings(char *cmdline_config_path) cur_section = next_section(cur_section); if (!cur_section) break; - if (strcmp(cur_section, "global") == 0 - || strcmp(cur_section, "frame") == 0 - || strcmp(cur_section, "experimental") == 0 - || strcmp(cur_section, "shortcuts") == 0 - || strcmp(cur_section, "urgency_low") == 0 - || strcmp(cur_section, "urgency_normal") == 0 - || strcmp(cur_section, "urgency_critical") == 0) + if (STR_EQ(cur_section, "global") + || STR_EQ(cur_section, "frame") + || STR_EQ(cur_section, "experimental") + || STR_EQ(cur_section, "shortcuts") + || STR_EQ(cur_section, "urgency_low") + || STR_EQ(cur_section, "urgency_normal") + || STR_EQ(cur_section, "urgency_critical")) continue; /* check for existing rule with same name */ @@ -741,7 +769,7 @@ void load_settings(char *cmdline_config_path) for (GSList *iter = rules; iter; iter = iter->next) { struct rule *match = iter->data; if (match->name && - strcmp(match->name, cur_section) == 0) + STR_EQ(match->name, cur_section)) r = match; } @@ -797,7 +825,6 @@ void load_settings(char *cmdline_config_path) if (config_file) { fclose(config_file); free_ini(); - xdgWipeHandle(&xdg); } #endif } diff --git a/src/utils.c b/src/utils.c index e5e7d54..adfa14b 100644 --- a/src/utils.c +++ b/src/utils.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include "log.h" @@ -79,11 +78,11 @@ char *string_replace_all(const char *needle, const char *replacement, char *hays char *string_append(char *a, const char *b, const char *sep) { - if (!a || *a == '\0') { + if (STR_EMPTY(a)) { g_free(a); return g_strdup(b); } - if (!b || *b == '\0') + if (STR_EMPTY(b)) return a; char *new; @@ -132,7 +131,7 @@ void string_strip_delimited(char *str, char a, char b) char *string_to_path(char *string) { - if (string && 0 == strncmp(string, "~/", 2)) { + if (string && STRN_EQ(string, "~/", 2)) { char *home = g_strconcat(getenv("HOME"), "/", NULL); string = string_replace("~/", home, string); @@ -169,15 +168,15 @@ gint64 string_to_time(const char *string) while (*endptr == ' ') endptr++; - if (0 == strncmp(endptr, "ms", 2)) + if (STRN_EQ(endptr, "ms", 2)) return val * 1000; - else if (0 == strncmp(endptr, "s", 1)) + else if (STRN_EQ(endptr, "s", 1)) return val * G_USEC_PER_SEC; - else if (0 == strncmp(endptr, "m", 1)) + else if (STRN_EQ(endptr, "m", 1)) return val * G_USEC_PER_SEC * 60; - else if (0 == strncmp(endptr, "h", 1)) + else if (STRN_EQ(endptr, "h", 1)) return val * G_USEC_PER_SEC * 60 * 60; - else if (0 == strncmp(endptr, "d", 1)) + else if (STRN_EQ(endptr, "d", 1)) return val * G_USEC_PER_SEC * 60 * 60 * 24; else return 0; diff --git a/src/utils.h b/src/utils.h index ca9022e..6ea3b4e 100644 --- a/src/utils.h +++ b/src/utils.h @@ -3,6 +3,18 @@ #define DUNST_UTILS_H #include +#include + +//! Test if a string is NULL or empty +#define STR_EMPTY(s) (!s || (*s == '\0')) +//! Test if a string is non-NULL and not empty +#define STR_FULL(s) !(STR_EMPTY(s)) +//! Test if string a and b contain the same chars +#define STR_EQ(a, b) (strcmp(a, b) == 0) +//! Test if string a and b are same up to n chars +#define STRN_EQ(a, b, n) (strncmp(a, b, n) == 0) +//! Test if string a and b are the same case-insensitively +#define STR_CASEQ(a, b) (strcasecmp(a, b) == 0) /* replace all occurrences of the character needle with the character replacement in haystack */ char *string_replace_char(char needle, char replacement, char *haystack); diff --git a/src/x11/screen.c b/src/x11/screen.c index edf9838..af47e85 100644 --- a/src/x11/screen.c +++ b/src/x11/screen.c @@ -17,6 +17,7 @@ #include "src/log.h" #include "src/settings.h" +#include "src/utils.h" #include "x.h" struct screen_info *screens; @@ -259,7 +260,7 @@ bool window_is_fullscreen(Window window) char *atom = XGetAtomName(xctx.dpy, ((Atom*)prop_to_return)[i]); if (atom) { - if(0 == strcmp("_NET_WM_STATE_FULLSCREEN", atom)) + if(STR_EQ("_NET_WM_STATE_FULLSCREEN", atom)) fs = true; XFree(atom); if(fs) diff --git a/src/x11/x.c b/src/x11/x.c index aa8d7c9..b96174a 100644 --- a/src/x11/x.c +++ b/src/x11/x.c @@ -335,7 +335,7 @@ gboolean x_mainloop_fd_dispatch(GSource *source, GSourceFunc callback, gpointer case FocusIn: case FocusOut: case PropertyNotify: - LOG_D("XEvent: Checking for active sceen changes"); + LOG_D("XEvent: Checking for active screen changes"); fullscreen_now = have_fullscreen_window(); scr = get_active_screen(); @@ -712,17 +712,17 @@ void x_win_hide(struct window_x11 *win) */ KeySym x_shortcut_string_to_mask(const char *str) { - if (!strcmp(str, "ctrl")) { + if (STR_EQ(str, "ctrl")) { return ControlMask; - } else if (!strcmp(str, "mod4")) { + } else if (STR_EQ(str, "mod4")) { return Mod4Mask; - } else if (!strcmp(str, "mod3")) { + } else if (STR_EQ(str, "mod3")) { return Mod3Mask; - } else if (!strcmp(str, "mod2")) { + } else if (STR_EQ(str, "mod2")) { return Mod2Mask; - } else if (!strcmp(str, "mod1")) { + } else if (STR_EQ(str, "mod1")) { return Mod1Mask; - } else if (!strcmp(str, "shift")) { + } else if (STR_EQ(str, "shift")) { return ShiftMask; } else { LOG_W("Unknown Modifier: '%s'", str); @@ -828,7 +828,7 @@ static void x_shortcut_init(struct keyboard_shortcut *ks) if (!ks|| !ks->str) return; - if (!strcmp(ks->str, "none") || (!strcmp(ks->str, ""))) { + if (STR_EQ(ks->str, "none") || (STR_EQ(ks->str, ""))) { ks->is_valid = false; return; }