target = target->parent;
}
- /* 3: if the target container is floating, we get the workspace instead.
- * Only tiling windows need to get inserted next to the current container.
- * */
- Con *floatingcon = con_inside_floating(target);
- if (floatingcon != NULL) {
+ /* 3: if the original target is the direct child of a floating container, we
+ * can't move con next to it - floating containers have only one child - so
+ * we get the workspace instead. */
+ if (target->type == CT_FLOATING_CON) {
DLOG("floatingcon, going up even further\n");
- target = floatingcon->parent;
+ orig_target = target;
+ target = target->parent;
}
if (con->type == CT_FLOATING_CON) {
($nodes, $focus) = get_ws_content($target_ws);
is(@{$nodes}, 1, 'tiling container moved to the target workspace');
+###############################################################################
+# Given 'S' and 'M' where 'M' is inside a floating container but not its direct
+# child, when 'S' is moved to 'M', i3 should not crash.
+# See issue: #3402
+###############################################################################
+
+$target_ws = fresh_workspace;
+$S = open_window;
+open_window;
+cmd 'splitv';
+$M = open_window;
+cmd 'mark target';
+cmd 'focus parent, floating enable, focus child';
+
+cmd '[id="' . $S->{id} . '"] move container to mark target';
+does_i3_live;
+
+# Note: this is not actively supported behavior.
+$nodes = get_ws($target_ws)->{floating_nodes}->[0]->{nodes}->[0]->{nodes};
+is(1, (grep { $_->{window} == $S->{id} } @{$nodes}), 'tiling container moved inside floating container');
+
###############################################################################
# Given 'S' and 'M' are the same container, when 'S' is moved to 'M', then
# the command is ignored.