@@ -82,6 +82,30 @@ struct output_config *new_output_config(const char *name) {
82
82
return oc ;
83
83
}
84
84
85
+ static bool empty_output_config (struct output_config * oc ) {
86
+ return oc -> enabled == -1 &&
87
+ oc -> width == -1 &&
88
+ oc -> height == -1 &&
89
+ oc -> x == INT_MAX &&
90
+ oc -> y == INT_MAX &&
91
+ oc -> scale == -1 &&
92
+ oc -> scale_filter == SCALE_FILTER_DEFAULT &&
93
+ oc -> subpixel == WL_OUTPUT_SUBPIXEL_UNKNOWN &&
94
+ oc -> refresh_rate == -1 &&
95
+ oc -> custom_mode == -1 &&
96
+ oc -> drm_mode .type == (uint32_t )-1 &&
97
+ oc -> transform == -1 &&
98
+ oc -> max_render_time == -1 &&
99
+ oc -> adaptive_sync == -1 &&
100
+ oc -> render_bit_depth == RENDER_BIT_DEPTH_DEFAULT &&
101
+ oc -> set_color_transform == false &&
102
+ oc -> background == NULL &&
103
+ oc -> background_option == NULL &&
104
+ oc -> background_fallback == NULL &&
105
+ oc -> power == -1 &&
106
+ oc -> allow_tearing == -1 ;
107
+ }
108
+
85
109
// supersede_output_config clears all fields in dst that were set in src
86
110
static void supersede_output_config (struct output_config * dst , struct output_config * src ) {
87
111
if (src -> enabled != -1 ) {
@@ -232,57 +256,37 @@ static void merge_output_config(struct output_config *dst, struct output_config
232
256
}
233
257
234
258
void store_output_config (struct output_config * oc ) {
235
- bool merged = false;
236
259
bool wildcard = strcmp (oc -> name , "*" ) == 0 ;
237
- struct sway_output * output = wildcard ? NULL : all_output_by_name_or_id (oc -> name );
238
-
239
- char id [128 ];
240
- if (output ) {
241
- output_get_identifier (id , sizeof (id ), output );
242
- }
243
-
244
- for (int i = 0 ; i < config -> output_configs -> length ; i ++ ) {
245
- struct output_config * old = config -> output_configs -> items [i ];
246
-
247
- // If the old config matches the new config's name, regardless of
248
- // whether it was name or identifier, merge on top of the existing
249
- // config. If the new config is a wildcard, this also merges on top of
250
- // old wildcard configs.
251
- if (strcmp (old -> name , oc -> name ) == 0 ) {
252
- merge_output_config (old , oc );
253
- merged = true;
254
- continue ;
255
- }
256
-
257
- // If the new config is a wildcard config we supersede all non-wildcard
258
- // configs. Old wildcard configs have already been handled above.
259
- if (wildcard ) {
260
- supersede_output_config (old , oc );
261
- continue ;
262
- }
263
260
264
- // If the new config matches an output's name, and the old config
265
- // matches on that output's identifier, supersede it.
266
- if (output && strcmp (old -> name , id ) == 0 &&
267
- strcmp (oc -> name , output -> wlr_output -> name ) == 0 ) {
261
+ // Supersede any existing configurations that match by clearing settings
262
+ // that can no longer be reached anyway, which allows us to later garbage
263
+ // collect configurations that no longer have any value
264
+ struct output_config * old ;
265
+ for (int idx = 0 ; idx < config -> output_configs -> length ; idx ++ ) {
266
+ old = config -> output_configs -> items [idx ];
267
+ if (wildcard || strcmp (old -> name , oc -> name ) == 0 ) {
268
268
supersede_output_config (old , oc );
269
269
}
270
270
}
271
271
272
- sway_log (SWAY_DEBUG , "Config stored for output %s (enabled: %d) (%dx%d@%fHz "
273
- "position %d,%d scale %f subpixel %s transform %d) (bg %s %s) (power %d) "
274
- "(max render time: %d) (allow tearing: %d)" ,
275
- oc -> name , oc -> enabled , oc -> width , oc -> height , oc -> refresh_rate ,
276
- oc -> x , oc -> y , oc -> scale , sway_wl_output_subpixel_to_string (oc -> subpixel ),
277
- oc -> transform , oc -> background , oc -> background_option , oc -> power ,
278
- oc -> max_render_time , oc -> allow_tearing );
279
-
280
- // If the configuration was not merged into an existing configuration, add
281
- // it to the list. Otherwise we're done with it and can free it.
282
- if (!merged ) {
283
- list_add (config -> output_configs , oc );
284
- } else {
272
+ // As a very minor optimization, if the last config is for the same name,
273
+ // we can merge with that instead of adding a new config, reducing the
274
+ // number of configs when sequentially changing different settings
275
+ if (old != NULL && strcmp (old -> name , oc -> name ) == 0 ) {
276
+ merge_output_config (old , oc );
285
277
free_output_config (oc );
278
+ } else {
279
+ list_add (config -> output_configs , oc );
280
+ }
281
+
282
+ // Remove any configurations that have had all their settings removed
283
+ for (int idx = 0 ; idx < config -> output_configs -> length ; idx ++ ) {
284
+ old = config -> output_configs -> items [idx ];
285
+ if (empty_output_config (old )) {
286
+ list_del (config -> output_configs , idx );
287
+ free_output_config (old );
288
+ idx -- ;
289
+ }
286
290
}
287
291
}
288
292
@@ -588,14 +592,13 @@ static struct output_config *find_output_config_from_list(
588
592
char id [128 ];
589
593
output_get_identifier (id , sizeof (id ), sway_output );
590
594
591
- // We take a new config and merge on top, in order, the wildcard config,
592
- // output config by name, and output config by identifier to form the final
593
- // config. If there are multiple matches, they are merged in order.
594
- struct output_config * oc = NULL ;
595
- const char * names [] = {"*" , name , id , NULL };
596
- for (const char * * name = & names [0 ]; * name ; name ++ ) {
597
- for (size_t idx = 0 ; idx < configs_len ; idx ++ ) {
598
- oc = configs [idx ];
595
+ // To create the output config for this output, we merge all configurations
596
+ // that match the output in the order they were stored, such that later
597
+ // configurations override earlier ones
598
+ for (size_t idx = 0 ; idx < configs_len ; idx ++ ) {
599
+ struct output_config * oc = configs [idx ];
600
+ const char * names [] = {"*" , name , id , NULL };
601
+ for (const char * * name = & names [0 ]; * name ; name ++ ) {
599
602
if (strcmp (oc -> name , * name ) == 0 ) {
600
603
merge_output_config (result , oc );
601
604
}
0 commit comments