@@ -79,6 +79,71 @@ struct output_config *new_output_config(const char *name) {
79
79
return oc ;
80
80
}
81
81
82
+ // supersede_output_config clears all fields in dst that were set in src
83
+ static void supersede_output_config (struct output_config * dst , struct output_config * src ) {
84
+ if (src -> enabled != -1 ) {
85
+ dst -> enabled = -1 ;
86
+ }
87
+ if (src -> width != -1 ) {
88
+ dst -> width = -1 ;
89
+ }
90
+ if (src -> height != -1 ) {
91
+ dst -> height = -1 ;
92
+ }
93
+ if (src -> x != -1 ) {
94
+ dst -> x = -1 ;
95
+ }
96
+ if (src -> y != -1 ) {
97
+ dst -> y = -1 ;
98
+ }
99
+ if (src -> scale != -1 ) {
100
+ dst -> scale = -1 ;
101
+ }
102
+ if (src -> scale_filter != SCALE_FILTER_DEFAULT ) {
103
+ dst -> scale_filter = SCALE_FILTER_DEFAULT ;
104
+ }
105
+ if (src -> subpixel != WL_OUTPUT_SUBPIXEL_UNKNOWN ) {
106
+ dst -> subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN ;
107
+ }
108
+ if (src -> refresh_rate != -1 ) {
109
+ dst -> refresh_rate = -1 ;
110
+ }
111
+ if (src -> custom_mode != -1 ) {
112
+ dst -> custom_mode = -1 ;
113
+ }
114
+ if (src -> drm_mode .type != (uint32_t ) -1 ) {
115
+ dst -> drm_mode .type = -1 ;
116
+ }
117
+ if (src -> transform != -1 ) {
118
+ dst -> transform = -1 ;
119
+ }
120
+ if (src -> max_render_time != -1 ) {
121
+ dst -> max_render_time = -1 ;
122
+ }
123
+ if (src -> adaptive_sync != -1 ) {
124
+ dst -> adaptive_sync = -1 ;
125
+ }
126
+ if (src -> render_bit_depth != RENDER_BIT_DEPTH_DEFAULT ) {
127
+ dst -> render_bit_depth = RENDER_BIT_DEPTH_DEFAULT ;
128
+ }
129
+ if (src -> background ) {
130
+ free (dst -> background );
131
+ dst -> background = NULL ;
132
+ }
133
+ if (src -> background_option ) {
134
+ free (dst -> background_option );
135
+ dst -> background_option = NULL ;
136
+ }
137
+ if (src -> background_fallback ) {
138
+ free (dst -> background_fallback );
139
+ dst -> background_fallback = NULL ;
140
+ }
141
+ if (src -> power != -1 ) {
142
+ dst -> power = -1 ;
143
+ }
144
+ }
145
+
146
+ // merge_output_config sets all fields in dst that were set in src
82
147
static void merge_output_config (struct output_config * dst , struct output_config * src ) {
83
148
if (src -> enabled != -1 ) {
84
149
dst -> enabled = src -> enabled ;
@@ -142,96 +207,46 @@ static void merge_output_config(struct output_config *dst, struct output_config
142
207
}
143
208
}
144
209
145
- static void merge_wildcard_on_all (struct output_config * wildcard ) {
146
- for (int i = 0 ; i < config -> output_configs -> length ; i ++ ) {
147
- struct output_config * oc = config -> output_configs -> items [i ];
148
- if (strcmp (wildcard -> name , oc -> name ) != 0 ) {
149
- sway_log (SWAY_DEBUG , "Merging output * config on %s" , oc -> name );
150
- merge_output_config (oc , wildcard );
151
- }
152
- }
153
- }
154
-
155
- static void merge_id_on_name (struct output_config * oc ) {
156
- struct sway_output * output = all_output_by_name_or_id (oc -> name );
157
- if (output == NULL ) {
158
- return ;
210
+ void store_output_config (struct output_config * oc ) {
211
+ bool merged = false;
212
+ bool wildcard = strcmp (oc -> name , "*" ) == 0 ;
213
+ struct sway_output * output = wildcard ? NULL : output_by_name_or_id (oc -> name );
214
+ if (!output && !wildcard ) {
215
+ // There is no config by this name, just add it in
216
+ goto done ;
159
217
}
160
218
161
- const char * name = output -> wlr_output -> name ;
162
219
char id [128 ];
163
220
output_get_identifier (id , sizeof (id ), output );
164
-
165
- char * id_on_name = format_str ("%s on %s" , id , name );
166
- if (!id_on_name ) {
167
- return ;
168
- }
169
-
170
- int i = list_seq_find (config -> output_configs , output_name_cmp , id_on_name );
171
- if (i >= 0 ) {
172
- sway_log (SWAY_DEBUG , "Merging on top of existing id on name config" );
173
- merge_output_config (config -> output_configs -> items [i ], oc );
174
- } else {
175
- // If both a name and identifier config, exist generate an id on name
176
- int ni = list_seq_find (config -> output_configs , output_name_cmp , name );
177
- int ii = list_seq_find (config -> output_configs , output_name_cmp , id );
178
- if ((ni >= 0 && ii >= 0 ) || (ni >= 0 && strcmp (oc -> name , id ) == 0 )
179
- || (ii >= 0 && strcmp (oc -> name , name ) == 0 )) {
180
- struct output_config * ion_oc = new_output_config (id_on_name );
181
- if (ni >= 0 ) {
182
- merge_output_config (ion_oc , config -> output_configs -> items [ni ]);
183
- }
184
- if (ii >= 0 ) {
185
- merge_output_config (ion_oc , config -> output_configs -> items [ii ]);
186
- }
187
- merge_output_config (ion_oc , oc );
188
- list_add (config -> output_configs , ion_oc );
189
- sway_log (SWAY_DEBUG , "Generated id on name output config \"%s\""
190
- " (enabled: %d) (%dx%d@%fHz position %d,%d scale %f "
191
- "transform %d) (bg %s %s) (power %d) (max render time: %d)" ,
192
- ion_oc -> name , ion_oc -> enabled , ion_oc -> width , ion_oc -> height ,
193
- ion_oc -> refresh_rate , ion_oc -> x , ion_oc -> y , ion_oc -> scale ,
194
- ion_oc -> transform , ion_oc -> background ,
195
- ion_oc -> background_option , ion_oc -> power ,
196
- ion_oc -> max_render_time );
221
+ for (int i = 0 ; i < config -> output_configs -> length ; i ++ ) {
222
+ struct output_config * old = config -> output_configs -> items [i ];
223
+
224
+ // If the old config matches the new config's name, regardless of
225
+ // whether it was name or identifier, merge on top of the existing
226
+ // config. If the new config is a wildcard, this also merges on top of
227
+ // old wildcard configs.
228
+ if (strcmp (old -> name , oc -> name ) == 0 ) {
229
+ merge_output_config (old , oc );
230
+ merged = true;
231
+ continue ;
197
232
}
198
- }
199
- free (id_on_name );
200
- }
201
233
202
- struct output_config * store_output_config (struct output_config * oc ) {
203
- bool wildcard = strcmp (oc -> name , "*" ) == 0 ;
204
- if (wildcard ) {
205
- merge_wildcard_on_all (oc );
206
- } else {
207
- merge_id_on_name (oc );
208
- }
234
+ // If the new config is a wildcard config we supersede all non-wildcard
235
+ // configs. Old wildcard configs have already been handled above.
236
+ if (wildcard ) {
237
+ supersede_output_config (old , oc );
238
+ continue ;
239
+ }
209
240
210
- int i = list_seq_find (config -> output_configs , output_name_cmp , oc -> name );
211
- if (i >= 0 ) {
212
- sway_log (SWAY_DEBUG , "Merging on top of existing output config" );
213
- struct output_config * current = config -> output_configs -> items [i ];
214
- merge_output_config (current , oc );
215
- free_output_config (oc );
216
- oc = current ;
217
- } else if (!wildcard ) {
218
- sway_log (SWAY_DEBUG , "Adding non-wildcard output config" );
219
- i = list_seq_find (config -> output_configs , output_name_cmp , "*" );
220
- if (i >= 0 ) {
221
- sway_log (SWAY_DEBUG , "Merging on top of output * config" );
222
- struct output_config * current = new_output_config (oc -> name );
223
- merge_output_config (current , config -> output_configs -> items [i ]);
224
- merge_output_config (current , oc );
225
- free_output_config (oc );
226
- oc = current ;
241
+ // If the new config matches an output's name, and the old config
242
+ // matches on that output's identifier, supersede it.
243
+ if (strcmp (old -> name , id ) == 0 &&
244
+ strcmp (oc -> name , output -> wlr_output -> name ) == 0 ) {
245
+ supersede_output_config (old , oc );
227
246
}
228
- list_add (config -> output_configs , oc );
229
- } else {
230
- // New wildcard config. Just add it
231
- sway_log (SWAY_DEBUG , "Adding output * config" );
232
- list_add (config -> output_configs , oc );
233
247
}
234
248
249
+ done :
235
250
sway_log (SWAY_DEBUG , "Config stored for output %s (enabled: %d) (%dx%d@%fHz "
236
251
"position %d,%d scale %f subpixel %s transform %d) (bg %s %s) (power %d) "
237
252
"(max render time: %d)" ,
@@ -240,7 +255,13 @@ struct output_config *store_output_config(struct output_config *oc) {
240
255
oc -> transform , oc -> background , oc -> background_option , oc -> power ,
241
256
oc -> max_render_time );
242
257
243
- return oc ;
258
+ // If the configuration was not merged into an existing configuration, add
259
+ // it to the list. Otherwise we're done with it and can free it.
260
+ if (!merged ) {
261
+ list_add (config -> output_configs , oc );
262
+ } else {
263
+ free_output_config (oc );
264
+ }
244
265
}
245
266
246
267
static void set_mode (struct wlr_output * output , struct wlr_output_state * pending ,
@@ -587,96 +608,49 @@ static void default_output_config(struct output_config *oc,
587
608
oc -> max_render_time = 0 ;
588
609
}
589
610
590
- static struct output_config * get_output_config (char * identifier ,
591
- struct sway_output * sway_output ) {
611
+ // find_output_config returns a merged output_config containing all stored
612
+ // configuration that applies to the specified output.
613
+ struct output_config * find_output_config (struct sway_output * sway_output ) {
592
614
const char * name = sway_output -> wlr_output -> name ;
615
+ struct output_config * oc = NULL ;
593
616
594
- struct output_config * oc_id_on_name = NULL ;
595
- struct output_config * oc_name = NULL ;
596
- struct output_config * oc_id = NULL ;
597
-
598
- char * id_on_name = format_str ("%s on %s" , identifier , name );
599
- int i = list_seq_find (config -> output_configs , output_name_cmp , id_on_name );
600
- if (i >= 0 ) {
601
- oc_id_on_name = config -> output_configs -> items [i ];
602
- } else {
603
- i = list_seq_find (config -> output_configs , output_name_cmp , name );
604
- if (i >= 0 ) {
605
- oc_name = config -> output_configs -> items [i ];
606
- }
607
-
608
- i = list_seq_find (config -> output_configs , output_name_cmp , identifier );
609
- if (i >= 0 ) {
610
- oc_id = config -> output_configs -> items [i ];
611
- }
612
- }
613
-
614
- struct output_config * result = new_output_config ("temp" );
617
+ struct output_config * result = new_output_config (name );
615
618
if (config -> reloading ) {
616
619
default_output_config (result , sway_output -> wlr_output );
617
620
}
618
- if (oc_id_on_name ) {
619
- // Already have an identifier on name config, use that
620
- free (result -> name );
621
- result -> name = strdup (id_on_name );
622
- merge_output_config (result , oc_id_on_name );
623
- } else if (oc_name && oc_id ) {
624
- // Generate a config named `<identifier> on <name>` which contains a
625
- // merged copy of the identifier on name. This will make sure that both
626
- // identifier and name configs are respected, with identifier getting
627
- // priority
628
- struct output_config * temp = new_output_config (id_on_name );
629
- merge_output_config (temp , oc_name );
630
- merge_output_config (temp , oc_id );
631
- list_add (config -> output_configs , temp );
632
-
633
- free (result -> name );
634
- result -> name = strdup (id_on_name );
635
- merge_output_config (result , temp );
636
-
637
- sway_log (SWAY_DEBUG , "Generated output config \"%s\" (enabled: %d)"
638
- " (%dx%d@%fHz position %d,%d scale %f transform %d) (bg %s %s)"
639
- " (power %d) (max render time: %d)" , result -> name , result -> enabled ,
640
- result -> width , result -> height , result -> refresh_rate ,
641
- result -> x , result -> y , result -> scale , result -> transform ,
642
- result -> background , result -> background_option , result -> power ,
643
- result -> max_render_time );
644
- } else if (oc_name ) {
645
- // No identifier config, just return a copy of the name config
646
- free (result -> name );
647
- result -> name = strdup (name );
648
- merge_output_config (result , oc_name );
649
- } else if (oc_id ) {
650
- // No name config, just return a copy of the identifier config
651
- free (result -> name );
652
- result -> name = strdup (identifier );
653
- merge_output_config (result , oc_id );
654
- } else {
655
- i = list_seq_find (config -> output_configs , output_name_cmp , "*" );
656
- if (i >= 0 ) {
657
- // No name or identifier config, but there is a wildcard config
658
- free (result -> name );
659
- result -> name = strdup ("*" );
660
- merge_output_config (result , config -> output_configs -> items [i ]);
661
- } else if (!config -> reloading ) {
662
- // No name, identifier, or wildcard config. Since we are not
663
- // reloading with defaults, the output config will be empty, so
664
- // just return NULL
665
- free_output_config (result );
666
- result = NULL ;
667
- }
621
+
622
+ char id [128 ];
623
+ output_get_identifier (id , sizeof (id ), sway_output );
624
+
625
+ int i ;
626
+ bool match = false;
627
+ if ((i = list_seq_find (config -> output_configs , output_name_cmp , "*" )) >= 0 ) {
628
+ match = true;
629
+ oc = config -> output_configs -> items [i ];
630
+ merge_output_config (result , oc );
631
+ }
632
+ if ((i = list_seq_find (config -> output_configs , output_name_cmp , name )) >= 0 ) {
633
+ match = true;
634
+ oc = config -> output_configs -> items [i ];
635
+ merge_output_config (result , oc );
636
+ }
637
+ if ((i = list_seq_find (config -> output_configs , output_name_cmp , id )) >= 0 ) {
638
+ match = true;
639
+ oc = config -> output_configs -> items [i ];
640
+ merge_output_config (result , oc );
641
+ }
642
+
643
+ if (!match && !config -> reloading ) {
644
+ // No name, identifier, or wildcard config. Since we are not
645
+ // reloading with defaults, the output config will be empty, so
646
+ // just return NULL
647
+ free_output_config (result );
648
+ return NULL ;
668
649
}
669
650
670
- free (id_on_name );
671
651
return result ;
672
652
}
673
653
674
- struct output_config * find_output_config (struct sway_output * output ) {
675
- char id [128 ];
676
- output_get_identifier (id , sizeof (id ), output );
677
- return get_output_config (id , output );
678
- }
679
-
680
654
bool apply_output_configs (struct matched_output_config * configs ,
681
655
size_t configs_len , bool test_only ) {
682
656
struct wlr_backend_output_state * states = calloc (configs_len , sizeof (* states ));
0 commit comments