From 1decae2938f50c56d9fc164b42d335a3863ebb42 Mon Sep 17 00:00:00 2001 From: Juho Peltonen Date: Thu, 9 Jul 2020 10:18:57 +0300 Subject: [PATCH] Change splits layout neighbors to only include real neighbors --- kitty/layout/splits.py | 20 +++++++++++++++++--- kitty_tests/layout.py | 4 ++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/kitty/layout/splits.py b/kitty/layout/splits.py index 901dbf85e..4a99fa2d5 100644 --- a/kitty/layout/splits.py +++ b/kitty/layout/splits.py @@ -244,7 +244,7 @@ class Pair: return parent.modify_size_of_child(which, increment, is_horizontal, layout_object) return False - def neighbors_for_window(self, window_id: int, ans: NeighborsMap, layout_object: 'Splits') -> None: + def neighbors_for_window(self, window_id: int, ans: NeighborsMap, layout_object: 'Splits', all_windows: WindowList) -> None: def quadrant(is_horizontal: bool, is_first: bool) -> Tuple[EdgeLiteral, EdgeLiteral]: if is_horizontal: @@ -255,13 +255,27 @@ class Pair: return 'top', 'bottom' return 'bottom', 'top' + geometries = dict((group.id, group.geometry) for group in all_windows.groups if group.geometry) + def extend(other: Union[int, 'Pair', None], edge: EdgeLiteral, which: EdgeLiteral) -> None: if not ans[which] and other: if isinstance(other, Pair): - ans[which].extend(other.edge_windows(edge)) + neighbors = ( + w for w in other.edge_windows(edge) + if is_neighbouring_geometry(geometries[w], geometries[window_id], which)) + ans[which].extend(neighbors) else: ans[which].append(other) + def is_neighbouring_geometry(a: WindowGeometry, b: WindowGeometry, direction: str) -> bool: + def edges(g: WindowGeometry) -> Tuple[int, int]: + return (g.top, g.bottom) if direction in ['left', 'right'] else (g.left, g.right) + + a1, a2 = edges(a) + b1, b2 = edges(b) + + return a1 < b2 and a2 > b1 + other = self.two if self.one == window_id else self.one extend(other, *quadrant(self.horizontal, self.one == window_id)) @@ -418,7 +432,7 @@ class Splits(Layout): pair = self.pairs_root.pair_for_window(wg.id) ans: NeighborsMap = {'left': [], 'right': [], 'top': [], 'bottom': []} if pair is not None: - pair.neighbors_for_window(wg.id, ans, self) + pair.neighbors_for_window(wg.id, ans, self, all_windows) return ans def move_window(self, all_windows: WindowList, delta: Union[str, int] = 1) -> bool: diff --git a/kitty_tests/layout.py b/kitty_tests/layout.py index a9a2d8f14..7d82f372d 100644 --- a/kitty_tests/layout.py +++ b/kitty_tests/layout.py @@ -250,6 +250,10 @@ class TestLayout(BaseTest): self.ae(q.pairs_root.pair_for_window(2).horizontal, False) q.add_window(all_windows, Window(4), location='vsplit') windows = list(all_windows) + windows[0].set_geometry(WindowGeometry(0, 0, 10, 20, 0, 0)) + windows[1].set_geometry(WindowGeometry(11, 0, 20, 10, 0, 0)) + windows[2].set_geometry(WindowGeometry(11, 11, 15, 20, 0, 0)) + windows[3].set_geometry(WindowGeometry(16, 11, 20, 20, 0, 0)) self.ae(q.neighbors_for_window(windows[0], all_windows), {'left': [], 'right': [2, 3], 'top': [], 'bottom': []}) self.ae(q.neighbors_for_window(windows[1], all_windows), {'left': [1], 'right': [], 'top': [], 'bottom': [3, 4]}) self.ae(q.neighbors_for_window(windows[2], all_windows), {'left': [1], 'right': [4], 'top': [2], 'bottom': []})