From 18804efb7e0596860ba7eb946cc641fbf2a17e01 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 6 Jul 2018 17:14:25 +0530 Subject: [PATCH] Let the layout control which window borders are drawn --- kitty/borders.py | 50 +++++++++++++++++++---------------- kitty/layout.py | 68 ++++++++++-------------------------------------- kitty/window.py | 42 ------------------------------ 3 files changed, 41 insertions(+), 119 deletions(-) diff --git a/kitty/borders.py b/kitty/borders.py index 3c3736303..a43e545b4 100644 --- a/kitty/borders.py +++ b/kitty/borders.py @@ -8,7 +8,6 @@ from .fast_data_types import ( BORDERS_PROGRAM, add_borders_rect, compile_program, init_borders_program ) from .utils import load_shaders -from .window import Widths try: from enum import IntFlag @@ -29,19 +28,15 @@ def horizontal_edge(os_window_id, tab_id, color, height, left, right, top): add_borders_rect(os_window_id, tab_id, left, top, right, top + height, color) -def border(os_window_id, tab_id, color, widths, geometry, base_width=0): - left = geometry.left - (widths.left + base_width) - top = geometry.top - (widths.top + base_width) - right = geometry.right + (widths.right + base_width) - bottom = geometry.bottom + (widths.bottom + base_width) - if widths.top > 0: - horizontal_edge(os_window_id, tab_id, color, widths.top, left, right, top) - if widths.bottom > 0: - horizontal_edge(os_window_id, tab_id, color, widths.bottom, left, right, geometry.bottom + base_width) - if widths.left > 0: - vertical_edge(os_window_id, tab_id, color, widths.left, top, bottom, left) - if widths.right > 0: - vertical_edge(os_window_id, tab_id, color, widths.right, top, bottom, geometry.right + base_width) +def draw_edges(os_window_id, tab_id, colors, width, geometry, base_width=0): + left = geometry.left - (width + base_width) + top = geometry.top - (width + base_width) + right = geometry.right + (width + base_width) + bottom = geometry.bottom + (width + base_width) + horizontal_edge(os_window_id, tab_id, colors[1], width, left, right, top) + horizontal_edge(os_window_id, tab_id, colors[3], width, left, right, geometry.bottom + base_width) + vertical_edge(os_window_id, tab_id, colors[0], width, top, bottom, left) + vertical_edge(os_window_id, tab_id, colors[2], width, top, bottom, geometry.right + base_width) def load_borders_program(): @@ -70,18 +65,27 @@ class Borders: for br in chain(current_layout.blank_rects, extra_blank_rects): add_borders_rect(self.os_window_id, self.tab_id, *br, BorderColor.default_bg) bw, pw = self.border_width, self.padding_width - if bw + pw <= 0: return - for w in windows: + draw_borders = bw > 0 and draw_window_borders and len(windows) > 1 + if draw_borders: + border_data = current_layout.resolve_borders(windows, active_window) + + for i, w in enumerate(windows): g = w.geometry - if bw > 0 and draw_window_borders: + window_bg = w.screen.color_profile.default_bg + window_bg = (window_bg << 8) | BorderColor.window_bg + if draw_borders: # Draw the border rectangles - color = BorderColor.active if w is active_window else (BorderColor.bell if w.needs_attention else BorderColor.inactive) - border(self.os_window_id, self.tab_id, color, w.border_widths, g, base_width=pw) + if w is active_window: + color = BorderColor.active + else: + color = BorderColor.bell if w.needs_attention else BorderColor.inactive + colors = tuple(color if needed else window_bg for needed in next(border_data)) + draw_edges( + self.os_window_id, self.tab_id, colors, bw, g, base_width=pw) if pw > 0: - widths = Widths(pw) # Draw the background rectangles over the padding region - color = w.screen.color_profile.default_bg - border( - self.os_window_id, self.tab_id, (color << 8) | BorderColor.window_bg, widths, g) + colors = (window_bg, window_bg, window_bg, window_bg) + draw_edges( + self.os_window_id, self.tab_id, colors, pw, g) diff --git a/kitty/layout.py b/kitty/layout.py index 051b98215..0caa35446 100644 --- a/kitty/layout.py +++ b/kitty/layout.py @@ -14,6 +14,8 @@ from .fast_data_types import ( # Utils {{{ central = Region((0, 0, 199, 199, 200, 200)) cell_width = cell_height = 20 +all_borders = True, True, True, True +no_borders = False, False, False, False def idx_for_id(win_id, windows): @@ -22,6 +24,10 @@ def idx_for_id(win_id, windows): return i +def window_needs_borders(window, active_window): + return window is active_window or window.needs_attention + + def layout_dimension(start_at, length, cell_length, decoration_pairs, left_align=False, bias=None): number_of_windows = len(decoration_pairs) number_of_cells = length // cell_length @@ -325,9 +331,6 @@ 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) @@ -362,6 +365,13 @@ class Layout: # {{{ def do_layout(self, windows, active_window_idx): raise NotImplementedError() + + def resolve_borders(self, windows, active_window): + yield from self.do_resolve_borders(windows, active_window) + + def do_resolve_borders(self, windows, active_window): + for w in windows: + yield all_borders # }}} @@ -433,15 +443,6 @@ 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)) @@ -459,6 +460,7 @@ class Tall(Layout): # {{{ self.between_blank_rect(windows[0], windows[1]) # left bottom blank rect self.bottom_blank_rect(windows[0]) + # }}} @@ -471,15 +473,6 @@ 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) @@ -613,29 +606,6 @@ 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) - - 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 # }}} @@ -670,11 +640,6 @@ 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) @@ -699,11 +664,6 @@ 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) diff --git a/kitty/window.py b/kitty/window.py index 32202aaab..1e11e3022 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -8,7 +8,6 @@ import sys import weakref from collections import deque from enum import IntEnum -from operator import attrgetter from .child import cwd_of_process from .config import build_ansi_color_table @@ -38,45 +37,6 @@ 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, @@ -134,8 +94,6 @@ 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