From 647b95631f518d56249e50d52d5c367f45f08ed9 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 3 Feb 2018 14:18:44 +0530 Subject: [PATCH] Add tests for layout operations with an overlay window --- kitty/layout.py | 20 +++++++-- kitty/tabs.py | 2 +- kitty_tests/layout.py | 101 +++++++++++++++++++++++++++++++++++------- 3 files changed, 102 insertions(+), 21 deletions(-) diff --git a/kitty/layout.py b/kitty/layout.py index ea795cdf5..0d0ba88d6 100644 --- a/kitty/layout.py +++ b/kitty/layout.py @@ -125,18 +125,30 @@ class Layout: self.set_active_window_in_os_window(active_window_idx) return active_window_idx - def remove_window(self, all_windows, window, current_active_window_idx): + def remove_window(self, all_windows, window, current_active_window_idx, swapped=False): try: active_window = all_windows[current_active_window_idx] except Exception: active_window = window - all_windows.remove(window) + if not swapped and window.overlay_for is not None: + nidx = idx_for_id(window.overlay_for, all_windows) + if nidx is not None: + idx = all_windows.index(window) + all_windows[nidx], all_windows[idx] = all_windows[idx], all_windows[nidx] + self.swap_windows_in_os_window(nidx, idx) + return self.remove_window(all_windows, window, current_active_window_idx, swapped=True) + + position = all_windows.index(window) + del all_windows[position] active_window_idx = None if window.overlay_for is not None: i = idx_for_id(window.overlay_for, all_windows) if i is not None: - active_window_idx = i - all_windows[i].overlay_window_id = None + overlaid_window = all_windows[i] + overlaid_window.overlay_window_id = None + if active_window is window: + active_window = overlaid_window + active_window_idx = idx_for_id(active_window.id, all_windows) if active_window_idx is None: if active_window is window: active_window_idx = max(0, min(current_active_window_idx, len(all_windows) - 1)) diff --git a/kitty/tabs.py b/kitty/tabs.py index ebfcf15bf..d92730790 100644 --- a/kitty/tabs.py +++ b/kitty/tabs.py @@ -154,8 +154,8 @@ class Tab: # {{{ self.remove_window(self.windows[self.active_window_idx]) def remove_window(self, window): - remove_window(self.os_window_id, self.id, window.id) self.active_window_idx = self.current_layout.remove_window(self.windows, window, self.active_window_idx) + remove_window(self.os_window_id, self.id, window.id) self.relayout_borders() glfw_post_empty_event() diff --git a/kitty_tests/layout.py b/kitty_tests/layout.py index bb8e1360e..35e2541a6 100644 --- a/kitty_tests/layout.py +++ b/kitty_tests/layout.py @@ -4,7 +4,7 @@ from . import BaseTest from kitty.config import defaults -from kitty.layout import Stack, Horizontal +from kitty.layout import Stack, Horizontal, idx_for_id class Window: @@ -35,26 +35,32 @@ def create_windows(num=5): return [Window(i + 1) for i in range(num)] +def utils(self, q, windows): + def ids(): + return [w.id for w in windows] + + def visible_ids(): + return {w.id for w in windows if w.is_visible_in_layout} + + def expect_ids(*a): + self.assertEqual(tuple(ids()), a) + + def check_visible(active_window_idx): + if q.only_active_window_visible: + self.ae(visible_ids(), {windows[active_window_idx].id}) + else: + self.ae(visible_ids(), {w.id for w in windows if w.overlay_window_id is None}) + return ids, visible_ids, expect_ids, check_visible + + class TestLayout(BaseTest): def do_ops_test(self, q): windows = create_windows() - - def ids(): - return [w.id for w in windows] - - def visible_ids(): - return {w.id for w in windows if w.is_visible_in_layout} - - def expect_ids(*a): - self.assertEqual(tuple(ids()), a) + ids, visible_ids, expect_ids, cv = utils(self, q, windows) def check_visible(): - if q.only_active_window_visible: - self.ae(visible_ids(), {windows[active_window_idx].id}) - else: - self.ae(visible_ids(), set(ids())) - + return cv(active_window_idx) active_window_idx = 0 # Test layout self.ae(q(windows, active_window_idx), active_window_idx) @@ -105,7 +111,70 @@ class TestLayout(BaseTest): self.ae(i, active_window_idx) check_visible() + def do_overlay_test(self, q): + windows = create_windows() + ids, visible_ids, expect_ids, cv = utils(self, q, windows) + + def check_visible(): + return cv(active_window_idx) + + def aidx(i): + return idx_for_id(visible_windows[i].id, windows) + + # Test add_window + w = Window(len(windows) + 1) + active_window_idx = 1 + w.overlay_for = windows[active_window_idx].id + windows[active_window_idx].overlay_window_id = w.id + active_window_idx = q.add_window(windows, w, active_window_idx) + self.ae(active_window_idx, 1) + expect_ids(1, 6, 3, 4, 5, 2) + check_visible() + # Test layout + self.ae(q(windows, active_window_idx), active_window_idx) + expect_ids(1, 6, 3, 4, 5, 2) + check_visible() + w = Window(len(windows) + 1) + active_window_idx = q.add_window(windows, w, active_window_idx) + self.ae(active_window_idx, 6) + visible_windows = [w for w in windows if w.overlay_window_id is None] + # Test nth_window + for i in range(len(visible_windows)): + active_window_idx = q.nth_window(windows, i) + self.ae(active_window_idx, aidx(i)) + expect_ids(1, 6, 3, 4, 5, 2, 7) + check_visible() + # Test next_window + for i in range(len(visible_windows)): + active_window_idx = q.next_window(windows, aidx(i)) + expected = (i + 1) % len(visible_windows) + self.ae(active_window_idx, aidx(expected)) + expect_ids(1, 6, 3, 4, 5, 2, 7) + check_visible() + # Test move_window + active_window_idx = q.move_window(windows, 4) + self.ae(active_window_idx, 6) + expect_ids(1, 6, 3, 4, 7, 2, 5) + check_visible() + # Test set_active_window + active_window_idx = q.set_active_window(windows, 0) + self.ae(active_window_idx, 0) + check_visible() + active_window_idx = q.set_active_window(windows, 5) + self.ae(active_window_idx, 1) + check_visible() + # Test remove_window + active_window_idx = q.remove_window(windows, windows[1], 1) + expect_ids(1, 2, 3, 4, 7, 5) + self.ae(active_window_idx, 1) + check_visible() + def test_layout_operations(self): for layout_class in Stack, Horizontal: - q = create_layout(Stack) + q = create_layout(layout_class) self.do_ops_test(q) + + def test_overlay_layout_operations(self): + for layout_class in Stack, Horizontal: + q = create_layout(layout_class) + self.do_overlay_test(q)