@@ -1527,3 +1527,151 @@ def test_focus_shift_completion(hlwm):
15271527 # actually, passing both -i and -e makes no sense,
15281528 # but ArgParse does not know that the flags exclude each other
15291529 hlwm .command_has_all_args ([cmd , 'down' , '-i' , '-e' ])
1530+
1531+
1532+ def test_frame_leaf_selection_change (hlwm ):
1533+ """test the attribute FrameLeaf::selection"""
1534+ clients = hlwm .create_clients (3 )
1535+
1536+ def layout (idx ):
1537+ return f"(clients vertical:{ idx } { clients [0 ]} { clients [1 ]} { clients [2 ]} )"
1538+
1539+ hlwm .call (['load' , layout (0 )])
1540+
1541+ for i in range (0 , 3 ):
1542+ hlwm .attr .tags .focus .tiling .focused_frame .selection = i
1543+ assert hlwm .attr .clients .focus .winid () == clients [i ]
1544+ assert hlwm .call ('dump' ).stdout == layout (i )
1545+
1546+
1547+ def test_frame_leaf_selection_if_empty (hlwm ):
1548+ assert hlwm .attr .tags .focus .tiling .root .selection () == '0'
1549+ hlwm .attr .tags .focus .tiling .root .selection = 0
1550+ assert hlwm .attr .tags .focus .tiling .root .selection () == '0'
1551+
1552+ hlwm .call_xfail ('attr tags.focus.tiling.root.selection 1' ) \
1553+ .expect_stderr ('out of range' )
1554+
1555+ hlwm .call_xfail ('attr tags.focus.tiling.root.selection 2' ) \
1556+ .expect_stderr ('out of range' )
1557+
1558+ hlwm .call_xfail ('attr tags.focus.tiling.root.selection -1' ) \
1559+ .expect_stderr ('out of range' )
1560+
1561+
1562+ def test_frame_split_selection_change (hlwm ):
1563+ """test the attribute FrameSplit::selection"""
1564+ clients = hlwm .create_clients (2 )
1565+
1566+ def layout (idx ):
1567+ return normalize_layout_string (f"""
1568+ (split horizontal:0.5:{ idx }
1569+ (clients vertical:0 { clients [0 ]} )
1570+ (clients vertical:0 { clients [1 ]} ))
1571+ """ )
1572+
1573+ hlwm .call (['load' , layout (0 )])
1574+
1575+ for i in [0 , 1 ]:
1576+ hlwm .attr .tags .focus .tiling .root .selection = i
1577+ assert hlwm .attr .clients .focus .winid () == clients [i ]
1578+ assert hlwm .call ('dump' ).stdout == layout (i )
1579+
1580+
1581+ def test_frame_selection_invalid_arg (hlwm ):
1582+ hlwm .create_clients (6 ) # 6 clients
1583+ hlwm .call ('split explode' ) # 2 frames, so 3 clients per frame
1584+ hlwm .call ('dump' )
1585+
1586+ # for frame splits, the selection can be 0 or 1
1587+ hlwm .call ('attr tags.focus.tiling.root.selection 0' ) # no failure
1588+ hlwm .call ('attr tags.focus.tiling.root.selection 1' ) # no failure
1589+ hlwm .call_xfail ('attr tags.focus.tiling.root.selection -1' ) \
1590+ .expect_stderr ('out of range' )
1591+ hlwm .call_xfail ('attr tags.focus.tiling.root.selection 2' ) \
1592+ .expect_stderr ('out of range' )
1593+
1594+ # for frame leafs, the selection only must be lower than the client count
1595+ hlwm .call ('attr tags.focus.tiling.focused_frame.selection 0' ) # no failure
1596+ hlwm .call ('attr tags.focus.tiling.focused_frame.selection 1' ) # no failure
1597+ hlwm .call ('attr tags.focus.tiling.focused_frame.selection 2' ) # no failure
1598+ hlwm .call_xfail ('attr tags.focus.tiling.focused_frame.selection -1' ) \
1599+ .expect_stderr ('out of range' )
1600+ hlwm .call_xfail ('attr tags.focus.tiling.focused_frame.selection 3' ) \
1601+ .expect_stderr ('out of range' )
1602+
1603+
1604+ def test_frame_split_attribute_size_changes (hlwm , x11 ):
1605+ """
1606+ Test that changing the attributes 'fraction' or 'split_type' of FrameSplit
1607+ affects window sizes
1608+ """
1609+ # two clients side by side:
1610+ win1 , winid1 = x11 .create_client ()
1611+ win2 , winid2 = x11 .create_client ()
1612+ layout = f'(split horizontal:0.5:0 (clients max:0 { winid1 } ) (clients max:0 { winid2 } ))'
1613+ layout = normalize_layout_string (layout )
1614+ for attr , value in [('fraction' , '0.6' ), ('split_type' , 'vertical' )]:
1615+ hlwm .call (['load' , layout ])
1616+ x11 .sync_with_hlwm ()
1617+ width1 = win1 .get_geometry ().width
1618+ width2 = win2 .get_geometry ().width
1619+
1620+ hlwm .attr .tags .focus .tiling .root [attr ] = value
1621+ assert hlwm .attr .tags .focus .tiling .root [attr ]() == value
1622+ assert hlwm .call ('dump' ).stdout .strip () != layout
1623+
1624+ x11 .sync_with_hlwm ()
1625+ # both updated attributes must lead to an increase of width of
1626+ # the first client:
1627+ assert width1 < win1 .get_geometry ().width
1628+ assert width2 != win2 .get_geometry ().width
1629+
1630+
1631+ def test_frame_split_fraction_invalid_arg (hlwm ):
1632+ hlwm .call (['load' , '(split horizontal:0.5:0 (clients max:0) (clients max:0))' ])
1633+
1634+ # test values that clamp to 0.1
1635+ for val in ['0.0' , '0' , '-0.1' , '0.05' , '0.1' , '0.09' , '-5' , '-0.11' ]:
1636+ # reset the fraction
1637+ hlwm .attr .tags .focus .tiling .root .fraction = '0.5'
1638+ assert hlwm .attr .tags .focus .tiling .root .fraction () == '0.5'
1639+
1640+ hlwm .attr .tags .focus .tiling .root .fraction = val
1641+ assert hlwm .attr .tags .focus .tiling .root .fraction () == '0.1'
1642+
1643+ # test values that clamp to 0.9
1644+ for val in ['12' , '1' , '0.9' , '0.95' , '0.9' , '0.91' , '12312' , '+23' ]:
1645+ # reset the fraction
1646+ hlwm .attr .tags .focus .tiling .root .fraction = '0.87'
1647+ assert hlwm .attr .tags .focus .tiling .root .fraction () == '0.87'
1648+
1649+ hlwm .attr .tags .focus .tiling .root .fraction = val
1650+ assert hlwm .attr .tags .focus .tiling .root .fraction () == '0.9'
1651+
1652+
1653+ def test_frame_leaf_algorithm_change (hlwm , x11 ):
1654+ """
1655+ Test that changing the layout algorithm affects window sizes
1656+ """
1657+ # two clients below each other
1658+ win1 , winid1 = x11 .create_client ()
1659+ win2 , winid2 = x11 .create_client ()
1660+ hlwm .call ('set_layout vertical' )
1661+
1662+ geom1_before = win1 .get_geometry ()
1663+ geom2_before = win2 .get_geometry ()
1664+ assert geom1_before .width == geom2_before .width
1665+ assert geom1_before .height == geom2_before .height
1666+
1667+ # put them side by side
1668+ hlwm .attr .tags .focus .tiling .root .algorithm = 'horizontal'
1669+
1670+ x11 .sync_with_hlwm ()
1671+ geom1_now = win1 .get_geometry ()
1672+ geom2_now = win2 .get_geometry ()
1673+ # side by side implies: width decreases but height increases
1674+ assert geom1_before .width > geom1_now .width
1675+ assert geom1_before .height < geom1_now .height
1676+ assert geom1_now .width == geom2_now .width
1677+ assert geom1_now .height == geom2_now .height
0 commit comments