Horizontal extends Vertical, and Fat extends Tall. Declaring
drag_overlay_mode with a narrower Literal type in the subclass
conflicts with the parent's declared type, causing mypy error
"Incompatible types in assignment". Since the base Layout class already
declares the full union type, subclasses only need a bare assignment.
Also removes now-unused ClassVar and Literal imports from vertical.py,
tall.py, and grid.py.
Previously, body drops in all non-Splits layouts showed a full-window overlay
and performed a positional swap. This adds proper top/bottom or left/right
half-window overlays and true before/after insertion for the five layouts
Kovid identified.
Architecture:
- New `drag_overlay_mode` ClassVar on Layout ('full'|'axis_y'|'axis_x'|'free')
controls both overlay display and valid direction axis. Layout subclasses set
one line; tabs.py and boss.py dispatch on this attribute instead of hasattr.
- New `insert_window_group_next_to(target_group_id, after)` on WindowList
performs a positional insert (not swap) by popping the active group and
inserting it before or after the target.
- New base `insert_window_next_to` on Layout uses insert_window_group_next_to
for axis_x/axis_y layouts and falls back to swap for 'full' (Stack).
Splits overrides this with its existing tree-based implementation.
- `_insert_window_in_direction` in boss.py collapses from a 7-line hasattr
branch to a single layout.insert_window_next_to() call.
Direction constraints:
Vertical, Tall, Grid -> top/bottom (axis_y)
Horizontal, Fat -> left/right (axis_x)
Splits -> 4-way free (unchanged)
Stack -> full-window swap (unchanged)
placement_strategy previously only accepted 'center' and 'top-left', but
others are potentially useful too. I personally like 'bottom-left'. The
new set of accepted values mirrors the window_logo_position option.