diff --git a/libqtile/layout/screensplit.py b/libqtile/layout/screensplit.py index 97ca9d3ac9..46aedc346d 100644 --- a/libqtile/layout/screensplit.py +++ b/libqtile/layout/screensplit.py @@ -120,7 +120,7 @@ def __init__(self, **config): self._split_index = 0 self.layouts = {} self._move_win = None - self._has_matches = False + self._has_matches = None print(self.splits) splits = [] for s in self.splits: @@ -134,6 +134,13 @@ def __init__(self, **config): def _should_check(self, win): return win not in self.layouts and self._move_win is None + @property + def has_matches(self): + if self._has_matches is None: + self._has_matches = any(split.matches for split in self.splits) + + return self._has_matches + @property def active_split(self): return self.splits[self._split_index] @@ -201,7 +208,7 @@ def add_client(self, win: Window) -> None: split = None # If this is a new window and we're not moving this window between splits # then we should check for match rules - if self._has_matches and self._should_check(win): + if self.has_matches and self._should_check(win): split = self._match_win(win) if split is not None: diff --git a/test/layouts/test_screensplit.py b/test/layouts/test_screensplit.py index a19c6c4e96..fc3fb08aee 100644 --- a/test/layouts/test_screensplit.py +++ b/test/layouts/test_screensplit.py @@ -26,79 +26,110 @@ from test.layouts.layout_utils import assert_dimensions -class ScreenSplitConfig(Config): - auto_fullscreen = True - groups = [libqtile.config.Group("a")] - layouts = [layout.ScreenSplit()] - floating_layout = libqtile.resources.default_config.floating_layout - keys = [] - mouse = [] - screens = [] - follow_mouse_focus = False +@pytest.fixture(scope="function") +def ss_manager(manager_nospawn, request): + class ScreenSplitConfig(Config): + auto_fullscreen = True + groups = [libqtile.config.Group("a")] + layouts = [layout.ScreenSplit(**getattr(request, "param", dict()))] + floating_layout = libqtile.resources.default_config.floating_layout + keys = [] + mouse = [] + screens = [] + follow_mouse_focus = False + manager_nospawn.start(ScreenSplitConfig) -screensplit_config = pytest.mark.parametrize("manager", [ScreenSplitConfig], indirect=True) + yield manager_nospawn -@screensplit_config -def test_screensplit(manager): +def ss_config(**kwargs): + return pytest.mark.parametrize("ss_manager", [kwargs], indirect=True) + + +@ss_config() +def test_screensplit(ss_manager): # Max layout is default, occupies top half of screen - assert manager.c.layout.info()["current_layout"] == "max" - manager.test_window("one") - assert_dimensions(manager, 0, 0, 800, 300) - manager.test_window("two") - assert_dimensions(manager, 0, 0, 800, 300) - assert manager.c.layout.info()["current_clients"] == ["one", "two"] + assert ss_manager.c.layout.info()["current_layout"] == "max" + ss_manager.test_window("one") + assert_dimensions(ss_manager, 0, 0, 800, 300) + ss_manager.test_window("two") + assert_dimensions(ss_manager, 0, 0, 800, 300) + assert ss_manager.c.layout.info()["current_clients"] == ["one", "two"] - manager.c.layout.next_split() - assert manager.c.layout.info()["current_layout"] == "columns" - assert manager.c.layout.info()["current_clients"] == [] + ss_manager.c.layout.next_split() + assert ss_manager.c.layout.info()["current_layout"] == "columns" + assert ss_manager.c.layout.info()["current_clients"] == [] # Columns layout has no border on single... - manager.test_window("three") - assert_dimensions(manager, 0, 300, 800, 300) + ss_manager.test_window("three") + assert_dimensions(ss_manager, 0, 300, 800, 300) # ... but a border of 2 when multiple windows - manager.test_window("four") - assert_dimensions(manager, 400, 300, 396, 296) - assert manager.c.layout.info()["current_clients"] == ["three", "four"] + ss_manager.test_window("four") + assert_dimensions(ss_manager, 400, 300, 396, 296) + assert ss_manager.c.layout.info()["current_clients"] == ["three", "four"] - manager.c.layout.next_split() - assert manager.c.layout.info()["current_layout"] == "max" - assert manager.c.layout.info()["current_clients"] == ["one", "two"] + ss_manager.c.layout.next_split() + assert ss_manager.c.layout.info()["current_layout"] == "max" + assert ss_manager.c.layout.info()["current_clients"] == ["one", "two"] -@screensplit_config -def test_commands_passthrough(manager): - assert manager.c.layout.info()["current_layout"] == "max" - assert "grow_left" not in manager.c.layout.commands() +@ss_config() +def test_commands_passthrough(ss_manager): + assert ss_manager.c.layout.info()["current_layout"] == "max" + assert "grow_left" not in ss_manager.c.layout.commands() - manager.c.layout.next_split() - assert manager.c.layout.info()["current_layout"] == "columns" + ss_manager.c.layout.next_split() + assert ss_manager.c.layout.info()["current_layout"] == "columns" - manager.test_window("one") - assert_dimensions(manager, 0, 300, 800, 300) - manager.test_window("two") - assert_dimensions(manager, 400, 300, 396, 296) + ss_manager.test_window("one") + assert_dimensions(ss_manager, 0, 300, 800, 300) + ss_manager.test_window("two") + assert_dimensions(ss_manager, 400, 300, 396, 296) - assert "grow_left" in manager.c.layout.commands() + assert "grow_left" in ss_manager.c.layout.commands() # Grow window by 40 pixels - manager.c.layout.grow_left() - assert_dimensions(manager, 360, 300, 436, 296) - - -@screensplit_config -def test_move_window_to_split(manager): - assert manager.c.layout.info()["current_layout"] == "max" - manager.test_window("one") - assert_dimensions(manager, 0, 0, 800, 300) - - manager.c.layout.move_window_to_next_split() - assert manager.c.layout.info()["current_layout"] == "columns" - assert_dimensions(manager, 0, 300, 800, 300) - - manager.c.layout.move_window_to_previous_split() - assert manager.c.layout.info()["current_layout"] == "max" - assert_dimensions(manager, 0, 0, 800, 300) + ss_manager.c.layout.grow_left() + assert_dimensions(ss_manager, 360, 300, 436, 296) + + +@ss_config() +def test_move_window_to_split(ss_manager): + assert ss_manager.c.layout.info()["current_layout"] == "max" + ss_manager.test_window("one") + assert_dimensions(ss_manager, 0, 0, 800, 300) + + ss_manager.c.layout.move_window_to_next_split() + assert ss_manager.c.layout.info()["current_layout"] == "columns" + assert_dimensions(ss_manager, 0, 300, 800, 300) + + ss_manager.c.layout.move_window_to_previous_split() + assert ss_manager.c.layout.info()["current_layout"] == "max" + assert_dimensions(ss_manager, 0, 0, 800, 300) + + +@ss_config( + splits=[ + { + "name": "no_match", + "rect": (0, 0, 1, 0.5), + "layout": layout.Max(), + }, + { + "name": "match", + "rect": (0, 0.5, 1, 0.5), + "layout": layout.Spiral(), + "matches": [Match(title="test")], + }, + ] +) +def test_match_window(ss_manager): + assert ss_manager.c.layout.info()["current_layout"] == "max" + ss_manager.test_window("one") + assert ss_manager.c.layout.info()["current_layout"] == "max" + + ss_manager.test_window("test") + assert ss_manager.c.layout.info()["current_layout"] == "spiral" def test_invalid_splits():