Bare literal assignments (drag_overlay_mode = 'axis_y') cause mypy to
narrow-infer the type as Literal['axis_y'] on the parent class, making
the subclass override (Horizontal = 'axis_x', Fat = 'axis_x') an
incompatible assignment. Fix by explicitly annotating Vertical and Tall
with the full union type from the base class, so the declared type stays
wide and subclasses can freely assign any valid mode.
Also removes unused ClassVar/Literal imports from splits.py.
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)
Add --allow-fallback option to the map command that controls shifted
and ascii (alternate_key) fallback for individual key mappings.
For non-Latin keyboard layouts, when the current layout key is
non-ascii (codepoint > 127 and < 0xE000), the alternate_key from
the base layout is used for matching if the mapping opts in via
--allow-fallback=shifted,ascii.
Default kitty bindings use --allow-fallback=shifted,ascii so they
work out of the box with non-Latin layouts. User custom mappings
default to --allow-fallback=shifted (preserving existing shifted_key
behavior without ascii fallback).
--allow-fallback=none disables all fallback for a mapping.
Python side: parse_options_for_map() in options/utils.py handles flag
parsing, ShortcutMapping uses it in __init__. get_shortcut() filters
candidates by per-mapping allow_fallback.
Go side: ParseMap() handles --allow-fallback, KeyAction stores
AllowFallback, ShortcutTracker.Match passes it to matching.
MatchesParsedShortcut defaults to shifted,ascii for hardcoded shortcuts.
Migrated kittens (themes, command_palette, diff, choose_files) to
use ShortcutTracker with configurable map entries.
Tests added for Python (5 test methods) and Go (ParseMap + key matching).
Add --hints-text-background-color option (default: auto) that can apply
a background color to the matched text after the hint label. This makes
it more clear exactly which text each hint covers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two fixes:
1. boss.py: scope window drag is_dest to the receiving OS window only.
Previously all tab managers got is_dest=True with the same window-local
coordinates. Since every OS window's viewport starts at (0,0), a drag at
(x,y) in Window 1 also matched windows in Window 2 at the same coords,
causing spurious highlights and incorrect drop-target state in the second
window.
2. tabs.py: filter synthetic tab IDs (< 0) from all_tabs in on_tab_drop_move.
The '+' new-tab indicator uses tab_id=-1. If a tab drag started while
window_drag_active or tab_bar_show_new_tab_button was set, the -1 ended
up in tab_being_dropped.tab_ids, then tab_bar_data crashed with KeyError
when it tried tmap[-1].
According to
https://nixos.org/manual/nixpkgs/stable/#sec-darwin-legacy-frameworks,
the darwin.apple_sdk.framework namespace has been deprecated.
This commit updates shell.nix to be compatible with the nixos-unstable
channel on darwin. Tested by running `nix-shell --pure` and then `make`
inside that shell.