diff options
-rw-r--r-- | include/sway/config.h | 2 | ||||
-rw-r--r-- | sway/commands/output.c | 104 | ||||
-rw-r--r-- | sway/config/output.c | 64 |
3 files changed, 108 insertions, 62 deletions
diff --git a/include/sway/config.h b/include/sway/config.h index f660a269..6f6710e9 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -461,6 +461,8 @@ void merge_output_config(struct output_config *dst, struct output_config *src); | |||
461 | void apply_output_config(struct output_config *oc, | 461 | void apply_output_config(struct output_config *oc, |
462 | struct sway_container *output); | 462 | struct sway_container *output); |
463 | 463 | ||
464 | struct output_config *store_output_config(struct output_config *oc); | ||
465 | |||
464 | void free_output_config(struct output_config *oc); | 466 | void free_output_config(struct output_config *oc); |
465 | 467 | ||
466 | int workspace_output_cmp_workspace(const void *a, const void *b); | 468 | int workspace_output_cmp_workspace(const void *a, const void *b); |
diff --git a/sway/commands/output.c b/sway/commands/output.c index 15bbd687..4d98162b 100644 --- a/sway/commands/output.c +++ b/sway/commands/output.c | |||
@@ -21,6 +21,60 @@ static struct cmd_handler output_handlers[] = { | |||
21 | { "transform", output_cmd_transform }, | 21 | { "transform", output_cmd_transform }, |
22 | }; | 22 | }; |
23 | 23 | ||
24 | static struct output_config *get_output_config(char *name, char *identifier) { | ||
25 | int i = list_seq_find(config->output_configs, output_name_cmp, name); | ||
26 | if (i >= 0) { | ||
27 | return config->output_configs->items[i]; | ||
28 | } | ||
29 | |||
30 | i = list_seq_find(config->output_configs, output_name_cmp, identifier); | ||
31 | if (i >= 0) { | ||
32 | return config->output_configs->items[i]; | ||
33 | } | ||
34 | |||
35 | return NULL; | ||
36 | } | ||
37 | |||
38 | static void apply_output_config_to_outputs(struct output_config *oc) { | ||
39 | // Try to find the output container and apply configuration now. If | ||
40 | // this is during startup then there will be no container and config | ||
41 | // will be applied during normal "new output" event from wlroots. | ||
42 | bool wildcard = strcmp(oc->name, "*") == 0; | ||
43 | char id[128]; | ||
44 | struct sway_output *sway_output; | ||
45 | wl_list_for_each(sway_output, &root_container.sway_root->outputs, link) { | ||
46 | char *name = sway_output->wlr_output->name; | ||
47 | output_get_identifier(id, sizeof(id), sway_output); | ||
48 | if (wildcard || !strcmp(name, oc->name) || !strcmp(id, oc->name)) { | ||
49 | if (!sway_output->swayc) { | ||
50 | if (!oc->enabled) { | ||
51 | if (!wildcard) { | ||
52 | break; | ||
53 | } | ||
54 | continue; | ||
55 | } | ||
56 | |||
57 | output_enable(sway_output); | ||
58 | } | ||
59 | |||
60 | struct output_config *current = oc; | ||
61 | if (wildcard) { | ||
62 | struct output_config *tmp = get_output_config(name, id); | ||
63 | if (tmp) { | ||
64 | current = tmp; | ||
65 | } | ||
66 | } | ||
67 | apply_output_config(current, sway_output->swayc); | ||
68 | |||
69 | if (!wildcard) { | ||
70 | // Stop looking if the output config isn't applicable to all | ||
71 | // outputs | ||
72 | break; | ||
73 | } | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | |||
24 | struct cmd_results *cmd_output(int argc, char **argv) { | 78 | struct cmd_results *cmd_output(int argc, char **argv) { |
25 | struct cmd_results *error = checkarg(argc, "output", EXPECTED_AT_LEAST, 1); | 79 | struct cmd_results *error = checkarg(argc, "output", EXPECTED_AT_LEAST, 1); |
26 | if (error != NULL) { | 80 | if (error != NULL) { |
@@ -60,54 +114,8 @@ struct cmd_results *cmd_output(int argc, char **argv) { | |||
60 | config->handler_context.leftovers.argc = 0; | 114 | config->handler_context.leftovers.argc = 0; |
61 | config->handler_context.leftovers.argv = NULL; | 115 | config->handler_context.leftovers.argv = NULL; |
62 | 116 | ||
63 | int i = list_seq_find(config->output_configs, output_name_cmp, output->name); | 117 | output = store_output_config(output); |
64 | if (i >= 0) { | 118 | apply_output_config_to_outputs(output); |
65 | // Merge existing config | ||
66 | struct output_config *current = config->output_configs->items[i]; | ||
67 | merge_output_config(current, output); | ||
68 | free_output_config(output); | ||
69 | output = current; | ||
70 | } else { | ||
71 | list_add(config->output_configs, output); | ||
72 | } | ||
73 | |||
74 | wlr_log(WLR_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz " | ||
75 | "position %d,%d scale %f transform %d) (bg %s %s) (dpms %d)", | ||
76 | output->name, output->enabled, output->width, output->height, | ||
77 | output->refresh_rate, output->x, output->y, output->scale, | ||
78 | output->transform, output->background, output->background_option, output->dpms_state); | ||
79 | |||
80 | // Try to find the output container and apply configuration now. If | ||
81 | // this is during startup then there will be no container and config | ||
82 | // will be applied during normal "new output" event from wlroots. | ||
83 | char identifier[128]; | ||
84 | bool all = strcmp(output->name, "*") == 0; | ||
85 | struct sway_output *sway_output; | ||
86 | wl_list_for_each(sway_output, &root_container.sway_root->outputs, link) { | ||
87 | output_get_identifier(identifier, sizeof(identifier), sway_output); | ||
88 | wlr_log(WLR_DEBUG, "Checking identifier %s", identifier); | ||
89 | if (all || strcmp(sway_output->wlr_output->name, output->name) == 0 | ||
90 | || strcmp(identifier, output->name) == 0) { | ||
91 | if (!sway_output->swayc) { | ||
92 | if (!output->enabled) { | ||
93 | if (!all) { | ||
94 | break; | ||
95 | } | ||
96 | continue; | ||
97 | } | ||
98 | |||
99 | output_enable(sway_output); | ||
100 | } | ||
101 | |||
102 | apply_output_config(output, sway_output->swayc); | ||
103 | |||
104 | if (!all) { | ||
105 | // Stop looking if the output config isn't applicable to all | ||
106 | // outputs | ||
107 | break; | ||
108 | } | ||
109 | } | ||
110 | } | ||
111 | 119 | ||
112 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 120 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
113 | 121 | ||
diff --git a/sway/config/output.c b/sway/config/output.c index 1bf9e5f1..505fa745 100644 --- a/sway/config/output.c +++ b/sway/config/output.c | |||
@@ -45,10 +45,6 @@ struct output_config *new_output_config(const char *name) { | |||
45 | } | 45 | } |
46 | 46 | ||
47 | void merge_output_config(struct output_config *dst, struct output_config *src) { | 47 | void merge_output_config(struct output_config *dst, struct output_config *src) { |
48 | if (src->name) { | ||
49 | free(dst->name); | ||
50 | dst->name = strdup(src->name); | ||
51 | } | ||
52 | if (src->enabled != -1) { | 48 | if (src->enabled != -1) { |
53 | dst->enabled = src->enabled; | 49 | dst->enabled = src->enabled; |
54 | } | 50 | } |
@@ -86,6 +82,56 @@ void merge_output_config(struct output_config *dst, struct output_config *src) { | |||
86 | } | 82 | } |
87 | } | 83 | } |
88 | 84 | ||
85 | static void merge_wildcard_on_all(struct output_config *wildcard) { | ||
86 | for (int i = 0; i < config->output_configs->length; i++) { | ||
87 | struct output_config *oc = config->output_configs->items[i]; | ||
88 | if (strcmp(wildcard->name, oc->name) != 0) { | ||
89 | wlr_log(WLR_DEBUG, "Merging output * config on %s", oc->name); | ||
90 | merge_output_config(oc, wildcard); | ||
91 | } | ||
92 | } | ||
93 | } | ||
94 | |||
95 | struct output_config *store_output_config(struct output_config *oc) { | ||
96 | bool wildcard = strcmp(oc->name, "*") == 0; | ||
97 | if (wildcard) { | ||
98 | merge_wildcard_on_all(oc); | ||
99 | } | ||
100 | |||
101 | int i = list_seq_find(config->output_configs, output_name_cmp, oc->name); | ||
102 | if (i >= 0) { | ||
103 | wlr_log(WLR_DEBUG, "Merging on top of existing output config"); | ||
104 | struct output_config *current = config->output_configs->items[i]; | ||
105 | merge_output_config(current, oc); | ||
106 | free_output_config(oc); | ||
107 | oc = current; | ||
108 | } else if (!wildcard) { | ||
109 | wlr_log(WLR_DEBUG, "Adding non-wildcard output config"); | ||
110 | i = list_seq_find(config->output_configs, output_name_cmp, "*"); | ||
111 | if (i >= 0) { | ||
112 | wlr_log(WLR_DEBUG, "Merging on top of output * config"); | ||
113 | struct output_config *current = new_output_config(oc->name); | ||
114 | merge_output_config(current, config->output_configs->items[i]); | ||
115 | merge_output_config(current, oc); | ||
116 | free_output_config(oc); | ||
117 | oc = current; | ||
118 | } | ||
119 | list_add(config->output_configs, oc); | ||
120 | } else { | ||
121 | // New wildcard config. Just add it | ||
122 | wlr_log(WLR_DEBUG, "Adding output * config"); | ||
123 | list_add(config->output_configs, oc); | ||
124 | } | ||
125 | |||
126 | wlr_log(WLR_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz " | ||
127 | "position %d,%d scale %f transform %d) (bg %s %s) (dpms %d)", | ||
128 | oc->name, oc->enabled, oc->width, oc->height, oc->refresh_rate, | ||
129 | oc->x, oc->y, oc->scale, oc->transform, oc->background, | ||
130 | oc->background_option, oc->dpms_state); | ||
131 | |||
132 | return oc; | ||
133 | } | ||
134 | |||
89 | static void set_mode(struct wlr_output *output, int width, int height, | 135 | static void set_mode(struct wlr_output *output, int width, int height, |
90 | float refresh_rate) { | 136 | float refresh_rate) { |
91 | int mhz = (int)(refresh_rate * 1000); | 137 | int mhz = (int)(refresh_rate * 1000); |
@@ -165,16 +211,6 @@ void apply_output_config(struct output_config *oc, struct sway_container *output | |||
165 | wlr_output_layout_add_auto(output_layout, wlr_output); | 211 | wlr_output_layout_add_auto(output_layout, wlr_output); |
166 | } | 212 | } |
167 | 213 | ||
168 | if (!oc || !oc->background) { | ||
169 | // Look for a * config for background | ||
170 | int i = list_seq_find(config->output_configs, output_name_cmp, "*"); | ||
171 | if (i >= 0) { | ||
172 | oc = config->output_configs->items[i]; | ||
173 | } else { | ||
174 | oc = NULL; | ||
175 | } | ||
176 | } | ||
177 | |||
178 | int output_i; | 214 | int output_i; |
179 | for (output_i = 0; output_i < root_container.children->length; ++output_i) { | 215 | for (output_i = 0; output_i < root_container.children->length; ++output_i) { |
180 | if (root_container.children->items[output_i] == output) { | 216 | if (root_container.children->items[output_i] == output) { |