aboutsummaryrefslogtreecommitdiffstats
path: root/swaynag
diff options
context:
space:
mode:
authorLibravatar Brian Ashworth <bosrsf04@gmail.com>2018-07-29 22:42:03 -0400
committerLibravatar Brian Ashworth <bosrsf04@gmail.com>2018-08-01 22:47:54 -0400
commite01acb6097b583fcf2f6d0e0afe1bd878dd9b683 (patch)
treecf3e715870bb22d9ef7d5bee9457fdcc70e31ee2 /swaynag
parentswaynag: add math to meson.build (diff)
downloadsway-e01acb6097b583fcf2f6d0e0afe1bd878dd9b683.tar.gz
sway-e01acb6097b583fcf2f6d0e0afe1bd878dd9b683.tar.zst
sway-e01acb6097b583fcf2f6d0e0afe1bd878dd9b683.zip
swaynag: allow more config options
Diffstat (limited to 'swaynag')
-rw-r--r--swaynag/config.c149
-rw-r--r--swaynag/main.c33
-rw-r--r--swaynag/render.c51
-rw-r--r--swaynag/swaynag.1.scd46
-rw-r--r--swaynag/swaynag.5.scd52
-rw-r--r--swaynag/swaynag.c4
-rw-r--r--swaynag/types.c150
7 files changed, 362 insertions, 123 deletions
diff --git a/swaynag/config.c b/swaynag/config.c
index 289fc82a..80c5ad88 100644
--- a/swaynag/config.c
+++ b/swaynag/config.c
@@ -8,6 +8,7 @@
8#include "readline.h" 8#include "readline.h"
9#include "swaynag/swaynag.h" 9#include "swaynag/swaynag.h"
10#include "swaynag/types.h" 10#include "swaynag/types.h"
11#include "util.h"
11#include "wlr-layer-shell-unstable-v1-client-protocol.h" 12#include "wlr-layer-shell-unstable-v1-client-protocol.h"
12 13
13static char *read_from_stdin() { 14static char *read_from_stdin() {
@@ -37,7 +38,23 @@ static char *read_from_stdin() {
37} 38}
38 39
39int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag, 40int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag,
40 list_t *types, char **config, bool *debug) { 41 list_t *types, struct swaynag_type *type, char **config, bool *debug) {
42 enum type_options {
43 TO_COLOR_BACKGROUND = 256,
44 TO_COLOR_BORDER,
45 TO_COLOR_BORDER_BOTTOM,
46 TO_COLOR_BUTTON,
47 TO_COLOR_TEXT,
48 TO_THICK_BAR_BORDER,
49 TO_PADDING_MESSAGE,
50 TO_THICK_DET_BORDER,
51 TO_THICK_BTN_BORDER,
52 TO_GAP_BTN,
53 TO_GAP_BTN_DISMISS,
54 TO_MARGIN_BTN_RIGHT,
55 TO_PADDING_BTN,
56 };
57
41 static struct option opts[] = { 58 static struct option opts[] = {
42 {"button", required_argument, NULL, 'b'}, 59 {"button", required_argument, NULL, 'b'},
43 {"config", required_argument, NULL, 'c'}, 60 {"config", required_argument, NULL, 'c'},
@@ -52,6 +69,21 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag,
52 {"dismiss-button", required_argument, NULL, 's'}, 69 {"dismiss-button", required_argument, NULL, 's'},
53 {"type", required_argument, NULL, 't'}, 70 {"type", required_argument, NULL, 't'},
54 {"version", no_argument, NULL, 'v'}, 71 {"version", no_argument, NULL, 'v'},
72
73 {"background", required_argument, NULL, TO_COLOR_BACKGROUND},
74 {"border", required_argument, NULL, TO_COLOR_BORDER},
75 {"border-bottom", required_argument, NULL, TO_COLOR_BORDER_BOTTOM},
76 {"button-background", required_argument, NULL, TO_COLOR_BUTTON},
77 {"text", required_argument, NULL, TO_COLOR_TEXT},
78 {"border-bottom-size", required_argument, NULL, TO_THICK_BAR_BORDER},
79 {"message-padding", required_argument, NULL, TO_PADDING_MESSAGE},
80 {"details-border-size", required_argument, NULL, TO_THICK_DET_BORDER},
81 {"button-border-size", required_argument, NULL, TO_THICK_BTN_BORDER},
82 {"button-gap", required_argument, NULL, TO_GAP_BTN},
83 {"button-dismiss-gap", required_argument, NULL, TO_GAP_BTN_DISMISS},
84 {"button-margin-right", required_argument, NULL, TO_MARGIN_BTN_RIGHT},
85 {"button-padding", required_argument, NULL, TO_PADDING_BTN},
86
55 {0, 0, 0, 0} 87 {0, 0, 0, 0}
56 }; 88 };
57 89
@@ -71,7 +103,22 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag,
71 " -o, --output <output> Set the output to use.\n" 103 " -o, --output <output> Set the output to use.\n"
72 " -s, --dismiss-button <text> Set the dismiss button text.\n" 104 " -s, --dismiss-button <text> Set the dismiss button text.\n"
73 " -t, --type <type> Set the message type.\n" 105 " -t, --type <type> Set the message type.\n"
74 " -v, --version Show the version number and quit.\n"; 106 " -v, --version Show the version number and quit.\n"
107 "\n"
108 "The following appearance options can also be given:\n"
109 " --background RRGGBB[AA] Background color.\n"
110 " --border RRGGBB[AA] Border color.\n"
111 " --border-bottom RRGGBB[AA] Bottom border color.\n"
112 " --button-background RRGGBB[AA] Button background color.\n"
113 " --text RRGGBB[AA] Text color.\n"
114 " --border-bottom-size size Thickness of the bar border.\n"
115 " --message-padding padding Padding for the message.\n"
116 " --details-border-size size Thickness for the details border.\n"
117 " --button-border-size size Thickness for the button border.\n"
118 " --button-gap gap Size of the gap between buttons\n"
119 " --button-dismiss-gap gap Size of the gap for dismiss button.\n"
120 " --button-margin-right margin Margin from dismiss button to edge.\n"
121 " --button-padding padding Padding for the button text.\n";
75 122
76 optind = 1; 123 optind = 1;
77 while (1) { 124 while (1) {
@@ -106,13 +153,13 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag,
106 } 153 }
107 break; 154 break;
108 case 'e': // Edge 155 case 'e': // Edge
109 if (swaynag) { 156 if (type) {
110 if (strcmp(optarg, "top") == 0) { 157 if (strcmp(optarg, "top") == 0) {
111 swaynag->anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP 158 type->anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP
112 | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT 159 | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
113 | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; 160 | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
114 } else if (strcmp(optarg, "bottom") == 0) { 161 } else if (strcmp(optarg, "bottom") == 0) {
115 swaynag->anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM 162 type->anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM
116 | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT 163 | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
117 | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; 164 | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
118 } else { 165 } else {
@@ -122,9 +169,9 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag,
122 } 169 }
123 break; 170 break;
124 case 'f': // Font 171 case 'f': // Font
125 if (swaynag) { 172 if (type) {
126 free(swaynag->font); 173 free(type->font);
127 swaynag->font = strdup(optarg); 174 type->font = strdup(optarg);
128 } 175 }
129 break; 176 break;
130 case 'l': // Detailed Message 177 case 'l': // Detailed Message
@@ -148,9 +195,9 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag,
148 } 195 }
149 break; 196 break;
150 case 'o': // Output 197 case 'o': // Output
151 if (swaynag) { 198 if (type) {
152 free(swaynag->output.name); 199 free(type->output);
153 swaynag->output.name = strdup(optarg); 200 type->output = strdup(optarg);
154 } 201 }
155 break; 202 break;
156 case 's': // Dismiss Button Text 203 case 's': // Dismiss Button Text
@@ -173,6 +220,71 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag,
173 case 'v': // Version 220 case 'v': // Version
174 fprintf(stdout, "swaynag version " SWAY_VERSION "\n"); 221 fprintf(stdout, "swaynag version " SWAY_VERSION "\n");
175 return -1; 222 return -1;
223 case TO_COLOR_BACKGROUND: // Background color
224 if (type) {
225 type->background = parse_color(optarg);
226 }
227 break;
228 case TO_COLOR_BORDER: // Border color
229 if (type) {
230 type->border = parse_color(optarg);
231 }
232 break;
233 case TO_COLOR_BORDER_BOTTOM: // Bottom border color
234 if (type) {
235 type->border_bottom = parse_color(optarg);
236 }
237 break;
238 case TO_COLOR_BUTTON: // Button background color
239 if (type) {
240 type->button_background = parse_color(optarg);
241 }
242 break;
243 case TO_COLOR_TEXT: // Text color
244 if (type) {
245 type->text = parse_color(optarg);
246 }
247 break;
248 case TO_THICK_BAR_BORDER: // Bottom border thickness
249 if (type) {
250 type->bar_border_thickness = strtol(optarg, NULL, 0);
251 }
252 break;
253 case TO_PADDING_MESSAGE: // Message padding
254 if (type) {
255 type->message_padding = strtol(optarg, NULL, 0);
256 }
257 break;
258 case TO_THICK_DET_BORDER: // Details border thickness
259 if (type) {
260 type->details_border_thickness = strtol(optarg, NULL, 0);
261 }
262 break;
263 case TO_THICK_BTN_BORDER: // Button border thickness
264 if (type) {
265 type->button_border_thickness = strtol(optarg, NULL, 0);
266 }
267 break;
268 case TO_GAP_BTN: // Gap between buttons
269 if (type) {
270 type->button_gap = strtol(optarg, NULL, 0);
271 }
272 break;
273 case TO_GAP_BTN_DISMISS: // Gap between dismiss button
274 if (type) {
275 type->button_gap_close = strtol(optarg, NULL, 0);
276 }
277 break;
278 case TO_MARGIN_BTN_RIGHT: // Margin on the right side of button area
279 if (type) {
280 type->button_margin_right = strtol(optarg, NULL, 0);
281 }
282 break;
283 case TO_PADDING_BTN: // Padding for the button text
284 if (type) {
285 type->button_padding = strtol(optarg, NULL, 0);
286 }
287 break;
176 default: // Help or unknown flag 288 default: // Help or unknown flag
177 fprintf(c == 'h' ? stdout : stderr, "%s", usage); 289 fprintf(c == 'h' ? stdout : stderr, "%s", usage);
178 return -1; 290 return -1;
@@ -229,7 +341,12 @@ int swaynag_load_config(char *path, struct swaynag *swaynag, list_t *types) {
229 fprintf(stderr, "Failed to read config. Running without it.\n"); 341 fprintf(stderr, "Failed to read config. Running without it.\n");
230 return 0; 342 return 0;
231 } 343 }
232 struct swaynag_type *type = NULL; 344
345 struct swaynag_type *type;
346 type = calloc(1, sizeof(struct swaynag_type));
347 type->name = strdup("<config>");
348 list_add(types, type);
349
233 char *line; 350 char *line;
234 int line_number = 0; 351 int line_number = 0;
235 while (!feof(config)) { 352 while (!feof(config)) {
@@ -271,12 +388,8 @@ int swaynag_load_config(char *path, struct swaynag *swaynag, list_t *types) {
271 sprintf(flag, "--%s", line); 388 sprintf(flag, "--%s", line);
272 char *argv[] = {"swaynag", flag}; 389 char *argv[] = {"swaynag", flag};
273 int result; 390 int result;
274 if (type) { 391 result = swaynag_parse_options(2, argv, swaynag, types, type,
275 result = swaynag_parse_type(2, argv, type); 392 NULL, NULL);
276 } else {
277 result = swaynag_parse_options(2, argv, swaynag, types,
278 NULL, NULL);
279 }
280 if (result != 0) { 393 if (result != 0) {
281 free(line); 394 free(line);
282 fclose(config); 395 fclose(config);
diff --git a/swaynag/main.c b/swaynag/main.c
index 0493c1f0..20d03c31 100644
--- a/swaynag/main.c
+++ b/swaynag/main.c
@@ -5,7 +5,6 @@
5#include "swaynag/config.h" 5#include "swaynag/config.h"
6#include "swaynag/swaynag.h" 6#include "swaynag/swaynag.h"
7#include "swaynag/types.h" 7#include "swaynag/types.h"
8#include "wlr-layer-shell-unstable-v1-client-protocol.h"
9 8
10static struct swaynag swaynag; 9static struct swaynag swaynag;
11 10
@@ -26,10 +25,6 @@ int main(int argc, char **argv) {
26 swaynag_types_add_default(types); 25 swaynag_types_add_default(types);
27 26
28 memset(&swaynag, 0, sizeof(swaynag)); 27 memset(&swaynag, 0, sizeof(swaynag));
29 swaynag.anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP
30 | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
31 | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
32 swaynag.font = strdup("pango:monospace 10");
33 swaynag.buttons = create_list(); 28 swaynag.buttons = create_list();
34 29
35 struct swaynag_button *button_close = 30 struct swaynag_button *button_close =
@@ -44,7 +39,7 @@ int main(int argc, char **argv) {
44 39
45 char *config_path = NULL; 40 char *config_path = NULL;
46 bool debug = false; 41 bool debug = false;
47 int launch_status = swaynag_parse_options(argc, argv, NULL, NULL, 42 int launch_status = swaynag_parse_options(argc, argv, NULL, NULL, NULL,
48 &config_path, &debug); 43 &config_path, &debug);
49 if (launch_status != 0) { 44 if (launch_status != 0) {
50 exit_code = launch_status; 45 exit_code = launch_status;
@@ -66,8 +61,13 @@ int main(int argc, char **argv) {
66 } 61 }
67 62
68 if (argc > 1) { 63 if (argc > 1) {
64 struct swaynag_type *type_args;
65 type_args = calloc(1, sizeof(struct swaynag_type));
66 type_args->name = strdup("<args>");
67 list_add(types, type_args);
68
69 int result = swaynag_parse_options(argc, argv, &swaynag, types, 69 int result = swaynag_parse_options(argc, argv, &swaynag, types,
70 NULL, NULL); 70 type_args, NULL, NULL);
71 if (result != 0) { 71 if (result != 0) {
72 exit_code = result; 72 exit_code = result;
73 goto cleanup; 73 goto cleanup;
@@ -84,7 +84,20 @@ int main(int argc, char **argv) {
84 swaynag.type = swaynag_type_get(types, "error"); 84 swaynag.type = swaynag_type_get(types, "error");
85 } 85 }
86 86
87 swaynag.type = swaynag_type_clone(swaynag.type); 87 // Construct a new type using the config defaults as base, then merging
88 // config type defaults on top, then merging arguments on top of that, and
89 // finally merging defaults on top.
90 struct swaynag_type *type = calloc(1, sizeof(struct swaynag_type));
91 type->name = strdup(swaynag.type->name);
92 swaynag_type_merge(type, swaynag_type_get(types, "<args>"));
93 swaynag_type_merge(type, swaynag.type);
94 swaynag_type_merge(type, swaynag_type_get(types, "<config>"));
95 swaynag_type_merge(type, swaynag_type_get(types, "<defaults>"));
96 swaynag.type = type;
97 if (swaynag.type->output) {
98 swaynag.output.name = strdup(swaynag.type->output);
99 }
100
88 swaynag_types_free(types); 101 swaynag_types_free(types);
89 102
90 if (swaynag.details.message) { 103 if (swaynag.details.message) {
@@ -94,10 +107,10 @@ int main(int argc, char **argv) {
94 } 107 }
95 108
96 wlr_log(WLR_DEBUG, "Output: %s", swaynag.output.name); 109 wlr_log(WLR_DEBUG, "Output: %s", swaynag.output.name);
97 wlr_log(WLR_DEBUG, "Anchors: %d", swaynag.anchors); 110 wlr_log(WLR_DEBUG, "Anchors: %d", swaynag.type->anchors);
98 wlr_log(WLR_DEBUG, "Type: %s", swaynag.type->name); 111 wlr_log(WLR_DEBUG, "Type: %s", swaynag.type->name);
99 wlr_log(WLR_DEBUG, "Message: %s", swaynag.message); 112 wlr_log(WLR_DEBUG, "Message: %s", swaynag.message);
100 wlr_log(WLR_DEBUG, "Font: %s", swaynag.font); 113 wlr_log(WLR_DEBUG, "Font: %s", swaynag.type->font);
101 wlr_log(WLR_DEBUG, "Buttons"); 114 wlr_log(WLR_DEBUG, "Buttons");
102 for (int i = 0; i < swaynag.buttons->length; i++) { 115 for (int i = 0; i < swaynag.buttons->length; i++) {
103 struct swaynag_button *button = swaynag.buttons->items[i]; 116 struct swaynag_button *button = swaynag.buttons->items[i];
diff --git a/swaynag/render.c b/swaynag/render.c
index 67e26eaf..bc3e520e 100644
--- a/swaynag/render.c
+++ b/swaynag/render.c
@@ -9,13 +9,13 @@
9 9
10static uint32_t render_message(cairo_t *cairo, struct swaynag *swaynag) { 10static uint32_t render_message(cairo_t *cairo, struct swaynag *swaynag) {
11 uint32_t height = swaynag->height * swaynag->scale; 11 uint32_t height = swaynag->height * swaynag->scale;
12 height -= SWAYNAG_BAR_BORDER_THICKNESS * swaynag->scale; 12 height -= swaynag->type->bar_border_thickness * swaynag->scale;
13 13
14 int text_width, text_height; 14 int text_width, text_height;
15 get_text_size(cairo, swaynag->font, &text_width, &text_height, 15 get_text_size(cairo, swaynag->type->font, &text_width, &text_height,
16 swaynag->scale, true, "%s", swaynag->message); 16 swaynag->scale, true, "%s", swaynag->message);
17 17
18 int padding = SWAYNAG_MESSAGE_PADDING * swaynag->scale; 18 int padding = swaynag->type->message_padding * swaynag->scale;
19 19
20 uint32_t ideal_height = text_height + padding * 2; 20 uint32_t ideal_height = text_height + padding * 2;
21 uint32_t ideal_surface_height = ideal_height / swaynag->scale; 21 uint32_t ideal_surface_height = ideal_height / swaynag->scale;
@@ -25,7 +25,7 @@ static uint32_t render_message(cairo_t *cairo, struct swaynag *swaynag) {
25 25
26 cairo_set_source_u32(cairo, swaynag->type->text); 26 cairo_set_source_u32(cairo, swaynag->type->text);
27 cairo_move_to(cairo, padding, (int)(ideal_height - text_height) / 2); 27 cairo_move_to(cairo, padding, (int)(ideal_height - text_height) / 2);
28 pango_printf(cairo, swaynag->font, swaynag->scale, false, "%s", 28 pango_printf(cairo, swaynag->type->font, swaynag->scale, false, "%s",
29 swaynag->message); 29 swaynag->message);
30 30
31 return ideal_height; 31 return ideal_height;
@@ -34,11 +34,11 @@ static uint32_t render_message(cairo_t *cairo, struct swaynag *swaynag) {
34static void render_details_scroll_button(cairo_t *cairo, 34static void render_details_scroll_button(cairo_t *cairo,
35 struct swaynag *swaynag, struct swaynag_button *button) { 35 struct swaynag *swaynag, struct swaynag_button *button) {
36 int text_width, text_height; 36 int text_width, text_height;
37 get_text_size(cairo, swaynag->font, &text_width, &text_height, 37 get_text_size(cairo, swaynag->type->font, &text_width, &text_height,
38 swaynag->scale, true, "%s", button->text); 38 swaynag->scale, true, "%s", button->text);
39 39
40 int border = SWAYNAG_BUTTON_BORDER_THICKNESS * swaynag->scale; 40 int border = swaynag->type->button_border_thickness * swaynag->scale;
41 int padding = SWAYNAG_BUTTON_PADDING * swaynag->scale; 41 int padding = swaynag->type->button_padding * swaynag->scale;
42 42
43 cairo_set_source_u32(cairo, swaynag->type->border); 43 cairo_set_source_u32(cairo, swaynag->type->border);
44 cairo_rectangle(cairo, button->x, button->y, 44 cairo_rectangle(cairo, button->x, button->y,
@@ -53,21 +53,21 @@ static void render_details_scroll_button(cairo_t *cairo,
53 cairo_set_source_u32(cairo, swaynag->type->text); 53 cairo_set_source_u32(cairo, swaynag->type->text);
54 cairo_move_to(cairo, button->x + border + padding, 54 cairo_move_to(cairo, button->x + border + padding,
55 button->y + border + (button->height - text_height) / 2); 55 button->y + border + (button->height - text_height) / 2);
56 pango_printf(cairo, swaynag->font, swaynag->scale, true, 56 pango_printf(cairo, swaynag->type->font, swaynag->scale, true,
57 "%s", button->text); 57 "%s", button->text);
58} 58}
59 59
60static int get_detailed_scroll_button_width(cairo_t *cairo, 60static int get_detailed_scroll_button_width(cairo_t *cairo,
61 struct swaynag *swaynag) { 61 struct swaynag *swaynag) {
62 int up_width, down_width, temp_height; 62 int up_width, down_width, temp_height;
63 get_text_size(cairo, swaynag->font, &up_width, &temp_height, 63 get_text_size(cairo, swaynag->type->font, &up_width, &temp_height,
64 swaynag->scale, true, "%s", swaynag->details.button_up.text); 64 swaynag->scale, true, "%s", swaynag->details.button_up.text);
65 get_text_size(cairo, swaynag->font, &down_width, &temp_height, 65 get_text_size(cairo, swaynag->type->font, &down_width, &temp_height,
66 swaynag->scale, true, "%s", swaynag->details.button_down.text); 66 swaynag->scale, true, "%s", swaynag->details.button_down.text);
67 67
68 int text_width = up_width > down_width ? up_width : down_width; 68 int text_width = up_width > down_width ? up_width : down_width;
69 int border = SWAYNAG_BUTTON_BORDER_THICKNESS * swaynag->scale; 69 int border = swaynag->type->button_border_thickness * swaynag->scale;
70 int padding = SWAYNAG_BUTTON_PADDING * swaynag->scale; 70 int padding = swaynag->type->button_padding * swaynag->scale;
71 71
72 return text_width + border * 2 + padding * 2; 72 return text_width + border * 2 + padding * 2;
73} 73}
@@ -76,17 +76,17 @@ static uint32_t render_detailed(cairo_t *cairo, struct swaynag *swaynag,
76 uint32_t y) { 76 uint32_t y) {
77 uint32_t width = swaynag->width * swaynag->scale; 77 uint32_t width = swaynag->width * swaynag->scale;
78 uint32_t height = swaynag->height * swaynag->scale; 78 uint32_t height = swaynag->height * swaynag->scale;
79 height -= SWAYNAG_BAR_BORDER_THICKNESS * swaynag->scale; 79 height -= swaynag->type->bar_border_thickness * swaynag->scale;
80 80
81 int border = SWAYNAG_DETAILS_BORDER_THICKNESS * swaynag->scale; 81 int border = swaynag->type->details_border_thickness * swaynag->scale;
82 int padding = SWAYNAG_MESSAGE_PADDING * swaynag->scale; 82 int padding = swaynag->type->message_padding * swaynag->scale;
83 int decor = padding + border; 83 int decor = padding + border;
84 84
85 swaynag->details.x = decor; 85 swaynag->details.x = decor;
86 swaynag->details.y = y + decor; 86 swaynag->details.y = y + decor;
87 swaynag->details.width = width - decor * 2; 87 swaynag->details.width = width - decor * 2;
88 88
89 PangoLayout *layout = get_pango_layout(cairo, swaynag->font, 89 PangoLayout *layout = get_pango_layout(cairo, swaynag->type->font,
90 swaynag->details.message, swaynag->scale, false); 90 swaynag->details.message, swaynag->scale, false);
91 pango_layout_set_width(layout, 91 pango_layout_set_width(layout,
92 (swaynag->details.width - padding * 2) * PANGO_SCALE); 92 (swaynag->details.width - padding * 2) * PANGO_SCALE);
@@ -173,15 +173,15 @@ static uint32_t render_detailed(cairo_t *cairo, struct swaynag *swaynag,
173static uint32_t render_button(cairo_t *cairo, struct swaynag *swaynag, 173static uint32_t render_button(cairo_t *cairo, struct swaynag *swaynag,
174 int button_index, int *x) { 174 int button_index, int *x) {
175 uint32_t height = swaynag->height * swaynag->scale; 175 uint32_t height = swaynag->height * swaynag->scale;
176 height -= SWAYNAG_BAR_BORDER_THICKNESS * swaynag->scale; 176 height -= swaynag->type->bar_border_thickness * swaynag->scale;
177 struct swaynag_button *button = swaynag->buttons->items[button_index]; 177 struct swaynag_button *button = swaynag->buttons->items[button_index];
178 178
179 int text_width, text_height; 179 int text_width, text_height;
180 get_text_size(cairo, swaynag->font, &text_width, &text_height, 180 get_text_size(cairo, swaynag->type->font, &text_width, &text_height,
181 swaynag->scale, true, "%s", button->text); 181 swaynag->scale, true, "%s", button->text);
182 182
183 int border = SWAYNAG_BUTTON_BORDER_THICKNESS * swaynag->scale; 183 int border = swaynag->type->button_border_thickness * swaynag->scale;
184 int padding = SWAYNAG_BUTTON_PADDING * swaynag->scale; 184 int padding = swaynag->type->button_padding * swaynag->scale;
185 185
186 uint32_t ideal_height = text_height + padding * 2 + border * 2; 186 uint32_t ideal_height = text_height + padding * 2 + border * 2;
187 uint32_t ideal_surface_height = ideal_height / swaynag->scale; 187 uint32_t ideal_surface_height = ideal_height / swaynag->scale;
@@ -206,7 +206,7 @@ static uint32_t render_button(cairo_t *cairo, struct swaynag *swaynag,
206 206
207 cairo_set_source_u32(cairo, swaynag->type->text); 207 cairo_set_source_u32(cairo, swaynag->type->text);
208 cairo_move_to(cairo, button->x + padding, button->y + padding); 208 cairo_move_to(cairo, button->x + padding, button->y + padding);
209 pango_printf(cairo, swaynag->font, swaynag->scale, true, 209 pango_printf(cairo, swaynag->type->font, swaynag->scale, true,
210 "%s", button->text); 210 "%s", button->text);
211 211
212 *x = button->x - border; 212 *x = button->x - border;
@@ -224,13 +224,14 @@ static uint32_t render_to_cairo(cairo_t *cairo, struct swaynag *swaynag) {
224 uint32_t h = render_message(cairo, swaynag); 224 uint32_t h = render_message(cairo, swaynag);
225 max_height = h > max_height ? h : max_height; 225 max_height = h > max_height ? h : max_height;
226 226
227 int x = (swaynag->width - SWAYNAG_BUTTON_MARGIN_RIGHT) * swaynag->scale; 227 int x = swaynag->width - swaynag->type->button_margin_right;
228 x *= swaynag->scale;
228 for (int i = 0; i < swaynag->buttons->length; i++) { 229 for (int i = 0; i < swaynag->buttons->length; i++) {
229 h = render_button(cairo, swaynag, i, &x); 230 h = render_button(cairo, swaynag, i, &x);
230 max_height = h > max_height ? h : max_height; 231 max_height = h > max_height ? h : max_height;
231 x -= SWAYNAG_BUTTON_GAP * swaynag->scale; 232 x -= swaynag->type->button_gap * swaynag->scale;
232 if (i == 0) { 233 if (i == 0) {
233 x -= SWAYNAG_BUTTON_GAP_CLOSE * swaynag->scale; 234 x -= swaynag->type->button_gap_close * swaynag->scale;
234 } 235 }
235 } 236 }
236 237
@@ -239,7 +240,7 @@ static uint32_t render_to_cairo(cairo_t *cairo, struct swaynag *swaynag) {
239 max_height = h > max_height ? h : max_height; 240 max_height = h > max_height ? h : max_height;
240 } 241 }
241 242
242 int border = SWAYNAG_BAR_BORDER_THICKNESS * swaynag->scale; 243 int border = swaynag->type->bar_border_thickness * swaynag->scale;
243 if (max_height > swaynag->height) { 244 if (max_height > swaynag->height) {
244 max_height += border; 245 max_height += border;
245 } 246 }
diff --git a/swaynag/swaynag.1.scd b/swaynag/swaynag.1.scd
index 7d250a45..12787c3c 100644
--- a/swaynag/swaynag.1.scd
+++ b/swaynag/swaynag.1.scd
@@ -45,14 +45,12 @@ _swaynag_ [options...]
45 Set the message text. 45 Set the message text.
46 46
47*-o, --output* <output> 47*-o, --output* <output>
48 Set the output to use. This should be the name of a _xdg\_output_. If 48 Set the output to use. This should be the name of a _xdg\_output_.
49 _xdg\_output\_manager_ is not supported, then the first detected output
50 will be used
51 49
52*-s, --dismiss-button* <text> 50*-s, --dismiss-button* <text>
53 Sets the text for the dismiss nagbar button. The default is _X_. 51 Sets the text for the dismiss nagbar button. The default is _X_.
54 52
55*-t, --type* 53*-t, --type* <type>
56 Set the message type. Two types are created by default _error_ and 54 Set the message type. Two types are created by default _error_ and
57 _warning_. Custom types can be defined in the config file. See 55 _warning_. Custom types can be defined in the config file. See
58 _--config_ and swaynag(5) for details. Both of the default types can be 56 _--config_ and swaynag(5) for details. Both of the default types can be
@@ -61,5 +59,45 @@ _swaynag_ [options...]
61*-v, --version* 59*-v, --version*
62 Show the version number and quit. 60 Show the version number and quit.
63 61
62# APPEARANCE OPTIONS
63*--background* <RRGGBB[AA]>
64 Set the color of the background.
65
66*--border* <RRGGBB[AA]>
67 Set the color of the border.
68
69*--border-bottom* <RRGGBB[AA]>
70 Set the color of the bottom border.
71
72*--button-background* <RRGGBB[AA]>
73 Set the color for the background for buttons.
74
75*--text* <RRGGBB[AA]>
76 Set the text color.
77
78*--border-bottom-size* <size>
79 Set the thickness of the bottom border.
80
81*--message-padding* <padding>
82 Set the padding for the message.
83
84*--details-border-size* <size>
85 Set the thickness for the details border.
86
87*--button-border-size* <size>
88 Set the thickness for the button border.
89
90*--button-gap* <gap>
91 Set the size of the gap between buttons.
92
93*--button-dismiss-gap* <gap>
94 Set the size of the gap between the dismiss button and another button.
95
96*--button-margin-right* <margin>
97 Set the margin from the right of the dismiss button to edge.
98
99*--button-padding* <padding>
100 Set the padding for the button text.
101
64# SEE 102# SEE
65swaynag(5) 103swaynag(5)
diff --git a/swaynag/swaynag.5.scd b/swaynag/swaynag.5.scd
index a4e05e3a..e2348d8b 100644
--- a/swaynag/swaynag.5.scd
+++ b/swaynag/swaynag.5.scd
@@ -20,37 +20,77 @@ following format:
20 20
21``` 21```
22[name-of-type] 22[name-of-type]
23color=RRGGBB[AA] 23option=value
24``` 24```
25 25
26All colors may be given in the form _RRGGBB_ or _RRGGBBAA_. The following 26All colors may be given in the form _RRGGBB_ or _RRGGBBAA_. The following
27colors can be set: 27colors can be set:
28 28
29*background* 29*background=<color>*
30 The background color for _swaynag_. 30 The background color for _swaynag_.
31 31
32*border* 32*border=<color>*
33 The color to use for borders of buttons. 33 The color to use for borders of buttons.
34 34
35*border-bottom* 35*border-bottom=<color>*
36 The color of the border line at the bottom of _swaynag_. 36 The color of the border line at the bottom of _swaynag_.
37 37
38*button-background* 38*button-background=<color>*
39 The background color for the buttons. 39 The background color for the buttons.
40 40
41*text* 41*text=<color>*
42 The color of the text. 42 The color of the text.
43 43
44The following sizing options can also be set:
45
46*border-bottom-size=<size>*
47 Set the thickness of the bottom border.
48
49*message-padding=<padding>*
50 Set the padding for the message.
51
52*details-border-size=<size>*
53 Set the thickness for the details border.
54
55*button-border-size=<size>*
56 Set the thickness for the button border.
57
58*button-gap=<gap>*
59 Set the size of the gap between buttons.
60
61*button-dismiss-gap=<gap>*
62 Set the size of the gap between the dismiss button and another button.
63
64*button-margin-right=<margin>*
65 Set the margin from the right of the dismiss button to edge.
66
67*button-padding=<padding>*
68 Set the padding for the button text.
69
70Additionally, the following options can be assigned a default per-type:
71
72*edge=top|bottom*
73 Set the edge to use.
74
75*font=<font>*
76 Set the font to use.
77
78*output=<output>*
79 Set the output to use. This should be the name of a _xdg\_output_.
80
44# EXAMPLE 81# EXAMPLE
45``` 82```
46font=Monospace 12 83font=Monospace 12
84edge=bottom
47 85
48[green] 86[green]
87edge=top
49background=00AA00 88background=00AA00
50border=006600 89border=006600
51border-bottom=004400 90border-bottom=004400
52text=FFFFFF 91text=FFFFFF
53button-background=00CC00 92button-background=00CC00
93message-padding=10
54``` 94```
55 95
56# SEE 96# SEE
diff --git a/swaynag/swaynag.c b/swaynag/swaynag.c
index e5d2e216..e79cd879 100644
--- a/swaynag/swaynag.c
+++ b/swaynag/swaynag.c
@@ -345,7 +345,8 @@ void swaynag_setup(struct swaynag *swaynag) {
345 assert(swaynag->layer_surface); 345 assert(swaynag->layer_surface);
346 zwlr_layer_surface_v1_add_listener(swaynag->layer_surface, 346 zwlr_layer_surface_v1_add_listener(swaynag->layer_surface,
347 &layer_surface_listener, swaynag); 347 &layer_surface_listener, swaynag);
348 zwlr_layer_surface_v1_set_anchor(swaynag->layer_surface, swaynag->anchors); 348 zwlr_layer_surface_v1_set_anchor(swaynag->layer_surface,
349 swaynag->type->anchors);
349 350
350 wl_registry_destroy(registry); 351 wl_registry_destroy(registry);
351} 352}
@@ -363,7 +364,6 @@ void swaynag_destroy(struct swaynag *swaynag) {
363 swaynag->run_display = false; 364 swaynag->run_display = false;
364 365
365 free(swaynag->message); 366 free(swaynag->message);
366 free(swaynag->font);
367 while (swaynag->buttons->length) { 367 while (swaynag->buttons->length) {
368 struct swaynag_button *button = swaynag->buttons->items[0]; 368 struct swaynag_button *button = swaynag->buttons->items[0];
369 list_del(swaynag->buttons, 0); 369 list_del(swaynag->buttons, 0);
diff --git a/swaynag/types.c b/swaynag/types.c
index c92d0e89..f429baf0 100644
--- a/swaynag/types.c
+++ b/swaynag/types.c
@@ -9,8 +9,26 @@
9#include "swaynag/config.h" 9#include "swaynag/config.h"
10#include "swaynag/types.h" 10#include "swaynag/types.h"
11#include "util.h" 11#include "util.h"
12#include "wlr-layer-shell-unstable-v1-client-protocol.h"
12 13
13void swaynag_types_add_default(list_t *types) { 14void swaynag_types_add_default(list_t *types) {
15 struct swaynag_type *type_defaults;
16 type_defaults = calloc(1, sizeof(struct swaynag_type));
17 type_defaults->name = strdup("<defaults>");
18 type_defaults->font = strdup("pango:Monospace 10");
19 type_defaults->anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP
20 | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
21 | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
22 type_defaults->bar_border_thickness = 2;
23 type_defaults->message_padding = 8;
24 type_defaults->details_border_thickness = 3;
25 type_defaults->button_border_thickness = 3;
26 type_defaults->button_gap = 20;
27 type_defaults->button_gap_close = 15;
28 type_defaults->button_margin_right = 2;
29 type_defaults->button_padding = 3;
30 list_add(types, type_defaults);
31
14 struct swaynag_type *type_error; 32 struct swaynag_type *type_error;
15 type_error = calloc(1, sizeof(struct swaynag_type)); 33 type_error = calloc(1, sizeof(struct swaynag_type));
16 type_error->name = strdup("error"); 34 type_error->name = strdup("error");
@@ -42,20 +60,84 @@ struct swaynag_type *swaynag_type_get(list_t *types, char *name) {
42 return NULL; 60 return NULL;
43} 61}
44 62
45struct swaynag_type *swaynag_type_clone(struct swaynag_type *type) { 63void swaynag_type_merge(struct swaynag_type *dest, struct swaynag_type *src) {
46 struct swaynag_type *clone; 64 if (!dest || !src) {
47 clone = calloc(1, sizeof(struct swaynag_type)); 65 return;
48 clone->name = strdup(type->name); 66 }
49 clone->button_background = type->button_background; 67
50 clone->background = type->background; 68 if (!dest->font && src->font) {
51 clone->text = type->text; 69 dest->font = strdup(src->font);
52 clone->border = type->border; 70 }
53 clone->border_bottom = type->border_bottom; 71
54 return clone; 72 if (!dest->output && src->output) {
73 dest->output = strdup(src->output);
74 }
75
76 if (dest->anchors == 0 && src->anchors > 0) {
77 dest->anchors = src->anchors;
78 }
79
80 // Colors
81 if (dest->button_background == 0 && src->button_background > 0) {
82 dest->button_background = src->button_background;
83 }
84
85 if (dest->background == 0 && src->background > 0) {
86 dest->background = src->background;
87 }
88
89 if (dest->text == 0 && src->text > 0) {
90 dest->text = src->text;
91 }
92
93 if (dest->border == 0 && src->border > 0) {
94 dest->border = src->border;
95 }
96
97 if (dest->border_bottom == 0 && src->border_bottom > 0) {
98 dest->border_bottom = src->border_bottom;
99 }
100
101 // Sizing
102 if (dest->bar_border_thickness == 0 && src->bar_border_thickness > 0) {
103 dest->bar_border_thickness = src->bar_border_thickness;
104 }
105
106 if (dest->message_padding == 0 && src->message_padding > 0) {
107 dest->message_padding = src->message_padding;
108 }
109
110 if (dest->details_border_thickness == 0
111 && src->details_border_thickness > 0) {
112 dest->details_border_thickness = src->details_border_thickness;
113 }
114
115 if (dest->button_border_thickness == 0
116 && src->button_border_thickness > 0) {
117 dest->button_border_thickness = src->button_border_thickness;
118 }
119
120 if (dest->button_gap == 0 && src->button_gap > 0) {
121 dest->button_gap = src->button_gap;
122 }
123
124 if (dest->button_gap_close == 0 && src->button_gap_close > 0) {
125 dest->button_gap_close = src->button_gap_close;
126 }
127
128 if (dest->button_margin_right == 0 && src->button_margin_right > 0) {
129 dest->button_margin_right = src->button_margin_right;
130 }
131
132 if (dest->button_padding == 0 && src->button_padding > 0) {
133 dest->button_padding = src->button_padding;
134 }
55} 135}
56 136
57void swaynag_type_free(struct swaynag_type *type) { 137void swaynag_type_free(struct swaynag_type *type) {
58 free(type->name); 138 free(type->name);
139 free(type->font);
140 free(type->output);
59 free(type); 141 free(type);
60} 142}
61 143
@@ -67,51 +149,3 @@ void swaynag_types_free(list_t *types) {
67 } 149 }
68 list_free(types); 150 list_free(types);
69} 151}
70
71int swaynag_parse_type(int argc, char **argv, struct swaynag_type *type) {
72 enum color_option {
73 COLOR_BACKGROUND,
74 COLOR_BORDER,
75 COLOR_BORDER_BOTTOM,
76 COLOR_BUTTON,
77 COLOR_TEXT,
78 };
79
80 static struct option opts[] = {
81 {"background", required_argument, NULL, COLOR_BACKGROUND},
82 {"border", required_argument, NULL, COLOR_BORDER},
83 {"border-bottom", required_argument, NULL, COLOR_BORDER_BOTTOM},
84 {"button-background", required_argument, NULL, COLOR_BUTTON},
85 {"text", required_argument, NULL, COLOR_TEXT},
86 {0, 0, 0, 0}
87 };
88
89 optind = 1;
90 while (1) {
91 int c = getopt_long(argc, argv, "", opts, NULL);
92 if (c == -1) {
93 break;
94 }
95 switch (c) {
96 case COLOR_BACKGROUND:
97 type->background = parse_color(optarg);
98 break;
99 case COLOR_BORDER:
100 type->border = parse_color(optarg);
101 break;
102 case COLOR_BORDER_BOTTOM:
103 type->border_bottom = parse_color(optarg);
104 break;
105 case COLOR_BUTTON:
106 type->button_background = parse_color(optarg);
107 break;
108 case COLOR_TEXT:
109 type->text = parse_color(optarg);
110 break;
111 default:
112 break;
113 }
114 }
115 return 0;
116}
117