config/output: don't change output state before commit
Previously, we called output_disable prior to wlr_output_commit. This mutates Sway's output state before the output commit actually succeeds. This results in Sway's state getting out-of-sync with wlroots'. An alternative fix [1] was to revert the changes made by output_disable in case of failure. This is a little complicated. Instead, this patch makes it so Sway's internal state is never changed before a successful wlr_output commit. We had two output flags: enabled and configured. However enabled was set prior to the output becoming enabled, and was used to prevent the output event handlers (specifically, the mode handler) from calling apply_output_config again (infinite loop). Rename enabled to enabling and use it exclusively for this purpose. Rename configure to enabled, because that's what it really means. [1]: https://github.com/swaywm/sway/pull/5521 Closes: https://github.com/swaywm/sway/issues/5483
This commit is contained in:
parent
ea3ba203cc
commit
5432f00adf
|
@ -36,7 +36,7 @@ struct sway_output {
|
||||||
// last applied mode when the output is DPMS'ed
|
// last applied mode when the output is DPMS'ed
|
||||||
struct wlr_output_mode *current_mode;
|
struct wlr_output_mode *current_mode;
|
||||||
|
|
||||||
bool enabled, configured;
|
bool enabling, enabled;
|
||||||
list_t *workspaces;
|
list_t *workspaces;
|
||||||
|
|
||||||
struct sway_output_state current;
|
struct sway_output_state current;
|
||||||
|
@ -98,7 +98,7 @@ struct sway_output *all_output_by_name_or_id(const char *name_or_id);
|
||||||
|
|
||||||
void output_sort_workspaces(struct sway_output *output);
|
void output_sort_workspaces(struct sway_output *output);
|
||||||
|
|
||||||
void output_configure(struct sway_output *output);
|
void output_enable(struct sway_output *output);
|
||||||
|
|
||||||
void output_disable(struct sway_output *output);
|
void output_disable(struct sway_output *output);
|
||||||
|
|
||||||
|
|
|
@ -397,17 +397,8 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
|
||||||
|
|
||||||
struct wlr_output *wlr_output = output->wlr_output;
|
struct wlr_output *wlr_output = output->wlr_output;
|
||||||
|
|
||||||
bool was_enabled = output->enabled;
|
// Flag to prevent the output mode event handler from calling us
|
||||||
if (oc && !oc->enabled) {
|
output->enabling = (!oc || oc->enabled);
|
||||||
// Output is configured to be disabled
|
|
||||||
sway_log(SWAY_DEBUG, "Disabling output %s", oc->name);
|
|
||||||
if (output->enabled) {
|
|
||||||
output_disable(output);
|
|
||||||
wlr_output_layout_remove(root->output_layout, wlr_output);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
output->enabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
queue_output_config(oc, output);
|
queue_output_config(oc, output);
|
||||||
|
|
||||||
|
@ -421,11 +412,18 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
|
||||||
// Leave the output disabled for now and try again when the output gets
|
// Leave the output disabled for now and try again when the output gets
|
||||||
// the mode we asked for.
|
// the mode we asked for.
|
||||||
sway_log(SWAY_ERROR, "Failed to commit output %s", wlr_output->name);
|
sway_log(SWAY_ERROR, "Failed to commit output %s", wlr_output->name);
|
||||||
output->enabled = was_enabled;
|
output->enabling = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
output->enabling = false;
|
||||||
|
|
||||||
if (oc && !oc->enabled) {
|
if (oc && !oc->enabled) {
|
||||||
|
sway_log(SWAY_DEBUG, "Disabling output %s", oc->name);
|
||||||
|
if (output->enabled) {
|
||||||
|
output_disable(output);
|
||||||
|
wlr_output_layout_remove(root->output_layout, wlr_output);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,8 +466,8 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
|
||||||
output->width = output_box->width;
|
output->width = output_box->width;
|
||||||
output->height = output_box->height;
|
output->height = output_box->height;
|
||||||
|
|
||||||
if (!output->configured) {
|
if (!output->enabled) {
|
||||||
output_configure(output);
|
output_enable(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oc && oc->max_render_time >= 0) {
|
if (oc && oc->max_render_time >= 0) {
|
||||||
|
|
|
@ -844,7 +844,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
static void handle_mode(struct wl_listener *listener, void *data) {
|
static void handle_mode(struct wl_listener *listener, void *data) {
|
||||||
struct sway_output *output = wl_container_of(listener, output, mode);
|
struct sway_output *output = wl_container_of(listener, output, mode);
|
||||||
if (!output->configured && !output->enabled) {
|
if (!output->enabled && !output->enabling) {
|
||||||
struct output_config *oc = find_output_config(output);
|
struct output_config *oc = find_output_config(output);
|
||||||
if (output->wlr_output->current_mode != NULL &&
|
if (output->wlr_output->current_mode != NULL &&
|
||||||
(!oc || oc->enabled)) {
|
(!oc || oc->enabled)) {
|
||||||
|
@ -857,7 +857,7 @@ static void handle_mode(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!output->enabled || !output->configured) {
|
if (!output->enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
arrange_layers(output);
|
arrange_layers(output);
|
||||||
|
@ -869,7 +869,7 @@ static void handle_mode(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
static void handle_transform(struct wl_listener *listener, void *data) {
|
static void handle_transform(struct wl_listener *listener, void *data) {
|
||||||
struct sway_output *output = wl_container_of(listener, output, transform);
|
struct sway_output *output = wl_container_of(listener, output, transform);
|
||||||
if (!output->enabled || !output->configured) {
|
if (!output->enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
arrange_layers(output);
|
arrange_layers(output);
|
||||||
|
@ -886,7 +886,7 @@ static void update_textures(struct sway_container *con, void *data) {
|
||||||
|
|
||||||
static void handle_scale(struct wl_listener *listener, void *data) {
|
static void handle_scale(struct wl_listener *listener, void *data) {
|
||||||
struct sway_output *output = wl_container_of(listener, output, scale);
|
struct sway_output *output = wl_container_of(listener, output, scale);
|
||||||
if (!output->enabled || !output->configured) {
|
if (!output->enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
arrange_layers(output);
|
arrange_layers(output);
|
||||||
|
|
|
@ -99,8 +99,8 @@ struct sway_node *node_at_coords(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
struct sway_output *output = wlr_output->data;
|
struct sway_output *output = wlr_output->data;
|
||||||
if (!output || !output->configured) {
|
if (!output || !output->enabled) {
|
||||||
// output is being destroyed or is being configured
|
// output is being destroyed or is being enabled
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
double ox = lx, oy = ly;
|
double ox = lx, oy = ly;
|
||||||
|
|
|
@ -110,12 +110,12 @@ struct sway_output *output_create(struct wlr_output *wlr_output) {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
void output_configure(struct sway_output *output) {
|
void output_enable(struct sway_output *output) {
|
||||||
if (!sway_assert(!output->configured, "output is already configured")) {
|
if (!sway_assert(!output->enabled, "output is already enabled")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct wlr_output *wlr_output = output->wlr_output;
|
struct wlr_output *wlr_output = output->wlr_output;
|
||||||
output->configured = true;
|
output->enabled = true;
|
||||||
list_add(root->outputs, output);
|
list_add(root->outputs, output);
|
||||||
|
|
||||||
restore_workspaces(output);
|
restore_workspaces(output);
|
||||||
|
@ -262,7 +262,6 @@ void output_disable(struct sway_output *output) {
|
||||||
list_del(root->outputs, index);
|
list_del(root->outputs, index);
|
||||||
|
|
||||||
output->enabled = false;
|
output->enabled = false;
|
||||||
output->configured = false;
|
|
||||||
output->current_mode = NULL;
|
output->current_mode = NULL;
|
||||||
|
|
||||||
arrange_root();
|
arrange_root();
|
||||||
|
|
Loading…
Reference in a new issue