Skip to content

Commit

Permalink
config/output: don't change output state before commit
Browse files Browse the repository at this point in the history
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]: swaywm#5521

Closes: swaywm#5483
  • Loading branch information
emersion committed Jul 10, 2020
1 parent ea3ba20 commit d852de3
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 26 deletions.
4 changes: 2 additions & 2 deletions include/sway/output.h
Expand Up @@ -36,7 +36,7 @@ struct sway_output {
// last applied mode when the output is DPMS'ed
struct wlr_output_mode *current_mode;

bool enabled, configured;
bool enabling, enabled;
list_t *workspaces;

struct sway_output_state current;
Expand Down Expand Up @@ -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_configure(struct sway_output *output);
void output_enable(struct sway_output *output);

void output_disable(struct sway_output *output);

Expand Down
26 changes: 12 additions & 14 deletions sway/config/output.c
Expand Up @@ -397,17 +397,8 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {

struct wlr_output *wlr_output = output->wlr_output;

bool was_enabled = output->enabled;
if (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;
}
// Flag to prevent the output mode event handler from calling us
output->enabling = (!oc || oc->enabled);

queue_output_config(oc, output);

Expand All @@ -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
// the mode we asked for.
sway_log(SWAY_ERROR, "Failed to commit output %s", wlr_output->name);
output->enabled = was_enabled;
output->enabling = false;
return false;
}

output->enabling = false;

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;
}

Expand Down Expand Up @@ -468,8 +466,8 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
output->width = output_box->width;
output->height = output_box->height;

if (!output->configured) {
output_configure(output);
if (!output->enabled) {
output_enable(output);
}

if (oc && oc->max_render_time >= 0) {
Expand Down
8 changes: 4 additions & 4 deletions sway/desktop/output.c
Expand Up @@ -844,7 +844,7 @@ static void handle_destroy(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);
if (!output->configured && !output->enabled) {
if (!output->enabled && !output->enabling) {
struct output_config *oc = find_output_config(output);
if (output->wlr_output->current_mode != NULL &&
(!oc || oc->enabled)) {
Expand All @@ -857,7 +857,7 @@ static void handle_mode(struct wl_listener *listener, void *data) {
}
return;
}
if (!output->enabled || !output->configured) {
if (!output->enabled) {
return;
}
arrange_layers(output);
Expand All @@ -869,7 +869,7 @@ static void handle_mode(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);
if (!output->enabled || !output->configured) {
if (!output->enabled) {
return;
}
arrange_layers(output);
Expand All @@ -886,7 +886,7 @@ static void update_textures(struct sway_container *con, void *data) {

static void handle_scale(struct wl_listener *listener, void *data) {
struct sway_output *output = wl_container_of(listener, output, scale);
if (!output->enabled || !output->configured) {
if (!output->enabled) {
return;
}
arrange_layers(output);
Expand Down
4 changes: 2 additions & 2 deletions sway/input/cursor.c
Expand Up @@ -99,8 +99,8 @@ struct sway_node *node_at_coords(
return NULL;
}
struct sway_output *output = wlr_output->data;
if (!output || !output->configured) {
// output is being destroyed or is being configured
if (!output || !output->enabled) {
// output is being destroyed or is being enabled
return NULL;
}
double ox = lx, oy = ly;
Expand Down
7 changes: 3 additions & 4 deletions sway/tree/output.c
Expand Up @@ -110,12 +110,12 @@ struct sway_output *output_create(struct wlr_output *wlr_output) {
return output;
}

void output_configure(struct sway_output *output) {
if (!sway_assert(!output->configured, "output is already configured")) {
void output_enable(struct sway_output *output) {
if (!sway_assert(!output->enabled, "output is already enabled")) {
return;
}
struct wlr_output *wlr_output = output->wlr_output;
output->configured = true;
output->enabled = true;
list_add(root->outputs, output);

restore_workspaces(output);
Expand Down Expand Up @@ -262,7 +262,6 @@ void output_disable(struct sway_output *output) {
list_del(root->outputs, index);

output->enabled = false;
output->configured = false;
output->current_mode = NULL;

arrange_root();
Expand Down

0 comments on commit d852de3

Please sign in to comment.