diff options
-rw-r--r-- | sway/config/output.c | 116 |
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 | ||
101 | static 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 | |||
101 | struct output_config *store_output_config(struct output_config *oc) { | 156 | struct 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, | |||
374 | static struct output_config *get_output_config(char *identifier, | 431 | static 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); |