diff options
Diffstat (limited to 'sway')
-rw-r--r-- | sway/config/output.c | 38 | ||||
-rw-r--r-- | sway/desktop/output.c | 12 | ||||
-rw-r--r-- | sway/tree/output.c | 8 |
3 files changed, 45 insertions, 13 deletions
diff --git a/sway/config/output.c b/sway/config/output.c index f23d316d..6e504751 100644 --- a/sway/config/output.c +++ b/sway/config/output.c | |||
@@ -137,13 +137,12 @@ struct output_config *store_output_config(struct output_config *oc) { | |||
137 | return oc; | 137 | return oc; |
138 | } | 138 | } |
139 | 139 | ||
140 | static void set_mode(struct wlr_output *output, int width, int height, | 140 | static bool set_mode(struct wlr_output *output, int width, int height, |
141 | float refresh_rate) { | 141 | float refresh_rate) { |
142 | int mhz = (int)(refresh_rate * 1000); | 142 | int mhz = (int)(refresh_rate * 1000); |
143 | if (wl_list_empty(&output->modes)) { | 143 | if (wl_list_empty(&output->modes)) { |
144 | wlr_log(WLR_DEBUG, "Assigning custom mode to %s", output->name); | 144 | wlr_log(WLR_DEBUG, "Assigning custom mode to %s", output->name); |
145 | wlr_output_set_custom_mode(output, width, height, mhz); | 145 | return wlr_output_set_custom_mode(output, width, height, mhz); |
146 | return; | ||
147 | } | 146 | } |
148 | 147 | ||
149 | struct wlr_output_mode *mode, *best = NULL; | 148 | struct wlr_output_mode *mode, *best = NULL; |
@@ -158,10 +157,12 @@ static void set_mode(struct wlr_output *output, int width, int height, | |||
158 | } | 157 | } |
159 | if (!best) { | 158 | if (!best) { |
160 | wlr_log(WLR_ERROR, "Configured mode for %s not available", output->name); | 159 | wlr_log(WLR_ERROR, "Configured mode for %s not available", output->name); |
160 | wlr_log(WLR_INFO, "Picking default mode instead"); | ||
161 | best = wl_container_of(output->modes.prev, mode, link); | ||
161 | } else { | 162 | } else { |
162 | wlr_log(WLR_DEBUG, "Assigning configured mode to %s", output->name); | 163 | wlr_log(WLR_DEBUG, "Assigning configured mode to %s", output->name); |
163 | wlr_output_set_mode(output, best); | ||
164 | } | 164 | } |
165 | return wlr_output_set_mode(output, best); | ||
165 | } | 166 | } |
166 | 167 | ||
167 | void terminate_swaybg(pid_t pid) { | 168 | void terminate_swaybg(pid_t pid) { |
@@ -174,33 +175,48 @@ void terminate_swaybg(pid_t pid) { | |||
174 | } | 175 | } |
175 | } | 176 | } |
176 | 177 | ||
177 | void apply_output_config(struct output_config *oc, struct sway_output *output) { | 178 | bool apply_output_config(struct output_config *oc, struct sway_output *output) { |
178 | struct wlr_output *wlr_output = output->wlr_output; | 179 | struct wlr_output *wlr_output = output->wlr_output; |
179 | 180 | ||
180 | if (oc && oc->enabled == 0) { | 181 | if (oc && !oc->enabled) { |
182 | // Output is configured to be disabled | ||
181 | if (output->enabled) { | 183 | if (output->enabled) { |
182 | output_disable(output); | 184 | output_disable(output); |
183 | wlr_output_layout_remove(root->output_layout, wlr_output); | 185 | wlr_output_layout_remove(root->output_layout, wlr_output); |
184 | } | 186 | } |
185 | wlr_output_enable(wlr_output, false); | 187 | wlr_output_enable(wlr_output, false); |
186 | return; | 188 | return true; |
187 | } else if (!output->enabled) { | 189 | } else if (!output->enabled) { |
190 | // Output is not enabled. Enable it, output_enable will call us again. | ||
188 | if (!oc || oc->dpms_state != DPMS_OFF) { | 191 | if (!oc || oc->dpms_state != DPMS_OFF) { |
189 | wlr_output_enable(wlr_output, true); | 192 | wlr_output_enable(wlr_output, true); |
190 | } | 193 | } |
191 | output_enable(output, oc); | 194 | output_enable(output, oc); |
192 | return; | 195 | return true; |
193 | } | 196 | } |
194 | 197 | ||
198 | bool modeset_success; | ||
195 | if (oc && oc->width > 0 && oc->height > 0) { | 199 | if (oc && oc->width > 0 && oc->height > 0) { |
196 | wlr_log(WLR_DEBUG, "Set %s mode to %dx%d (%f GHz)", oc->name, oc->width, | 200 | wlr_log(WLR_DEBUG, "Set %s mode to %dx%d (%f GHz)", oc->name, oc->width, |
197 | oc->height, oc->refresh_rate); | 201 | oc->height, oc->refresh_rate); |
198 | set_mode(wlr_output, oc->width, oc->height, oc->refresh_rate); | 202 | modeset_success = |
203 | set_mode(wlr_output, oc->width, oc->height, oc->refresh_rate); | ||
199 | } else if (!wl_list_empty(&wlr_output->modes)) { | 204 | } else if (!wl_list_empty(&wlr_output->modes)) { |
200 | struct wlr_output_mode *mode = | 205 | struct wlr_output_mode *mode = |
201 | wl_container_of(wlr_output->modes.prev, mode, link); | 206 | wl_container_of(wlr_output->modes.prev, mode, link); |
202 | wlr_output_set_mode(wlr_output, mode); | 207 | modeset_success = wlr_output_set_mode(wlr_output, mode); |
208 | } else { | ||
209 | // Output doesn't support modes | ||
210 | modeset_success = true; | ||
203 | } | 211 | } |
212 | if (!modeset_success) { | ||
213 | // Failed to modeset, maybe the output is missing a CRTC. Leave the | ||
214 | // output disabled for now and try again when the output gets the mode | ||
215 | // we asked for. | ||
216 | wlr_log(WLR_ERROR, "Failed to modeset output %s", wlr_output->name); | ||
217 | return false; | ||
218 | } | ||
219 | |||
204 | if (oc && oc->scale > 0) { | 220 | if (oc && oc->scale > 0) { |
205 | wlr_log(WLR_DEBUG, "Set %s scale to %f", oc->name, oc->scale); | 221 | wlr_log(WLR_DEBUG, "Set %s scale to %f", oc->name, oc->scale); |
206 | wlr_output_set_scale(wlr_output, oc->scale); | 222 | wlr_output_set_scale(wlr_output, oc->scale); |
@@ -264,6 +280,8 @@ void apply_output_config(struct output_config *oc, struct sway_output *output) { | |||
264 | break; | 280 | break; |
265 | } | 281 | } |
266 | } | 282 | } |
283 | |||
284 | return true; | ||
267 | } | 285 | } |
268 | 286 | ||
269 | static void default_output_config(struct output_config *oc, | 287 | static void default_output_config(struct output_config *oc, |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 3f6c3d87..37651d66 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -503,7 +503,18 @@ static void handle_destroy(struct wl_listener *listener, void *data) { | |||
503 | 503 | ||
504 | static void handle_mode(struct wl_listener *listener, void *data) { | 504 | static void handle_mode(struct wl_listener *listener, void *data) { |
505 | struct sway_output *output = wl_container_of(listener, output, mode); | 505 | struct sway_output *output = wl_container_of(listener, output, mode); |
506 | if (!output->configured) { | ||
507 | return; | ||
508 | } | ||
506 | if (!output->enabled) { | 509 | if (!output->enabled) { |
510 | struct output_config *oc = output_find_config(output); | ||
511 | if (output->wlr_output->current_mode != NULL && | ||
512 | (!oc || oc->enabled)) { | ||
513 | // We want to enable this output, but it didn't work last time, | ||
514 | // possibly because we hadn't enough CRTCs. Try again now that the | ||
515 | // output has a mode. | ||
516 | output_enable(output, oc); | ||
517 | } | ||
507 | return; | 518 | return; |
508 | } | 519 | } |
509 | arrange_layers(output); | 520 | arrange_layers(output); |
@@ -592,7 +603,6 @@ void handle_new_output(struct wl_listener *listener, void *data) { | |||
592 | output->damage_destroy.notify = damage_handle_destroy; | 603 | output->damage_destroy.notify = damage_handle_destroy; |
593 | 604 | ||
594 | struct output_config *oc = output_find_config(output); | 605 | struct output_config *oc = output_find_config(output); |
595 | |||
596 | if (!oc || oc->enabled) { | 606 | if (!oc || oc->enabled) { |
597 | output_enable(output, oc); | 607 | output_enable(output, oc); |
598 | } else { | 608 | } else { |
diff --git a/sway/tree/output.c b/sway/tree/output.c index 3c376c6b..21beb504 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c | |||
@@ -78,6 +78,12 @@ void output_enable(struct sway_output *output, struct output_config *oc) { | |||
78 | } | 78 | } |
79 | 79 | ||
80 | output->enabled = true; | 80 | output->enabled = true; |
81 | if (!apply_output_config(oc, output)) { | ||
82 | output->enabled = false; | ||
83 | return; | ||
84 | } | ||
85 | |||
86 | output->configured = true; | ||
81 | list_add(root->outputs, output); | 87 | list_add(root->outputs, output); |
82 | 88 | ||
83 | output->lx = wlr_output->lx; | 89 | output->lx = wlr_output->lx; |
@@ -104,8 +110,6 @@ void output_enable(struct sway_output *output, struct output_config *oc) { | |||
104 | ipc_event_workspace(NULL, ws, "init"); | 110 | ipc_event_workspace(NULL, ws, "init"); |
105 | } | 111 | } |
106 | 112 | ||
107 | apply_output_config(oc, output); | ||
108 | |||
109 | if (ws && config->default_orientation == L_NONE) { | 113 | if (ws && config->default_orientation == L_NONE) { |
110 | // Since the output transformation and resolution could have changed | 114 | // Since the output transformation and resolution could have changed |
111 | // due to applying the output config, the previously set layout for the | 115 | // due to applying the output config, the previously set layout for the |