diff options
author | Kenny Levinsen <kl@kl.wtf> | 2024-03-16 00:48:56 +0100 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2024-03-28 10:45:20 +0100 |
commit | 3e03eb3a017d144137dbe6591891f3a51a61dea0 (patch) | |
tree | 571828cfe9eb98fe524dc55ce115111aa24dbb9b /sway | |
parent | config/output: Split apply_output_config (diff) | |
download | sway-3e03eb3a017d144137dbe6591891f3a51a61dea0.tar.gz sway-3e03eb3a017d144137dbe6591891f3a51a61dea0.tar.zst sway-3e03eb3a017d144137dbe6591891f3a51a61dea0.zip |
config/output: Introduce apply_output_configs
Introduce apply_output_configs, which applies the specified matched
output configs as a single backend commit.
Reimplement apply_output_config_to_outputs using apply_output_configs.
Diffstat (limited to 'sway')
-rw-r--r-- | sway/config/output.c | 148 |
1 files changed, 124 insertions, 24 deletions
diff --git a/sway/config/output.c b/sway/config/output.c index fd1d6e3c..de9515e2 100644 --- a/sway/config/output.c +++ b/sway/config/output.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <wlr/types/wlr_cursor.h> | 9 | #include <wlr/types/wlr_cursor.h> |
10 | #include <wlr/types/wlr_output_layout.h> | 10 | #include <wlr/types/wlr_output_layout.h> |
11 | #include <wlr/types/wlr_output.h> | 11 | #include <wlr/types/wlr_output.h> |
12 | #include <wlr/types/wlr_output_swapchain_manager.h> | ||
12 | #include "sway/config.h" | 13 | #include "sway/config.h" |
13 | #include "sway/input/cursor.h" | 14 | #include "sway/input/cursor.h" |
14 | #include "sway/output.h" | 15 | #include "sway/output.h" |
@@ -716,39 +717,138 @@ struct output_config *find_output_config(struct sway_output *output) { | |||
716 | return get_output_config(id, output); | 717 | return get_output_config(id, output); |
717 | } | 718 | } |
718 | 719 | ||
719 | void apply_output_config_to_outputs(struct output_config *oc) { | 720 | bool apply_output_configs(struct matched_output_config *configs, |
720 | // Try to find the output container and apply configuration now. If | 721 | size_t configs_len, bool test_only) { |
721 | // this is during startup then there will be no container and config | 722 | struct wlr_backend_output_state *states = calloc(configs_len, sizeof(*states)); |
722 | // will be applied during normal "new output" event from wlroots. | 723 | if (!states) { |
723 | bool wildcard = strcmp(oc->name, "*") == 0; | 724 | return false; |
724 | struct sway_output *sway_output, *tmp; | 725 | } |
725 | wl_list_for_each_safe(sway_output, tmp, &root->all_outputs, link) { | ||
726 | if (output_match_name_or_id(sway_output, oc->name)) { | ||
727 | char id[128]; | ||
728 | output_get_identifier(id, sizeof(id), sway_output); | ||
729 | struct output_config *current = get_output_config(id, sway_output); | ||
730 | if (!current) { | ||
731 | // No stored output config matched, apply oc directly | ||
732 | sway_log(SWAY_DEBUG, "Applying oc directly"); | ||
733 | current = new_output_config(oc->name); | ||
734 | merge_output_config(current, oc); | ||
735 | } | ||
736 | apply_output_config(current, sway_output); | ||
737 | free_output_config(current); | ||
738 | 726 | ||
739 | if (!wildcard) { | 727 | sway_log(SWAY_DEBUG, "Committing %zd outputs", configs_len); |
740 | // Stop looking if the output config isn't applicable to all | 728 | for (size_t idx = 0; idx < configs_len; idx++) { |
741 | // outputs | 729 | struct matched_output_config *cfg = &configs[idx]; |
742 | break; | 730 | struct wlr_backend_output_state *backend_state = &states[idx]; |
743 | } | 731 | |
732 | backend_state->output = cfg->output->wlr_output; | ||
733 | wlr_output_state_init(&backend_state->base); | ||
734 | |||
735 | sway_log(SWAY_DEBUG, "Preparing config for %s", | ||
736 | cfg->output->wlr_output->name); | ||
737 | queue_output_config(cfg->config, cfg->output, &backend_state->base); | ||
738 | } | ||
739 | |||
740 | struct wlr_output_swapchain_manager swapchain_mgr; | ||
741 | wlr_output_swapchain_manager_init(&swapchain_mgr, server.backend); | ||
742 | |||
743 | bool ok = wlr_output_swapchain_manager_prepare(&swapchain_mgr, states, configs_len); | ||
744 | if (!ok) { | ||
745 | sway_log(SWAY_ERROR, "Swapchain prepare failed"); | ||
746 | goto out; | ||
747 | } | ||
748 | |||
749 | if (test_only) { | ||
750 | // The swapchain manager already did a test for us | ||
751 | goto out; | ||
752 | } | ||
753 | |||
754 | for (size_t idx = 0; idx < configs_len; idx++) { | ||
755 | struct matched_output_config *cfg = &configs[idx]; | ||
756 | struct wlr_backend_output_state *backend_state = &states[idx]; | ||
757 | |||
758 | struct wlr_scene_output_state_options opts = { | ||
759 | .swapchain = wlr_output_swapchain_manager_get_swapchain( | ||
760 | &swapchain_mgr, backend_state->output), | ||
761 | }; | ||
762 | struct wlr_scene_output *scene_output = cfg->output->scene_output; | ||
763 | struct wlr_output_state *state = &backend_state->base; | ||
764 | if (!wlr_scene_output_build_state(scene_output, state, &opts)) { | ||
765 | sway_log(SWAY_ERROR, "Building output state for '%s' failed", | ||
766 | backend_state->output->name); | ||
767 | goto out; | ||
744 | } | 768 | } |
745 | } | 769 | } |
746 | 770 | ||
771 | ok = wlr_backend_commit(server.backend, states, configs_len); | ||
772 | if (!ok) { | ||
773 | sway_log(SWAY_ERROR, "Backend commit failed"); | ||
774 | goto out; | ||
775 | } | ||
776 | |||
777 | sway_log(SWAY_DEBUG, "Commit of %zd outputs succeeded", configs_len); | ||
778 | |||
779 | wlr_output_swapchain_manager_apply(&swapchain_mgr); | ||
780 | |||
781 | for (size_t idx = 0; idx < configs_len; idx++) { | ||
782 | struct matched_output_config *cfg = &configs[idx]; | ||
783 | sway_log(SWAY_DEBUG, "Finalizing config for %s", | ||
784 | cfg->output->wlr_output->name); | ||
785 | finalize_output_config(cfg->config, cfg->output); | ||
786 | } | ||
787 | |||
788 | out: | ||
789 | wlr_output_swapchain_manager_finish(&swapchain_mgr); | ||
790 | for (size_t idx = 0; idx < configs_len; idx++) { | ||
791 | struct wlr_backend_output_state *backend_state = &states[idx]; | ||
792 | wlr_output_state_finish(&backend_state->base); | ||
793 | } | ||
794 | free(states); | ||
795 | |||
796 | // Reconfigure all devices, since input config may have been applied before | ||
797 | // this output came online, and some config items (like map_to_output) are | ||
798 | // dependent on an output being present. | ||
799 | input_manager_configure_all_input_mappings(); | ||
800 | // Reconfigure the cursor images, since the scale may have changed. | ||
801 | input_manager_configure_xcursor(); | ||
802 | |||
747 | struct sway_seat *seat; | 803 | struct sway_seat *seat; |
748 | wl_list_for_each(seat, &server.input->seats, link) { | 804 | wl_list_for_each(seat, &server.input->seats, link) { |
749 | wlr_seat_pointer_notify_clear_focus(seat->wlr_seat); | 805 | wlr_seat_pointer_notify_clear_focus(seat->wlr_seat); |
750 | cursor_rebase(seat->cursor); | 806 | cursor_rebase(seat->cursor); |
751 | } | 807 | } |
808 | |||
809 | return ok; | ||
810 | } | ||
811 | |||
812 | void apply_output_config_to_outputs(struct output_config *oc) { | ||
813 | size_t configs_len = wl_list_length(&root->all_outputs); | ||
814 | struct matched_output_config *configs = calloc(configs_len, sizeof(*configs)); | ||
815 | if (!configs) { | ||
816 | return; | ||
817 | } | ||
818 | |||
819 | // Try to find the output container and apply configuration now. If | ||
820 | // this is during startup then there will be no container and config | ||
821 | // will be applied during normal "new output" event from wlroots. | ||
822 | int config_idx = 0; | ||
823 | struct sway_output *sway_output; | ||
824 | wl_list_for_each(sway_output, &root->all_outputs, link) { | ||
825 | if (sway_output == root->fallback_output) { | ||
826 | configs_len--; | ||
827 | continue; | ||
828 | } | ||
829 | |||
830 | struct matched_output_config *config = &configs[config_idx++]; | ||
831 | config->output = sway_output; | ||
832 | config->config = find_output_config(sway_output); | ||
833 | |||
834 | if (!output_match_name_or_id(sway_output, oc->name)) { | ||
835 | continue; | ||
836 | } | ||
837 | |||
838 | if (!config->config && oc) { | ||
839 | // No stored output config matched, apply oc directly | ||
840 | sway_log(SWAY_DEBUG, "Applying oc directly"); | ||
841 | config->config = new_output_config(oc->name); | ||
842 | merge_output_config(config->config, oc); | ||
843 | } | ||
844 | } | ||
845 | |||
846 | apply_output_configs(configs, configs_len, false); | ||
847 | for (size_t idx = 0; idx < configs_len; idx++) { | ||
848 | struct matched_output_config *cfg = &configs[idx]; | ||
849 | free_output_config(cfg->config); | ||
850 | } | ||
851 | free(configs); | ||
752 | } | 852 | } |
753 | 853 | ||
754 | void reset_outputs(void) { | 854 | void reset_outputs(void) { |