aboutsummaryrefslogtreecommitdiff
path: root/sway
diff options
context:
space:
mode:
Diffstat (limited to 'sway')
-rw-r--r--sway/desktop/output.c93
-rw-r--r--sway/server.c9
2 files changed, 102 insertions, 0 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 1636a58b..dccb2432 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -578,6 +578,30 @@ static void update_textures(struct sway_container *con, void *data) {
container_update_marks_textures(con);
}
+static void update_output_manager_config(struct sway_server *server) {
+ struct wlr_output_configuration_v1 *config =
+ wlr_output_configuration_v1_create();
+
+ struct sway_output *output;
+ wl_list_for_each(output, &root->all_outputs, link) {
+ if (output == root->noop_output) {
+ continue;
+ }
+ struct wlr_output_configuration_head_v1 *config_head =
+ wlr_output_configuration_head_v1_create(config, output->wlr_output);
+ struct wlr_box *output_box = wlr_output_layout_get_box(
+ root->output_layout, output->wlr_output);
+ // We mark the output enabled even if it is switched off by DPMS
+ config_head->state.enabled = output->enabled;
+ if (output_box) {
+ config_head->state.x = output_box->x;
+ config_head->state.y = output_box->y;
+ }
+ }
+
+ wlr_output_manager_v1_set_configuration(server->output_manager_v1, config);
+}
+
static void handle_scale(struct wl_listener *listener, void *data) {
struct sway_output *output = wl_container_of(listener, output, scale);
if (!output->enabled || !output->configured) {
@@ -651,4 +675,73 @@ void handle_new_output(struct wl_listener *listener, void *data) {
}
transaction_commit_dirty();
+
+ update_output_manager_config(server);
+}
+
+void handle_output_manager_apply(struct wl_listener *listener, void *data) {
+ struct sway_server *server =
+ wl_container_of(listener, server, output_manager_apply);
+ struct wlr_output_configuration_v1 *config = data;
+
+ struct wlr_output_configuration_head_v1 *config_head;
+ // First disable outputs we need to disable
+ bool ok = true;
+ wl_list_for_each(config_head, &config->heads, link) {
+ struct wlr_output *wlr_output = config_head->state.output;
+ struct sway_output *output = wlr_output->data;
+ if (!output->enabled || config_head->state.enabled) {
+ continue;
+ }
+ struct output_config *oc = new_output_config(output->wlr_output->name);
+ oc->enabled = false;
+
+ oc = store_output_config(oc);
+ ok &= apply_output_config(oc, output);
+ }
+
+ // Then enable outputs that need to
+ wl_list_for_each(config_head, &config->heads, link) {
+ struct wlr_output *wlr_output = config_head->state.output;
+ struct sway_output *output = wlr_output->data;
+ if (!config_head->state.enabled) {
+ continue;
+ }
+ struct output_config *oc = new_output_config(output->wlr_output->name);
+ oc->enabled = true;
+ if (config_head->state.mode != NULL) {
+ struct wlr_output_mode *mode = config_head->state.mode;
+ oc->width = mode->width;
+ oc->height = mode->height;
+ oc->refresh_rate = mode->refresh;
+ } else {
+ oc->width = config_head->state.custom_mode.width;
+ oc->height = config_head->state.custom_mode.height;
+ oc->refresh_rate = config_head->state.custom_mode.refresh;
+ }
+ oc->x = config_head->state.x;
+ oc->y = config_head->state.y;
+ oc->transform = config_head->state.transform;
+ oc->scale = config_head->state.scale;
+
+ oc = store_output_config(oc);
+ ok &= apply_output_config(oc, output);
+ }
+
+ if (ok) {
+ wlr_output_configuration_v1_send_succeeded(config);
+ } else {
+ wlr_output_configuration_v1_send_failed(config);
+ }
+ wlr_output_configuration_v1_destroy(config);
+
+ update_output_manager_config(server);
+}
+
+void handle_output_manager_test(struct wl_listener *listener, void *data) {
+ struct wlr_output_configuration_v1 *config = data;
+
+ // TODO: implement test-only mode
+ wlr_output_configuration_v1_send_succeeded(config);
+ wlr_output_configuration_v1_destroy(config);
}
diff --git a/sway/server.c b/sway/server.c
index b24cc1dc..e5200d59 100644
--- a/sway/server.c
+++ b/sway/server.c
@@ -120,6 +120,15 @@ bool server_init(struct sway_server *server) {
server->presentation =
wlr_presentation_create(server->wl_display, server->backend);
+ server->output_manager_v1 =
+ wlr_output_manager_v1_create(server->wl_display);
+ server->output_manager_apply.notify = handle_output_manager_apply;
+ wl_signal_add(&server->output_manager_v1->events.apply,
+ &server->output_manager_apply);
+ server->output_manager_test.notify = handle_output_manager_test;
+ wl_signal_add(&server->output_manager_v1->events.test,
+ &server->output_manager_test);
+
wlr_export_dmabuf_manager_v1_create(server->wl_display);
wlr_screencopy_manager_v1_create(server->wl_display);
wlr_data_control_manager_v1_create(server->wl_display);