diff --git a/docs/changelog.rst b/docs/changelog.rst index c2e1dfeb6..4a0266cb3 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -94,6 +94,11 @@ consumption to do the same tasks. Detailed list of changes ------------------------------------- +0.40.1 [future] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Do not count background processes by default for :opt:`confirm_os_window_close` (:iss:`8358`) + 0.40.0 [2025-03-08] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/kitty/boss.py b/kitty/boss.py index 074bff809..cf652559f 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -962,6 +962,7 @@ class Boss: def close_windows_with_confirmation_msg(self, windows: Iterable[Window], active_window: Window | None) -> tuple[str, int]: num_running_programs = 0 num_background_programs = 0 + count_background = get_options().confirm_os_window_close[1] running_program = background_program = '' windows = sorted(windows, key=lambda w: 0 if w is active_window else 1) with cached_process_data(): @@ -969,7 +970,7 @@ class Boss: if window.has_running_program: num_running_programs += 1 running_program = running_program or (window.child.foreground_cmdline or [''])[0] - elif bp := window.child.background_processes: + elif count_background and (bp := window.child.background_processes): num_background_programs += len(bp) for q in bp: background_program = background_program or (q['cmdline'] or [''])[0] @@ -1141,7 +1142,7 @@ class Boss: def confirm_tab_close(self, tab: Tab) -> None: msg, num_active_windows = self.close_windows_with_confirmation_msg(tab, tab.active_window) - x = get_options().confirm_os_window_close + x = get_options().confirm_os_window_close[0] num = num_active_windows if x < 0 else len(tab) needs_confirmation = x != 0 and num >= abs(x) if not needs_confirmation: @@ -1777,7 +1778,7 @@ class Boss: for tab in tm: windows += list(tab) msg, num_active_windows = self.close_windows_with_confirmation_msg(windows, active_window) - q = get_options().confirm_os_window_close + q = get_options().confirm_os_window_close[0] num = num_active_windows if q < 0 else len(windows) needs_confirmation = tm is not None and q != 0 and num >= abs(q) if not needs_confirmation: @@ -1820,7 +1821,7 @@ class Boss: windows += list(qt) active_window = self.active_window msg, num_active_windows = self.close_windows_with_confirmation_msg(windows, active_window) - x = get_options().confirm_os_window_close + x = get_options().confirm_os_window_close[0] num = num_active_windows if x < 0 else len(windows) needs_confirmation = x != 0 and num >= abs(x) if not needs_confirmation: diff --git a/kitty/options/definition.py b/kitty/options/definition.py index eeb8ea77b..56e23e868 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -1236,9 +1236,7 @@ Specify your preference as a string of characters. ''' ) -opt('confirm_os_window_close', '-1', - option_type='int', - long_text=''' +opt('confirm_os_window_close', '-1', option_type='confirm_close', long_text=''' Ask for confirmation when closing an OS window or a tab with at least this number of kitty windows in it by window manager (e.g. clicking the window close button or pressing the operating system shortcut to close windows) or by the @@ -1247,10 +1245,11 @@ also applies to requests to quit the entire application (all OS windows, via the :ac:`quit` action). Negative values are converted to positive ones, however, with :opt:`shell_integration` enabled, using negative values means windows sitting at a shell prompt are not counted, only windows where some command is -currently running or is running in the background. Note that if you want confirmation -when closing individual windows, you can map the :ac:`close_window_with_confirmation` action. -''' - ) +currently running. You can also have backgrounded jobs prevent closing, +by adding :code:`count-background` ot the setting, for example: :code:`-1 count-background`. +Note that if you want confirmation when closing individual windows, +you can map the :ac:`close_window_with_confirmation` action. +''') egr() # }}} diff --git a/kitty/options/parse.py b/kitty/options/parse.py index 25d6c0232..4a3248166 100644 --- a/kitty/options/parse.py +++ b/kitty/options/parse.py @@ -10,7 +10,7 @@ from kitty.conf.utils import ( from kitty.options.utils import ( action_alias, active_tab_title_template, allow_hyperlinks, bell_on_tab, box_drawing_scale, clear_all_mouse_actions, clear_all_shortcuts, clipboard_control, clone_source_strategies, - config_or_absolute_path, copy_on_select, cursor_blink_interval, cursor_text_color, + config_or_absolute_path, confirm_close, copy_on_select, cursor_blink_interval, cursor_text_color, cursor_trail_decay, deprecated_adjust_line_height, deprecated_hide_window_decorations_aliases, deprecated_macos_show_window_title_in_menubar_alias, deprecated_send_text, disable_ligatures, edge_width, env, filter_notification, font_features, hide_window_decorations, macos_option_as_alt, @@ -906,7 +906,7 @@ class Parser: ans['command_on_bell'] = to_cmdline(val) def confirm_os_window_close(self, val: str, ans: dict[str, typing.Any]) -> None: - ans['confirm_os_window_close'] = int(val) + ans['confirm_os_window_close'] = confirm_close(val) def copy_on_select(self, val: str, ans: dict[str, typing.Any]) -> None: ans['copy_on_select'] = copy_on_select(val) diff --git a/kitty/options/types.py b/kitty/options/types.py index ae04efde0..d27bf8525 100644 --- a/kitty/options/types.py +++ b/kitty/options/types.py @@ -506,7 +506,7 @@ class Options: clone_source_strategies: frozenset[str] = frozenset({'conda', 'env_var', 'path', 'venv'}) close_on_child_death: bool = False command_on_bell: list[str] = ['none'] - confirm_os_window_close: int = -1 + confirm_os_window_close: tuple[int, bool] = (-1, False) copy_on_select: str = '' cursor: kitty.fast_data_types.Color | None = Color(204, 204, 204) cursor_beam_thickness: float = 1.5 diff --git a/kitty/options/utils.py b/kitty/options/utils.py index cf90c7503..cb8b7b92c 100644 --- a/kitty/options/utils.py +++ b/kitty/options/utils.py @@ -1007,6 +1007,13 @@ def shell_integration(x: str) -> frozenset[str]: return q +def confirm_close(x: str) -> tuple[int, bool]: + parts = x.split(maxsplit=1) + num = int(parts[0]) + allow_background = len(parts) > 1 and parts[1] == 'count-background' + return num, allow_background + + def underline_exclusion(x: str) -> tuple[float, Literal['', 'px', 'pt']]: try: return float(x), ''