diff options
author | Kenny Levinsen <kl@kl.wtf> | 2024-03-16 01:01:56 +0100 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2024-03-28 10:45:20 +0100 |
commit | 3b419020a32f4f8385e49d2137ceb4d9b8262176 (patch) | |
tree | e664fa90419d88fb654a09c75afc95b6a04cfe0a /sway/desktop/output.c | |
parent | Use apply_all_output_configs to light up outputs (diff) | |
download | sway-3b419020a32f4f8385e49d2137ceb4d9b8262176.tar.gz sway-3b419020a32f4f8385e49d2137ceb4d9b8262176.tar.zst sway-3b419020a32f4f8385e49d2137ceb4d9b8262176.zip |
desktop/output: Use apply_output_configs for output mgmt
Diffstat (limited to 'sway/desktop/output.c')
-rw-r--r-- | sway/desktop/output.c | 115 |
1 files changed, 70 insertions, 45 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index b2647219..bd3de3fe 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -550,63 +550,88 @@ void handle_gamma_control_set_gamma(struct wl_listener *listener, void *data) { | |||
550 | wlr_output_schedule_frame(output->wlr_output); | 550 | wlr_output_schedule_frame(output->wlr_output); |
551 | } | 551 | } |
552 | 552 | ||
553 | static 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 | |||
553 | static void output_manager_apply(struct sway_server *server, | 581 | static void output_manager_apply(struct sway_server *server, |
554 | struct wlr_output_configuration_v1 *config, bool test_only) { | 582 | struct wlr_output_configuration_v1 *config, bool test_only) { |
555 | // TODO: perform atomic tests on the whole backend atomically | 583 | size_t configs_len = wl_list_length(&root->all_outputs); |
556 | 584 | struct matched_output_config *configs = calloc(configs_len, sizeof(*configs)); | |
557 | struct wlr_output_configuration_head_v1 *config_head; | 585 | if (!configs) { |
558 | // First disable outputs we need to disable | 586 | return; |
559 | bool ok = true; | 587 | } |
560 | wl_list_for_each(config_head, &config->heads, link) { | 588 | |
561 | struct wlr_output *wlr_output = config_head->state.output; | 589 | int config_idx = 0; |
562 | struct sway_output *output = wlr_output->data; | 590 | struct sway_output *sway_output; |
563 | 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--; | ||
564 | continue; | 594 | continue; |
565 | } | 595 | } |
566 | struct output_config *oc = new_output_config(output->wlr_output->name); | ||
567 | oc->enabled = false; | ||
568 | 596 | ||
569 | if (test_only) { | 597 | struct matched_output_config *cfg = &configs[config_idx++]; |
570 | ok &= test_output_config(oc, output); | 598 | cfg->output = sway_output; |
571 | } else { | 599 | |
572 | oc = store_output_config(oc); | 600 | struct wlr_output_configuration_head_v1 *config_head; |
573 | 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); | ||
574 | } | 609 | } |
575 | } | 610 | } |
576 | 611 | ||
577 | // Then enable outputs that need to | 612 | bool ok = apply_output_configs(configs, configs_len, test_only); |
578 | wl_list_for_each(config_head, &config->heads, link) { | 613 | for (size_t idx = 0; idx < configs_len; idx++) { |
579 | struct wlr_output *wlr_output = config_head->state.output; | 614 | struct matched_output_config *cfg = &configs[idx]; |
580 | struct sway_output *output = wlr_output->data; | 615 | |
581 | if (!config_head->state.enabled) { | 616 | // Only store new configs for successful non-test commits. Old configs, |
582 | continue; | 617 | // test-only and failed commits just get freed. |
583 | } | 618 | bool store_config = false; |
584 | struct output_config *oc = new_output_config(output->wlr_output->name); | 619 | if (!test_only && ok) { |
585 | oc->enabled = true; | 620 | struct wlr_output_configuration_head_v1 *config_head; |
586 | if (config_head->state.mode != NULL) { | 621 | wl_list_for_each(config_head, &config->heads, link) { |
587 | struct wlr_output_mode *mode = config_head->state.mode; | 622 | if (config_head->state.output == sway_output->wlr_output) { |
588 | oc->width = mode->width; | 623 | store_config = true; |
589 | oc->height = mode->height; | 624 | break; |
590 | oc->refresh_rate = mode->refresh / 1000.f; | 625 | } |
591 | } else { | 626 | } |
592 | oc->width = config_head->state.custom_mode.width; | ||
593 | oc->height = config_head->state.custom_mode.height; | ||
594 | oc->refresh_rate = | ||
595 | config_head->state.custom_mode.refresh / 1000.f; | ||
596 | } | 627 | } |
597 | oc->x = config_head->state.x; | 628 | if (store_config) { |
598 | oc->y = config_head->state.y; | 629 | store_output_config(cfg->config); |
599 | oc->transform = config_head->state.transform; | ||
600 | oc->scale = config_head->state.scale; | ||
601 | oc->adaptive_sync = config_head->state.adaptive_sync_enabled; | ||
602 | |||
603 | if (test_only) { | ||
604 | ok &= test_output_config(oc, output); | ||
605 | } else { | 630 | } else { |
606 | oc = store_output_config(oc); | 631 | free_output_config(cfg->config); |
607 | ok &= apply_output_config(oc, output); | ||
608 | } | 632 | } |
609 | } | 633 | } |
634 | free(configs); | ||
610 | 635 | ||
611 | if (ok) { | 636 | if (ok) { |
612 | wlr_output_configuration_v1_send_succeeded(config); | 637 | wlr_output_configuration_v1_send_succeeded(config); |