From 94704b73e577f1353f22e300d624b1207e74d8aa Mon Sep 17 00:00:00 2001 From: sewn Date: Fri, 22 Mar 2024 22:12:40 +0300 Subject: [PATCH] implement mininum width for notification fixes #69 --- config.c | 13 ++++++++++++- doc/mako.5.scd | 8 ++++++++ include/config.h | 3 ++- main.c | 3 +++ render.c | 31 +++++++++++++++++++++---------- 5 files changed, 46 insertions(+), 12 deletions(-) diff --git a/config.c b/config.c index 817f7e97..79ed95f6 100644 --- a/config.c +++ b/config.c @@ -69,6 +69,7 @@ void finish_config(struct mako_config *config) { void init_default_style(struct mako_style *style) { style->width = 300; + style->min_width = 0; style->height = 100; style->outer_margin.top = 0; @@ -222,12 +223,17 @@ bool apply_style(struct mako_style *target, const struct mako_style *style) { } // Now on to actually setting things! - + if (style->spec.width) { target->width = style->width; target->spec.width = true; } + if (style->spec.width) { + target->min_width = style->min_width; + target->spec.min_width = true; + } + if (style->spec.height) { target->height = style->height; target->spec.height = true; @@ -412,6 +418,7 @@ bool apply_superset_style( struct mako_style *target, struct mako_config *config) { // Specify eveything that we'll be combining. target->spec.width = true; + target->spec.min_width = true; target->spec.height = true; target->spec.outer_margin = true; target->spec.margin = true; @@ -442,6 +449,7 @@ bool apply_superset_style( // since we're looking for the max and unspecified ones will be // initialized to zero. target->width = max(style->width, target->width); + target->min_width = max(style->min_width, target->min_width); target->height = max(style->height, target->height); target->outer_margin.top = max(style->outer_margin.top, target->outer_margin.top); target->outer_margin.right = max(style->outer_margin.right, target->outer_margin.right); @@ -568,6 +576,8 @@ static bool apply_style_option(struct mako_style *style, const char *name, return spec->colors.text = parse_color(value, &style->colors.text); } else if (strcmp(name, "width") == 0) { return spec->width = parse_int_ge(value, &style->width, 1); + } else if (strcmp(name, "min-width") == 0) { + return spec->min_width = parse_int_ge(value, &style->min_width, 1); } else if (strcmp(name, "height") == 0) { return spec->height = parse_int_ge(value, &style->height, 1); } else if (strcmp(name, "outer-margin") == 0) { @@ -901,6 +911,7 @@ int parse_config_arguments(struct mako_config *config, int argc, char **argv) { {"text-color", required_argument, 0, 0}, {"width", required_argument, 0, 0}, {"height", required_argument, 0, 0}, + {"min-width", required_argument, 0, 0}, {"outer-margin", required_argument, 0, 0}, {"margin", required_argument, 0, 0}, {"padding", required_argument, 0, 0}, diff --git a/doc/mako.5.scd b/doc/mako.5.scd index 6c1683a2..d1000f94 100644 --- a/doc/mako.5.scd +++ b/doc/mako.5.scd @@ -138,6 +138,14 @@ Supported actions: Default: 300 +*min-width*=_px_ + Set mininum (dynamic) width of notification popups. + The normal width of notifications will be considered + the maximum notification width. + Set to 0 to disable. + + Default: 0 + *height*=_px_ Set maximum height of notification popups. Notifications whose text takes up less space are shrunk to fit. diff --git a/include/config.h b/include/config.h index 48769898..8e208319 100644 --- a/include/config.h +++ b/include/config.h @@ -39,7 +39,7 @@ enum mako_icon_location { // fields in the mako_style structure should have a counterpart here. Inline // structs are also mirrored. struct mako_style_spec { - bool width, height, outer_margin, margin, padding, border_size, border_radius, font, + bool width, min_width, height, outer_margin, margin, padding, border_size, border_radius, font, markup, format, text_alignment, actions, default_timeout, ignore_timeout, icons, max_icon_size, icon_path, icon_border_radius, group_criteria_spec, invisible, history, icon_location, max_visible, layer, output, anchor; @@ -57,6 +57,7 @@ struct mako_style { struct mako_style_spec spec; int32_t width; + int32_t min_width; int32_t height; struct mako_directional outer_margin; struct mako_directional margin; diff --git a/main.c b/main.c index c273a4b8..4df015de 100644 --- a/main.c +++ b/main.c @@ -21,6 +21,9 @@ static const char usage[] = " --text-color Text color.\n" " --width Notification width.\n" " --height Max notification height.\n" + " --min-width Minimum (dynamic) notification width.\n" + " The normal notification width will be\n" + " used as the maximum notification width.\n" " --outer-margin [,...] Outer margin values, comma separated.\n" " Up to four values, with the same\n" " meaning as in CSS.\n" diff --git a/render.c b/render.c index 4be967b0..d576617c 100644 --- a/render.c +++ b/render.c @@ -113,16 +113,6 @@ static int render_notification(cairo_t *cairo, struct mako_state *state, struct int notif_width = (style->width <= surface->width) ? style->width : surface->width; - // offset_x is for the entire draw operation inside the surface - int offset_x; - if (surface->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT) { - offset_x = surface->width - notif_width - style->margin.right; - } else if (surface->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT) { - offset_x = style->margin.left; - } else { // CENTER has nothing to & with, so it's the else case - offset_x = (surface->width - notif_width) / 2; - } - // text_x is the offset of the text inside our draw operation double text_x = style->padding.left; if (icon != NULL && style->icon_location == MAKO_ICON_LOCATION_LEFT) { @@ -191,6 +181,27 @@ static int render_notification(cairo_t *cairo, struct mako_state *state, struct int text_height = buffer_text_height / scale; int text_width = buffer_text_width / scale; + if (style->min_width > 0) { + int min_width = text_width + border_size + padding_width; + if (icon && ! icon_vertical) { + min_width += icon->width; + min_width += style->icon_location == MAKO_ICON_LOCATION_LEFT ? + style->padding.left : style->padding.right; + } + + notif_width = MAX(style->min_width, min_width); + } + + // offset_x is for the entire draw operation inside the surface + int offset_x; + if (surface->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT) { + offset_x = surface->width - notif_width - style->margin.right; + } else if (surface->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT) { + offset_x = style->margin.left; + } else { // CENTER has nothing to & with, so it's the else case + offset_x = (surface->width - notif_width) / 2; + } + if (text_height > text_layout_height) { text_height = text_layout_height; }