From db64aef66668db36d7816fadfcb0dc1e8cdc4de8 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 23 Aug 2020 08:38:25 +0530 Subject: [PATCH] Prevent an infinite recursion if a watcher causes a resize in the on_resize handler --- kitty/fast_data_types.pyi | 2 +- kitty/update_check.py | 8 ++++++-- kitty/window.py | 23 +++++++++++++++++------ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/kitty/fast_data_types.pyi b/kitty/fast_data_types.pyi index 783f8801e..d7136fb8d 100644 --- a/kitty/fast_data_types.pyi +++ b/kitty/fast_data_types.pyi @@ -461,7 +461,7 @@ def coretext_all_fonts() -> Tuple[CoreTextFont, ...]: def add_timer( - callback: Callable[[Optional[int]], bool], + callback: Callable[[Optional[int]], None], interval: float, repeats: bool = True ) -> int: diff --git a/kitty/update_check.py b/kitty/update_check.py index fe5d2b30c..95caa1ea2 100644 --- a/kitty/update_check.py +++ b/kitty/update_check.py @@ -109,7 +109,7 @@ def run_worker() -> None: print(get_released_version()) -def update_check(timer_id: Optional[int] = None) -> bool: +def update_check() -> bool: try: p = subprocess.Popen([ kitty_exe(), '+runpy', @@ -123,6 +123,10 @@ def update_check(timer_id: Optional[int] = None) -> bool: return True +def update_check_callback(timer_id: Optional[int]) -> None: + update_check() + + def run_update_check(interval: float = CHECK_INTERVAL) -> None: if update_check(): - add_timer(update_check, interval) + add_timer(update_check_callback, interval) diff --git a/kitty/window.py b/kitty/window.py index af24898f3..af76ef8ea 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -23,11 +23,11 @@ from .fast_data_types import ( CELL_PROGRAM, CELL_SPECIAL_PROGRAM, CSI, DCS, DECORATION, DIM, GRAPHICS_ALPHA_MASK_PROGRAM, GRAPHICS_PREMULT_PROGRAM, GRAPHICS_PROGRAM, MARK, MARK_MASK, OSC, REVERSE, SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, - STRIKETHROUGH, TINT_PROGRAM, Screen, add_window, cell_size_for_window, - compile_program, get_boss, get_clipboard_string, init_cell_program, - pt_to_px, set_clipboard_string, set_titlebar_color, set_window_padding, - set_window_render_data, update_window_title, update_window_visibility, - viewport_for_window + STRIKETHROUGH, TINT_PROGRAM, Screen, add_timer, add_window, + cell_size_for_window, compile_program, get_boss, get_clipboard_string, + init_cell_program, pt_to_px, set_clipboard_string, set_titlebar_color, + set_window_padding, set_window_render_data, update_window_title, + update_window_visibility, viewport_for_window ) from .keys import defines, extended_key_event, keyboard_mode_name from .notify import NotificationCommand, handle_notification_cmd @@ -92,6 +92,17 @@ class Watchers: self.on_close: List[Watcher] = [] +def call_watchers(windowref: Callable[[], Optional['Window']], which: str, data: Dict[str, Any]) -> None: + + def callback(timer_id: Optional[int]) -> None: + w = windowref() + if w is not None: + watchers: List[Watcher] = getattr(w.watchers, which) + w.call_watchers(watchers, data) + + add_timer(callback, 0, False) + + def calculate_gl_geometry(window_geometry: WindowGeometry, viewport_width: int, viewport_height: int, cell_width: int, cell_height: int) -> ScreenGeometry: dx, dy = 2 * cell_width / viewport_width, 2 * cell_height / viewport_height xmargin = window_geometry.left / viewport_width @@ -385,7 +396,7 @@ class Window: self.screen.resize(new_geometry.ynum, new_geometry.xnum) sg = self.update_position(new_geometry) self.needs_layout = False - self.call_watchers(self.watchers.on_resize, {'old_geometry': self.geometry, 'new_geometry': new_geometry}) + call_watchers(weakref.ref(self), 'on_resize', {'old_geometry': self.geometry, 'new_geometry': new_geometry}) else: sg = self.update_position(new_geometry) current_pty_size = (