diff --git a/config.c b/config.c index 817f7e9..8f594ea 100644 --- a/config.c +++ b/config.c @@ -10,6 +10,7 @@ #include "criteria.h" #include "string-util.h" #include "types.h" +#include "styling.h" static int32_t max(int32_t a, int32_t b) { return (a > b) ? a : b; @@ -135,8 +136,10 @@ void init_default_style(struct mako_style *style) { style->button_bindings.middle.action = MAKO_BINDING_NONE; style->touch_binding.action = MAKO_BINDING_DISMISS; - // Everything in the default config is explicitly specified. + // Everything in the default config is explicitly specified ... memset(&style->spec, true, sizeof(struct mako_style_spec)); + // ... except override. + memset(&style->spec.override, false, sizeof(style->spec.override)); } void init_empty_style(struct mako_style *style) { @@ -148,12 +151,22 @@ static void finish_binding(struct mako_binding *binding) { free(binding->action_name); } +static void finish_override(struct mako_override *override) { + free(override->app_name); + free(override->app_icon); + free(override->category); + free(override->desktop_entry); + free(override->summary); + free(override->body); +} + void finish_style(struct mako_style *style) { finish_binding(&style->button_bindings.left); finish_binding(&style->button_bindings.middle); finish_binding(&style->button_bindings.right); finish_binding(&style->touch_binding); finish_binding(&style->notify_binding); + finish_override(&style->override); free(style->icon_path); free(style->font); free(style->format); @@ -175,7 +188,7 @@ static void copy_binding(struct mako_binding *dst, // Update `target` with the values specified in `style`. If a failure occurs, // `target` will remain unchanged. -bool apply_style(struct mako_style *target, const struct mako_style *style) { +bool apply_style(struct mako_notification *notif, const struct mako_style *style) { // Try to duplicate strings up front in case allocation fails and we have // to bail without changing `target`. char *new_font = NULL; @@ -223,6 +236,8 @@ bool apply_style(struct mako_style *target, const struct mako_style *style) { // Now on to actually setting things! + struct mako_style *target = ¬if->style; + if (style->spec.width) { target->width = style->width; target->spec.width = true; @@ -400,6 +415,47 @@ bool apply_style(struct mako_style *target, const struct mako_style *style) { target->spec.notify_binding = true; } + if (style->spec.override.app_name) { + target->override.app_name = style->override.app_name; + target->spec.override.app_name = true; + notif->app_name = strdup(style->override.app_name); + } + if (style->spec.override.app_icon) { + target->override.app_icon = style->override.app_icon; + target->spec.override.app_icon = true; + notif->app_icon = strdup(style->override.app_icon); + } + if (style->spec.override.category) { + target->override.category = style->override.category; + target->spec.override.category = true; + notif->category = strdup(style->override.category); + } + if (style->spec.override.desktop_entry) { + target->override.desktop_entry = style->override.desktop_entry; + target->spec.override.desktop_entry = true; + notif->desktop_entry = strdup(style->override.desktop_entry); + } + if (style->spec.override.summary) { + target->override.summary = style->override.summary; + target->spec.override.summary = true; + notif->summary = strdup(style->override.summary); + } + if (style->spec.override.body) { + target->override.body = style->override.body; + target->spec.override.body = true; + notif->body = strdup(style->override.body); + } + if (style->spec.override.urgency) { + target->override.urgency = style->override.urgency; + target->spec.override.urgency = true; + notif->urgency = style->override.urgency; + } + if (style->spec.override.timeout) { + target->override.timeout = style->override.timeout; + target->spec.override.timeout = true; + notif->requested_timeout = style->override.timeout; + } + return true; } @@ -723,6 +779,36 @@ static bool apply_style_option(struct mako_style *style, const char *name, return false; } + return true; + } else if (has_prefix(name, "override.")) { + if (strcmp(name, "override.urgency") == 0) { + return spec->override.urgency = + parse_urgency(value, &style->override.timeout); + } else if (strcmp(name, "override.timeout") == 0) { + return spec->override.timeout = + parse_int_ge(value, &style->override.timeout, 0); + } else if (strcmp(name, "override.app-name") == 0) { + style->override.app_name = strdup(value); + spec->override.app_name = true; + } else if (strcmp(name, "override.app-icon") == 0) { + style->override.app_icon = strdup(value); + spec->override.app_icon = true; + } else if (strcmp(name, "override.category") == 0) { + style->override.category = strdup(value); + spec->override.category = true; + } else if (strcmp(name, "override.desktop-entry") == 0) { + style->override.desktop_entry = strdup(value); + spec->override.desktop_entry = true; + } else if (strcmp(name, "override.summary") == 0) { + style->override.summary = strdup(value); + spec->override.summary = true; + } else if (strcmp(name, "override.body") == 0) { + style->override.body = strdup(value); + spec->override.body = true; + } else { + return false; + } + return true; } @@ -930,6 +1016,14 @@ int parse_config_arguments(struct mako_config *config, int argc, char **argv) { {"on-button-right", required_argument, 0, 0}, {"on-button-middle", required_argument, 0, 0}, {"on-touch", required_argument, 0, 0}, + {"override.app-name", required_argument, 0, 0}, + {"override.app-icon", required_argument, 0, 0}, + {"override.category", required_argument, 0, 0}, + {"override.desktop-entry", required_argument, 0, 0}, + {"override.summary", required_argument, 0, 0}, + {"override.body", required_argument, 0, 0}, + {"override.urgency", required_argument, 0, 0}, + {"override.timeout", required_argument, 0, 0}, {0}, }; diff --git a/criteria.c b/criteria.c index 9db3966..a49e1b9 100644 --- a/criteria.c +++ b/criteria.c @@ -14,6 +14,7 @@ #include "notification.h" #include "surface.h" #include "wayland.h" +#include "styling.h" struct mako_criteria *create_criteria(struct mako_config *config) { struct mako_criteria *criteria = calloc(1, sizeof(struct mako_criteria)); @@ -432,7 +433,7 @@ ssize_t apply_each_criteria(struct wl_list *criteria_list, } ++match_count; - if (!apply_style(¬if->style, &criteria->style)) { + if (!apply_style(notif, &criteria->style)) { return -1; } } diff --git a/dbus/mako.c b/dbus/mako.c index 0b58cc3..94c3251 100644 --- a/dbus/mako.c +++ b/dbus/mako.c @@ -10,6 +10,7 @@ #include "mode.h" #include "notification.h" #include "wayland.h" +#include "styling.h" static const char *service_path = "/fr/emersion/Mako"; static const char *service_interface = "fr.emersion.Mako"; @@ -445,9 +446,9 @@ static int handle_set_modes(sd_bus_message *msg, void *data, } static int get_modes(sd_bus *bus, const char *path, - const char *interface, const char *property, - sd_bus_message *reply, void *data, - sd_bus_error *ret_error) { + const char *interface, const char *property, + sd_bus_message *reply, void *data, + sd_bus_error *ret_error) { struct mako_state *state = data; int ret = sd_bus_message_open_container(reply, 'a', "s"); @@ -477,9 +478,9 @@ void emit_modes_changed(struct mako_state *state) { static int get_notifications(sd_bus *bus, const char *path, - const char *interface, const char *property, - sd_bus_message *reply, void *data, - sd_bus_error *ret_error) { + const char *interface, const char *property, + sd_bus_message *reply, void *data, + sd_bus_error *ret_error) { struct mako_state *state = data; int ret = handle_list_for_each(reply, &state->notifications); diff --git a/include/config.h b/include/config.h index 4876989..02efd6a 100644 --- a/include/config.h +++ b/include/config.h @@ -7,6 +7,7 @@ #include #include "types.h" + enum mako_binding_action { MAKO_BINDING_NONE, MAKO_BINDING_DISMISS, @@ -23,6 +24,17 @@ struct mako_binding { char *action_name; // for MAKO_BINDING_INVOKE_ACTION }; +struct mako_override { + char *app_name; + char *app_icon; + char *category; + char *desktop_entry; + char *summary; + char *body; + enum mako_notification_urgency urgency; + int32_t timeout; +}; + enum mako_sort_criteria { MAKO_SORT_CRITERIA_TIME = 1, MAKO_SORT_CRITERIA_URGENCY = 2, @@ -50,6 +62,9 @@ struct mako_style_spec { bool left, right, middle; } button_bindings; bool touch_binding, notify_binding; + struct { + bool app_name, app_icon, category, desktop_entry, summary, body, urgency, timeout; + } override; }; @@ -100,6 +115,8 @@ struct mako_style { struct mako_binding left, right, middle; } button_bindings; struct mako_binding touch_binding, notify_binding; + + struct mako_override override; }; struct mako_config { @@ -117,13 +134,6 @@ struct mako_config { void init_default_config(struct mako_config *config); void finish_config(struct mako_config *config); -void init_default_style(struct mako_style *style); -void init_empty_style(struct mako_style *style); -void finish_style(struct mako_style *style); -bool apply_style(struct mako_style *target, const struct mako_style *style); -bool apply_superset_style( - struct mako_style *target, struct mako_config *config); - int parse_config_arguments(struct mako_config *config, int argc, char **argv); int load_config_file(struct mako_config *config, char *config_arg); int reload_config(struct mako_config *config, int argc, char **argv); diff --git a/include/styling.h b/include/styling.h new file mode 100644 index 0000000..515e2c3 --- /dev/null +++ b/include/styling.h @@ -0,0 +1,14 @@ +#ifndef MAKO_STYLING_H +#define MAKO_STYLING_H + +#include "config.h" +#include "notification.h" + +void init_default_style(struct mako_style *style); +void init_empty_style(struct mako_style *style); +void finish_style(struct mako_style *style); +bool apply_style(struct mako_notification *notif, const struct mako_style *style); +bool apply_superset_style( + struct mako_style *target, struct mako_config *config); + +#endif diff --git a/notification.c b/notification.c index b556c1d..40237e6 100644 --- a/notification.c +++ b/notification.c @@ -19,6 +19,7 @@ #include "icon.h" #include "string-util.h" #include "wayland.h" +#include "styling.h" bool hotspot_at(struct mako_hotspot *hotspot, int32_t x, int32_t y) { return x >= hotspot->x &&