mirror of
https://github.com/swaywm/sway.git
synced 2024-11-22 07:51:28 +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;
|
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
|
* 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_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);
|
bool test_output_config(struct output_config *oc, struct sway_output *output);
|
||||||
|
|
||||||
struct output_config *store_output_config(struct output_config *oc);
|
struct output_config *store_output_config(struct output_config *oc);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <wlr/types/wlr_cursor.h>
|
#include <wlr/types/wlr_cursor.h>
|
||||||
#include <wlr/types/wlr_output_layout.h>
|
#include <wlr/types/wlr_output_layout.h>
|
||||||
#include <wlr/types/wlr_output.h>
|
#include <wlr/types/wlr_output.h>
|
||||||
|
#include <wlr/types/wlr_output_swapchain_manager.h>
|
||||||
#include "sway/config.h"
|
#include "sway/config.h"
|
||||||
#include "sway/input/cursor.h"
|
#include "sway/input/cursor.h"
|
||||||
#include "sway/output.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);
|
return get_output_config(id, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
void apply_output_config_to_outputs(struct output_config *oc) {
|
bool apply_output_configs(struct matched_output_config *configs,
|
||||||
// Try to find the output container and apply configuration now. If
|
size_t configs_len, bool test_only) {
|
||||||
// this is during startup then there will be no container and config
|
struct wlr_backend_output_state *states = calloc(configs_len, sizeof(*states));
|
||||||
// will be applied during normal "new output" event from wlroots.
|
if (!states) {
|
||||||
bool wildcard = strcmp(oc->name, "*") == 0;
|
return false;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
apply_output_config(current, sway_output);
|
|
||||||
free_output_config(current);
|
|
||||||
|
|
||||||
if (!wildcard) {
|
sway_log(SWAY_DEBUG, "Committing %zd outputs", configs_len);
|
||||||
// Stop looking if the output config isn't applicable to all
|
for (size_t idx = 0; idx < configs_len; idx++) {
|
||||||
// outputs
|
struct matched_output_config *cfg = &configs[idx];
|
||||||
break;
|
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;
|
struct sway_seat *seat;
|
||||||
wl_list_for_each(seat, &server.input->seats, link) {
|
wl_list_for_each(seat, &server.input->seats, link) {
|
||||||
wlr_seat_pointer_notify_clear_focus(seat->wlr_seat);
|
wlr_seat_pointer_notify_clear_focus(seat->wlr_seat);
|
||||||
cursor_rebase(seat->cursor);
|
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) {
|
void reset_outputs(void) {
|
||||||
|
|
Loading…
Reference in a new issue