aboutsummaryrefslogtreecommitdiffstats
path: root/sway/config/output.c
diff options
context:
space:
mode:
authorLibravatar Brian Ashworth <bosrsf04@gmail.com>2019-03-15 02:20:07 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2019-03-16 10:41:02 -0600
commit73605dac2ae18e2ca84a74da895c4098a1bee6f8 (patch)
tree06cdbf312fe65c44becb39ca80dde118f3be66b6 /sway/config/output.c
parentFix output config retrieval for new outputs (diff)
downloadsway-73605dac2ae18e2ca84a74da895c4098a1bee6f8.tar.gz
sway-73605dac2ae18e2ca84a74da895c4098a1bee6f8.tar.zst
sway-73605dac2ae18e2ca84a74da895c4098a1bee6f8.zip
config/output: revamp identifier/name layering
This revamps the way that output configs are handled when referencing an output by both identifier and name. If an output is always referred to by name or by identifier, this should have no noticeable change. As soon as there is a name output config and an identifier output config that matches an output, an output config is generated that is named `<identifier> on <name>` that is generated with the identifier output config merged on top of the name output config and stored. When a change to either is stored, the delta is merged on top of that "id on name" output config, as well. If the "id on name" output config exists, it has the highest precedence and will be used when applying a config to the output. This fixes the following case: - `swaymsg output <name> bg /path/to/wallpaper1 fill` - `swaymsg output <identifier> bg /path/to/wallpaper2 fill` - `swaymsg output <name> dpms on` Without this, the wallpaper is changed to `/path/to/wallpaper1`. With this, the wallpaper remains `/path/to/wallpaper2`.
Diffstat (limited to 'sway/config/output.c')
-rw-r--r--sway/config/output.c116
1 files changed, 94 insertions, 22 deletions
diff --git a/sway/config/output.c b/sway/config/output.c
index a20c5ad4..5656e2c1 100644
--- a/sway/config/output.c
+++ b/sway/config/output.c
@@ -98,10 +98,67 @@ static void merge_wildcard_on_all(struct output_config *wildcard) {
98 } 98 }
99} 99}
100 100
101static void merge_id_on_name(struct output_config *oc) {
102 char *id_on_name = NULL;
103 char id[128];
104 char *name = NULL;
105 struct sway_output *output;
106 wl_list_for_each(output, &root->all_outputs, link) {
107 name = output->wlr_output->name;
108 output_get_identifier(id, sizeof(id), output);
109 if (strcmp(name, oc->name) != 0 || strcmp(id, oc->name) != 0) {
110 size_t length = snprintf(NULL, 0, "%s on %s", id, name) + 1;
111 id_on_name = malloc(length);
112 if (!id_on_name) {
113 sway_log(SWAY_ERROR, "Failed to allocate id on name string");
114 return;
115 }
116 snprintf(id_on_name, length, "%s on %s", id, name);
117 break;
118 }
119 }
120
121 if (!id_on_name) {
122 return;
123 }
124
125 int i = list_seq_find(config->output_configs, output_name_cmp, id_on_name);
126 if (i >= 0) {
127 sway_log(SWAY_DEBUG, "Merging on top of existing id on name config");
128 merge_output_config(config->output_configs->items[i], oc);
129 } else {
130 // If both a name and identifier config, exist generate an id on name
131 int ni = list_seq_find(config->output_configs, output_name_cmp, name);
132 int ii = list_seq_find(config->output_configs, output_name_cmp, id);
133 if ((ni >= 0 && ii >= 0) || (ni >= 0 && strcmp(oc->name, id) == 0)
134 || (ii >= 0 && strcmp(oc->name, name) == 0)) {
135 struct output_config *ion_oc = new_output_config(id_on_name);
136 if (ni >= 0) {
137 merge_output_config(ion_oc, config->output_configs->items[ni]);
138 }
139 if (ii >= 0) {
140 merge_output_config(ion_oc, config->output_configs->items[ii]);
141 }
142 merge_output_config(ion_oc, oc);
143 list_add(config->output_configs, ion_oc);
144 sway_log(SWAY_DEBUG, "Generated id on name output config \"%s\""
145 " (enabled: %d) (%dx%d@%fHz position %d,%d scale %f "
146 "transform %d) (bg %s %s) (dpms %d)", ion_oc->name,
147 ion_oc->enabled, ion_oc->width, ion_oc->height,
148 ion_oc->refresh_rate, ion_oc->x, ion_oc->y, ion_oc->scale,
149 ion_oc->transform, ion_oc->background,
150 ion_oc->background_option, ion_oc->dpms_state);
151 }
152 }
153 free(id_on_name);
154}
155
101struct output_config *store_output_config(struct output_config *oc) { 156struct output_config *store_output_config(struct output_config *oc) {
102 bool wildcard = strcmp(oc->name, "*") == 0; 157 bool wildcard = strcmp(oc->name, "*") == 0;
103 if (wildcard) { 158 if (wildcard) {
104 merge_wildcard_on_all(oc); 159 merge_wildcard_on_all(oc);
160 } else {
161 merge_id_on_name(oc);
105 } 162 }
106 163
107 int i = list_seq_find(config->output_configs, output_name_cmp, oc->name); 164 int i = list_seq_find(config->output_configs, output_name_cmp, oc->name);
@@ -374,35 +431,51 @@ static void default_output_config(struct output_config *oc,
374static struct output_config *get_output_config(char *identifier, 431static struct output_config *get_output_config(char *identifier,
375 struct sway_output *sway_output) { 432 struct sway_output *sway_output) {
376 const char *name = sway_output->wlr_output->name; 433 const char *name = sway_output->wlr_output->name;
377 struct output_config *oc_name = NULL;
378 int i = list_seq_find(config->output_configs, output_name_cmp, name);
379 if (i >= 0) {
380 oc_name = config->output_configs->items[i];
381 }
382 434
435 struct output_config *oc_id_on_name = NULL;
436 struct output_config *oc_name = NULL;
383 struct output_config *oc_id = NULL; 437 struct output_config *oc_id = NULL;
384 i = list_seq_find(config->output_configs, output_name_cmp, identifier); 438
439 size_t length = snprintf(NULL, 0, "%s on %s", identifier, name) + 1;
440 char *id_on_name = malloc(length);
441 snprintf(id_on_name, length, "%s on %s", identifier, name);
442 int i = list_seq_find(config->output_configs, output_name_cmp, id_on_name);
385 if (i >= 0) { 443 if (i >= 0) {
386 oc_id = config->output_configs->items[i]; 444 oc_id_on_name = config->output_configs->items[i];
445 } else {
446 i = list_seq_find(config->output_configs, output_name_cmp, name);
447 if (i >= 0) {
448 oc_name = config->output_configs->items[i];
449 }
450
451 i = list_seq_find(config->output_configs, output_name_cmp, identifier);
452 if (i >= 0) {
453 oc_id = config->output_configs->items[i];
454 }
387 } 455 }
388 456
389 struct output_config *result = new_output_config("temp"); 457 struct output_config *result = new_output_config("temp");
390 if (config->reloading) { 458 if (config->reloading) {
391 default_output_config(result, sway_output->wlr_output); 459 default_output_config(result, sway_output->wlr_output);
392 } 460 }
393 if (oc_name && oc_id) { 461 if (oc_id_on_name) {
462 // Already have an identifier on name config, use that
463 free(result->name);
464 result->name = strdup(id_on_name);
465 merge_output_config(result, oc_id_on_name);
466 } else if (oc_name && oc_id) {
394 // Generate a config named `<identifier> on <name>` which contains a 467 // Generate a config named `<identifier> on <name>` which contains a
395 // merged copy of the identifier on name. This will make sure that both 468 // merged copy of the identifier on name. This will make sure that both
396 // identifier and name configs are respected, with identifier getting 469 // identifier and name configs are respected, with identifier getting
397 // priority 470 // priority
398 size_t length = snprintf(NULL, 0, "%s on %s", identifier, name) + 1; 471 struct output_config *temp = new_output_config(id_on_name);
399 char *temp = malloc(length); 472 merge_output_config(temp, oc_name);
400 snprintf(temp, length, "%s on %s", identifier, name); 473 merge_output_config(temp, oc_id);
474 list_add(config->output_configs, temp);
401 475
402 free(result->name); 476 free(result->name);
403 result->name = temp; 477 result->name = strdup(id_on_name);
404 merge_output_config(result, oc_name); 478 merge_output_config(result, temp);
405 merge_output_config(result, oc_id);
406 479
407 sway_log(SWAY_DEBUG, "Generated output config \"%s\" (enabled: %d)" 480 sway_log(SWAY_DEBUG, "Generated output config \"%s\" (enabled: %d)"
408 " (%dx%d@%fHz position %d,%d scale %f transform %d) (bg %s %s)" 481 " (%dx%d@%fHz position %d,%d scale %f transform %d) (bg %s %s)"
@@ -435,6 +508,7 @@ static struct output_config *get_output_config(char *identifier,
435 result = NULL; 508 result = NULL;
436 } 509 }
437 510
511 free(id_on_name);
438 return result; 512 return result;
439} 513}
440 514
@@ -455,14 +529,12 @@ void apply_output_config_to_outputs(struct output_config *oc) {
455 char *name = sway_output->wlr_output->name; 529 char *name = sway_output->wlr_output->name;
456 output_get_identifier(id, sizeof(id), sway_output); 530 output_get_identifier(id, sizeof(id), sway_output);
457 if (wildcard || !strcmp(name, oc->name) || !strcmp(id, oc->name)) { 531 if (wildcard || !strcmp(name, oc->name) || !strcmp(id, oc->name)) {
458 struct output_config *current = new_output_config(oc->name); 532 struct output_config *current = get_output_config(id, sway_output);
459 merge_output_config(current, oc); 533 if (!current) {
460 if (wildcard) { 534 // No stored output config matched, apply oc directly
461 struct output_config *tmp = get_output_config(id, sway_output); 535 sway_log(SWAY_DEBUG, "Applying oc directly");
462 if (tmp) { 536 current = new_output_config(oc->name);
463 free_output_config(current); 537 merge_output_config(current, oc);
464 current = tmp;
465 }
466 } 538 }
467 apply_output_config(current, sway_output); 539 apply_output_config(current, sway_output);
468 free_output_config(current); 540 free_output_config(current);