From 19f9dbc49ab49f21ec5fdac243797bb0b82b5e1b Mon Sep 17 00:00:00 2001 From: Milad Alizadeh Date: Sun, 22 Feb 2026 18:18:22 +0000 Subject: [PATCH] Re-evaluate default_orientation auto when workspaces change outputs Workspaces created with default_orientation auto now re-orient when moved to a different output, evacuated on disconnect, restored on reconnect, or when output mode/transform changes. --- include/sway/tree/workspace.h | 2 ++ sway/commands/move.c | 1 + sway/config/output.c | 5 +++++ sway/tree/output.c | 10 +++++----- sway/tree/workspace.c | 31 +++++++++++++++++++++++++++++++ 5 files changed, 44 insertions(+), 5 deletions(-) diff --git a/include/sway/tree/workspace.h b/include/sway/tree/workspace.h index 27ed649fd..76d205cd2 100644 --- a/include/sway/tree/workspace.h +++ b/include/sway/tree/workspace.h @@ -157,4 +157,6 @@ size_t workspace_num_sticky_containers(struct sway_workspace *ws); */ void workspace_squash(struct sway_workspace *workspace); +void workspace_reorient_auto(struct sway_workspace *ws); + #endif diff --git a/sway/commands/move.c b/sway/commands/move.c index 90e8585b4..fcd864673 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c @@ -641,6 +641,7 @@ static void workspace_move_to_output(struct sway_workspace *workspace, } output_add_workspace(output, workspace); + workspace_reorient_auto(workspace); // If moving the last workspace from the old output, create a new workspace // on the old output diff --git a/sway/config/output.c b/sway/config/output.c index 3d25b46c7..17e58037b 100644 --- a/sway/config/output.c +++ b/sway/config/output.c @@ -21,6 +21,7 @@ #include "sway/server.h" #include "sway/tree/arrange.h" #include "sway/tree/root.h" +#include "sway/tree/workspace.h" #include "log.h" #include "util.h" @@ -1086,6 +1087,10 @@ static bool apply_resolved_output_configs(struct matched_output_config *configs, struct matched_output_config *cfg = &configs[idx]; output_update_position(cfg->output); arrange_layers(cfg->output); + for (int i = 0; i < cfg->output->workspaces->length; i++) { + struct sway_workspace *ws = cfg->output->workspaces->items[i]; + workspace_reorient_auto(ws); + } } arrange_root(); diff --git a/sway/tree/output.c b/sway/tree/output.c index 90ec9331d..9c2f34c4f 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c @@ -41,6 +41,7 @@ static void restore_workspaces(struct sway_output *output) { if (highest == output) { workspace_detach(ws); output_add_workspace(output, ws); + workspace_reorient_auto(ws); ipc_event_workspace(NULL, ws, "move"); j--; } @@ -59,6 +60,7 @@ static void restore_workspaces(struct sway_output *output) { struct sway_workspace *ws = root->fallback_output->workspaces->items[0]; workspace_detach(ws); output_add_workspace(output, ws); + workspace_reorient_auto(ws); // If the floater was made floating while on the NOOP output, its width // and height will be zero and it should be reinitialized as a floating @@ -172,11 +174,8 @@ void output_enable(struct sway_output *output) { ipc_event_workspace(NULL, ws, "init"); } - if (ws && config->default_orientation == L_NONE) { - // Since the output transformation and resolution could have changed - // due to applying the output config, the previously set layout for the - // created workspace may not be correct for `default_orientation auto` - ws->layout = output_get_default_layout(output); + if (ws) { + workspace_reorient_auto(ws); } wl_signal_emit_mutable(&root->events.new_node, &output->node); @@ -241,6 +240,7 @@ static void output_evacuate(struct sway_output *output) { workspace_output_add_priority(workspace, new_output); output_add_workspace(new_output, workspace); + workspace_reorient_auto(workspace); output_sort_workspaces(new_output); ipc_event_workspace(NULL, workspace, "move"); diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 733a002b4..699ca3cf1 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -979,3 +979,34 @@ void workspace_squash(struct sway_workspace *workspace) { i += container_squash(child); } } + +void workspace_reorient_auto(struct sway_workspace *ws) { + if (config->default_orientation != L_NONE) { + return; + } + if (!ws->output) { + return; + } + if (ws->tiling->length > 1) { + return; + } + if (ws->layout == L_TABBED || ws->layout == L_STACKED) { + return; + } + + enum sway_container_layout new_layout = output_get_default_layout(ws->output); + if (ws->layout == new_layout) { + return; + } + ws->layout = new_layout; + workspace_update_representation(ws); + + if (ws->tiling->length == 1) { + struct sway_container *child = ws->tiling->items[0]; + if (!child->view && + (child->pending.layout == L_HORIZ || child->pending.layout == L_VERT)) { + child->pending.layout = new_layout; + container_update_representation(child); + } + } +}