When confirming close commands dont count windows sitting at shell prompts

This commit is contained in:
Kovid Goyal 2021-08-14 13:40:48 +05:30
parent 81654c9874
commit 2a634af2bc
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 27 additions and 11 deletions

View File

@ -30,7 +30,10 @@ Features
* Glitch free window resizing even with complex prompts. Achieved by erasing * Glitch free window resizing even with complex prompts. Achieved by erasing
the prompt on resize and allowing the shell to redraw it cleanly. the prompt on resize and allowing the shell to redraw it cleanly.
* Sophisticated completion for the :program:`kitty` command in the shell * Sophisticated completion for the :program:`kitty` command in the shell.
* When confirming a quit command if a window is sitting at a shell prompt,
it is not counted.
Configuration Configuration

View File

@ -541,14 +541,14 @@ class Boss:
self.confirm_tab_close(tab) self.confirm_tab_close(tab)
def confirm_tab_close(self, tab: Tab) -> None: def confirm_tab_close(self, tab: Tab) -> None:
windows = tuple(tab) num = tab.number_of_windows_with_running_programs
needs_confirmation = get_options().confirm_os_window_close > 0 and len(windows) >= get_options().confirm_os_window_close needs_confirmation = get_options().confirm_os_window_close > 0 and num >= get_options().confirm_os_window_close
if not needs_confirmation: if not needs_confirmation:
self.close_tab_no_confirm(tab) self.close_tab_no_confirm(tab)
return return
self._run_kitten('ask', ['--type=yesno', '--message', _( self._run_kitten('ask', ['--type=yesno', '--message', _(
'Are you sure you want to close this tab, it has {}' 'Are you sure you want to close this tab, it has {}'
' windows running?').format(len(windows))], ' windows running?').format(num)],
window=tab.active_window, window=tab.active_window,
custom_callback=partial(self.handle_close_tab_confirmation, tab.id) custom_callback=partial(self.handle_close_tab_confirmation, tab.id)
) )
@ -930,7 +930,8 @@ class Boss:
def confirm_os_window_close(self, os_window_id: int) -> None: def confirm_os_window_close(self, os_window_id: int) -> None:
tm = self.os_window_map.get(os_window_id) tm = self.os_window_map.get(os_window_id)
needs_confirmation = tm is not None and get_options().confirm_os_window_close > 0 and tm.number_of_windows >= get_options().confirm_os_window_close num = 0 if tm is None else tm.number_of_windows_with_running_programs
needs_confirmation = tm is not None and get_options().confirm_os_window_close > 0 and num >= get_options().confirm_os_window_close
if not needs_confirmation: if not needs_confirmation:
mark_os_window_for_close(os_window_id) mark_os_window_for_close(os_window_id)
return return
@ -938,7 +939,7 @@ class Boss:
w = tm.active_window w = tm.active_window
self._run_kitten('ask', ['--type=yesno', '--message', _( self._run_kitten('ask', ['--type=yesno', '--message', _(
'Are you sure you want to close this OS window, it has {}' 'Are you sure you want to close this OS window, it has {}'
' windows running?').format(tm.number_of_windows)], ' windows running?').format(num)],
window=w, window=w,
custom_callback=partial(self.handle_close_os_window_confirmation, os_window_id) custom_callback=partial(self.handle_close_os_window_confirmation, os_window_id)
) )
@ -967,7 +968,7 @@ class Boss:
tm = self.active_tab tm = self.active_tab
num = 0 num = 0
for q in self.os_window_map.values(): for q in self.os_window_map.values():
num += q.number_of_windows num += q.number_of_windows_with_running_programs
needs_confirmation = tm is not None and get_options().confirm_os_window_close > 0 and num >= get_options().confirm_os_window_close needs_confirmation = tm is not None and get_options().confirm_os_window_close > 0 and num >= get_options().confirm_os_window_close
if not needs_confirmation: if not needs_confirmation:
set_application_quit_request(IMPERATIVE_CLOSE_REQUESTED) set_application_quit_request(IMPERATIVE_CLOSE_REQUESTED)

View File

@ -864,7 +864,8 @@ opt('confirm_os_window_close', '0',
Ask for confirmation when closing an OS window or a tab that has at least this Ask for confirmation when closing an OS window or a tab that has at least this
number of kitty windows in it. A value of zero disables confirmation. This number of kitty windows in it. A value of zero disables confirmation. This
confirmation also applies to requests to quit the entire application (all OS confirmation also applies to requests to quit the entire application (all OS
windows, via the quit action). windows, via the quit action). Note that if you have :ref:`shell_integration`
enabled, a window that is sitting at a shell prompt is not counted.
''' '''
) )
egr() # }}} egr() # }}}

View File

@ -189,6 +189,14 @@ class Tab: # {{{
def title(self) -> str: def title(self) -> str:
return cast(str, getattr(self.active_window, 'title', appname)) return cast(str, getattr(self.active_window, 'title', appname))
@property
def number_of_windows_with_running_programs(self) -> int:
ans = 0
for window in self:
if window.has_running_program:
ans += 1
return ans
def set_title(self, title: str) -> None: def set_title(self, title: str) -> None:
self.name = title or '' self.name = title or ''
self.mark_tab_bar_dirty() self.mark_tab_bar_dirty()
@ -800,11 +808,10 @@ class TabManager: # {{{
return t.active_window return t.active_window
@property @property
def number_of_windows(self) -> int: def number_of_windows_with_running_programs(self) -> int:
count = 0 count = 0
for tab in self: for tab in self:
for window in tab: count += tab.number_of_windows_with_running_programs
count += 1
return count return count
def tab_for_id(self, tab_id: int) -> Optional[Tab]: def tab_for_id(self, tab_id: int) -> Optional[Tab]:

View File

@ -454,6 +454,10 @@ class Window:
def current_colors(self) -> Dict: def current_colors(self) -> Dict:
return self.screen.color_profile.as_dict() return self.screen.color_profile.as_dict()
@property
def has_running_program(self) -> bool:
return not self.screen.cursor_at_prompt()
def matches(self, field: str, pat: MatchPatternType) -> bool: def matches(self, field: str, pat: MatchPatternType) -> bool:
if not pat: if not pat:
return False return False