From 78fa4e985618209a289f892dc54d67c83494a9d2 Mon Sep 17 00:00:00 2001 From: Kenny Levinsen Date: Tue, 5 Nov 2024 15:31:13 +0100 Subject: [PATCH] config/output: Update output position in two passes The modeset logic iterates over all outputs at the end, sets their new position in the layout and takes a copy of its geometry that is later referenced by layout and scene management code. If one output is auto configured, then a later output that is manually configured can lead to the first output being moved without the stored geometry being updated. Split this into two passes: The first pass finalizes the output config and makes updates to the layout, while the second pass updates the copy of the geometry and arranges things as a result of it. --- sway/config/output.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/sway/config/output.c b/sway/config/output.c index 5fb282d4..f8922ea5 100644 --- a/sway/config/output.c +++ b/sway/config/output.c @@ -533,14 +533,6 @@ static bool finalize_output_config(struct output_config *oc, struct sway_output wlr_output_layout_add_auto(root->output_layout, wlr_output); } - // Update output->{lx, ly, width, height} - struct wlr_box output_box; - wlr_output_layout_get_box(root->output_layout, wlr_output, &output_box); - output->lx = output_box.x; - output->ly = output_box.y; - output->width = output_box.width; - output->height = output_box.height; - if (!output->enabled) { output_enable(output); } @@ -562,6 +554,15 @@ static bool finalize_output_config(struct output_config *oc, struct sway_output return true; } +static void output_update_position(struct sway_output *output) { + struct wlr_box output_box; + wlr_output_layout_get_box(root->output_layout, output->wlr_output, &output_box); + output->lx = output_box.x; + output->ly = output_box.y; + output->width = output_box.width; + output->height = output_box.height; +} + // find_output_config_from_list returns a merged output_config containing all // stored configuration that applies to the specified output. static struct output_config *find_output_config_from_list( @@ -933,6 +934,13 @@ static bool apply_resolved_output_configs(struct matched_output_config *configs, sway_log(SWAY_DEBUG, "Finalizing config for %s", cfg->output->wlr_output->name); finalize_output_config(cfg->config, cfg->output); + } + + // Output layout being applied in finalize_output_config can shift outputs + // around, so we do a second pass to update positions and arrange. + for (size_t idx = 0; idx < configs_len; idx++) { + struct matched_output_config *cfg = &configs[idx]; + output_update_position(cfg->output); arrange_layers(cfg->output); }