Skip to content

Commit 5668f8f

Browse files
committed
config/output: Store output configs sequentially
The current output configuration system merges configurations such that only one configuration per match is stored. This is a simplification of a previous design and has the benefit that a minimal number of output configurations are retained, but to correctly merge and supersede configurations it is required that an identifier can be resolved from a connector, which leads to differences in how output configurations are interpreted based on whether a display is currently connected or not. Instead, append all new output configurations to the list. To mitigate unbounded growth, supersede old configurations that are an exact match by clearing the fiels that can no longer take effect. Once a particular output configuration no longer contains any set fields, remove it from the list. Based on work by Pedro Côrte-Real <pedro@pedrocr.net> in #5629 which targeted an older iteration of the output configuration system.
1 parent ff6dc85 commit 5668f8f

File tree

1 file changed

+35
-34
lines changed

1 file changed

+35
-34
lines changed

sway/config/output.c

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,30 @@ struct output_config *new_output_config(const char *name) {
8282
return oc;
8383
}
8484

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 == -1 &&
90+
oc->y == -1 &&
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+
85109
// supersede_output_config clears all fields in dst that were set in src
86110
static void supersede_output_config(struct output_config *dst, struct output_config *src) {
87111
if (src->enabled != -1) {
@@ -232,40 +256,23 @@ static void merge_output_config(struct output_config *dst, struct output_config
232256
}
233257

234258
void store_output_config(struct output_config *oc) {
235-
bool merged = false;
236259
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-
}
243260

261+
// Supersede any existing configurations that match
244262
for (int i = 0; i < config->output_configs->length; i++) {
245263
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) {
264+
if (wildcard || strcmp(old->name, oc->name) == 0) {
260265
supersede_output_config(old, oc);
261-
continue;
262266
}
267+
}
263268

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) {
268-
supersede_output_config(old, oc);
269+
// Remove any fully superseded configurations
270+
for (int i = 0; i < config->output_configs->length; i++) {
271+
struct output_config *old = config->output_configs->items[i];
272+
if (empty_output_config(old)) {
273+
list_del(config->output_configs, i);
274+
free_output_config(old);
275+
i--;
269276
}
270277
}
271278

@@ -277,13 +284,7 @@ void store_output_config(struct output_config *oc) {
277284
oc->transform, oc->background, oc->background_option, oc->power,
278285
oc->max_render_time, oc->allow_tearing);
279286

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 {
285-
free_output_config(oc);
286-
}
287+
list_add(config->output_configs, oc);
287288
}
288289

289290
static void set_mode(struct wlr_output *output, struct wlr_output_state *pending,

0 commit comments

Comments
 (0)