mirror of
https://github.com/swaywm/sway.git
synced 2024-11-21 23:41:27 +00:00
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.
This commit is contained in:
parent
e2f3ebad8c
commit
3e03eb3a01
|
@ -291,6 +291,14 @@ struct output_config {
|
|||
char *background_fallback;
|
||||
};
|
||||
|
||||
/**
|
||||
* An output config pre-matched to an output
|
||||
*/
|
||||
struct matched_output_config {
|
||||
struct sway_output *output;
|
||||
struct output_config *config;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stores size of gaps for each side
|
||||
*/
|
||||
|
@ -684,6 +692,9 @@ void merge_output_config(struct output_config *dst, struct output_config *src);
|
|||
|
||||
bool apply_output_config(struct output_config *oc, struct sway_output *output);
|
||||
|
||||
bool apply_output_configs(struct matched_output_config *configs,
|
||||
size_t configs_len, bool test_only);
|
||||
|
||||
bool test_output_config(struct output_config *oc, struct sway_output *output);
|
||||
|
||||
struct output_config *store_output_config(struct output_config *oc);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <wlr/types/wlr_cursor.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_output_swapchain_manager.h>
|
||||
#include "sway/config.h"
|
||||
#include "sway/input/cursor.h"
|
||||
#include "sway/output.h"
|
||||
|
@ -716,39 +717,138 @@ struct output_config *find_output_config(struct sway_output *output) {
|
|||
return get_output_config(id, output);
|
||||
}
|
||||
|
||||
void apply_output_config_to_outputs(struct output_config *oc) {
|
||||
// Try to find the output container and apply configuration now. If
|
||||
// this is during startup then there will be no container and config
|
||||
// will be applied during normal "new output" event from wlroots.
|
||||
bool wildcard = strcmp(oc->name, "*") == 0;
|
||||
struct sway_output *sway_output, *tmp;
|
||||
wl_list_for_each_safe(sway_output, tmp, &root->all_outputs, link) {
|
||||
if (output_match_name_or_id(sway_output, oc->name)) {
|
||||
char id[128];
|
||||
output_get_identifier(id, sizeof(id), sway_output);
|
||||
struct output_config *current = get_output_config(id, sway_output);
|
||||
if (!current) {
|
||||
// No stored output config matched, apply oc directly
|
||||
sway_log(SWAY_DEBUG, "Applying oc directly");
|
||||
current = new_output_config(oc->name);
|
||||
merge_output_config(current, oc);
|
||||
bool apply_output_configs(struct matched_output_config *configs,
|
||||
size_t configs_len, bool test_only) {
|
||||
struct wlr_backend_output_state *states = calloc(configs_len, sizeof(*states));
|
||||
if (!states) {
|
||||
return false;
|
||||
}
|
||||
apply_output_config(current, sway_output);
|
||||
free_output_config(current);
|
||||
|
||||
if (!wildcard) {
|
||||
// Stop looking if the output config isn't applicable to all
|
||||
// outputs
|
||||
break;
|
||||
sway_log(SWAY_DEBUG, "Committing %zd outputs", configs_len);
|
||||
for (size_t idx = 0; idx < configs_len; idx++) {
|
||||
struct matched_output_config *cfg = &configs[idx];
|
||||
struct wlr_backend_output_state *backend_state = &states[idx];
|
||||
|
||||
backend_state->output = cfg->output->wlr_output;
|
||||
wlr_output_state_init(&backend_state->base);
|
||||
|
||||
sway_log(SWAY_DEBUG, "Preparing config for %s",
|
||||
cfg->output->wlr_output->name);
|
||||
queue_output_config(cfg->config, cfg->output, &backend_state->base);
|
||||
}
|
||||
|
||||
struct wlr_output_swapchain_manager swapchain_mgr;
|
||||
wlr_output_swapchain_manager_init(&swapchain_mgr, server.backend);
|
||||
|
||||
bool ok = wlr_output_swapchain_manager_prepare(&swapchain_mgr, states, configs_len);
|
||||
if (!ok) {
|
||||
sway_log(SWAY_ERROR, "Swapchain prepare failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (test_only) {
|
||||
// The swapchain manager already did a test for us
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (size_t idx = 0; idx < configs_len; idx++) {
|
||||
struct matched_output_config *cfg = &configs[idx];
|
||||
struct wlr_backend_output_state *backend_state = &states[idx];
|
||||
|
||||
struct wlr_scene_output_state_options opts = {
|
||||
.swapchain = wlr_output_swapchain_manager_get_swapchain(
|
||||
&swapchain_mgr, backend_state->output),
|
||||
};
|
||||
struct wlr_scene_output *scene_output = cfg->output->scene_output;
|
||||
struct wlr_output_state *state = &backend_state->base;
|
||||
if (!wlr_scene_output_build_state(scene_output, state, &opts)) {
|
||||
sway_log(SWAY_ERROR, "Building output state for '%s' failed",
|
||||
backend_state->output->name);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ok = wlr_backend_commit(server.backend, states, configs_len);
|
||||
if (!ok) {
|
||||
sway_log(SWAY_ERROR, "Backend commit failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
sway_log(SWAY_DEBUG, "Commit of %zd outputs succeeded", configs_len);
|
||||
|
||||
wlr_output_swapchain_manager_apply(&swapchain_mgr);
|
||||
|
||||
for (size_t idx = 0; idx < configs_len; idx++) {
|
||||
struct matched_output_config *cfg = &configs[idx];
|
||||
sway_log(SWAY_DEBUG, "Finalizing config for %s",
|
||||
cfg->output->wlr_output->name);
|
||||
finalize_output_config(cfg->config, cfg->output);
|
||||
}
|
||||
|
||||
out:
|
||||
wlr_output_swapchain_manager_finish(&swapchain_mgr);
|
||||
for (size_t idx = 0; idx < configs_len; idx++) {
|
||||
struct wlr_backend_output_state *backend_state = &states[idx];
|
||||
wlr_output_state_finish(&backend_state->base);
|
||||
}
|
||||
free(states);
|
||||
|
||||
// Reconfigure all devices, since input config may have been applied before
|
||||
// this output came online, and some config items (like map_to_output) are
|
||||
// dependent on an output being present.
|
||||
input_manager_configure_all_input_mappings();
|
||||
// Reconfigure the cursor images, since the scale may have changed.
|
||||
input_manager_configure_xcursor();
|
||||
|
||||
struct sway_seat *seat;
|
||||
wl_list_for_each(seat, &server.input->seats, link) {
|
||||
wlr_seat_pointer_notify_clear_focus(seat->wlr_seat);
|
||||
cursor_rebase(seat->cursor);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
void apply_output_config_to_outputs(struct output_config *oc) {
|
||||
size_t configs_len = wl_list_length(&root->all_outputs);
|
||||
struct matched_output_config *configs = calloc(configs_len, sizeof(*configs));
|
||||
if (!configs) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to find the output container and apply configuration now. If
|
||||
// this is during startup then there will be no container and config
|
||||
// will be applied during normal "new output" event from wlroots.
|
||||
int config_idx = 0;
|
||||
struct sway_output *sway_output;
|
||||
wl_list_for_each(sway_output, &root->all_outputs, link) {
|
||||
if (sway_output == root->fallback_output) {
|
||||
configs_len--;
|
||||
continue;
|
||||
}
|
||||
|
||||
struct matched_output_config *config = &configs[config_idx++];
|
||||
config->output = sway_output;
|
||||
config->config = find_output_config(sway_output);
|
||||
|
||||
if (!output_match_name_or_id(sway_output, oc->name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!config->config && oc) {
|
||||
// No stored output config matched, apply oc directly
|
||||
sway_log(SWAY_DEBUG, "Applying oc directly");
|
||||
config->config = new_output_config(oc->name);
|
||||
merge_output_config(config->config, oc);
|
||||
}
|
||||
}
|
||||
|
||||
apply_output_configs(configs, configs_len, false);
|
||||
for (size_t idx = 0; idx < configs_len; idx++) {
|
||||
struct matched_output_config *cfg = &configs[idx];
|
||||
free_output_config(cfg->config);
|
||||
}
|
||||
free(configs);
|
||||
}
|
||||
|
||||
void reset_outputs(void) {
|
||||
|
|
Loading…
Reference in a new issue