Skip to content

Commit

Permalink
fix(core/tree): ensure push_in_with_neighbor() and merge_with_neighbo…
Browse files Browse the repository at this point in the history
…r_to_subtab() don't fail when there are no neighbor nodes
  • Loading branch information
aravinda0 committed Apr 15, 2024
1 parent 45a3601 commit 43913bb
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 18 deletions.
15 changes: 6 additions & 9 deletions src/qtile_bonsai/core/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -771,23 +771,23 @@ def resolve_node_neighbor_selection(
mode = NodeHierarchySelectionMode(selection_mode)
border_direction = Direction(border_direction)

adjacent_panes = self.adjacent_panes(node, border_direction, wrap=wrap)
if not adjacent_panes:
raise InvalidNodeSelectionError("There is no neighbor node to select.")

if mode == NodeHierarchySelectionMode.mru_deepest:
adjacent_panes = self.adjacent_panes(node, border_direction, wrap=wrap)
resolved_node = self.find_mru_pane(panes=adjacent_panes)
elif mode == NodeHierarchySelectionMode.mru_largest:
besp = self.find_border_encompassing_supernode(
node, border_direction, stop_at_tc=False
)
if besp is None:
raise InvalidNodeSelectionError("There is no suitable node to select.")
assert besp is not None
resolved_node = besp.sibling(border_direction.axis_unit, wrap=wrap)
elif mode == NodeHierarchySelectionMode.mru_subtab_else_deepest:
adjacent_panes = self.adjacent_panes(node, border_direction, wrap=wrap)
deepest = self.find_mru_pane(panes=adjacent_panes)
tc = deepest.get_first_ancestor(TabContainer)
resolved_node = tc if tc.tab_level > 1 else deepest
elif mode == NodeHierarchySelectionMode.mru_subtab_else_largest:
adjacent_panes = self.adjacent_panes(node, border_direction, wrap=wrap)
deepest = self.find_mru_pane(panes=adjacent_panes)
tc = deepest.get_first_ancestor(TabContainer)
if tc.tab_level > 1:
Expand All @@ -796,10 +796,7 @@ def resolve_node_neighbor_selection(
besp = self.find_border_encompassing_supernode(
node, border_direction, stop_at_tc=False
)
if besp is None:
raise InvalidNodeSelectionError(
"There is no suitable node to select."
)
assert besp is not None
resolved_node = besp.sibling(border_direction.axis_unit, wrap=wrap)
else:
raise ValueError(f"Invalid `selection_mode`: {selection_mode}")
Expand Down
20 changes: 12 additions & 8 deletions src/qtile_bonsai/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -734,13 +734,17 @@ def merge_to_subtab(
if self._tree.is_empty:
return

self._tree.merge_with_neighbor_to_subtab(
self.focused_pane,
direction,
src_selection_mode=src_selection_mode,
dest_selection_mode=dest_selection_mode,
normalize=normalize,
)
try:
self._tree.merge_with_neighbor_to_subtab(
self.focused_pane,
direction,
src_selection_mode=src_selection_mode,
dest_selection_mode=dest_selection_mode,
normalize=normalize,
)
except InvalidNodeSelectionError:
return

self._request_relayout()

@expose_command
Expand All @@ -749,7 +753,7 @@ def push_in(
direction: DirectionParam,
*,
src_selection_mode: NodeHierarchySelectionMode = NodeHierarchySelectionMode.mru_deepest,
dest_selection_mode: NodeHierarchySelectionMode = NodeHierarchySelectionMode.mru_largest,
dest_selection_mode: NodeHierarchySelectionMode = NodeHierarchySelectionMode.mru_deepest,
normalize: bool = True,
wrap: bool = True,
):
Expand Down
19 changes: 18 additions & 1 deletion tests/unit/core/test_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
import pytest

import tests.data.tree_state
from qtile_bonsai.core.geometry import Rect
from qtile_bonsai.core.geometry import Direction, Rect
from qtile_bonsai.core.tree import (
InvalidNodeSelectionError,
NodeHierarchySelectionMode,
Pane,
Tab,
Expand Down Expand Up @@ -5351,6 +5352,22 @@ def test_given_deep_tree_when_src_is_sc_with_inv_axis_of_dest_push_axis(
assert cb_remove.mock_calls == [mock.call([sc_y_to_prune])]


class TestResolveNodeNeighborSelection:
@pytest.mark.parametrize("selection_mode", list(NodeHierarchySelectionMode))
def test_when_there_are_no_adjacent_nodes_then_error_is_raised(
self, tree: Tree, selection_mode: NodeHierarchySelectionMode
):
p1 = tree.tab()

err_msg = "There is no neighbor node to select"
with pytest.raises(InvalidNodeSelectionError, match=err_msg):
tree.resolve_node_neighbor_selection(
p1,
selection_mode,
Direction.right,
)


class TestConfig:
def test_when_config_is_passed_on_init_then_it_overrides_default_config(self):
# Default window.margin is 0
Expand Down

0 comments on commit 43913bb

Please sign in to comment.