aboutsummaryrefslogtreecommitdiffstats
path: root/sway
diff options
context:
space:
mode:
authorLibravatar Kenny Levinsen <kl@kl.wtf>2024-03-16 00:48:56 +0100
committerLibravatar Simon Ser <contact@emersion.fr>2024-03-28 10:45:20 +0100
commit3e03eb3a017d144137dbe6591891f3a51a61dea0 (patch)
tree571828cfe9eb98fe524dc55ce115111aa24dbb9b /sway
parentconfig/output: Split apply_output_config (diff)
downloadsway-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.c148
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
719void apply_output_config_to_outputs(struct output_config *oc) { 720bool 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
788out:
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
812void 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
754void reset_outputs(void) { 854void reset_outputs(void) {