aboutsummaryrefslogtreecommitdiffstats
path: root/sway/config/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/config/output.c')
-rw-r--r--sway/config/output.c203
1 files changed, 148 insertions, 55 deletions
diff --git a/sway/config/output.c b/sway/config/output.c
index c9ec6745..b3e8371e 100644
--- a/sway/config/output.c
+++ b/sway/config/output.c
@@ -1,5 +1,6 @@
1#define _POSIX_C_SOURCE 200809L 1#define _POSIX_C_SOURCE 200809L
2#include <assert.h> 2#include <assert.h>
3#include <drm_fourcc.h>
3#include <stdbool.h> 4#include <stdbool.h>
4#include <string.h> 5#include <string.h>
5#include <sys/socket.h> 6#include <sys/socket.h>
@@ -8,6 +9,7 @@
8#include <wlr/types/wlr_cursor.h> 9#include <wlr/types/wlr_cursor.h>
9#include <wlr/types/wlr_output_layout.h> 10#include <wlr/types/wlr_output_layout.h>
10#include <wlr/types/wlr_output.h> 11#include <wlr/types/wlr_output.h>
12#include <wlr/backend/drm.h>
11#include "sway/config.h" 13#include "sway/config.h"
12#include "sway/input/cursor.h" 14#include "sway/input/cursor.h"
13#include "sway/output.h" 15#include "sway/output.h"
@@ -25,8 +27,10 @@ int output_name_cmp(const void *item, const void *data) {
25void output_get_identifier(char *identifier, size_t len, 27void output_get_identifier(char *identifier, size_t len,
26 struct sway_output *output) { 28 struct sway_output *output) {
27 struct wlr_output *wlr_output = output->wlr_output; 29 struct wlr_output *wlr_output = output->wlr_output;
28 snprintf(identifier, len, "%s %s %s", wlr_output->make, wlr_output->model, 30 snprintf(identifier, len, "%s %s %s",
29 wlr_output->serial); 31 wlr_output->make ? wlr_output->make : "Unknown",
32 wlr_output->model ? wlr_output->model : "Unknown",
33 wlr_output->serial ? wlr_output->serial : "Unknown");
30} 34}
31 35
32const char *sway_output_scale_filter_to_string(enum scale_filter_mode scale_filter) { 36const char *sway_output_scale_filter_to_string(enum scale_filter_mode scale_filter) {
@@ -58,6 +62,7 @@ struct output_config *new_output_config(const char *name) {
58 oc->width = oc->height = -1; 62 oc->width = oc->height = -1;
59 oc->refresh_rate = -1; 63 oc->refresh_rate = -1;
60 oc->custom_mode = -1; 64 oc->custom_mode = -1;
65 oc->drm_mode.type = -1;
61 oc->x = oc->y = -1; 66 oc->x = oc->y = -1;
62 oc->scale = -1; 67 oc->scale = -1;
63 oc->scale_filter = SCALE_FILTER_DEFAULT; 68 oc->scale_filter = SCALE_FILTER_DEFAULT;
@@ -65,6 +70,8 @@ struct output_config *new_output_config(const char *name) {
65 oc->subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN; 70 oc->subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN;
66 oc->max_render_time = -1; 71 oc->max_render_time = -1;
67 oc->adaptive_sync = -1; 72 oc->adaptive_sync = -1;
73 oc->render_bit_depth = RENDER_BIT_DEPTH_DEFAULT;
74 oc->power = -1;
68 return oc; 75 return oc;
69} 76}
70 77
@@ -99,6 +106,9 @@ void merge_output_config(struct output_config *dst, struct output_config *src) {
99 if (src->custom_mode != -1) { 106 if (src->custom_mode != -1) {
100 dst->custom_mode = src->custom_mode; 107 dst->custom_mode = src->custom_mode;
101 } 108 }
109 if (src->drm_mode.type != (uint32_t) -1) {
110 memcpy(&dst->drm_mode, &src->drm_mode, sizeof(src->drm_mode));
111 }
102 if (src->transform != -1) { 112 if (src->transform != -1) {
103 dst->transform = src->transform; 113 dst->transform = src->transform;
104 } 114 }
@@ -108,6 +118,9 @@ void merge_output_config(struct output_config *dst, struct output_config *src) {
108 if (src->adaptive_sync != -1) { 118 if (src->adaptive_sync != -1) {
109 dst->adaptive_sync = src->adaptive_sync; 119 dst->adaptive_sync = src->adaptive_sync;
110 } 120 }
121 if (src->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) {
122 dst->render_bit_depth = src->render_bit_depth;
123 }
111 if (src->background) { 124 if (src->background) {
112 free(dst->background); 125 free(dst->background);
113 dst->background = strdup(src->background); 126 dst->background = strdup(src->background);
@@ -120,8 +133,8 @@ void merge_output_config(struct output_config *dst, struct output_config *src) {
120 free(dst->background_fallback); 133 free(dst->background_fallback);
121 dst->background_fallback = strdup(src->background_fallback); 134 dst->background_fallback = strdup(src->background_fallback);
122 } 135 }
123 if (src->dpms_state != 0) { 136 if (src->power != -1) {
124 dst->dpms_state = src->dpms_state; 137 dst->power = src->power;
125 } 138 }
126} 139}
127 140
@@ -180,11 +193,11 @@ static void merge_id_on_name(struct output_config *oc) {
180 list_add(config->output_configs, ion_oc); 193 list_add(config->output_configs, ion_oc);
181 sway_log(SWAY_DEBUG, "Generated id on name output config \"%s\"" 194 sway_log(SWAY_DEBUG, "Generated id on name output config \"%s\""
182 " (enabled: %d) (%dx%d@%fHz position %d,%d scale %f " 195 " (enabled: %d) (%dx%d@%fHz position %d,%d scale %f "
183 "transform %d) (bg %s %s) (dpms %d) (max render time: %d)", 196 "transform %d) (bg %s %s) (power %d) (max render time: %d)",
184 ion_oc->name, ion_oc->enabled, ion_oc->width, ion_oc->height, 197 ion_oc->name, ion_oc->enabled, ion_oc->width, ion_oc->height,
185 ion_oc->refresh_rate, ion_oc->x, ion_oc->y, ion_oc->scale, 198 ion_oc->refresh_rate, ion_oc->x, ion_oc->y, ion_oc->scale,
186 ion_oc->transform, ion_oc->background, 199 ion_oc->transform, ion_oc->background,
187 ion_oc->background_option, ion_oc->dpms_state, 200 ion_oc->background_option, ion_oc->power,
188 ion_oc->max_render_time); 201 ion_oc->max_render_time);
189 } 202 }
190 } 203 }
@@ -225,18 +238,18 @@ struct output_config *store_output_config(struct output_config *oc) {
225 } 238 }
226 239
227 sway_log(SWAY_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz " 240 sway_log(SWAY_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz "
228 "position %d,%d scale %f subpixel %s transform %d) (bg %s %s) (dpms %d) " 241 "position %d,%d scale %f subpixel %s transform %d) (bg %s %s) (power %d) "
229 "(max render time: %d)", 242 "(max render time: %d)",
230 oc->name, oc->enabled, oc->width, oc->height, oc->refresh_rate, 243 oc->name, oc->enabled, oc->width, oc->height, oc->refresh_rate,
231 oc->x, oc->y, oc->scale, sway_wl_output_subpixel_to_string(oc->subpixel), 244 oc->x, oc->y, oc->scale, sway_wl_output_subpixel_to_string(oc->subpixel),
232 oc->transform, oc->background, oc->background_option, oc->dpms_state, 245 oc->transform, oc->background, oc->background_option, oc->power,
233 oc->max_render_time); 246 oc->max_render_time);
234 247
235 return oc; 248 return oc;
236} 249}
237 250
238static void set_mode(struct wlr_output *output, int width, int height, 251static void set_mode(struct wlr_output *output, struct wlr_output_state *pending,
239 float refresh_rate, bool custom) { 252 int width, int height, float refresh_rate, bool custom) {
240 // Not all floating point integers can be represented exactly 253 // Not all floating point integers can be represented exactly
241 // as (int)(1000 * mHz / 1000.f) 254 // as (int)(1000 * mHz / 1000.f)
242 // round() the result to avoid any error 255 // round() the result to avoid any error
@@ -244,7 +257,7 @@ static void set_mode(struct wlr_output *output, int width, int height,
244 257
245 if (wl_list_empty(&output->modes) || custom) { 258 if (wl_list_empty(&output->modes) || custom) {
246 sway_log(SWAY_DEBUG, "Assigning custom mode to %s", output->name); 259 sway_log(SWAY_DEBUG, "Assigning custom mode to %s", output->name);
247 wlr_output_set_custom_mode(output, width, height, 260 wlr_output_state_set_custom_mode(pending, width, height,
248 refresh_rate > 0 ? mhz : 0); 261 refresh_rate > 0 ? mhz : 0);
249 return; 262 return;
250 } 263 }
@@ -268,7 +281,20 @@ static void set_mode(struct wlr_output *output, int width, int height,
268 } else { 281 } else {
269 sway_log(SWAY_DEBUG, "Assigning configured mode to %s", output->name); 282 sway_log(SWAY_DEBUG, "Assigning configured mode to %s", output->name);
270 } 283 }
271 wlr_output_set_mode(output, best); 284 wlr_output_state_set_mode(pending, best);
285}
286
287static void set_modeline(struct wlr_output *output,
288 struct wlr_output_state *pending, drmModeModeInfo *drm_mode) {
289 if (!wlr_output_is_drm(output)) {
290 sway_log(SWAY_ERROR, "Modeline can only be set to DRM output");
291 return;
292 }
293 sway_log(SWAY_DEBUG, "Assigning custom modeline to %s", output->name);
294 struct wlr_output_mode *mode = wlr_drm_connector_add_mode(output, drm_mode);
295 if (mode) {
296 wlr_output_state_set_mode(pending, mode);
297 }
272} 298}
273 299
274/* Some manufacturers hardcode the aspect-ratio of the output in the physical 300/* Some manufacturers hardcode the aspect-ratio of the output in the physical
@@ -289,23 +315,24 @@ static bool phys_size_is_aspect_ratio(struct wlr_output *output) {
289// 1 inch = 25.4 mm 315// 1 inch = 25.4 mm
290#define MM_PER_INCH 25.4 316#define MM_PER_INCH 25.4
291 317
292static int compute_default_scale(struct wlr_output *output) { 318static int compute_default_scale(struct wlr_output *output,
319 struct wlr_output_state *pending) {
293 struct wlr_box box = { .width = output->width, .height = output->height }; 320 struct wlr_box box = { .width = output->width, .height = output->height };
294 if (output->pending.committed & WLR_OUTPUT_STATE_MODE) { 321 if (pending->committed & WLR_OUTPUT_STATE_MODE) {
295 switch (output->pending.mode_type) { 322 switch (pending->mode_type) {
296 case WLR_OUTPUT_STATE_MODE_FIXED: 323 case WLR_OUTPUT_STATE_MODE_FIXED:
297 box.width = output->pending.mode->width; 324 box.width = pending->mode->width;
298 box.height = output->pending.mode->height; 325 box.height = pending->mode->height;
299 break; 326 break;
300 case WLR_OUTPUT_STATE_MODE_CUSTOM: 327 case WLR_OUTPUT_STATE_MODE_CUSTOM:
301 box.width = output->pending.custom_mode.width; 328 box.width = pending->custom_mode.width;
302 box.height = output->pending.custom_mode.height; 329 box.height = pending->custom_mode.height;
303 break; 330 break;
304 } 331 }
305 } 332 }
306 enum wl_output_transform transform = output->transform; 333 enum wl_output_transform transform = output->transform;
307 if (output->pending.committed & WLR_OUTPUT_STATE_TRANSFORM) { 334 if (pending->committed & WLR_OUTPUT_STATE_TRANSFORM) {
308 transform = output->pending.transform; 335 transform = pending->transform;
309 } 336 }
310 wlr_box_transform(&box, &box, transform, box.width, box.height); 337 wlr_box_transform(&box, &box, transform, box.width, box.height);
311 338
@@ -334,42 +361,88 @@ static int compute_default_scale(struct wlr_output *output) {
334 return 2; 361 return 2;
335} 362}
336 363
364/* Lists of formats to try, in order, when a specific render bit depth has
365 * been asked for. The second to last format in each list should always
366 * be XRGB8888, as a reliable backup in case the others are not available;
367 * the last should be DRM_FORMAT_INVALID, to indicate the end of the list. */
368static const uint32_t *bit_depth_preferences[] = {
369 [RENDER_BIT_DEPTH_8] = (const uint32_t []){
370 DRM_FORMAT_XRGB8888,
371 DRM_FORMAT_INVALID,
372 },
373 [RENDER_BIT_DEPTH_10] = (const uint32_t []){
374 DRM_FORMAT_XRGB2101010,
375 DRM_FORMAT_XBGR2101010,
376 DRM_FORMAT_XRGB8888,
377 DRM_FORMAT_INVALID,
378 },
379};
380
337static void queue_output_config(struct output_config *oc, 381static void queue_output_config(struct output_config *oc,
338 struct sway_output *output) { 382 struct sway_output *output, struct wlr_output_state *pending) {
339 if (output == root->noop_output) { 383 if (output == root->fallback_output) {
340 return; 384 return;
341 } 385 }
342 386
343 struct wlr_output *wlr_output = output->wlr_output; 387 struct wlr_output *wlr_output = output->wlr_output;
344 388
345 if (oc && (!oc->enabled || oc->dpms_state == DPMS_OFF)) { 389 if (oc && (!oc->enabled || oc->power == 0)) {
346 sway_log(SWAY_DEBUG, "Turning off output %s", wlr_output->name); 390 sway_log(SWAY_DEBUG, "Turning off output %s", wlr_output->name);
347 wlr_output_enable(wlr_output, false); 391 wlr_output_state_set_enabled(pending, false);
348 return; 392 return;
349 } 393 }
350 394
351 sway_log(SWAY_DEBUG, "Turning on output %s", wlr_output->name); 395 sway_log(SWAY_DEBUG, "Turning on output %s", wlr_output->name);
352 wlr_output_enable(wlr_output, true); 396 wlr_output_state_set_enabled(pending, true);
353 397
354 if (oc && oc->width > 0 && oc->height > 0) { 398 if (oc && oc->drm_mode.type != 0 && oc->drm_mode.type != (uint32_t) -1) {
399 sway_log(SWAY_DEBUG, "Set %s modeline",
400 wlr_output->name);
401 set_modeline(wlr_output, pending, &oc->drm_mode);
402 } else if (oc && oc->width > 0 && oc->height > 0) {
355 sway_log(SWAY_DEBUG, "Set %s mode to %dx%d (%f Hz)", 403 sway_log(SWAY_DEBUG, "Set %s mode to %dx%d (%f Hz)",
356 wlr_output->name, oc->width, oc->height, oc->refresh_rate); 404 wlr_output->name, oc->width, oc->height, oc->refresh_rate);
357 set_mode(wlr_output, oc->width, oc->height, 405 set_mode(wlr_output, pending, oc->width, oc->height,
358 oc->refresh_rate, oc->custom_mode == 1); 406 oc->refresh_rate, oc->custom_mode == 1);
359 } else if (!wl_list_empty(&wlr_output->modes)) { 407 } else if (!wl_list_empty(&wlr_output->modes)) {
360 struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output); 408 sway_log(SWAY_DEBUG, "Set preferred mode");
361 wlr_output_set_mode(wlr_output, mode); 409 struct wlr_output_mode *preferred_mode =
410 wlr_output_preferred_mode(wlr_output);
411 wlr_output_state_set_mode(pending, preferred_mode);
412
413 if (!wlr_output_test_state(wlr_output, pending)) {
414 sway_log(SWAY_DEBUG, "Preferred mode rejected, "
415 "falling back to another mode");
416 struct wlr_output_mode *mode;
417 wl_list_for_each(mode, &wlr_output->modes, link) {
418 if (mode == preferred_mode) {
419 continue;
420 }
421
422 wlr_output_state_set_mode(pending, mode);
423 if (wlr_output_test_state(wlr_output, pending)) {
424 break;
425 }
426 }
427 }
362 } 428 }
363 429
364 if (oc && (oc->subpixel != WL_OUTPUT_SUBPIXEL_UNKNOWN || config->reloading)) { 430 if (oc && (oc->subpixel != WL_OUTPUT_SUBPIXEL_UNKNOWN || config->reloading)) {
365 sway_log(SWAY_DEBUG, "Set %s subpixel to %s", oc->name, 431 sway_log(SWAY_DEBUG, "Set %s subpixel to %s", oc->name,
366 sway_wl_output_subpixel_to_string(oc->subpixel)); 432 sway_wl_output_subpixel_to_string(oc->subpixel));
367 wlr_output_set_subpixel(wlr_output, oc->subpixel); 433 wlr_output_state_set_subpixel(pending, oc->subpixel);
368 } 434 }
369 435
436 enum wl_output_transform tr = WL_OUTPUT_TRANSFORM_NORMAL;
370 if (oc && oc->transform >= 0) { 437 if (oc && oc->transform >= 0) {
371 sway_log(SWAY_DEBUG, "Set %s transform to %d", oc->name, oc->transform); 438 tr = oc->transform;
372 wlr_output_set_transform(wlr_output, oc->transform); 439 } else if (wlr_output_is_drm(wlr_output)) {
440 tr = wlr_drm_connector_get_panel_orientation(wlr_output);
441 sway_log(SWAY_DEBUG, "Auto-detected output transform: %d", tr);
442 }
443 if (wlr_output->transform != tr) {
444 sway_log(SWAY_DEBUG, "Set %s transform to %d", oc->name, tr);
445 wlr_output_state_set_transform(pending, tr);
373 } 446 }
374 447
375 // Apply the scale last before the commit, because the scale auto-detection 448 // Apply the scale last before the commit, because the scale auto-detection
@@ -378,23 +451,39 @@ static void queue_output_config(struct output_config *oc,
378 if (oc && oc->scale > 0) { 451 if (oc && oc->scale > 0) {
379 scale = oc->scale; 452 scale = oc->scale;
380 } else { 453 } else {
381 scale = compute_default_scale(wlr_output); 454 scale = compute_default_scale(wlr_output, pending);
382 sway_log(SWAY_DEBUG, "Auto-detected output scale: %f", scale); 455 sway_log(SWAY_DEBUG, "Auto-detected output scale: %f", scale);
383 } 456 }
384 if (scale != wlr_output->scale) { 457 if (scale != wlr_output->scale) {
385 sway_log(SWAY_DEBUG, "Set %s scale to %f", wlr_output->name, scale); 458 sway_log(SWAY_DEBUG, "Set %s scale to %f", wlr_output->name, scale);
386 wlr_output_set_scale(wlr_output, scale); 459 wlr_output_state_set_scale(pending, scale);
387 } 460 }
388 461
389 if (oc && oc->adaptive_sync != -1) { 462 if (oc && oc->adaptive_sync != -1) {
390 sway_log(SWAY_DEBUG, "Set %s adaptive sync to %d", wlr_output->name, 463 sway_log(SWAY_DEBUG, "Set %s adaptive sync to %d", wlr_output->name,
391 oc->adaptive_sync); 464 oc->adaptive_sync);
392 wlr_output_enable_adaptive_sync(wlr_output, oc->adaptive_sync == 1); 465 wlr_output_state_set_adaptive_sync_enabled(pending, oc->adaptive_sync == 1);
466 }
467
468 if (oc && oc->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) {
469 const uint32_t *fmts = bit_depth_preferences[oc->render_bit_depth];
470 assert(fmts);
471
472 for (size_t i = 0; fmts[i] != DRM_FORMAT_INVALID; i++) {
473 wlr_output_state_set_render_format(pending, fmts[i]);
474 if (wlr_output_test_state(wlr_output, pending)) {
475 break;
476 }
477
478 sway_log(SWAY_DEBUG, "Preferred output format 0x%08x "
479 "failed to work, falling back to next in "
480 "list, 0x%08x", fmts[i], fmts[i + 1]);
481 }
393 } 482 }
394} 483}
395 484
396bool apply_output_config(struct output_config *oc, struct sway_output *output) { 485bool apply_output_config(struct output_config *oc, struct sway_output *output) {
397 if (output == root->noop_output) { 486 if (output == root->fallback_output) {
398 return false; 487 return false;
399 } 488 }
400 489
@@ -403,14 +492,15 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
403 // Flag to prevent the output mode event handler from calling us 492 // Flag to prevent the output mode event handler from calling us
404 output->enabling = (!oc || oc->enabled); 493 output->enabling = (!oc || oc->enabled);
405 494
406 queue_output_config(oc, output); 495 struct wlr_output_state pending = {0};
496 queue_output_config(oc, output, &pending);
407 497
408 if (!oc || oc->dpms_state != DPMS_OFF) { 498 if (!oc || oc->power != 0) {
409 output->current_mode = wlr_output->pending.mode; 499 output->current_mode = pending.mode;
410 } 500 }
411 501
412 sway_log(SWAY_DEBUG, "Committing output %s", wlr_output->name); 502 sway_log(SWAY_DEBUG, "Committing output %s", wlr_output->name);
413 if (!wlr_output_commit(wlr_output)) { 503 if (!wlr_output_commit_state(wlr_output, &pending)) {
414 // Failed to commit output changes, maybe the output is missing a CRTC. 504 // Failed to commit output changes, maybe the output is missing a CRTC.
415 // Leave the output disabled for now and try again when the output gets 505 // Leave the output disabled for now and try again when the output gets
416 // the mode we asked for. 506 // the mode we asked for.
@@ -462,12 +552,12 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
462 } 552 }
463 553
464 // Update output->{lx, ly, width, height} 554 // Update output->{lx, ly, width, height}
465 struct wlr_box *output_box = 555 struct wlr_box output_box;
466 wlr_output_layout_get_box(root->output_layout, wlr_output); 556 wlr_output_layout_get_box(root->output_layout, wlr_output, &output_box);
467 output->lx = output_box->x; 557 output->lx = output_box.x;
468 output->ly = output_box->y; 558 output->ly = output_box.y;
469 output->width = output_box->width; 559 output->width = output_box.width;
470 output->height = output_box->height; 560 output->height = output_box.height;
471 561
472 if (!output->enabled) { 562 if (!output->enabled) {
473 output_enable(output); 563 output_enable(output);
@@ -483,23 +573,25 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
483 // this output came online, and some config items (like map_to_output) are 573 // this output came online, and some config items (like map_to_output) are
484 // dependent on an output being present. 574 // dependent on an output being present.
485 input_manager_configure_all_inputs(); 575 input_manager_configure_all_inputs();
576 // Reconfigure the cursor images, since the scale may have changed.
577 input_manager_configure_xcursor();
486 return true; 578 return true;
487} 579}
488 580
489bool test_output_config(struct output_config *oc, struct sway_output *output) { 581bool test_output_config(struct output_config *oc, struct sway_output *output) {
490 if (output == root->noop_output) { 582 if (output == root->fallback_output) {
491 return false; 583 return false;
492 } 584 }
493 585
494 queue_output_config(oc, output); 586 struct wlr_output_state pending = {0};
495 bool ok = wlr_output_test(output->wlr_output); 587 queue_output_config(oc, output, &pending);
496 wlr_output_rollback(output->wlr_output); 588 return wlr_output_test_state(output->wlr_output, &pending);
497 return ok;
498} 589}
499 590
500static void default_output_config(struct output_config *oc, 591static void default_output_config(struct output_config *oc,
501 struct wlr_output *wlr_output) { 592 struct wlr_output *wlr_output) {
502 oc->enabled = 1; 593 oc->enabled = 1;
594 oc->power = 1;
503 struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output); 595 struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output);
504 if (mode != NULL) { 596 if (mode != NULL) {
505 oc->width = mode->width; 597 oc->width = mode->width;
@@ -512,7 +604,6 @@ static void default_output_config(struct output_config *oc,
512 struct sway_output *output = wlr_output->data; 604 struct sway_output *output = wlr_output->data;
513 oc->subpixel = output->detected_subpixel; 605 oc->subpixel = output->detected_subpixel;
514 oc->transform = WL_OUTPUT_TRANSFORM_NORMAL; 606 oc->transform = WL_OUTPUT_TRANSFORM_NORMAL;
515 oc->dpms_state = DPMS_ON;
516 oc->max_render_time = 0; 607 oc->max_render_time = 0;
517} 608}
518 609
@@ -567,10 +658,10 @@ static struct output_config *get_output_config(char *identifier,
567 658
568 sway_log(SWAY_DEBUG, "Generated output config \"%s\" (enabled: %d)" 659 sway_log(SWAY_DEBUG, "Generated output config \"%s\" (enabled: %d)"
569 " (%dx%d@%fHz position %d,%d scale %f transform %d) (bg %s %s)" 660 " (%dx%d@%fHz position %d,%d scale %f transform %d) (bg %s %s)"
570 " (dpms %d) (max render time: %d)", result->name, result->enabled, 661 " (power %d) (max render time: %d)", result->name, result->enabled,
571 result->width, result->height, result->refresh_rate, 662 result->width, result->height, result->refresh_rate,
572 result->x, result->y, result->scale, result->transform, 663 result->x, result->y, result->scale, result->transform,
573 result->background, result->background_option, result->dpms_state, 664 result->background, result->background_option, result->power,
574 result->max_render_time); 665 result->max_render_time);
575 } else if (oc_name) { 666 } else if (oc_name) {
576 // No identifier config, just return a copy of the name config 667 // No identifier config, just return a copy of the name config
@@ -702,6 +793,8 @@ static bool _spawn_swaybg(char **command) {
702 sway_log_errno(SWAY_ERROR, "fork failed"); 793 sway_log_errno(SWAY_ERROR, "fork failed");
703 return false; 794 return false;
704 } else if (pid == 0) { 795 } else if (pid == 0) {
796 restore_nofile_limit();
797
705 pid = fork(); 798 pid = fork();
706 if (pid < 0) { 799 if (pid < 0) {
707 sway_log_errno(SWAY_ERROR, "fork failed"); 800 sway_log_errno(SWAY_ERROR, "fork failed");