Refactor tmux.fix_layout()
The new code better determines all sizes with splits taken into account. The non-perfect divisions are also considered when splitting horizontally.
This commit is contained in:
parent
203ad715e0
commit
20a0881421
1 changed files with 46 additions and 51 deletions
|
|
@ -45,7 +45,10 @@ def fix_layout(
|
|||
clear_on_resize: bool = False,
|
||||
forced: bool = False,
|
||||
) -> None:
|
||||
"""Fix pane sizes based on layout."""
|
||||
"""Fix pane sizes based on layout.
|
||||
|
||||
NOTE: The magic +/- 1 values are for the split rows/columns.
|
||||
"""
|
||||
resize_kwargs = []
|
||||
|
||||
# Bail early
|
||||
|
|
@ -61,33 +64,49 @@ def fix_layout(
|
|||
for data in layout.values():
|
||||
data['Panes'] = [pane for pane in data['Panes'] if poll_pane(pane)]
|
||||
|
||||
# Calc height for "floating" row
|
||||
# NOTE: We start with height +1 to account for the splits (i.e. splits = num rows - 1)
|
||||
floating_height = 1 + get_window_size()[1]
|
||||
for group in ('Title', 'Info', 'Current', 'Workers'):
|
||||
if layout[group]['Panes']:
|
||||
group_height = 1 + layout[group].get('height', 0)
|
||||
if group == 'Workers':
|
||||
group_height *= len(layout[group]['Panes'])
|
||||
floating_height -= group_height
|
||||
|
||||
# Update main panes
|
||||
for section, data in layout.items():
|
||||
# "Floating" pane(s)
|
||||
if 'height' not in data and section in ('Info', 'Current', 'Workers'):
|
||||
for pane_id in data['Panes']:
|
||||
resize_kwargs.append({'pane_id': pane_id, 'height': floating_height})
|
||||
|
||||
# Rest of the panes
|
||||
if section == 'Workers':
|
||||
# Skip for now
|
||||
# Calculate constraints
|
||||
avail_horizontal, avail_vertical = get_window_size()
|
||||
avail_vertical -= layout['Current'].get('height', 0)
|
||||
for group in ('Title', 'Info'):
|
||||
if not layout[group]['Panes']:
|
||||
continue
|
||||
if 'height' in data:
|
||||
avail_vertical -= layout[group].get('height', 0) + 1
|
||||
num_workers = len(layout['Workers']['Panes'])
|
||||
avail_vertical -= num_workers * (layout['Workers'].get('height', 0) + 1)
|
||||
avail_horizontal -= layout['Started']['width'] + 1
|
||||
|
||||
# Fix heights
|
||||
for group, data in layout.items():
|
||||
if not data['Panes'] or group in ('Started', 'Progress'):
|
||||
continue
|
||||
resize_kwargs.append(
|
||||
{'pane_id': data['Panes'][0], 'height': data.get('height', avail_vertical)}
|
||||
)
|
||||
if group == 'Workers' and len(data['Panes']) > 1:
|
||||
for pane_id in data['Panes'][1:]:
|
||||
resize_kwargs.append(
|
||||
{'pane_id': pane_id, 'height': data.get('height', avail_vertical)}
|
||||
)
|
||||
|
||||
# Fix widths
|
||||
for group in ('Started', 'Progress'):
|
||||
resize_kwargs.append(
|
||||
{'pane_id': layout[group]['Panes'][0], 'width': layout[group]['width']}
|
||||
)
|
||||
for group, data in layout.items():
|
||||
num_panes = len(data['Panes'])
|
||||
if num_panes < 2 or group not in ('Title', 'Info'):
|
||||
continue
|
||||
avail_horizontal -= (num_panes - 1)
|
||||
pane_width, remainder = divmod(avail_horizontal, num_panes)
|
||||
for pane_id in data['Panes']:
|
||||
resize_kwargs.append({'pane_id': pane_id, 'height': data['height']})
|
||||
if 'width' in data:
|
||||
for pane_id in data['Panes']:
|
||||
resize_kwargs.append({'pane_id': pane_id, 'width': data['width']})
|
||||
new_width = pane_width
|
||||
if remainder > 0:
|
||||
new_width += 1
|
||||
remainder -= 1
|
||||
resize_kwargs.append({'pane_id': pane_id, 'width': new_width})
|
||||
|
||||
# Resize panes
|
||||
for kwargs in resize_kwargs:
|
||||
try:
|
||||
resize_pane(**kwargs)
|
||||
|
|
@ -95,30 +114,6 @@ def fix_layout(
|
|||
# Assuming pane was closed just before resizing
|
||||
pass
|
||||
|
||||
# Update "group" panes widths
|
||||
for group in ('Title', 'Info'):
|
||||
num_panes = len(layout[group]['Panes'])
|
||||
if num_panes <= 1:
|
||||
continue
|
||||
width = int( (get_pane_size()[0] - (1 - num_panes)) / num_panes )
|
||||
for pane_id in layout[group]['Panes']:
|
||||
resize_pane(pane_id, width=width)
|
||||
if group == 'Title':
|
||||
# (re)fix Started pane
|
||||
resize_pane(layout['Started']['Panes'][0], width=layout['Started']['width'])
|
||||
|
||||
# Bail early
|
||||
if not (
|
||||
layout['Workers']['Panes']
|
||||
and 'height' in layout['Workers']
|
||||
and floating_height > 0
|
||||
):
|
||||
return
|
||||
|
||||
# Update worker heights
|
||||
for worker in reversed(layout['Workers']['Panes']):
|
||||
resize_pane(worker, height=layout['Workers']['height'])
|
||||
|
||||
|
||||
def get_pane_size(pane_id: str | None = None) -> tuple[int, int]:
|
||||
"""Get current or target pane size, returns tuple."""
|
||||
|
|
|
|||
Loading…
Reference in a new issue