mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-05-13 08:26:56 +00:00
parent
02a34ecd04
commit
25f97f4ce5
4 changed files with 45 additions and 2 deletions
|
|
@ -185,6 +185,14 @@ create :file:`~/.config/kitty/mywatcher.py` and use :option:`launch --watcher` =
|
|||
# managing all tabs in a single OS Window.
|
||||
...
|
||||
|
||||
def on_quit(boss: Boss, window: Window, data: dict[str, Any]) -> None:
|
||||
# called when kitty is about to quit. This is called in *global watchers*
|
||||
# only. It is called twice: once before the quit confirmation dialog is
|
||||
# shown (data['confirmed'] will be False) and once after the user has
|
||||
# confirmed quitting (data['confirmed'] will be True). Setting
|
||||
# data['aborted'] to True will abort the quit in both cases.
|
||||
...
|
||||
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ from .utils import (
|
|||
timed_debug_print,
|
||||
which,
|
||||
)
|
||||
from .window import CommandOutput, CwdRequest, Window
|
||||
from .window import CommandOutput, CwdRequest, Window, global_watchers
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
||||
|
|
@ -2090,6 +2090,24 @@ class Boss:
|
|||
|
||||
quit_confirmation_window_id: int = 0
|
||||
|
||||
def _call_on_quit_watchers(self, data: dict[str, Any]) -> bool:
|
||||
w = self.active_window
|
||||
if w is None:
|
||||
for window in self.window_id_map.values():
|
||||
w = window
|
||||
break
|
||||
if w is None:
|
||||
return True
|
||||
for watcher in global_watchers().on_quit:
|
||||
try:
|
||||
watcher(self, w, data)
|
||||
except Exception:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
if data.get('aborted'):
|
||||
return False
|
||||
return True
|
||||
|
||||
@ac('win', 'Quit, closing all windows')
|
||||
def quit(self, *args: Any) -> None:
|
||||
windows = []
|
||||
|
|
@ -2102,6 +2120,8 @@ class Boss:
|
|||
num = num_active_windows if x < 0 else len(windows)
|
||||
needs_confirmation = x != 0 and num >= abs(x)
|
||||
if not needs_confirmation:
|
||||
if not self._call_on_quit_watchers({'confirmed': True}):
|
||||
return
|
||||
set_application_quit_request(IMPERATIVE_CLOSE_REQUESTED)
|
||||
return
|
||||
if current_application_quit_request() == CLOSE_BEING_CONFIRMED:
|
||||
|
|
@ -2116,6 +2136,8 @@ class Boss:
|
|||
tab.set_active_window(w)
|
||||
return
|
||||
return
|
||||
if not self._call_on_quit_watchers({'confirmed': False}):
|
||||
return
|
||||
msg = msg or _('It has {} windows.').format(num)
|
||||
w = self.confirm(_('Are you sure you want to quit kitty?') + ' ' + msg, self.handle_quit_confirmation, window=active_window, title=_('Quit kitty?'))
|
||||
self.quit_confirmation_window_id = w.id
|
||||
|
|
@ -2123,6 +2145,10 @@ class Boss:
|
|||
|
||||
def handle_quit_confirmation(self, confirmed: bool) -> None:
|
||||
self.quit_confirmation_window_id = 0
|
||||
if confirmed:
|
||||
if not self._call_on_quit_watchers({'confirmed': True}):
|
||||
set_application_quit_request(NO_CLOSE_REQUESTED)
|
||||
return
|
||||
set_application_quit_request(IMPERATIVE_CLOSE_REQUESTED if confirmed else NO_CLOSE_REQUESTED)
|
||||
|
||||
def notify_on_os_window_death(self, address: str) -> None:
|
||||
|
|
|
|||
|
|
@ -548,6 +548,9 @@ def load_watch_modules(watchers: Iterable[str]) -> Watchers | None:
|
|||
w = m.get('on_tab_bar_dirty')
|
||||
if callable(w):
|
||||
ans.on_tab_bar_dirty.append(w)
|
||||
w = m.get('on_quit')
|
||||
if callable(w):
|
||||
ans.on_quit.append(w)
|
||||
return ans
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -305,6 +305,7 @@ class Watchers:
|
|||
on_cmd_startstop: list[Watcher]
|
||||
on_color_scheme_preference_change: list[Watcher]
|
||||
on_tab_bar_dirty: list[Watcher]
|
||||
on_quit: list[Watcher]
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.on_resize = []
|
||||
|
|
@ -315,6 +316,7 @@ class Watchers:
|
|||
self.on_cmd_startstop = []
|
||||
self.on_color_scheme_preference_change = []
|
||||
self.on_tab_bar_dirty = []
|
||||
self.on_quit = []
|
||||
|
||||
def add(self, others: 'Watchers') -> None:
|
||||
def merge(base: list[Watcher], other: list[Watcher]) -> None:
|
||||
|
|
@ -329,12 +331,14 @@ class Watchers:
|
|||
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)
|
||||
merge(self.on_quit, others.on_quit)
|
||||
|
||||
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[:]
|
||||
del self.on_quit[:]
|
||||
|
||||
def copy(self) -> 'Watchers':
|
||||
ans = Watchers()
|
||||
|
|
@ -346,12 +350,14 @@ class Watchers:
|
|||
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[:]
|
||||
ans.on_quit = self.on_quit[:]
|
||||
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_tab_bar_dirty)
|
||||
or self.on_set_user_var or self.on_title_change or self.on_cmd_startstop or self.on_tab_bar_dirty
|
||||
or self.on_quit)
|
||||
|
||||
|
||||
def call_watchers(windowref: Callable[[], Optional['Window']], which: str, data: dict[str, Any]) -> None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue