diff options
author | Simon Ser <contact@emersion.fr> | 2020-07-10 18:04:45 +0200 |
---|---|---|
committer | Brian Ashworth <bosrsf04@gmail.com> | 2020-07-10 18:18:27 -0400 |
commit | 5432f00adfdd8375fb422ad9033253d17f04efc7 (patch) | |
tree | 857b6fbff00a7dd11a1b96904acd81bd05ef0ee0 | |
parent | Reload command now matches i3's implementation (diff) | |
download | sway-5432f00adfdd8375fb422ad9033253d17f04efc7.tar.gz sway-5432f00adfdd8375fb422ad9033253d17f04efc7.tar.zst sway-5432f00adfdd8375fb422ad9033253d17f04efc7.zip |
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
-rw-r--r-- | include/sway/output.h | 4 | ||||
-rw-r--r-- | sway/config/output.c | 26 | ||||
-rw-r--r-- | sway/desktop/output.c | 8 | ||||
-rw-r--r-- | sway/input/cursor.c | 4 | ||||
-rw-r--r-- | sway/tree/output.c | 7 |
5 files changed, 23 insertions, 26 deletions
diff --git a/include/sway/output.h b/include/sway/output.h index cabb4b55..f27f6344 100644 --- a/include/sway/output.h +++ b/include/sway/output.h | |||
@@ -36,7 +36,7 @@ struct sway_output { | |||
36 | // last applied mode when the output is DPMS'ed | 36 | // last applied mode when the output is DPMS'ed |
37 | struct wlr_output_mode *current_mode; | 37 | struct wlr_output_mode *current_mode; |
38 | 38 | ||
39 | bool enabled, configured; | 39 | bool enabling, enabled; |
40 | list_t *workspaces; | 40 | list_t *workspaces; |
41 | 41 | ||
42 | struct sway_output_state current; | 42 | struct sway_output_state current; |
@@ -98,7 +98,7 @@ struct sway_output *all_output_by_name_or_id(const char *name_or_id); | |||
98 | 98 | ||
99 | void output_sort_workspaces(struct sway_output *output); | 99 | void output_sort_workspaces(struct sway_output *output); |
100 | 100 | ||
101 | void output_configure(struct sway_output *output); | 101 | void output_enable(struct sway_output *output); |
102 | 102 | ||
103 | void output_disable(struct sway_output *output); | 103 | void output_disable(struct sway_output *output); |
104 | 104 | ||
diff --git a/sway/config/output.c b/sway/config/output.c index 68aafbe1..b59cabd4 100644 --- a/sway/config/output.c +++ b/sway/config/output.c | |||
@@ -397,17 +397,8 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) { | |||
397 | 397 | ||
398 | struct wlr_output *wlr_output = output->wlr_output; | 398 | struct wlr_output *wlr_output = output->wlr_output; |
399 | 399 | ||
400 | bool was_enabled = output->enabled; | 400 | // Flag to prevent the output mode event handler from calling us |
401 | if (oc && !oc->enabled) { | 401 | output->enabling = (!oc || oc->enabled); |
402 | // Output is configured to be disabled | ||
403 | sway_log(SWAY_DEBUG, "Disabling output %s", oc->name); | ||
404 | if (output->enabled) { | ||
405 | output_disable(output); | ||
406 | wlr_output_layout_remove(root->output_layout, wlr_output); | ||
407 | } | ||
408 | } else { | ||
409 | output->enabled = true; | ||
410 | } | ||
411 | 402 | ||
412 | queue_output_config(oc, output); | 403 | queue_output_config(oc, output); |
413 | 404 | ||
@@ -421,11 +412,18 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) { | |||
421 | // Leave the output disabled for now and try again when the output gets | 412 | // Leave the output disabled for now and try again when the output gets |
422 | // the mode we asked for. | 413 | // the mode we asked for. |
423 | sway_log(SWAY_ERROR, "Failed to commit output %s", wlr_output->name); | 414 | sway_log(SWAY_ERROR, "Failed to commit output %s", wlr_output->name); |
424 | output->enabled = was_enabled; | 415 | output->enabling = false; |
425 | return false; | 416 | return false; |
426 | } | 417 | } |
427 | 418 | ||
419 | output->enabling = false; | ||
420 | |||
428 | if (oc && !oc->enabled) { | 421 | if (oc && !oc->enabled) { |
422 | sway_log(SWAY_DEBUG, "Disabling output %s", oc->name); | ||
423 | if (output->enabled) { | ||
424 | output_disable(output); | ||
425 | wlr_output_layout_remove(root->output_layout, wlr_output); | ||
426 | } | ||
429 | return true; | 427 | return true; |
430 | } | 428 | } |
431 | 429 | ||
@@ -468,8 +466,8 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) { | |||
468 | output->width = output_box->width; | 466 | output->width = output_box->width; |
469 | output->height = output_box->height; | 467 | output->height = output_box->height; |
470 | 468 | ||
471 | if (!output->configured) { | 469 | if (!output->enabled) { |
472 | output_configure(output); | 470 | output_enable(output); |
473 | } | 471 | } |
474 | 472 | ||
475 | if (oc && oc->max_render_time >= 0) { | 473 | if (oc && oc->max_render_time >= 0) { |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 4a51b5cc..5fdaba68 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -844,7 +844,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) { | |||
844 | 844 | ||
845 | static void handle_mode(struct wl_listener *listener, void *data) { | 845 | static void handle_mode(struct wl_listener *listener, void *data) { |
846 | struct sway_output *output = wl_container_of(listener, output, mode); | 846 | struct sway_output *output = wl_container_of(listener, output, mode); |
847 | if (!output->configured && !output->enabled) { | 847 | if (!output->enabled && !output->enabling) { |
848 | struct output_config *oc = find_output_config(output); | 848 | struct output_config *oc = find_output_config(output); |
849 | if (output->wlr_output->current_mode != NULL && | 849 | if (output->wlr_output->current_mode != NULL && |
850 | (!oc || oc->enabled)) { | 850 | (!oc || oc->enabled)) { |
@@ -857,7 +857,7 @@ static void handle_mode(struct wl_listener *listener, void *data) { | |||
857 | } | 857 | } |
858 | return; | 858 | return; |
859 | } | 859 | } |
860 | if (!output->enabled || !output->configured) { | 860 | if (!output->enabled) { |
861 | return; | 861 | return; |
862 | } | 862 | } |
863 | arrange_layers(output); | 863 | arrange_layers(output); |
@@ -869,7 +869,7 @@ static void handle_mode(struct wl_listener *listener, void *data) { | |||
869 | 869 | ||
870 | static void handle_transform(struct wl_listener *listener, void *data) { | 870 | static void handle_transform(struct wl_listener *listener, void *data) { |
871 | struct sway_output *output = wl_container_of(listener, output, transform); | 871 | struct sway_output *output = wl_container_of(listener, output, transform); |
872 | if (!output->enabled || !output->configured) { | 872 | if (!output->enabled) { |
873 | return; | 873 | return; |
874 | } | 874 | } |
875 | arrange_layers(output); | 875 | arrange_layers(output); |
@@ -886,7 +886,7 @@ static void update_textures(struct sway_container *con, void *data) { | |||
886 | 886 | ||
887 | static void handle_scale(struct wl_listener *listener, void *data) { | 887 | static void handle_scale(struct wl_listener *listener, void *data) { |
888 | struct sway_output *output = wl_container_of(listener, output, scale); | 888 | struct sway_output *output = wl_container_of(listener, output, scale); |
889 | if (!output->enabled || !output->configured) { | 889 | if (!output->enabled) { |
890 | return; | 890 | return; |
891 | } | 891 | } |
892 | arrange_layers(output); | 892 | arrange_layers(output); |
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index d10ba444..0d5b076b 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -99,8 +99,8 @@ struct sway_node *node_at_coords( | |||
99 | return NULL; | 99 | return NULL; |
100 | } | 100 | } |
101 | struct sway_output *output = wlr_output->data; | 101 | struct sway_output *output = wlr_output->data; |
102 | if (!output || !output->configured) { | 102 | if (!output || !output->enabled) { |
103 | // output is being destroyed or is being configured | 103 | // output is being destroyed or is being enabled |
104 | return NULL; | 104 | return NULL; |
105 | } | 105 | } |
106 | double ox = lx, oy = ly; | 106 | double ox = lx, oy = ly; |
diff --git a/sway/tree/output.c b/sway/tree/output.c index 9a10c6a8..ae3c3abf 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c | |||
@@ -110,12 +110,12 @@ struct sway_output *output_create(struct wlr_output *wlr_output) { | |||
110 | return output; | 110 | return output; |
111 | } | 111 | } |
112 | 112 | ||
113 | void output_configure(struct sway_output *output) { | 113 | void output_enable(struct sway_output *output) { |
114 | if (!sway_assert(!output->configured, "output is already configured")) { | 114 | if (!sway_assert(!output->enabled, "output is already enabled")) { |
115 | return; | 115 | return; |
116 | } | 116 | } |
117 | struct wlr_output *wlr_output = output->wlr_output; | 117 | struct wlr_output *wlr_output = output->wlr_output; |
118 | output->configured = true; | 118 | output->enabled = true; |
119 | list_add(root->outputs, output); | 119 | list_add(root->outputs, output); |
120 | 120 | ||
121 | restore_workspaces(output); | 121 | restore_workspaces(output); |
@@ -262,7 +262,6 @@ void output_disable(struct sway_output *output) { | |||
262 | list_del(root->outputs, index); | 262 | list_del(root->outputs, index); |
263 | 263 | ||
264 | output->enabled = false; | 264 | output->enabled = false; |
265 | output->configured = false; | ||
266 | output->current_mode = NULL; | 265 | output->current_mode = NULL; |
267 | 266 | ||
268 | arrange_root(); | 267 | arrange_root(); |