swaynag: allow more config options

master
Brian Ashworth 6 years ago
parent ca40298af4
commit e01acb6097

@ -4,7 +4,7 @@
#include "list.h" #include "list.h"
int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag, int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag,
list_t *types, char **config, bool *debug); list_t *types, struct swaynag_type *type, char **config, bool *debug);
char *swaynag_get_config_path(void); char *swaynag_get_config_path(void);

@ -7,15 +7,6 @@
#include "swaynag/types.h" #include "swaynag/types.h"
#include "xdg-output-unstable-v1-client-protocol.h" #include "xdg-output-unstable-v1-client-protocol.h"
#define SWAYNAG_BAR_BORDER_THICKNESS 2
#define SWAYNAG_MESSAGE_PADDING 8
#define SWAYNAG_DETAILS_BORDER_THICKNESS 3
#define SWAYNAG_BUTTON_BORDER_THICKNESS 3
#define SWAYNAG_BUTTON_GAP 20
#define SWAYNAG_BUTTON_GAP_CLOSE 15
#define SWAYNAG_BUTTON_MARGIN_RIGHT 2
#define SWAYNAG_BUTTON_PADDING 3
#define SWAYNAG_MAX_HEIGHT 500 #define SWAYNAG_MAX_HEIGHT 500
enum swaynag_action_type { enum swaynag_action_type {
@ -88,9 +79,7 @@ struct swaynag {
struct pool_buffer *current_buffer; struct pool_buffer *current_buffer;
struct swaynag_type *type; struct swaynag_type *type;
uint32_t anchors;
char *message; char *message;
char *font;
list_t *buttons; list_t *buttons;
struct swaynag_details details; struct swaynag_details details;
}; };

@ -3,11 +3,25 @@
struct swaynag_type { struct swaynag_type {
char *name; char *name;
char *font;
char *output;
uint32_t anchors;
uint32_t button_background; uint32_t button_background;
uint32_t background; uint32_t background;
uint32_t text; uint32_t text;
uint32_t border; uint32_t border;
uint32_t border_bottom; uint32_t border_bottom;
uint32_t bar_border_thickness;
uint32_t message_padding;
uint32_t details_border_thickness;
uint32_t button_border_thickness;
uint32_t button_gap;
uint32_t button_gap_close;
uint32_t button_margin_right;
uint32_t button_padding;
}; };
void swaynag_types_add_default(list_t *types); void swaynag_types_add_default(list_t *types);
@ -16,10 +30,10 @@ struct swaynag_type *swaynag_type_get(list_t *types, char *name);
struct swaynag_type *swaynag_type_clone(struct swaynag_type *type); struct swaynag_type *swaynag_type_clone(struct swaynag_type *type);
void swaynag_type_merge(struct swaynag_type *dest, struct swaynag_type *src);
void swaynag_type_free(struct swaynag_type *type); void swaynag_type_free(struct swaynag_type *type);
void swaynag_types_free(list_t *types); void swaynag_types_free(list_t *types);
int swaynag_parse_type(int argc, char **argv, struct swaynag_type *type);
#endif #endif

@ -8,6 +8,7 @@
#include "readline.h" #include "readline.h"
#include "swaynag/swaynag.h" #include "swaynag/swaynag.h"
#include "swaynag/types.h" #include "swaynag/types.h"
#include "util.h"
#include "wlr-layer-shell-unstable-v1-client-protocol.h" #include "wlr-layer-shell-unstable-v1-client-protocol.h"
static char *read_from_stdin() { static char *read_from_stdin() {
@ -37,7 +38,23 @@ static char *read_from_stdin() {
} }
int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag, int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag,
list_t *types, char **config, bool *debug) { list_t *types, struct swaynag_type *type, char **config, bool *debug) {
enum type_options {
TO_COLOR_BACKGROUND = 256,
TO_COLOR_BORDER,
TO_COLOR_BORDER_BOTTOM,
TO_COLOR_BUTTON,
TO_COLOR_TEXT,
TO_THICK_BAR_BORDER,
TO_PADDING_MESSAGE,
TO_THICK_DET_BORDER,
TO_THICK_BTN_BORDER,
TO_GAP_BTN,
TO_GAP_BTN_DISMISS,
TO_MARGIN_BTN_RIGHT,
TO_PADDING_BTN,
};
static struct option opts[] = { static struct option opts[] = {
{"button", required_argument, NULL, 'b'}, {"button", required_argument, NULL, 'b'},
{"config", required_argument, NULL, 'c'}, {"config", required_argument, NULL, 'c'},
@ -52,6 +69,21 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag,
{"dismiss-button", required_argument, NULL, 's'}, {"dismiss-button", required_argument, NULL, 's'},
{"type", required_argument, NULL, 't'}, {"type", required_argument, NULL, 't'},
{"version", no_argument, NULL, 'v'}, {"version", no_argument, NULL, 'v'},
{"background", required_argument, NULL, TO_COLOR_BACKGROUND},
{"border", required_argument, NULL, TO_COLOR_BORDER},
{"border-bottom", required_argument, NULL, TO_COLOR_BORDER_BOTTOM},
{"button-background", required_argument, NULL, TO_COLOR_BUTTON},
{"text", required_argument, NULL, TO_COLOR_TEXT},
{"border-bottom-size", required_argument, NULL, TO_THICK_BAR_BORDER},
{"message-padding", required_argument, NULL, TO_PADDING_MESSAGE},
{"details-border-size", required_argument, NULL, TO_THICK_DET_BORDER},
{"button-border-size", required_argument, NULL, TO_THICK_BTN_BORDER},
{"button-gap", required_argument, NULL, TO_GAP_BTN},
{"button-dismiss-gap", required_argument, NULL, TO_GAP_BTN_DISMISS},
{"button-margin-right", required_argument, NULL, TO_MARGIN_BTN_RIGHT},
{"button-padding", required_argument, NULL, TO_PADDING_BTN},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
@ -71,7 +103,22 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag,
" -o, --output <output> Set the output to use.\n" " -o, --output <output> Set the output to use.\n"
" -s, --dismiss-button <text> Set the dismiss button text.\n" " -s, --dismiss-button <text> Set the dismiss button text.\n"
" -t, --type <type> Set the message type.\n" " -t, --type <type> Set the message type.\n"
" -v, --version Show the version number and quit.\n"; " -v, --version Show the version number and quit.\n"
"\n"
"The following appearance options can also be given:\n"
" --background RRGGBB[AA] Background color.\n"
" --border RRGGBB[AA] Border color.\n"
" --border-bottom RRGGBB[AA] Bottom border color.\n"
" --button-background RRGGBB[AA] Button background color.\n"
" --text RRGGBB[AA] Text color.\n"
" --border-bottom-size size Thickness of the bar border.\n"
" --message-padding padding Padding for the message.\n"
" --details-border-size size Thickness for the details border.\n"
" --button-border-size size Thickness for the button border.\n"
" --button-gap gap Size of the gap between buttons\n"
" --button-dismiss-gap gap Size of the gap for dismiss button.\n"
" --button-margin-right margin Margin from dismiss button to edge.\n"
" --button-padding padding Padding for the button text.\n";
optind = 1; optind = 1;
while (1) { while (1) {
@ -106,13 +153,13 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag,
} }
break; break;
case 'e': // Edge case 'e': // Edge
if (swaynag) { if (type) {
if (strcmp(optarg, "top") == 0) { if (strcmp(optarg, "top") == 0) {
swaynag->anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP type->anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP
| ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
| ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
} else if (strcmp(optarg, "bottom") == 0) { } else if (strcmp(optarg, "bottom") == 0) {
swaynag->anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM type->anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM
| ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
| ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
} else { } else {
@ -122,9 +169,9 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag,
} }
break; break;
case 'f': // Font case 'f': // Font
if (swaynag) { if (type) {
free(swaynag->font); free(type->font);
swaynag->font = strdup(optarg); type->font = strdup(optarg);
} }
break; break;
case 'l': // Detailed Message case 'l': // Detailed Message
@ -148,9 +195,9 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag,
} }
break; break;
case 'o': // Output case 'o': // Output
if (swaynag) { if (type) {
free(swaynag->output.name); free(type->output);
swaynag->output.name = strdup(optarg); type->output = strdup(optarg);
} }
break; break;
case 's': // Dismiss Button Text case 's': // Dismiss Button Text
@ -173,6 +220,71 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag,
case 'v': // Version case 'v': // Version
fprintf(stdout, "swaynag version " SWAY_VERSION "\n"); fprintf(stdout, "swaynag version " SWAY_VERSION "\n");
return -1; return -1;
case TO_COLOR_BACKGROUND: // Background color
if (type) {
type->background = parse_color(optarg);
}
break;
case TO_COLOR_BORDER: // Border color
if (type) {
type->border = parse_color(optarg);
}
break;
case TO_COLOR_BORDER_BOTTOM: // Bottom border color
if (type) {
type->border_bottom = parse_color(optarg);
}
break;
case TO_COLOR_BUTTON: // Button background color
if (type) {
type->button_background = parse_color(optarg);
}
break;
case TO_COLOR_TEXT: // Text color
if (type) {
type->text = parse_color(optarg);
}
break;
case TO_THICK_BAR_BORDER: // Bottom border thickness
if (type) {
type->bar_border_thickness = strtol(optarg, NULL, 0);
}
break;
case TO_PADDING_MESSAGE: // Message padding
if (type) {
type->message_padding = strtol(optarg, NULL, 0);
}
break;
case TO_THICK_DET_BORDER: // Details border thickness
if (type) {
type->details_border_thickness = strtol(optarg, NULL, 0);
}
break;
case TO_THICK_BTN_BORDER: // Button border thickness
if (type) {
type->button_border_thickness = strtol(optarg, NULL, 0);
}
break;
case TO_GAP_BTN: // Gap between buttons
if (type) {
type->button_gap = strtol(optarg, NULL, 0);
}
break;
case TO_GAP_BTN_DISMISS: // Gap between dismiss button
if (type) {
type->button_gap_close = strtol(optarg, NULL, 0);
}
break;
case TO_MARGIN_BTN_RIGHT: // Margin on the right side of button area
if (type) {
type->button_margin_right = strtol(optarg, NULL, 0);
}
break;
case TO_PADDING_BTN: // Padding for the button text
if (type) {
type->button_padding = strtol(optarg, NULL, 0);
}
break;
default: // Help or unknown flag default: // Help or unknown flag
fprintf(c == 'h' ? stdout : stderr, "%s", usage); fprintf(c == 'h' ? stdout : stderr, "%s", usage);
return -1; return -1;
@ -229,7 +341,12 @@ int swaynag_load_config(char *path, struct swaynag *swaynag, list_t *types) {
fprintf(stderr, "Failed to read config. Running without it.\n"); fprintf(stderr, "Failed to read config. Running without it.\n");
return 0; return 0;
} }
struct swaynag_type *type = NULL;
struct swaynag_type *type;
type = calloc(1, sizeof(struct swaynag_type));
type->name = strdup("<config>");
list_add(types, type);
char *line; char *line;
int line_number = 0; int line_number = 0;
while (!feof(config)) { while (!feof(config)) {
@ -271,12 +388,8 @@ int swaynag_load_config(char *path, struct swaynag *swaynag, list_t *types) {
sprintf(flag, "--%s", line); sprintf(flag, "--%s", line);
char *argv[] = {"swaynag", flag}; char *argv[] = {"swaynag", flag};
int result; int result;
if (type) { result = swaynag_parse_options(2, argv, swaynag, types, type,
result = swaynag_parse_type(2, argv, type);
} else {
result = swaynag_parse_options(2, argv, swaynag, types,
NULL, NULL); NULL, NULL);
}
if (result != 0) { if (result != 0) {
free(line); free(line);
fclose(config); fclose(config);

@ -5,7 +5,6 @@
#include "swaynag/config.h" #include "swaynag/config.h"
#include "swaynag/swaynag.h" #include "swaynag/swaynag.h"
#include "swaynag/types.h" #include "swaynag/types.h"
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
static struct swaynag swaynag; static struct swaynag swaynag;
@ -26,10 +25,6 @@ int main(int argc, char **argv) {
swaynag_types_add_default(types); swaynag_types_add_default(types);
memset(&swaynag, 0, sizeof(swaynag)); memset(&swaynag, 0, sizeof(swaynag));
swaynag.anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP
| ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
| ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
swaynag.font = strdup("pango:monospace 10");
swaynag.buttons = create_list(); swaynag.buttons = create_list();
struct swaynag_button *button_close = struct swaynag_button *button_close =
@ -44,7 +39,7 @@ int main(int argc, char **argv) {
char *config_path = NULL; char *config_path = NULL;
bool debug = false; bool debug = false;
int launch_status = swaynag_parse_options(argc, argv, NULL, NULL, int launch_status = swaynag_parse_options(argc, argv, NULL, NULL, NULL,
&config_path, &debug); &config_path, &debug);
if (launch_status != 0) { if (launch_status != 0) {
exit_code = launch_status; exit_code = launch_status;
@ -66,8 +61,13 @@ int main(int argc, char **argv) {
} }
if (argc > 1) { if (argc > 1) {
struct swaynag_type *type_args;
type_args = calloc(1, sizeof(struct swaynag_type));
type_args->name = strdup("<args>");
list_add(types, type_args);
int result = swaynag_parse_options(argc, argv, &swaynag, types, int result = swaynag_parse_options(argc, argv, &swaynag, types,
NULL, NULL); type_args, NULL, NULL);
if (result != 0) { if (result != 0) {
exit_code = result; exit_code = result;
goto cleanup; goto cleanup;
@ -84,7 +84,20 @@ int main(int argc, char **argv) {
swaynag.type = swaynag_type_get(types, "error"); swaynag.type = swaynag_type_get(types, "error");
} }
swaynag.type = swaynag_type_clone(swaynag.type); // Construct a new type using the config defaults as base, then merging
// config type defaults on top, then merging arguments on top of that, and
// finally merging defaults on top.
struct swaynag_type *type = calloc(1, sizeof(struct swaynag_type));
type->name = strdup(swaynag.type->name);
swaynag_type_merge(type, swaynag_type_get(types, "<args>"));
swaynag_type_merge(type, swaynag.type);
swaynag_type_merge(type, swaynag_type_get(types, "<config>"));
swaynag_type_merge(type, swaynag_type_get(types, "<defaults>"));
swaynag.type = type;
if (swaynag.type->output) {
swaynag.output.name = strdup(swaynag.type->output);
}
swaynag_types_free(types); swaynag_types_free(types);
if (swaynag.details.message) { if (swaynag.details.message) {
@ -94,10 +107,10 @@ int main(int argc, char **argv) {
} }
wlr_log(WLR_DEBUG, "Output: %s", swaynag.output.name); wlr_log(WLR_DEBUG, "Output: %s", swaynag.output.name);
wlr_log(WLR_DEBUG, "Anchors: %d", swaynag.anchors); wlr_log(WLR_DEBUG, "Anchors: %d", swaynag.type->anchors);
wlr_log(WLR_DEBUG, "Type: %s", swaynag.type->name); wlr_log(WLR_DEBUG, "Type: %s", swaynag.type->name);
wlr_log(WLR_DEBUG, "Message: %s", swaynag.message); wlr_log(WLR_DEBUG, "Message: %s", swaynag.message);
wlr_log(WLR_DEBUG, "Font: %s", swaynag.font); wlr_log(WLR_DEBUG, "Font: %s", swaynag.type->font);
wlr_log(WLR_DEBUG, "Buttons"); wlr_log(WLR_DEBUG, "Buttons");
for (int i = 0; i < swaynag.buttons->length; i++) { for (int i = 0; i < swaynag.buttons->length; i++) {
struct swaynag_button *button = swaynag.buttons->items[i]; struct swaynag_button *button = swaynag.buttons->items[i];

@ -9,13 +9,13 @@
static uint32_t render_message(cairo_t *cairo, struct swaynag *swaynag) { static uint32_t render_message(cairo_t *cairo, struct swaynag *swaynag) {
uint32_t height = swaynag->height * swaynag->scale; uint32_t height = swaynag->height * swaynag->scale;
height -= SWAYNAG_BAR_BORDER_THICKNESS * swaynag->scale; height -= swaynag->type->bar_border_thickness * swaynag->scale;
int text_width, text_height; int text_width, text_height;
get_text_size(cairo, swaynag->font, &text_width, &text_height, get_text_size(cairo, swaynag->type->font, &text_width, &text_height,
swaynag->scale, true, "%s", swaynag->message); swaynag->scale, true, "%s", swaynag->message);
int padding = SWAYNAG_MESSAGE_PADDING * swaynag->scale; int padding = swaynag->type->message_padding * swaynag->scale;
uint32_t ideal_height = text_height + padding * 2; uint32_t ideal_height = text_height + padding * 2;
uint32_t ideal_surface_height = ideal_height / swaynag->scale; uint32_t ideal_surface_height = ideal_height / swaynag->scale;
@ -25,7 +25,7 @@ static uint32_t render_message(cairo_t *cairo, struct swaynag *swaynag) {
cairo_set_source_u32(cairo, swaynag->type->text); cairo_set_source_u32(cairo, swaynag->type->text);
cairo_move_to(cairo, padding, (int)(ideal_height - text_height) / 2); cairo_move_to(cairo, padding, (int)(ideal_height - text_height) / 2);
pango_printf(cairo, swaynag->font, swaynag->scale, false, "%s", pango_printf(cairo, swaynag->type->font, swaynag->scale, false, "%s",
swaynag->message); swaynag->message);
return ideal_height; return ideal_height;
@ -34,11 +34,11 @@ static uint32_t render_message(cairo_t *cairo, struct swaynag *swaynag) {
static void render_details_scroll_button(cairo_t *cairo, static void render_details_scroll_button(cairo_t *cairo,
struct swaynag *swaynag, struct swaynag_button *button) { struct swaynag *swaynag, struct swaynag_button *button) {
int text_width, text_height; int text_width, text_height;
get_text_size(cairo, swaynag->font, &text_width, &text_height, get_text_size(cairo, swaynag->type->font, &text_width, &text_height,
swaynag->scale, true, "%s", button->text); swaynag->scale, true, "%s", button->text);
int border = SWAYNAG_BUTTON_BORDER_THICKNESS * swaynag->scale; int border = swaynag->type->button_border_thickness * swaynag->scale;
int padding = SWAYNAG_BUTTON_PADDING * swaynag->scale; int padding = swaynag->type->button_padding * swaynag->scale;
cairo_set_source_u32(cairo, swaynag->type->border); cairo_set_source_u32(cairo, swaynag->type->border);
cairo_rectangle(cairo, button->x, button->y, cairo_rectangle(cairo, button->x, button->y,
@ -53,21 +53,21 @@ static void render_details_scroll_button(cairo_t *cairo,
cairo_set_source_u32(cairo, swaynag->type->text); cairo_set_source_u32(cairo, swaynag->type->text);
cairo_move_to(cairo, button->x + border + padding, cairo_move_to(cairo, button->x + border + padding,
button->y + border + (button->height - text_height) / 2); button->y + border + (button->height - text_height) / 2);
pango_printf(cairo, swaynag->font, swaynag->scale, true, pango_printf(cairo, swaynag->type->font, swaynag->scale, true,
"%s", button->text); "%s", button->text);
} }
static int get_detailed_scroll_button_width(cairo_t *cairo, static int get_detailed_scroll_button_width(cairo_t *cairo,
struct swaynag *swaynag) { struct swaynag *swaynag) {
int up_width, down_width, temp_height; int up_width, down_width, temp_height;
get_text_size(cairo, swaynag->font, &up_width, &temp_height, get_text_size(cairo, swaynag->type->font, &up_width, &temp_height,
swaynag->scale, true, "%s", swaynag->details.button_up.text); swaynag->scale, true, "%s", swaynag->details.button_up.text);
get_text_size(cairo, swaynag->font, &down_width, &temp_height, get_text_size(cairo, swaynag->type->font, &down_width, &temp_height,
swaynag->scale, true, "%s", swaynag->details.button_down.text); swaynag->scale, true, "%s", swaynag->details.button_down.text);
int text_width = up_width > down_width ? up_width : down_width; int text_width = up_width > down_width ? up_width : down_width;
int border = SWAYNAG_BUTTON_BORDER_THICKNESS * swaynag->scale; int border = swaynag->type->button_border_thickness * swaynag->scale;
int padding = SWAYNAG_BUTTON_PADDING * swaynag->scale; int padding = swaynag->type->button_padding * swaynag->scale;
return text_width + border * 2 + padding * 2; return text_width + border * 2 + padding * 2;
} }
@ -76,17 +76,17 @@ static uint32_t render_detailed(cairo_t *cairo, struct swaynag *swaynag,
uint32_t y) { uint32_t y) {
uint32_t width = swaynag->width * swaynag->scale; uint32_t width = swaynag->width * swaynag->scale;
uint32_t height = swaynag->height * swaynag->scale; uint32_t height = swaynag->height * swaynag->scale;
height -= SWAYNAG_BAR_BORDER_THICKNESS * swaynag->scale; height -= swaynag->type->bar_border_thickness * swaynag->scale;
int border = SWAYNAG_DETAILS_BORDER_THICKNESS * swaynag->scale; int border = swaynag->type->details_border_thickness * swaynag->scale;
int padding = SWAYNAG_MESSAGE_PADDING * swaynag->scale; int padding = swaynag->type->message_padding * swaynag->scale;
int decor = padding + border; int decor = padding + border;
swaynag->details.x = decor; swaynag->details.x = decor;
swaynag->details.y = y + decor; swaynag->details.y = y + decor;
swaynag->details.width = width - decor * 2; swaynag->details.width = width - decor * 2;
PangoLayout *layout = get_pango_layout(cairo, swaynag->font, PangoLayout *layout = get_pango_layout(cairo, swaynag->type->font,
swaynag->details.message, swaynag->scale, false); swaynag->details.message, swaynag->scale, false);
pango_layout_set_width(layout, pango_layout_set_width(layout,
(swaynag->details.width - padding * 2) * PANGO_SCALE); (swaynag->details.width - padding * 2) * PANGO_SCALE);
@ -173,15 +173,15 @@ static uint32_t render_detailed(cairo_t *cairo, struct swaynag *swaynag,
static uint32_t render_button(cairo_t *cairo, struct swaynag *swaynag, static uint32_t render_button(cairo_t *cairo, struct swaynag *swaynag,
int button_index, int *x) { int button_index, int *x) {
uint32_t height = swaynag->height * swaynag->scale; uint32_t height = swaynag->height * swaynag->scale;
height -= SWAYNAG_BAR_BORDER_THICKNESS * swaynag->scale; height -= swaynag->type->bar_border_thickness * swaynag->scale;
struct swaynag_button *button = swaynag->buttons->items[button_index]; struct swaynag_button *button = swaynag->buttons->items[button_index];
int text_width, text_height; int text_width, text_height;
get_text_size(cairo, swaynag->font, &text_width, &text_height, get_text_size(cairo, swaynag->type->font, &text_width, &text_height,
swaynag->scale, true, "%s", button->text); swaynag->scale, true, "%s", button->text);
int border = SWAYNAG_BUTTON_BORDER_THICKNESS * swaynag->scale; int border = swaynag->type->button_border_thickness * swaynag->scale;
int padding = SWAYNAG_BUTTON_PADDING * swaynag->scale; int padding = swaynag->type->button_padding * swaynag->scale;
uint32_t ideal_height = text_height + padding * 2 + border * 2; uint32_t ideal_height = text_height + padding * 2 + border * 2;
uint32_t ideal_surface_height = ideal_height / swaynag->scale; uint32_t ideal_surface_height = ideal_height / swaynag->scale;
@ -206,7 +206,7 @@ static uint32_t render_button(cairo_t *cairo, struct swaynag *swaynag,
cairo_set_source_u32(cairo, swaynag->type->text); cairo_set_source_u32(cairo, swaynag->type->text);
cairo_move_to(cairo, button->x + padding, button->y + padding); cairo_move_to(cairo, button->x + padding, button->y + padding);
pango_printf(cairo, swaynag->font, swaynag->scale, true, pango_printf(cairo, swaynag->type->font, swaynag->scale, true,
"%s", button->text); "%s", button->text);
*x = button->x - border; *x = button->x - border;
@ -224,13 +224,14 @@ static uint32_t render_to_cairo(cairo_t *cairo, struct swaynag *swaynag) {
uint32_t h = render_message(cairo, swaynag); uint32_t h = render_message(cairo, swaynag);
max_height = h > max_height ? h : max_height; max_height = h > max_height ? h : max_height;
int x = (swaynag->width - SWAYNAG_BUTTON_MARGIN_RIGHT) * swaynag->scale; int x = swaynag->width - swaynag->type->button_margin_right;
x *= swaynag->scale;
for (int i = 0; i < swaynag->buttons->length; i++) { for (int i = 0; i < swaynag->buttons->length; i++) {
h = render_button(cairo, swaynag, i, &x); h = render_button(cairo, swaynag, i, &x);
max_height = h > max_height ? h : max_height; max_height = h > max_height ? h : max_height;
x -= SWAYNAG_BUTTON_GAP * swaynag->scale; x -= swaynag->type->button_gap * swaynag->scale;
if (i == 0) { if (i == 0) {
x -= SWAYNAG_BUTTON_GAP_CLOSE * swaynag->scale; x -= swaynag->type->button_gap_close * swaynag->scale;
} }
} }
@ -239,7 +240,7 @@ static uint32_t render_to_cairo(cairo_t *cairo, struct swaynag *swaynag) {
max_height = h > max_height ? h : max_height; max_height = h > max_height ? h : max_height;
} }
int border = SWAYNAG_BAR_BORDER_THICKNESS * swaynag->scale; int border = swaynag->type->bar_border_thickness * swaynag->scale;
if (max_height > swaynag->height) { if (max_height > swaynag->height) {
max_height += border; max_height += border;
} }

@ -45,14 +45,12 @@ _swaynag_ [options...]
Set the message text. Set the message text.
*-o, --output* <output> *-o, --output* <output>
Set the output to use. This should be the name of a _xdg\_output_. If Set the output to use. This should be the name of a _xdg\_output_.
_xdg\_output\_manager_ is not supported, then the first detected output
will be used
*-s, --dismiss-button* <text> *-s, --dismiss-button* <text>
Sets the text for the dismiss nagbar button. The default is _X_. Sets the text for the dismiss nagbar button. The default is _X_.
*-t, --type* *-t, --type* <type>
Set the message type. Two types are created by default _error_ and Set the message type. Two types are created by default _error_ and
_warning_. Custom types can be defined in the config file. See _warning_. Custom types can be defined in the config file. See
_--config_ and swaynag(5) for details. Both of the default types can be _--config_ and swaynag(5) for details. Both of the default types can be
@ -61,5 +59,45 @@ _swaynag_ [options...]
*-v, --version* *-v, --version*
Show the version number and quit. Show the version number and quit.
# APPEARANCE OPTIONS
*--background* <RRGGBB[AA]>
Set the color of the background.
*--border* <RRGGBB[AA]>
Set the color of the border.
*--border-bottom* <RRGGBB[AA]>
Set the color of the bottom border.
*--button-background* <RRGGBB[AA]>
Set the color for the background for buttons.
*--text* <RRGGBB[AA]>
Set the text color.
*--border-bottom-size* <size>
Set the thickness of the bottom border.
*--message-padding* <padding>
Set the padding for the message.
*--details-border-size* <size>
Set the thickness for the details border.
*--button-border-size* <size>
Set the thickness for the button border.
*--button-gap* <gap>
Set the size of the gap between buttons.
*--button-dismiss-gap* <gap>
Set the size of the gap between the dismiss button and another button.
*--button-margin-right* <margin>
Set the margin from the right of the dismiss button to edge.
*--button-padding* <padding>
Set the padding for the button text.
# SEE # SEE
swaynag(5) swaynag(5)

@ -20,37 +20,77 @@ following format:
``` ```
[name-of-type] [name-of-type]
color=RRGGBB[AA] option=value
``` ```
All colors may be given in the form _RRGGBB_ or _RRGGBBAA_. The following All colors may be given in the form _RRGGBB_ or _RRGGBBAA_. The following
colors can be set: colors can be set:
*background* *background=<color>*
The background color for _swaynag_. The background color for _swaynag_.
*border* *border=<color>*
The color to use for borders of buttons. The color to use for borders of buttons.
*border-bottom* *border-bottom=<color>*
The color of the border line at the bottom of _swaynag_. The color of the border line at the bottom of _swaynag_.
*button-background* *button-background=<color>*
The background color for the buttons. The background color for the buttons.
*text* *text=<color>*
The color of the text. The color of the text.
The following sizing options can also be set:
*border-bottom-size=<size>*
Set the thickness of the bottom border.
*message-padding=<padding>*
Set the padding for the message.
*details-border-size=<size>*
Set the thickness for the details border.
*button-border-size=<size>*
Set the thickness for the button border.
*button-gap=<gap>*
Set the size of the gap between buttons.
*button-dismiss-gap=<gap>*
Set the size of the gap between the dismiss button and another button.
*button-margin-right=<margin>*
Set the margin from the right of the dismiss button to edge.
*button-padding=<padding>*
Set the padding for the button text.
Additionally, the following options can be assigned a default per-type:
*edge=top|bottom*
Set the edge to use.
*font=<font>*
Set the font to use.
*output=<output>*
Set the output to use. This should be the name of a _xdg\_output_.
# EXAMPLE # EXAMPLE
``` ```
font=Monospace 12 font=Monospace 12
edge=bottom
[green] [green]
edge=top
background=00AA00 background=00AA00
border=006600 border=006600
border-bottom=004400 border-bottom=004400
text=FFFFFF text=FFFFFF
button-background=00CC00 button-background=00CC00
message-padding=10
``` ```
# SEE # SEE

@ -345,7 +345,8 @@ void swaynag_setup(struct swaynag *swaynag) {
assert(swaynag->layer_surface); assert(swaynag->layer_surface);
zwlr_layer_surface_v1_add_listener(swaynag->layer_surface, zwlr_layer_surface_v1_add_listener(swaynag->layer_surface,
&layer_surface_listener, swaynag); &layer_surface_listener, swaynag);
zwlr_layer_surface_v1_set_anchor(swaynag->layer_surface, swaynag->anchors); zwlr_layer_surface_v1_set_anchor(swaynag->layer_surface,
swaynag->type->anchors);
wl_registry_destroy(registry); wl_registry_destroy(registry);
} }
@ -363,7 +364,6 @@ void swaynag_destroy(struct swaynag *swaynag) {
swaynag->run_display = false; swaynag->run_display = false;
free(swaynag->message); free(swaynag->message);
free(swaynag->font);
while (swaynag->buttons->length) { while (swaynag->buttons->length) {
struct swaynag_button *button = swaynag->buttons->items[0]; struct swaynag_button *button = swaynag->buttons->items[0];
list_del(swaynag->buttons, 0); list_del(swaynag->buttons, 0);

@ -9,8 +9,26 @@
#include "swaynag/config.h" #include "swaynag/config.h"
#include "swaynag/types.h" #include "swaynag/types.h"
#include "util.h" #include "util.h"
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
void swaynag_types_add_default(list_t *types) { void swaynag_types_add_default(list_t *types) {
struct swaynag_type *type_defaults;
type_defaults = calloc(1, sizeof(struct swaynag_type));
type_defaults->name = strdup("<defaults>");
type_defaults->font = strdup("pango:Monospace 10");
type_defaults->anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP
| ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
| ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
type_defaults->bar_border_thickness = 2;
type_defaults->message_padding = 8;
type_defaults->details_border_thickness = 3;
type_defaults->button_border_thickness = 3;
type_defaults->button_gap = 20;
type_defaults->button_gap_close = 15;
type_defaults->button_margin_right = 2;
type_defaults->button_padding = 3;
list_add(types, type_defaults);
struct swaynag_type *type_error; struct swaynag_type *type_error;
type_error = calloc(1, sizeof(struct swaynag_type)); type_error = calloc(1, sizeof(struct swaynag_type));
type_error->name = strdup("error"); type_error->name = strdup("error");
@ -42,20 +60,84 @@ struct swaynag_type *swaynag_type_get(list_t *types, char *name) {
return NULL; return NULL;
} }
struct swaynag_type *swaynag_type_clone(struct swaynag_type *type) { void swaynag_type_merge(struct swaynag_type *dest, struct swaynag_type *src) {
struct swaynag_type *clone; if (!dest || !src) {
clone = calloc(1, sizeof(struct swaynag_type)); return;
clone->name = strdup(type->name); }
clone->button_background = type->button_background;
clone->background = type->background; if (!dest->font && src->font) {
clone->text = type->text; dest->font = strdup(src->font);
clone->border = type->border; }
clone->border_bottom = type->border_bottom;
return clone; if (!dest->output && src->output) {
dest->output = strdup(src->output);
}
if (dest->anchors == 0 && src->anchors > 0) {
dest->anchors = src->anchors;
}
// Colors
if (dest->button_background == 0 && src->button_background > 0) {
dest->button_background = src->button_background;
}
if (dest->background == 0 && src->background > 0) {
dest->background = src->background;
}
if (dest->text == 0 && src->text > 0) {
dest->text = src->text;
}
if (dest->border == 0 && src->border > 0) {
dest->border = src->border;
}
if (dest->border_bottom == 0 && src->border_bottom > 0) {
dest->border_bottom = src->border_bottom;
}
// Sizing
if (dest->bar_border_thickness == 0 && src->bar_border_thickness > 0) {
dest->bar_border_thickness = src->bar_border_thickness;
}
if (dest->message_padding == 0 && src->message_padding > 0) {
dest->message_padding = src->message_padding;
}
if (dest->details_border_thickness == 0
&& src->details_border_thickness > 0) {
dest->details_border_thickness = src->details_border_thickness;
}
if (dest->button_border_thickness == 0
&& src->button_border_thickness > 0) {
dest->button_border_thickness = src->button_border_thickness;
}
if (dest->button_gap == 0 && src->button_gap > 0) {
dest->button_gap = src->button_gap;
}
if (dest->button_gap_close == 0 && src->button_gap_close > 0) {
dest->button_gap_close = src->button_gap_close;
}
if (dest->button_margin_right == 0 && src->button_margin_right > 0) {
dest->button_margin_right = src->button_margin_right;
}
if (dest->button_padding == 0 && src->button_padding > 0) {
dest->button_padding = src->button_padding;
}
} }
void swaynag_type_free(struct swaynag_type *type) { void swaynag_type_free(struct swaynag_type *type) {
free(type->name); free(type->name);
free(type->font);
free(type->output);
free(type); free(type);
} }
@ -67,51 +149,3 @@ void swaynag_types_free(list_t *types) {
} }
list_free(types); list_free(types);
} }
int swaynag_parse_type(int argc, char **argv, struct swaynag_type *type) {
enum color_option {
COLOR_BACKGROUND,
COLOR_BORDER,
COLOR_BORDER_BOTTOM,
COLOR_BUTTON,
COLOR_TEXT,
};
static struct option opts[] = {
{"background", required_argument, NULL, COLOR_BACKGROUND},
{"border", required_argument, NULL, COLOR_BORDER},
{"border-bottom", required_argument, NULL, COLOR_BORDER_BOTTOM},
{"button-background", required_argument, NULL, COLOR_BUTTON},
{"text", required_argument, NULL, COLOR_TEXT},
{0, 0, 0, 0}
};
optind = 1;
while (1) {
int c = getopt_long(argc, argv, "", opts, NULL);
if (c == -1) {
break;
}
switch (c) {
case COLOR_BACKGROUND:
type->background = parse_color(optarg);
break;
case COLOR_BORDER:
type->border = parse_color(optarg);
break;
case COLOR_BORDER_BOTTOM:
type->border_bottom = parse_color(optarg);
break;
case COLOR_BUTTON:
type->button_background = parse_color(optarg);
break;
case COLOR_TEXT:
type->text = parse_color(optarg);
break;
default:
break;
}
}
return 0;
}

Loading…
Cancel
Save