diff --git a/kitty/layout.py b/kitty/layout.py index f808dff02..1418e483e 100644 --- a/kitty/layout.py +++ b/kitty/layout.py @@ -8,7 +8,7 @@ from itertools import islice from .constants import WindowGeometry from .fast_data_types import ( - Region, pt_to_px, set_active_window, swap_windows, viewport_for_window + Region, set_active_window, swap_windows, viewport_for_window ) central = Region((0, 0, 199, 199, 200, 200)) @@ -77,15 +77,14 @@ class Layout: needs_window_borders = True only_active_window_visible = False - def __init__(self, os_window_id, tab_id, opts, border_width, layout_opts=''): + def __init__(self, os_window_id, tab_id, margin_width, padding_width, border_width, layout_opts=''): self.os_window_id = os_window_id self.tab_id = tab_id self.set_active_window_in_os_window = partial(set_active_window, os_window_id, tab_id) self.swap_windows_in_os_window = partial(swap_windows, os_window_id, tab_id) - self.opts = opts self.border_width = border_width - self.margin_width = pt_to_px(opts.window_margin_width) - self.padding_width = pt_to_px(opts.window_padding_width) + self.margin_width = margin_width + self.padding_width = padding_width # A set of rectangles corresponding to the blank spaces at the edges of # this layout, i.e. spaces that are not covered by any window self.blank_rects = () @@ -485,3 +484,24 @@ class Horizontal(Layout): all_layouts = {o.name: o for o in globals().values() if isinstance(o, type) and issubclass(o, Layout) and o is not Layout} + + +def create_layout_object_for(name, os_window_id, tab_id, margin_width, padding_width, border_width, layout_opts=''): + key = name, os_window_id, tab_id, margin_width, padding_width, border_width, layout_opts + ans = create_layout_object_for.cache.get(key) + if ans is None: + name, layout_opts = name.partition(':')[::2] + ans = create_layout_object_for.cache[key] = all_layouts[name](os_window_id, tab_id, margin_width, padding_width, border_width, layout_opts) + return ans + + +create_layout_object_for.cache = {} + + +def evict_cached_layouts(tab_id): + remove = [] + for key in create_layout_object_for.cache: + if key[2] == tab_id: + remove.append(key) + for key in remove: + del create_layout_object_for.cache[key] diff --git a/kitty/tabs.py b/kitty/tabs.py index 6f7556034..0ebfe84da 100644 --- a/kitty/tabs.py +++ b/kitty/tabs.py @@ -12,10 +12,10 @@ from .config import build_ansi_color_table from .constants import WindowGeometry, appname, get_boss, is_macos, is_wayland from .fast_data_types import ( DECAWM, Screen, add_tab, glfw_post_empty_event, mark_tab_bar_dirty, - next_window_id, remove_tab, remove_window, set_active_tab, + next_window_id, pt_to_px, remove_tab, remove_window, set_active_tab, set_tab_bar_render_data, swap_tabs, viewport_for_window, x11_window_id ) -from .layout import Rect, all_layouts +from .layout import Rect, create_layout_object_for, evict_cached_layouts from .session import resolved_shell from .utils import color_as_int, log_error from .window import Window, calculate_gl_geometry @@ -38,6 +38,8 @@ class Tab: # {{{ if not self.id: raise Exception('No OS window with id {} found, or tab counter has wrapped'.format(self.os_window_id)) self.opts, self.args = tab_manager.opts, tab_manager.args + self.margin_width, self.padding_width = map(pt_to_px, ( + self.opts.window_margin_width, self.opts.window_padding_width)) self.name = getattr(session_tab, 'name', '') self.enabled_layouts = [x.lower() for x in getattr(session_tab, 'enabled_layouts', None) or self.opts.enabled_layouts] self.borders = Borders(self.os_window_id, self.id, self.opts) @@ -138,8 +140,7 @@ class Tab: # {{{ w.change_titlebar_color() def create_layout_object(self, name): - name, rest = name.partition(':')[::2] - return all_layouts[name](self.os_window_id, self.id, self.opts, self.borders.border_width, rest) + return create_layout_object_for(name, self.os_window_id, self.id, self.margin_width, self.padding_width, self.borders.border_width) def next_layout(self): if len(self.enabled_layouts) > 1: @@ -278,6 +279,7 @@ class Tab: # {{{ return window in self.windows def destroy(self): + evict_cached_layouts(self.id) for w in self.windows: w.destroy() self.windows = deque()