tree/workspace: fix crash on dragging container to workspace edge

When a container is moved, `finalize_move` previously assumed that
calling `workspace_split` would always result in a workspace with exactly
1 child (the wrapper container). Consequently, it safely assumed that
inserting a container with `after = 1` was always valid.

However, if the moved container was the only child of its workspace,
calling `container_detach` drops the workspace's tiling length to 0.
Calling `workspace_split` on an empty workspace simply changes its
layout enum and returns, leaving the length at 0. Passing `after`
(which evaluates to 1 when moving right/down) into
`workspace_insert_tiling` then causes an out-of-bounds insertion and a
subsequent segmentation fault during `container_build_representation`.

This commit fixes the issue by dynamically calculating the insertion
index based on the actual length of the workspace's tiling list at the
moment of insertion, rather than overloading the `after` boolean flag
as a hardcoded index.
This commit is contained in:
Furkan Sahin 2026-02-01 21:53:06 -05:00
parent 909a2ddb5f
commit 73e821b93c

View file

@ -373,7 +373,7 @@ static void finalize_move(struct sway_seat *seat) {
enum sway_container_layout new_layout = edge == WLR_EDGE_TOP ||
edge == WLR_EDGE_BOTTOM ? L_VERT : L_HORIZ;
workspace_split(new_ws, new_layout);
workspace_insert_tiling(new_ws, con, after);
workspace_insert_tiling(new_ws, con, after ? new_ws->tiling->length : 0);
}
if (old_parent) {