aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);