Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add window resize to absolute values #6386

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions kitty/layout/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,9 @@ def calculate_bias_increment_for_a_single_cell(self, all_windows: WindowList, wi
def apply_bias(self, window_id: int, increment: float, all_windows: WindowList, is_horizontal: bool = True) -> bool:
return False

def apply_bias_abs(self, window_id: int, bias: float, all_windows: WindowList, is_horizontal: bool = True) -> bool:
return False

def remove_all_biases(self) -> bool:
return False

Expand All @@ -246,6 +249,12 @@ def modify_size_of_window(self, all_windows: WindowList, window_id: int, increme
return False
return self.apply_bias(idx, increment, all_windows, is_horizontal)

def modify_size_of_window_abs(self, all_windows: WindowList, window_id: int, bias: float, is_horizontal: bool = True) -> bool:
idx = all_windows.group_idx_for_window(window_id)
if idx is None:
return False
return self.apply_bias_abs(idx, bias, all_windows, is_horizontal)

def parse_layout_opts(self, layout_opts: Optional[str] = None) -> LayoutOpts:
data: Dict[str, str] = {}
if layout_opts:
Expand Down
82 changes: 73 additions & 9 deletions kitty/layout/splits.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ class Extent(NamedTuple):

class Pair:

def __init__(self, horizontal: bool = True):
def __init__(self, horizontal: bool = True, bias: float = 0.5):
self.horizontal = horizontal
self.one: Optional[Union[Pair, int]] = None
self.two: Optional[Union[Pair, int]] = None
self.bias = 0.5
self.bias = bias
self.top = self.left = self.width = self.height = 0
self.between_borders: List[Edges] = []
self.first_extent = self.second_extent = Extent()
Expand Down Expand Up @@ -119,17 +119,17 @@ def balanced_add(self, window_id: int) -> 'Pair':
q = self.one if one_count < two_count else self.two
return q.balanced_add(window_id)
if not isinstance(self.one, Pair) and not isinstance(self.two, Pair):
pair = Pair(horizontal=self.horizontal)
pair = Pair(horizontal=self.horizontal, bias=self.bias)
pair.balanced_add(self.one)
pair.balanced_add(self.two)
self.one, self.two = pair, window_id
return self
if isinstance(self.one, Pair):
window_to_be_split = self.two
self.two = pair = Pair(horizontal=self.horizontal)
self.two = pair = Pair(horizontal=self.horizontal, bias=self.bias)
else:
window_to_be_split = self.one
self.one = pair = Pair(horizontal=self.horizontal)
self.one = pair = Pair(horizontal=self.horizontal, bias=self.bias)
assert isinstance(window_to_be_split, int)
pair.balanced_add(window_to_be_split)
pair.balanced_add(window_id)
Expand All @@ -142,7 +142,7 @@ def split_and_add(self, existing_window_id: int, new_window_id: int, horizontal:
pair.horizontal = horizontal
self.one, self.two = q
else:
pair = Pair(horizontal=horizontal)
pair = Pair(horizontal=horizontal, bias=self.bias)
if self.one == existing_window_id:
self.one = pair
else:
Expand Down Expand Up @@ -258,6 +258,21 @@ def modify_size_of_child(self, which: int, increment: float, is_horizontal: bool
return parent.modify_size_of_child(which, increment, is_horizontal, layout_object)
return False

def set_size_of_child(self, which: int, bias: float, is_horizontal: bool, layout_object: 'Splits') -> bool:
if is_horizontal == self.horizontal and not self.is_redundant:
if which == 2:
bias = 1 - bias
new_bias = max(0.1, min(bias, 0.9))
if new_bias != self.bias:
self.bias = new_bias
return True
return False
parent = self.parent(layout_object.pairs_root)
if parent is not None:
which = 1 if parent.one is self else 2
return parent.set_size_of_child(which, bias, is_horizontal, layout_object)
return False

def borders_for_window(self, layout_object: 'Splits', window_id: int) -> Generator[Edges, None, None]:
is_first = self.one == window_id
if self.between_borders:
Expand Down Expand Up @@ -379,12 +394,17 @@ def edge_windows(self, edge: str) -> Generator[int, None, None]:
class SplitsLayoutOpts(LayoutOpts):

default_axis_is_horizontal: bool = True
bias: float = 0.5

def __init__(self, data: Dict[str, str]):
self.default_axis_is_horizontal = data.get('split_axis', 'horizontal') == 'horizontal'
self.bias = data.get('bias', 0.5)

def serialized(self) -> Dict[str, Any]:
return {'default_axis_is_horizontal': self.default_axis_is_horizontal}
return {
'default_axis_is_horizontal': self.default_axis_is_horizontal,
'bias': self.bias,
}


class Splits(Layout):
Expand All @@ -401,7 +421,7 @@ def default_axis_is_horizontal(self) -> bool:
def pairs_root(self) -> Pair:
root: Optional[Pair] = getattr(self, '_pairs_root', None)
if root is None:
self._pairs_root = root = Pair(horizontal=self.default_axis_is_horizontal)
self._pairs_root = root = Pair(horizontal=self.default_axis_is_horizontal, bias=self.layout_opts.bias)
return root

@pairs_root.setter
Expand Down Expand Up @@ -485,6 +505,22 @@ def modify_size_of_window(
which = 1 if pair.one == grp.id else 2
return pair.modify_size_of_child(which, increment, is_horizontal, self)

def modify_size_of_window_abs(
self,
all_windows: WindowList,
window_id: int,
bias: float,
is_horizontal: bool = True
) -> bool:
grp = all_windows.group_for_window(window_id)
if grp is None:
return False
pair = self.pairs_root.pair_for_window(grp.id)
if pair is None:
return False
which = 1 if pair.one == grp.id else 2
return pair.set_size_of_child(which, bias, is_horizontal, self)

def remove_all_biases(self) -> bool:
for pair in self.pairs_root.self_and_descendants():
pair.bias = 0.5
Expand Down Expand Up @@ -529,6 +565,26 @@ def move_window_to_group(self, all_windows: WindowList, group: int) -> bool:
self.pairs_root.swap_windows(before.id, after.id)
return moved

def apply_bias(self, window_id: int, increment: float, all_windows: WindowList, is_horizontal: bool = True) -> bool:
for pair in self.pairs_root.self_and_descendants():
if pair.one == window_id:
pair.modify_size_of_child(1, increment, is_horizontal, self)
return True
elif pair.two == window_id:
pair.modify_size_of_child(2, increment, is_horizontal, self)
return True
return False

def apply_bias_abs(self, window_id: int, bias: float, all_windows: WindowList, is_horizontal: bool = True) -> bool:
for pair in self.pairs_root.self_and_descendants():
if pair.one == window_id:
pair.set_size_of_child(1, bias, is_horizontal, self)
return True
elif pair.two == window_id:
pair.set_size_of_child(2, bias, is_horizontal, self)
return True
return False

def layout_action(self, action_name: str, args: Sequence[str], all_windows: WindowList) -> Optional[bool]:
if action_name == 'rotate':
args = args or ('90',)
Expand Down Expand Up @@ -556,7 +612,7 @@ def layout_action(self, action_name: str, args: Sequence[str], all_windows: Wind
wg = all_windows.active_group
if wg is not None:
self.remove_windows(wg.id)
new_root = Pair(horizontal)
new_root = Pair(horizontal, self.layout_opts.bias)
if which in ('left', 'top'):
new_root.balanced_add(wg.id)
new_root.two = self.pairs_root
Expand All @@ -565,6 +621,14 @@ def layout_action(self, action_name: str, args: Sequence[str], all_windows: Wind
new_root.two = wg.id
self.pairs_root = new_root
return True
if action_name == 'bias':
try:
bias = float(args[0]) / 100.0
for pair in self.pairs_root.self_and_descendants():
pair.set_size_of_child(1, bias, pair.horizontal, self)
return True
except Exception:
return False

return None

Expand Down
4 changes: 3 additions & 1 deletion kitty/options/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,9 @@ def resize_window(func: str, rest: str) -> FuncArgsType:
args = ['wider', 1]
else:
quality = vals[0].lower()
if quality not in ('reset', 'taller', 'shorter', 'wider', 'narrower'):
if quality not in ('reset',
'taller', 'shorter', 'wider', 'narrower',
'width', 'height'):
log_error(f'Invalid quality specification: {quality}')
quality = 'wider'
increment = 1
Expand Down
27 changes: 20 additions & 7 deletions kitty/tabs.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,22 +388,35 @@ def resize_window_by(self, window_id: int, increment: float, is_horizontal: bool
return None
return 'Could not resize'

def resize_window_to(self, window_id: int, bias: float, is_horizontal: bool) -> Optional[str]:
if self.current_layout.modify_size_of_window_abs(self.windows, window_id, bias, is_horizontal):
self.relayout()
return None
return 'Could not resize'

@ac('win', '''
Resize the active window by the specified amount

See :ref:`window_resizing` for details.
''')
def resize_window(self, quality: str, increment: int) -> None:
def resize_window(self, quality: str, quantity: int) -> None:
if quality == 'reset':
self.reset_window_sizes()
return
if increment < 1:
raise ValueError(increment)
is_horizontal = quality in ('wider', 'narrower')
increment *= 1 if quality in ('wider', 'taller') else -1
w = self.active_window
if w is not None and self.resize_window_by(
w.id, increment, is_horizontal) is not None:
if w is None: return

if quantity < 1:
raise ValueError(quantity)

if quality in ('width', 'height'):
if self.resize_window_to(w.id, float(quantity) / 100.0, quality == 'width') is not None:
if get_options().enable_audio_bell: ring_bell()
return

is_horizontal = quality in ('wider', 'narrower')
quantity *= 1 if quality in ('wider', 'taller') else -1
if self.resize_window_by(w.id, quantity, is_horizontal) is not None:
if get_options().enable_audio_bell:
ring_bell()

Expand Down