From 6cfb451ec848a17d1dd70dc3e226b962510e0763 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 19 Oct 2023 07:54:33 +0530 Subject: [PATCH] Two new event types for watchers on_title_change and on_set_user_var --- docs/changelog.rst | 2 ++ docs/launch.rst | 11 ++++++++++- kitty/window.py | 17 ++++++++++++++++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index becbab23a..2b0b5cd51 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -68,6 +68,8 @@ Detailed list of changes - Fix a regression that broke ``kitten update-self`` (:iss:`6729`) +- Two new event types for :ref:`watchers `, :code:`on_title_change` and :code:`on_set_user_var` + 0.30.1 [2023-10-05] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/launch.rst b/docs/launch.rst index 414b42668..8b8dd6219 100644 --- a/docs/launch.rst +++ b/docs/launch.rst @@ -133,8 +133,17 @@ functions for the events you are interested in, for example: def on_close(boss: Boss, window: Window, data: Dict[str, Any])-> None: # called when window is closed, typically when the program running in - # it exits. + # it exits + def on_set_user_var(boss: Boss, window: Window, data: Dict[str, Any]) -> None: + # called when a "user variable" is set or deleted on a window. Here + # data will contain key and value + + def on_title_change(boss: Boss, window: Window, data: Dict[str, Any]) -> None: + # called when the window title is changed on a window. Here + # data will contain title and from_child. from_child will be True + # when a title change was requested via escape code from the program + # running in the terminal Every callback is passed a reference to the global ``Boss`` object as well as the ``Window`` object the action is occurring on. The ``data`` object is a dict diff --git a/kitty/window.py b/kitty/window.py index c618ce81b..557fbd808 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -257,11 +257,15 @@ class Watchers: on_resize: List[Watcher] on_close: List[Watcher] on_focus_change: List[Watcher] + on_set_user_var: List[Watcher] + on_title_change: List[Watcher] def __init__(self) -> None: self.on_resize = [] self.on_close = [] self.on_focus_change = [] + self.on_set_user_var = [] + self.on_title_change = [] def add(self, others: 'Watchers') -> None: def merge(base: List[Watcher], other: List[Watcher]) -> None: @@ -271,15 +275,20 @@ class Watchers: merge(self.on_resize, others.on_resize) merge(self.on_close, others.on_close) merge(self.on_focus_change, others.on_focus_change) + merge(self.on_set_user_var, others.on_set_user_var) + merge(self.on_title_change, others.on_title_change) def clear(self) -> None: del self.on_close[:], self.on_resize[:], self.on_focus_change[:] + del self.on_set_user_var[:], self.on_title_change[:] def copy(self) -> 'Watchers': ans = Watchers() ans.on_close = self.on_close[:] ans.on_resize = self.on_resize[:] ans.on_focus_change = self.on_focus_change[:] + ans.on_set_user_var = self.on_set_user_var[:] + ans.on_title_change = self.on_title_change[:] return ans @property @@ -856,6 +865,7 @@ class Window: if title: title = sanitize_title(title) self.override_title = title or None + self.call_watchers(self.watchers.on_title_change, {'title': self.child_title, 'from_child': False}) self.title_updated() def set_user_var(self, key: str, val: Optional[Union[str, bytes]]) -> None: @@ -867,7 +877,10 @@ class Window: if val is not None: if isinstance(val, bytes): val = val.decode('utf-8', 'replace') - self.user_vars[key] = sanitize_control_codes(val).replace('\n', ' ') + self.user_vars[key] = val = sanitize_control_codes(val).replace('\n', ' ') + self.call_watchers(self.watchers.on_set_user_var, {'key': key, 'value': val}) + else: + self.call_watchers(self.watchers.on_set_user_var, {'key': key, 'value': None}) # screen callbacks {{{ @@ -996,6 +1009,7 @@ class Window: def title_changed(self, new_title: Optional[str], is_base64: bool = False) -> None: self.child_title = process_title_from_child(new_title or self.default_title, is_base64) + self.call_watchers(self.watchers.on_title_change, {'title': self.child_title, 'from_child': True}) if self.override_title is None: self.title_updated() @@ -1241,6 +1255,7 @@ class Window: if pop: if self.title_stack: self.child_title = self.title_stack.pop() + self.call_watchers(self.watchers.on_title_change, {'title': self.child_title, 'from_child': True}) self.title_updated() else: if self.child_title: