mirror of
https://github.com/kovidgoyal/kitty.git
synced 2025-12-13 20:36:22 +01:00
Watchers: A new event for global watchers corresponding to the tab bar being changed
Fixes #8842
This commit is contained in:
@@ -120,6 +120,8 @@ Detailed list of changes
|
||||
|
||||
- Allow using backspace to move the cursor onto the previous line in cooked mode. This is indicated by the `bw` propert in kitty's terminfo (:iss:`8841`)
|
||||
|
||||
- Watchers: A new event for global watchers corresponding to the tab bar being changed (:disc:`8842`)
|
||||
|
||||
0.42.2 [2025-07-16]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -175,6 +175,17 @@ create :file:`~/.config/kitty/mywatcher.py` and use :option:`launch --watcher` =
|
||||
# code received from the program running in the window
|
||||
...
|
||||
|
||||
def on_tab_bar_dirty(boss: Boss, window: Window, data: dict[str, Any]) -> None:
|
||||
# called when any changes happen to the tab bar, such a new tabs being
|
||||
# created, tab titles changing, tabs moving, etc. Useful to display the
|
||||
# tab bar externally to kitty. This is called even if the tab bar is
|
||||
# hidden. Note that this is called only in *global watchers*, that is
|
||||
# watchers defined in kitty.conf or using the --watcher command line
|
||||
# flag. data contains tab_manager which is the object responsible for
|
||||
# managing all tabs in a single OS Window.
|
||||
...
|
||||
|
||||
|
||||
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
|
||||
that contains event dependent data. You have full access to kitty internals in
|
||||
|
||||
@@ -529,6 +529,9 @@ def load_watch_modules(watchers: Iterable[str]) -> Watchers | None:
|
||||
w = m.get('on_color_scheme_preference_change')
|
||||
if callable(w):
|
||||
ans.on_color_scheme_preference_change.append(w)
|
||||
w = m.get('on_tab_bar_dirty')
|
||||
if callable(w):
|
||||
ans.on_tab_bar_dirty.append(w)
|
||||
return ans
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ from .tab_bar import TabBar, TabBarData
|
||||
from .types import ac
|
||||
from .typing_compat import EdgeLiteral, SessionTab, SessionType, TypedDict
|
||||
from .utils import cmdline_for_hold, log_error, platform_window_id, resolved_shell, shlex_split, which
|
||||
from .window import CwdRequest, Watchers, Window, WindowDict
|
||||
from .window import CwdRequest, Watchers, Window, WindowDict, global_watchers
|
||||
from .window_list import WindowList
|
||||
|
||||
|
||||
@@ -1007,6 +1007,12 @@ class TabManager: # {{{
|
||||
def mark_tab_bar_dirty(self) -> None:
|
||||
if self.tab_bar_should_be_visible and not self.tab_bar_hidden:
|
||||
mark_tab_bar_dirty(self.os_window_id)
|
||||
boss = get_boss()
|
||||
w = self.active_window
|
||||
data = {'tab_manager': self}
|
||||
for g in global_watchers():
|
||||
for watcher in g.on_tab_bar_dirty:
|
||||
watcher(boss, w, data)
|
||||
|
||||
def update_tab_bar_data(self) -> None:
|
||||
self.tab_bar.update(self.tab_bar_data)
|
||||
|
||||
@@ -297,6 +297,7 @@ class Watchers:
|
||||
on_title_change: list[Watcher]
|
||||
on_cmd_startstop: list[Watcher]
|
||||
on_color_scheme_preference_change: list[Watcher]
|
||||
on_tab_bar_dirty: list[Watcher]
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.on_resize = []
|
||||
@@ -306,6 +307,7 @@ class Watchers:
|
||||
self.on_title_change = []
|
||||
self.on_cmd_startstop = []
|
||||
self.on_color_scheme_preference_change = []
|
||||
self.on_tab_bar_dirty = []
|
||||
|
||||
def add(self, others: 'Watchers') -> None:
|
||||
def merge(base: list[Watcher], other: list[Watcher]) -> None:
|
||||
@@ -319,11 +321,13 @@ class Watchers:
|
||||
merge(self.on_title_change, others.on_title_change)
|
||||
merge(self.on_cmd_startstop, others.on_cmd_startstop)
|
||||
merge(self.on_color_scheme_preference_change, others.on_color_scheme_preference_change)
|
||||
merge(self.on_tab_bar_dirty, others.on_tab_bar_dirty)
|
||||
|
||||
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[:], self.on_cmd_startstop[:]
|
||||
del self.on_color_scheme_preference_change[:]
|
||||
del self.on_tab_bar_dirty[:]
|
||||
|
||||
def copy(self) -> 'Watchers':
|
||||
ans = Watchers()
|
||||
@@ -334,12 +338,13 @@ class Watchers:
|
||||
ans.on_title_change = self.on_title_change[:]
|
||||
ans.on_cmd_startstop = self.on_cmd_startstop[:]
|
||||
ans.on_color_scheme_preference_change = self.on_color_scheme_preference_change[:]
|
||||
ans.on_tab_bar_dirty = self.on_tab_bar_dirty[:]
|
||||
return ans
|
||||
|
||||
@property
|
||||
def has_watchers(self) -> bool:
|
||||
return bool(self.on_close or self.on_resize or self.on_focus_change or self.on_color_scheme_preference_change
|
||||
or self.on_set_user_var or self.on_title_change or self.on_cmd_startstop)
|
||||
or self.on_set_user_var or self.on_title_change or self.on_cmd_startstop or self.on_tab_bar_dirty)
|
||||
|
||||
|
||||
def call_watchers(windowref: Callable[[], Optional['Window']], which: str, data: dict[str, Any]) -> None:
|
||||
|
||||
Reference in New Issue
Block a user