From 3eb9cf4a45b6b7ee6e0552c2f240d06ddde351aa Mon Sep 17 00:00:00 2001 From: Daniel Playfair Cal Date: Thu, 7 Jan 2021 23:44:43 +1100 Subject: [PATCH 1/2] output: reapply output config when fixed modes change Listen to the signal `available_modes` which indicates that an output has changed its set of available fixed modes, and reapply the output config. --- include/sway/output.h | 1 + sway/desktop/output.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/include/sway/output.h b/include/sway/output.h index 16451d81f..5950f0d6d 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -44,6 +44,7 @@ struct sway_output { struct wl_listener destroy; struct wl_listener commit; struct wl_listener mode; + struct wl_listener available_modes; struct wl_listener present; struct wl_listener damage_destroy; struct wl_listener damage_frame; diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 06acb8686..6a594c226 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -872,6 +872,17 @@ static void handle_mode(struct wl_listener *listener, void *data) { update_output_manager_config(output->server); } +static void handle_available_modes(struct wl_listener *listener, void *data) { + struct sway_output *output = wl_container_of(listener, output, available_modes); + struct output_config *oc = find_output_config(output); + apply_output_config(oc, output); + free_output_config(oc); + + transaction_commit_dirty(); + + update_output_manager_config(output->server); +} + static void update_textures(struct sway_container *con, void *data) { container_update_title_textures(con); container_update_marks_textures(con); @@ -928,6 +939,8 @@ void handle_new_output(struct wl_listener *listener, void *data) { output->commit.notify = handle_commit; wl_signal_add(&wlr_output->events.mode, &output->mode); output->mode.notify = handle_mode; + wl_signal_add(&wlr_output->events.available_modes, &output->available_modes); + output->available_modes.notify = handle_available_modes; wl_signal_add(&wlr_output->events.present, &output->present); output->present.notify = handle_present; wl_signal_add(&output->damage->events.frame, &output->damage_frame); From 57ae17b620a486b4de7ba19c9ad0d4c1feb231fd Mon Sep 17 00:00:00 2001 From: Daniel Playfair Cal Date: Sun, 10 Jan 2021 20:38:32 +1100 Subject: [PATCH 2/2] output: use suggested position for output by default Some virtualised outputs provide a suggested position which indicates the relative position of the outputs in the host WM. This change uses these positions for outputs with no configured position. --- include/sway/output.h | 1 + sway/config/output.c | 41 +++++++++++++++++++++++++++++++---------- sway/desktop/output.c | 13 +++++++++++++ 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/include/sway/output.h b/include/sway/output.h index 5950f0d6d..d8f7afae9 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -45,6 +45,7 @@ struct sway_output { struct wl_listener commit; struct wl_listener mode; struct wl_listener available_modes; + struct wl_listener suggested_position; struct wl_listener present; struct wl_listener damage_destroy; struct wl_listener damage_frame; diff --git a/sway/config/output.c b/sway/config/output.c index b59cabd4e..57aaa8d68 100644 --- a/sway/config/output.c +++ b/sway/config/output.c @@ -331,6 +331,18 @@ static int compute_default_scale(struct wlr_output *output) { return 2; } +static float get_effective_scale(struct output_config *oc, + struct wlr_output *wlr_output) { + float scale; + if (oc && oc->scale > 0) { + scale = oc->scale; + } else { + scale = compute_default_scale(wlr_output); + sway_log(SWAY_DEBUG, "Auto-detected output scale: %f", scale); + } + return scale; +} + static void queue_output_config(struct output_config *oc, struct sway_output *output) { if (output == root->noop_output) { @@ -371,13 +383,7 @@ static void queue_output_config(struct output_config *oc, // Apply the scale last before the commit, because the scale auto-detection // reads the pending output size - float scale; - if (oc && oc->scale > 0) { - scale = oc->scale; - } else { - scale = compute_default_scale(wlr_output); - sway_log(SWAY_DEBUG, "Auto-detected output scale: %f", scale); - } + float scale = get_effective_scale(oc, output->wlr_output); if (scale != wlr_output->scale) { sway_log(SWAY_DEBUG, "Set %s scale to %f", wlr_output->name, scale); wlr_output_set_scale(wlr_output, scale); @@ -451,9 +457,24 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) { } // Find position for it - if (oc && (oc->x != -1 || oc->y != -1)) { - sway_log(SWAY_DEBUG, "Set %s position to %d, %d", oc->name, oc->x, oc->y); - wlr_output_layout_add(root->output_layout, wlr_output, oc->x, oc->y); + int32_t effective_x = -1, effective_y = -1; + float effective_scale = get_effective_scale(oc, output->wlr_output); + if (output->wlr_output->suggested_x != -1) { + effective_x = output->wlr_output->suggested_x / effective_scale; + } + if (output->wlr_output->suggested_y != -1) { + effective_y = output->wlr_output->suggested_y / effective_scale; + } + if (oc && oc->x != -1) { + effective_x = oc->x; + } + if (oc && oc->y != -1) { + effective_y = oc->y; + } + + if (effective_x != -1 || effective_y != -1) { + sway_log(SWAY_DEBUG, "Set %s position to %d, %d", oc ? oc->name : wlr_output->name, effective_x, effective_y); + wlr_output_layout_add(root->output_layout, wlr_output, effective_x, effective_y); } else { wlr_output_layout_add_auto(root->output_layout, wlr_output); } diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 6a594c226..08c335846 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -883,6 +883,17 @@ static void handle_available_modes(struct wl_listener *listener, void *data) { update_output_manager_config(output->server); } +static void handle_suggested_position(struct wl_listener *listener, void *data) { + struct sway_output *output = wl_container_of(listener, output, suggested_position); + struct output_config *oc = find_output_config(output); + apply_output_config(oc, output); + free_output_config(oc); + + transaction_commit_dirty(); + + update_output_manager_config(output->server); +} + static void update_textures(struct sway_container *con, void *data) { container_update_title_textures(con); container_update_marks_textures(con); @@ -941,6 +952,8 @@ void handle_new_output(struct wl_listener *listener, void *data) { output->mode.notify = handle_mode; wl_signal_add(&wlr_output->events.available_modes, &output->available_modes); output->available_modes.notify = handle_available_modes; + wl_signal_add(&wlr_output->events.suggested_position, &output->suggested_position); + output->suggested_position.notify = handle_suggested_position; wl_signal_add(&wlr_output->events.present, &output->present); output->present.notify = handle_present; wl_signal_add(&output->damage->events.frame, &output->damage_frame);