From 2a634af2bc1dfd33d5759549f08ea8ecd40dfd3f Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 14 Aug 2021 13:40:48 +0530 Subject: [PATCH] When confirming close commands dont count windows sitting at shell prompts --- docs/shell-integration.rst | 5 ++++- kitty/boss.py | 13 +++++++------ kitty/options/definition.py | 3 ++- kitty/tabs.py | 13 ++++++++++--- kitty/window.py | 4 ++++ 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/docs/shell-integration.rst b/docs/shell-integration.rst index 40d96ce00..1006916dd 100644 --- a/docs/shell-integration.rst +++ b/docs/shell-integration.rst @@ -30,7 +30,10 @@ Features * Glitch free window resizing even with complex prompts. Achieved by erasing 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 diff --git a/kitty/boss.py b/kitty/boss.py index a6897dcd1..eb05a003a 100755 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -541,14 +541,14 @@ class Boss: self.confirm_tab_close(tab) def confirm_tab_close(self, tab: Tab) -> None: - windows = tuple(tab) - needs_confirmation = get_options().confirm_os_window_close > 0 and len(windows) >= get_options().confirm_os_window_close + num = tab.number_of_windows_with_running_programs + needs_confirmation = get_options().confirm_os_window_close > 0 and num >= get_options().confirm_os_window_close if not needs_confirmation: self.close_tab_no_confirm(tab) return self._run_kitten('ask', ['--type=yesno', '--message', _( 'Are you sure you want to close this tab, it has {}' - ' windows running?').format(len(windows))], + ' windows running?').format(num)], window=tab.active_window, 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: 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: mark_os_window_for_close(os_window_id) return @@ -938,7 +939,7 @@ class Boss: w = tm.active_window self._run_kitten('ask', ['--type=yesno', '--message', _( '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, custom_callback=partial(self.handle_close_os_window_confirmation, os_window_id) ) @@ -967,7 +968,7 @@ class Boss: tm = self.active_tab num = 0 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 if not needs_confirmation: set_application_quit_request(IMPERATIVE_CLOSE_REQUESTED) diff --git a/kitty/options/definition.py b/kitty/options/definition.py index 702d89e81..2d855904f 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -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 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 -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() # }}} diff --git a/kitty/tabs.py b/kitty/tabs.py index 5375b5dac..10faf3b88 100644 --- a/kitty/tabs.py +++ b/kitty/tabs.py @@ -189,6 +189,14 @@ class Tab: # {{{ def title(self) -> str: 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: self.name = title or '' self.mark_tab_bar_dirty() @@ -800,11 +808,10 @@ class TabManager: # {{{ return t.active_window @property - def number_of_windows(self) -> int: + def number_of_windows_with_running_programs(self) -> int: count = 0 for tab in self: - for window in tab: - count += 1 + count += tab.number_of_windows_with_running_programs return count def tab_for_id(self, tab_id: int) -> Optional[Tab]: diff --git a/kitty/window.py b/kitty/window.py index 237d0ce34..4a96f3ac6 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -454,6 +454,10 @@ class Window: def current_colors(self) -> 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: if not pat: return False