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);