diff --git a/include/sway/config.h b/include/sway/config.h index 045359ca..eecdde3a 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -397,6 +397,8 @@ struct seat_attachment_config *seat_config_get_attachment( void apply_seat_config(struct seat_config *seat); int output_name_cmp(const void *item, const void *data); +void output_get_identifier(char *identifier, size_t len, + struct sway_output *output); struct output_config *new_output_config(const char *name); void merge_output_config(struct output_config *dst, struct output_config *src); void apply_output_config(struct output_config *oc, swayc_t *output); diff --git a/sway/commands/output.c b/sway/commands/output.c index 8cc74bcc..8c0fa63c 100644 --- a/sway/commands/output.c +++ b/sway/commands/output.c @@ -231,8 +231,8 @@ static struct cmd_results *cmd_output_background(struct output_config *output, } struct cmd_results *cmd_output(int argc, char **argv) { - struct cmd_results *error = NULL; - if ((error = checkarg(argc, "output", EXPECTED_AT_LEAST, 1))) { + struct cmd_results *error = checkarg(argc, "output", EXPECTED_AT_LEAST, 1); + if (error != NULL) { return error; } @@ -275,11 +275,11 @@ struct cmd_results *cmd_output(int argc, char **argv) { int i = list_seq_find(config->output_configs, output_name_cmp, output->name); if (i >= 0) { - // merge existing config - struct output_config *oc = config->output_configs->items[i]; - merge_output_config(oc, output); + // Merge existing config + struct output_config *current = config->output_configs->items[i]; + merge_output_config(current, output); free_output_config(output); - output = oc; + output = current; } else { list_add(config->output_configs, output); } @@ -290,22 +290,26 @@ struct cmd_results *cmd_output(int argc, char **argv) { output->refresh_rate, output->x, output->y, output->scale, output->transform, output->background, output->background_option); - if (output->name) { - // Try to find the output container and apply configuration now. If - // this is during startup then there will be no container and config - // will be applied during normal "new output" event from wlroots. - swayc_t *cont = NULL; - for (int i = 0; i < root_container.children->length; ++i) { - cont = root_container.children->items[i]; - if (cont->name && ((strcmp(cont->name, output->name) == 0) || - (strcmp(output->name, "*") == 0))) { - apply_output_config(output, cont); + // Try to find the output container and apply configuration now. If + // this is during startup then there will be no container and config + // will be applied during normal "new output" event from wlroots. + char identifier[128]; + bool all = strcmp(output->name, "*") == 0; + for (int i = 0; i < root_container.children->length; ++i) { + swayc_t *cont = root_container.children->items[i]; + if (cont->type != C_OUTPUT) { + continue; + } - if (strcmp(output->name, "*") != 0) { - // Stop looking if the output config isn't applicable to all - // outputs - break; - } + output_get_identifier(identifier, sizeof(identifier), cont->sway_output); + if (all || strcmp(cont->name, output->name) == 0 || + strcmp(identifier, output->name) == 0) { + apply_output_config(output, cont); + + if (!all) { + // Stop looking if the output config isn't applicable to all + // outputs + break; } } } diff --git a/sway/config/output.c b/sway/config/output.c index f336c949..e798a20e 100644 --- a/sway/config/output.c +++ b/sway/config/output.c @@ -1,4 +1,5 @@ #define _XOPEN_SOURCE 700 +#include #include #include #include @@ -14,6 +15,13 @@ int output_name_cmp(const void *item, const void *data) { return strcmp(output->name, name); } +void output_get_identifier(char *identifier, size_t len, + struct sway_output *output) { + struct wlr_output *wlr_output = output->wlr_output; + snprintf(identifier, len, "%s %s %s", wlr_output->make, wlr_output->model, + wlr_output->serial); +} + struct output_config *new_output_config(const char *name) { struct output_config *oc = calloc(1, sizeof(struct output_config)); if (oc == NULL) { diff --git a/sway/tree/container.c b/sway/tree/container.c index 6f2a3abf..c5574275 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -49,16 +49,49 @@ static swayc_t *new_swayc(enum swayc_types type) { return c; } +static void free_swayc(swayc_t *cont) { + if (!sway_assert(cont, "free_swayc passed NULL")) { + return; + } + + wl_signal_emit(&cont->events.destroy, cont); + + if (cont->children) { + // remove children until there are no more, free_swayc calls + // remove_child, which removes child from this container + while (cont->children->length) { + free_swayc(cont->children->items[0]); + } + list_free(cont->children); + } + if (cont->marks) { + list_foreach(cont->marks, free); + list_free(cont->marks); + } + if (cont->parent) { + remove_child(cont); + } + if (cont->name) { + free(cont->name); + } + free(cont); +} + swayc_t *new_output(struct sway_output *sway_output) { struct wlr_box size; wlr_output_effective_resolution(sway_output->wlr_output, &size.width, &size.height); + const char *name = sway_output->wlr_output->name; + char identifier[128]; + output_get_identifier(identifier, sizeof(identifier), sway_output); struct output_config *oc = NULL, *all = NULL; for (int i = 0; i < config->output_configs->length; ++i) { struct output_config *cur = config->output_configs->items[i]; - if (strcasecmp(name, cur->name) == 0) { + + if (strcasecmp(name, cur->name) == 0 || + strcasecmp(identifier, cur->name) == 0) { sway_log(L_DEBUG, "Matched output config for %s", name); oc = cur; } @@ -74,13 +107,18 @@ swayc_t *new_output(struct sway_output *sway_output) { if (!oc) { oc = all; } + if (oc && !oc->enabled) { return NULL; } swayc_t *output = new_swayc(C_OUTPUT); output->sway_output = sway_output; - output->name = name ? strdup(name) : NULL; + output->name = strdup(name); + if (output->name == NULL) { + free_swayc(output); + return NULL; + } apply_output_config(oc, output); @@ -140,34 +178,6 @@ swayc_t *new_view(swayc_t *sibling, struct sway_view *sway_view) { return swayc; } -static void free_swayc(swayc_t *cont) { - if (!sway_assert(cont, "free_swayc passed NULL")) { - return; - } - - wl_signal_emit(&cont->events.destroy, cont); - - if (cont->children) { - // remove children until there are no more, free_swayc calls - // remove_child, which removes child from this container - while (cont->children->length) { - free_swayc(cont->children->items[0]); - } - list_free(cont->children); - } - if (cont->marks) { - list_foreach(cont->marks, free); - list_free(cont->marks); - } - if (cont->parent) { - remove_child(cont); - } - if (cont->name) { - free(cont->name); - } - free(cont); -} - swayc_t *destroy_output(swayc_t *output) { if (!sway_assert(output, "null output passed to destroy_output")) { return NULL;