Track window neighbors

This commit is contained in:
Kovid Goyal
2018-07-05 14:43:18 +05:30
parent fcb0033d25
commit f0f1c911ea
2 changed files with 104 additions and 5 deletions

View File

@@ -332,6 +332,9 @@ class Layout: # {{{
windows = all_windows
self.update_visibility(all_windows, active_window, overlaid_windows)
self.blank_rects = []
for w in all_windows:
w.border_widths.reset(self.border_width)
w.neighbors.reset()
self.do_layout(windows, active_window_idx)
return idx_for_id(active_window.id, all_windows)
@@ -435,6 +438,15 @@ class Tall(Layout): # {{{
def do_layout(self, windows, active_window_idx):
if len(windows) == 1:
return self.layout_single_window(windows[0])
# setup neighbors
if len(windows) == 2:
windows[0].neighbors.right = windows[1]
windows[1].neighbors.left = windows[0]
else:
num = len(windows)
for i in range(1, num - 1):
windows[i].neighbors.bottom = windows[i+1]
windows[i+1].neighbors.top = windows[i]
xlayout = self.xlayout(2, bias=self.main_bias)
xstart, xnum = next(xlayout)
ystart, ynum = next(self.vlayout(1))
@@ -464,6 +476,15 @@ class Fat(Tall): # {{{
def do_layout(self, windows, active_window_idx):
if len(windows) == 1:
return self.layout_single_window(windows[0])
# setup neighbors
if len(windows) == 2:
windows[0].neighbors.bottom = windows[1]
windows[1].neighbors.top = windows[0]
else:
num = len(windows)
for i in range(1, num - 1):
windows[i].neighbors.right = windows[i+1]
windows[i+1].neighbors.left = windows[i]
xstart, xnum = next(self.xlayout(1))
ylayout = self.ylayout(2, bias=self.main_bias)
ystart, ynum = next(ylayout)
@@ -597,8 +618,33 @@ class Grid(Layout): # {{{
for i in range(ncols - 1):
self.between_blank_rect(win_col_map[i][0], win_col_map[i + 1][0])
self.setup_neighbors(special_rows, nrows, win_col_map)
class Vertical(Layout):
def setup_neighbors(self, special_rows, nrows, win_col_map):
ncols = len(win_col_map)
def vertical_neighbors(windows):
for i in range(0, len(windows) - 1):
windows[i].neighbors.bottom = windows[i+1]
windows[i+1].neighbors.top = windows[i]
if ncols <= 1:
vertical_neighbors(win_col_map[0])
else:
if special_rows != nrows:
win_col_map = [cm for cm in win_col_map if len(cm) == nrows]
ncols = len(win_col_map)
for i, col_windows in enumerate(win_col_map):
vertical_neighbors(col_windows)
if i < ncols - 1:
next_col = win_col_map[i + 1]
for w, neighbor in zip(col_windows, next_col):
w.neighbors.right = neighbor
neighbor.neighbors.left = w
# }}}
class Vertical(Layout): # {{{
name = 'vertical'
main_is_horizontal = False
@@ -629,6 +675,11 @@ class Vertical(Layout):
window_count = len(windows)
if window_count == 1:
return self.layout_single_window(windows[0])
# setup neighbors
num = len(windows)
for i in range(num - 1):
windows[i].neighbors.bottom = windows[i+1]
windows[i + 1].neighbors.top = windows[i]
xlayout = self.xlayout(1)
xstart, xnum = next(xlayout)
@@ -640,9 +691,10 @@ class Vertical(Layout):
# left, top and right blank rects
self.simple_blank_rects(windows[0], windows[-1])
# }}}
class Horizontal(Vertical):
class Horizontal(Vertical): # {{{
name = 'horizontal'
main_is_horizontal = True
@@ -652,6 +704,11 @@ class Horizontal(Vertical):
window_count = len(windows)
if window_count == 1:
return self.layout_single_window(windows[0])
# setup neighbors
num = len(windows)
for i in range(num - 1):
windows[i].neighbors.right = windows[i+1]
windows[i + 1].neighbors.left = windows[i]
xlayout = self.variable_layout(window_count, self.biased_map)
ylayout = self.ylayout(1)

View File

@@ -7,7 +7,8 @@ import os
import sys
import weakref
from collections import deque
from enum import Enum
from enum import IntEnum
from operator import attrgetter
from .child import cwd_of_process
from .config import build_ansi_color_table
@@ -33,10 +34,49 @@ from .utils import (
)
class DynamicColor(Enum):
class DynamicColor(IntEnum):
default_fg, default_bg, cursor_color, highlight_fg, highlight_bg = range(1, 6)
def _none():
pass
def neighbor_property(which):
getter = attrgetter(which)
def fget(self):
return getter(self)()
def fset(self, window):
setattr(self, which, (_none if window is None else weakref.ref(window)))
return property(fget=fget, fset=fset)
class Neighbors:
__slots__ = '_left', '_top', '_right', '_bottom'
def __init__(self):
self.reset()
def reset(self):
self._left = self._top = self._right = self._bottom = _none
left, top, right, bottom = map(neighbor_property, __slots__)
class Widths:
__slots__ = 'left', 'top', 'right', 'bottom'
def __init__(self, val=0):
self.reset(val)
def reset(self, val=0):
self.left = self.top = self.right = self.bottom = val
DYNAMIC_COLOR_CODES = {
10: DynamicColor.default_fg,
11: DynamicColor.default_bg,
@@ -94,6 +134,8 @@ class Window:
def __init__(self, tab, child, opts, args, override_title=None):
self.action_on_close = None
self.border_widths = Widths()
self.neighbors = Neighbors()
self.needs_attention = False
self.override_title = override_title
self.overlay_window_id = None
@@ -101,12 +143,12 @@ class Window:
self.default_title = os.path.basename(child.argv[0] or appname)
self.child_title = self.default_title
self.id = add_window(tab.os_window_id, tab.id, self.title)
self.clipboard_control_buffers = {'p': '', 'c': ''}
if not self.id:
raise Exception('No tab with id: {} in OS Window: {} was found, or the window counter wrapped'.format(tab.id, tab.os_window_id))
self.tab_id = tab.id
self.os_window_id = tab.os_window_id
self.tabref = weakref.ref(tab)
self.clipboard_control_buffers = {'p': '', 'c': ''}
self.destroyed = False
self.click_queue = deque(maxlen=3)
self.geometry = WindowGeometry(0, 0, 0, 0, 0, 0)