Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a titlebar #255

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 99 additions & 23 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ void init_default_config(struct mako_config *config) {
new_criteria->style.spec.invisible = true;
new_criteria->style.format = strdup("(%g) <b>%s</b>\n%b");
new_criteria->style.spec.format = true;
new_criteria->style.title_format = strdup("");
new_criteria->style.spec.title_format = true;
new_criteria->raw_string = strdup("(default grouped)");

// ...but make the first one in the group visible.
Expand Down Expand Up @@ -93,6 +95,11 @@ void init_default_style(struct mako_style *style) {
style->padding.bottom = 5;
style->padding.left = 5;

style->title_padding.top = 5;
style->title_padding.right = 5;
style->title_padding.bottom = 5;
style->title_padding.left = 5;

style->border_size = 2;
style->border_radius = 0;

Expand All @@ -107,12 +114,14 @@ void init_default_style(struct mako_style *style) {
style->font = strdup("monospace 10");
style->markup = true;
style->format = strdup("<b>%s</b>\n%b");
style->title_format = strdup("");

style->actions = true;
style->default_timeout = 0;
style->ignore_timeout = false;

style->colors.background = 0x285577FF;
style->colors.title = 0xFFFFFFFF;
style->colors.text = 0xFFFFFFFF;
style->colors.border = 0x4C7899FF;
style->colors.progress.value = 0x5588AAFF;
Expand All @@ -134,6 +143,7 @@ void finish_style(struct mako_style *style) {
free(style->icon_path);
free(style->font);
free(style->format);
free(style->title_format);
}

// Update `target` with the values specified in `style`. If a failure occurs,
Expand All @@ -143,6 +153,7 @@ bool apply_style(struct mako_style *target, const struct mako_style *style) {
// to bail without changing `target`.
char *new_font = NULL;
char *new_format = NULL;
char *new_title_format = NULL;
char *new_icon_path = NULL;

if (style->spec.font) {
Expand All @@ -162,9 +173,20 @@ bool apply_style(struct mako_style *target, const struct mako_style *style) {
}
}

if (style->spec.title_format) {
new_title_format = strdup(style->title_format);
if (new_title_format == NULL) {
free(new_format);
free(new_font);
fprintf(stderr, "allocation failed\n");
return false;
}
}

if (style->spec.icon_path) {
new_icon_path = strdup(style->icon_path);
if (new_icon_path == NULL) {
free(new_title_format);
free(new_format);
free(new_font);
fprintf(stderr, "allocation failed\n");
Expand Down Expand Up @@ -194,6 +216,11 @@ bool apply_style(struct mako_style *target, const struct mako_style *style) {
target->spec.padding = true;
}

if (style->spec.title_padding) {
target->title_padding = style->title_padding;
target->spec.title_padding = true;
}

if (style->spec.border_size) {
target->border_size = style->border_size;
target->spec.border_size = true;
Expand Down Expand Up @@ -232,6 +259,12 @@ bool apply_style(struct mako_style *target, const struct mako_style *style) {
target->spec.format = true;
}

if (style->spec.title_format) {
free(target->title_format);
target->title_format = new_title_format;
target->spec.title_format = true;
}

if (style->spec.actions) {
target->actions = style->actions;
target->spec.actions = true;
Expand All @@ -252,6 +285,11 @@ bool apply_style(struct mako_style *target, const struct mako_style *style) {
target->spec.colors.background = true;
}

if (style->spec.colors.title) {
target->colors.title = style->colors.title;
target->spec.colors.title = true;
}

if (style->spec.colors.text) {
target->colors.text = style->colors.text;
target->spec.colors.text = true;
Expand Down Expand Up @@ -290,6 +328,31 @@ bool apply_style(struct mako_style *target, const struct mako_style *style) {
return true;
}

// Find unique specifiers in the given format
void find_unique_specifiers(char *format, char *target_format, char *target_format_pos) {
char *format_pos = format;
char current_specifier[3] = {0};
while (*format_pos) {
format_pos = strstr(format_pos, "%");
if (!format_pos) {
break;
}

// We only want to add the format specifier to the target if we
// haven't already seen it.
// Need to copy the specifier into its own string to use strstr
// here, because there's no way to limit how much of the string
// it uses in the comparison.
memcpy(&current_specifier, format_pos, 2);
if (!strstr(target_format, current_specifier)) {
memcpy(target_format_pos, format_pos, 2);
}

++format_pos; // Enough to move to the next match.
target_format_pos += 2; // This needs to go to the next slot.
}
}

// Given a config and a style in which to store the information, this will
// calculate a style that has the maximum value of all the configured criteria
// styles (including the default as a base), for values where it makes sense to
Expand All @@ -302,6 +365,7 @@ bool apply_superset_style(
target->spec.height = true;
target->spec.margin = true;
target->spec.padding = true;
target->spec.title_padding = true;
target->spec.border_size = true;
target->spec.icons = true;
target->spec.max_icon_size = true;
Expand All @@ -310,12 +374,16 @@ bool apply_superset_style(
target->spec.actions = true;
target->spec.history = true;
target->spec.format = true;
target->spec.title_format = true;

free(target->format);
free(target->title_format);

// The "format" needs enough space for one of each specifier.
// The "format" and "title_format" need enough space for one of each specifier.
target->format = calloc(1, (2 * strlen(VALID_FORMAT_SPECIFIERS)) + 1);
target->title_format = calloc(1, (2 * strlen(VALID_FORMAT_SPECIFIERS)) + 1);
char *target_format_pos = target->format;
char *target_format_pos_title = target->title_format;

// Now we loop over the criteria and add together those fields.
// We can't use apply_style, because it simply overwrites each field.
Expand All @@ -338,6 +406,11 @@ bool apply_superset_style(
target->padding.bottom =
max(style->padding.bottom, target->padding.bottom);
target->padding.left = max(style->padding.left, target->padding.left);
target->title_padding.top = max(style->title_padding.top, target->title_padding.top);
target->title_padding.right = max(style->title_padding.right, target->title_padding.right);
target->title_padding.bottom =
max(style->title_padding.bottom, target->title_padding.bottom);
target->title_padding.left = max(style->title_padding.left, target->title_padding.left);
target->border_size = max(style->border_size, target->border_size);
target->icons = style->icons || target->icons;
target->max_icon_size = max(style->max_icon_size, target->max_icon_size);
Expand All @@ -348,29 +421,13 @@ bool apply_superset_style(
target->actions |= style->actions;
target->history |= style->history;

// We do need to be safe about this one though.
// We do need to be safe about these two though.
if (style->spec.format) {
char *format_pos = style->format;
char current_specifier[3] = {0};
while (*format_pos) {
format_pos = strstr(format_pos, "%");
if (!format_pos) {
break;
}

// We only want to add the format specifier to the target if we
// haven't already seen it.
// Need to copy the specifier into its own string to use strstr
// here, because there's no way to limit how much of the string
// it uses in the comparison.
memcpy(&current_specifier, format_pos, 2);
if (!strstr(target->format, current_specifier)) {
memcpy(target_format_pos, format_pos, 2);
}

++format_pos; // Enough to move to the next match.
target_format_pos += 2; // This needs to go to the next slot.
}
find_unique_specifiers(style->format, target->format, target_format_pos);
}

if (style->spec.title_format) {
find_unique_specifiers(style->title_format, target->format, target_format_pos_title);
}
}

Expand Down Expand Up @@ -486,6 +543,8 @@ static bool apply_style_option(struct mako_style *style, const char *name,
} else if (strcmp(name, "background-color") == 0) {
return spec->colors.background =
parse_color(value, &style->colors.background);
} else if (strcmp(name, "title-color") == 0) {
return spec->colors.title = parse_color(value, &style->colors.title);
} else if (strcmp(name, "text-color") == 0) {
return spec->colors.text = parse_color(value, &style->colors.text);
} else if (strcmp(name, "width") == 0) {
Expand All @@ -501,6 +560,13 @@ static bool apply_style_option(struct mako_style *style, const char *name,
style->padding.right = max(style->border_radius, style->padding.right);
}
return spec->padding;
} else if (strcmp(name, "title-padding") == 0) {
spec->title_padding = parse_directional(value, &style->title_padding);
if (spec->border_radius && spec->title_padding) {
style->title_padding.left = max(style->border_radius, style->title_padding.left);
style->title_padding.right = max(style->border_radius, style->title_padding.right);
}
return spec->title_padding;
} else if (strcmp(name, "border-size") == 0) {
return spec->border_size = parse_int(value, &style->border_size);
} else if (strcmp(name, "border-color") == 0) {
Expand Down Expand Up @@ -528,6 +594,9 @@ static bool apply_style_option(struct mako_style *style, const char *name,
} else if (strcmp(name, "format") == 0) {
free(style->format);
return spec->format = parse_format(value, &style->format);
} else if (strcmp(name, "title-format") == 0) {
free(style->title_format);
return spec->title_format = parse_format(value, &style->title_format);
} else if (strcmp(name, "default-timeout") == 0) {
return spec->default_timeout =
parse_int(value, &style->default_timeout);
Expand All @@ -547,6 +616,10 @@ static bool apply_style_option(struct mako_style *style, const char *name,
style->padding.left = max(style->border_radius, style->padding.left);
style->padding.right = max(style->border_radius, style->padding.right);
}
if (spec->border_radius && spec->title_padding) {
style->title_padding.left = max(style->border_radius, style->title_padding.left);
style->title_padding.right = max(style->border_radius, style->title_padding.right);
}
return spec->border_radius;
}

Expand Down Expand Up @@ -702,11 +775,13 @@ int parse_config_arguments(struct mako_config *config, int argc, char **argv) {
{"config", required_argument, 0, 'c'},
{"font", required_argument, 0, 0},
{"background-color", required_argument, 0, 0},
{"title-color", required_argument, 0, 0},
{"text-color", required_argument, 0, 0},
{"width", required_argument, 0, 0},
{"height", required_argument, 0, 0},
{"margin", required_argument, 0, 0},
{"padding", required_argument, 0, 0},
{"title_padding", required_argument, 0, 0},
{"border-size", required_argument, 0, 0},
{"border-color", required_argument, 0, 0},
{"border-radius", required_argument, 0, 0},
Expand All @@ -717,6 +792,7 @@ int parse_config_arguments(struct mako_config *config, int argc, char **argv) {
{"markup", required_argument, 0, 0},
{"actions", required_argument, 0, 0},
{"format", required_argument, 0, 0},
{"title_format", required_argument, 0, 0},
{"max-visible", required_argument, 0, 0},
{"max-history", required_argument, 0, 0},
{"history", required_argument, 0, 0},
Expand Down
12 changes: 8 additions & 4 deletions include/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ enum mako_sort_criteria {
// fields in the mako_style structure should have a counterpart here. Inline
// structs are also mirrored.
struct mako_style_spec {
bool width, height, margin, padding, border_size, border_radius, font,
markup, format, actions, default_timeout, ignore_timeout, icons,
max_icon_size, icon_path, group_criteria_spec, invisible, history;
bool width, height, margin, padding, title_padding, border_size,
border_radius, font, markup, format, title_format, actions,
default_timeout, ignore_timeout, icons, max_icon_size, icon_path,
group_criteria_spec, invisible, history;

struct {
bool background, text, border, progress;
bool background, title, text, border, progress;
} colors;
};

Expand All @@ -41,6 +42,7 @@ struct mako_style {
int32_t height;
struct mako_directional margin;
struct mako_directional padding;
struct mako_directional title_padding;
int32_t border_size;
int32_t border_radius;

Expand All @@ -51,13 +53,15 @@ struct mako_style {
char *font;
bool markup;
char *format;
char *title_format;

bool actions;
int default_timeout; // in ms
bool ignore_timeout;

struct {
uint32_t background;
uint32_t title;
uint32_t text;
uint32_t border;
struct mako_color progress;
Expand Down
20 changes: 20 additions & 0 deletions mako.5.scd
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ _none_, _dismiss_, _dismiss-all_, _dismiss-group_, _invoke-default-action_,

Default: #285577FF

*title-color* = _color_
Set title text color to _color_. See *COLORS* for more information.

Default: #FFFFFFFF

*text-color* = _color_
Set text color to _color_. See *COLORS* for more information.

Expand Down Expand Up @@ -118,13 +123,20 @@ _none_, _dismiss_, _dismiss-all_, _dismiss-group_, _invoke-default-action_,

Default: 5

*title-padding* = _directional_
Set padding on each side of the title (in the titlebar) to the size
specified by _directional_. See *DIRECTIONAL VALUES* for more information.

Default: 5

*border-size* = _px_
Set popup border size to _px_ pixels.

Default: 1

*border-color* = _color_
Set popup border color to _color_. See *COLORS* for more information.
The titlebar background will be the same color as *border-color*.

Default: #4C7899FF

Expand Down Expand Up @@ -191,6 +203,14 @@ _none_, _dismiss_, _dismiss-all_, _dismiss-group_, _invoke-default-action_,
Default: <b>%s</b>\\n%b
Default when grouped: (%g) <b>%s</b>\\n%b

*title-format* = _format_
Set title format string to _format_. See *FORMAT SPECIFIERS* for
more information. To change this for grouped notifications, set it within
a _grouped_ criteria.
If there is no format set, the titlebar won't be rendered.

Default: "" (empty string)

*default-timeout* = _timeout_
Set the default timeout to _timeout_ in milliseconds. To disable the
timeout, set it to zero.
Expand Down
Loading