aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/desktop/output.c')
-rw-r--r--sway/desktop/output.c124
1 files changed, 74 insertions, 50 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index b8f2d32d..2722e556 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -521,9 +521,7 @@ void handle_new_output(struct wl_listener *listener, void *data) {
521 sway_session_lock_add_output(server->session_lock.lock, output); 521 sway_session_lock_add_output(server->session_lock.lock, output);
522 } 522 }
523 523
524 struct output_config *oc = find_output_config(output); 524 apply_all_output_configs();
525 apply_output_config(oc, output);
526 free_output_config(oc);
527 525
528 transaction_commit_dirty(); 526 transaction_commit_dirty();
529 527
@@ -552,63 +550,89 @@ void handle_gamma_control_set_gamma(struct wl_listener *listener, void *data) {
552 wlr_output_schedule_frame(output->wlr_output); 550 wlr_output_schedule_frame(output->wlr_output);
553} 551}
554 552
553static struct output_config *output_config_for_config_head(
554 struct wlr_output_configuration_head_v1 *config_head,
555 struct sway_output *output) {
556 struct output_config *oc = new_output_config(output->wlr_output->name);
557 oc->enabled = config_head->state.enabled;
558 if (!oc->enabled) {
559 return oc;
560 }
561
562 if (config_head->state.mode != NULL) {
563 struct wlr_output_mode *mode = config_head->state.mode;
564 oc->width = mode->width;
565 oc->height = mode->height;
566 oc->refresh_rate = mode->refresh / 1000.f;
567 } else {
568 oc->width = config_head->state.custom_mode.width;
569 oc->height = config_head->state.custom_mode.height;
570 oc->refresh_rate =
571 config_head->state.custom_mode.refresh / 1000.f;
572 }
573 oc->x = config_head->state.x;
574 oc->y = config_head->state.y;
575 oc->transform = config_head->state.transform;
576 oc->scale = config_head->state.scale;
577 oc->adaptive_sync = config_head->state.adaptive_sync_enabled;
578 return oc;
579}
580
555static void output_manager_apply(struct sway_server *server, 581static void output_manager_apply(struct sway_server *server,
556 struct wlr_output_configuration_v1 *config, bool test_only) { 582 struct wlr_output_configuration_v1 *config, bool test_only) {
557 // TODO: perform atomic tests on the whole backend atomically 583 size_t configs_len = wl_list_length(&root->all_outputs);
558 584 struct matched_output_config *configs = calloc(configs_len, sizeof(*configs));
559 struct wlr_output_configuration_head_v1 *config_head; 585 if (!configs) {
560 // First disable outputs we need to disable 586 return;
561 bool ok = true; 587 }
562 wl_list_for_each(config_head, &config->heads, link) { 588
563 struct wlr_output *wlr_output = config_head->state.output; 589 int config_idx = 0;
564 struct sway_output *output = wlr_output->data; 590 struct sway_output *sway_output;
565 if (!output->enabled || config_head->state.enabled) { 591 wl_list_for_each(sway_output, &root->all_outputs, link) {
592 if (sway_output == root->fallback_output) {
593 configs_len--;
566 continue; 594 continue;
567 } 595 }
568 struct output_config *oc = new_output_config(output->wlr_output->name);
569 oc->enabled = false;
570 596
571 if (test_only) { 597 struct matched_output_config *cfg = &configs[config_idx++];
572 ok &= test_output_config(oc, output); 598 cfg->output = sway_output;
573 } else { 599
574 oc = store_output_config(oc); 600 struct wlr_output_configuration_head_v1 *config_head;
575 ok &= apply_output_config(oc, output); 601 wl_list_for_each(config_head, &config->heads, link) {
602 if (config_head->state.output == sway_output->wlr_output) {
603 cfg->config = output_config_for_config_head(config_head, sway_output);
604 break;
605 }
606 }
607 if (!cfg->config) {
608 cfg->config = find_output_config(sway_output);
576 } 609 }
577 } 610 }
578 611
579 // Then enable outputs that need to 612 sort_output_configs_by_priority(configs, configs_len);
580 wl_list_for_each(config_head, &config->heads, link) { 613 bool ok = apply_output_configs(configs, configs_len, test_only, false);
581 struct wlr_output *wlr_output = config_head->state.output; 614 for (size_t idx = 0; idx < configs_len; idx++) {
582 struct sway_output *output = wlr_output->data; 615 struct matched_output_config *cfg = &configs[idx];
583 if (!config_head->state.enabled) { 616
584 continue; 617 // Only store new configs for successful non-test commits. Old configs,
585 } 618 // test-only and failed commits just get freed.
586 struct output_config *oc = new_output_config(output->wlr_output->name); 619 bool store_config = false;
587 oc->enabled = true; 620 if (!test_only && ok) {
588 if (config_head->state.mode != NULL) { 621 struct wlr_output_configuration_head_v1 *config_head;
589 struct wlr_output_mode *mode = config_head->state.mode; 622 wl_list_for_each(config_head, &config->heads, link) {
590 oc->width = mode->width; 623 if (config_head->state.output == cfg->output->wlr_output) {
591 oc->height = mode->height; 624 store_config = true;
592 oc->refresh_rate = mode->refresh / 1000.f; 625 break;
593 } else { 626 }
594 oc->width = config_head->state.custom_mode.width; 627 }
595 oc->height = config_head->state.custom_mode.height;
596 oc->refresh_rate =
597 config_head->state.custom_mode.refresh / 1000.f;
598 } 628 }
599 oc->x = config_head->state.x; 629 if (store_config) {
600 oc->y = config_head->state.y; 630 store_output_config(cfg->config);
601 oc->transform = config_head->state.transform;
602 oc->scale = config_head->state.scale;
603 oc->adaptive_sync = config_head->state.adaptive_sync_enabled;
604
605 if (test_only) {
606 ok &= test_output_config(oc, output);
607 } else { 631 } else {
608 oc = store_output_config(oc); 632 free_output_config(cfg->config);
609 ok &= apply_output_config(oc, output);
610 } 633 }
611 } 634 }
635 free(configs);
612 636
613 if (ok) { 637 if (ok) {
614 wlr_output_configuration_v1_send_succeeded(config); 638 wlr_output_configuration_v1_send_succeeded(config);
@@ -652,6 +676,6 @@ void handle_output_power_manager_set_mode(struct wl_listener *listener,
652 oc->power = 1; 676 oc->power = 1;
653 break; 677 break;
654 } 678 }
655 oc = store_output_config(oc); 679 store_output_config(oc);
656 apply_output_config(oc, output); 680 apply_all_output_configs();
657} 681}