From 4b997a961c59cb17c8e5092f185dc4ddc9065928 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 20 Oct 2023 08:37:45 +0530 Subject: [PATCH] A new option single_window_padding_width to use a different padding when only a single window is visible Fixes #6734 --- docs/changelog.rst | 2 ++ kitty/options/definition.py | 11 +++++++++++ kitty/options/parse.py | 5 ++++- kitty/options/types.py | 4 +++- kitty/os_window_size.py | 11 +++++++++-- kitty/session.py | 2 +- kitty/tabs.py | 8 ++++++++ kitty/window.py | 13 +++++++++++-- kitty/window_list.py | 2 +- kitty_tests/layout.py | 4 ++-- 10 files changed, 52 insertions(+), 10 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 2b0b5cd51..c2cf04247 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -52,6 +52,8 @@ Detailed list of changes - A new :doc:`escape code ` that can be used by programs running in the terminal to change the shape of the mouse pointer (:iss:`6711`) +- A new option :opt:`single_window_padding_width` to use a different padding when only a single window is visible (:iss:`6734`) + - A new mouse action ``mouse_selection word_and_line_from_point`` to select the current word under the mouse cursor and extend to end of line (:pull:`6663`) - Allow using the full range of standard mouse cursor shapes when customizing the mouse cursor diff --git a/kitty/options/definition.py b/kitty/options/definition.py index 8e0e72217..9a2ca804d 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -1026,6 +1026,17 @@ bottom and left. ''' ) +opt('single_window_padding_width', '-1', + option_type='optional_edge_width', + long_text=''' +The window padding to use when only a single window is visible (in pts). Negative +values will cause the value of :opt:`window_padding_width` to be used instead. A +single value sets all four sides. Two values set the vertical and horizontal +sides. Three values set top, horizontal and bottom. Four values set top, right, +bottom and left. +''' + ) + opt('placement_strategy', 'center', choices=('center', 'top-left'), long_text=''' diff --git a/kitty/options/parse.py b/kitty/options/parse.py index 15212848d..f6cb0c536 100644 --- a/kitty/options/parse.py +++ b/kitty/options/parse.py @@ -934,7 +934,7 @@ class Parser: raise ValueError(f"The value {val} is not a valid choice for default_pointer_shape") ans["default_pointer_shape"] = val - choices_for_default_pointer_shape = frozenset(('arrow', 'beam', 'text', 'pointer', 'hand', 'help', 'wait', 'progress', 'crosshair', 'vertical-text', 'move', 'e-resize', 'ne-resize', 'nw-resize', 'n-resize', 'se-resize', 'sw-resize', 's-resize', 'w-resize', 'ew-resize', 'ns-resize', 'nesw-resize', 'nwse-resize', 'zoom-in', 'zoom-out', 'alias', 'copy', 'not-allowed', 'no-drop', 'grab', 'grabbing')) + choices_for_default_pointer_shape = frozenset(('arrow', 'beam', 'text', 'pointer', 'hand', 'help', 'wait', 'progress', 'crosshair', 'cell', 'vertical-text', 'move', 'e-resize', 'ne-resize', 'nw-resize', 'n-resize', 'se-resize', 'sw-resize', 's-resize', 'w-resize', 'ew-resize', 'ns-resize', 'nesw-resize', 'nwse-resize', 'zoom-in', 'zoom-out', 'alias', 'copy', 'not-allowed', 'no-drop', 'grab', 'grabbing')) def detect_urls(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: ans['detect_urls'] = to_bool(val) @@ -1202,6 +1202,9 @@ class Parser: def single_window_margin_width(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: ans['single_window_margin_width'] = optional_edge_width(val) + def single_window_padding_width(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: + ans['single_window_padding_width'] = optional_edge_width(val) + def startup_session(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: ans['startup_session'] = config_or_absolute_path(val) diff --git a/kitty/options/types.py b/kitty/options/types.py index 1b72cc4c0..45d05aa82 100644 --- a/kitty/options/types.py +++ b/kitty/options/types.py @@ -16,7 +16,7 @@ import kitty.types choices_for_allow_cloning = typing.Literal['yes', 'y', 'true', 'no', 'n', 'false', 'ask'] choices_for_allow_remote_control = typing.Literal['password', 'socket-only', 'socket', 'no', 'n', 'false', 'yes', 'y', 'true'] choices_for_background_image_layout = typing.Literal['mirror-tiled', 'scaled', 'tiled', 'clamped', 'centered', 'cscaled'] -choices_for_default_pointer_shape = typing.Literal['arrow', 'beam', 'text', 'pointer', 'hand', 'help', 'wait', 'progress', 'crosshair', 'vertical-text', 'move', 'e-resize', 'ne-resize', 'nw-resize', 'n-resize', 'se-resize', 'sw-resize', 's-resize', 'w-resize', 'ew-resize', 'ns-resize', 'nesw-resize', 'nwse-resize', 'zoom-in', 'zoom-out', 'alias', 'copy', 'not-allowed', 'no-drop', 'grab', 'grabbing'] +choices_for_default_pointer_shape = typing.Literal['arrow', 'beam', 'text', 'pointer', 'hand', 'help', 'wait', 'progress', 'crosshair', 'cell', 'vertical-text', 'move', 'e-resize', 'ne-resize', 'nw-resize', 'n-resize', 'se-resize', 'sw-resize', 's-resize', 'w-resize', 'ew-resize', 'ns-resize', 'nesw-resize', 'nwse-resize', 'zoom-in', 'zoom-out', 'alias', 'copy', 'not-allowed', 'no-drop', 'grab', 'grabbing'] choices_for_linux_display_server = typing.Literal['auto', 'wayland', 'x11'] choices_for_macos_colorspace = typing.Literal['srgb', 'default', 'displayp3'] choices_for_macos_show_window_title_in = typing.Literal['all', 'menubar', 'none', 'window'] @@ -407,6 +407,7 @@ option_names = ( # {{{ 'shell_integration', 'show_hyperlink_targets', 'single_window_margin_width', + 'single_window_padding_width', 'startup_session', 'strip_trailing_spaces', 'symbol_map', @@ -563,6 +564,7 @@ class Options: shell_integration: typing.FrozenSet[str] = frozenset({'enabled'}) show_hyperlink_targets: bool = False single_window_margin_width: FloatEdges = FloatEdges(left=-1.0, top=-1.0, right=-1.0, bottom=-1.0) + single_window_padding_width: FloatEdges = FloatEdges(left=-1.0, top=-1.0, right=-1.0, bottom=-1.0) startup_session: typing.Optional[str] = None strip_trailing_spaces: choices_for_strip_trailing_spaces = 'never' sync_to_monitor: bool = True diff --git a/kitty/os_window_size.py b/kitty/os_window_size.py index e720e0976..61833db53 100644 --- a/kitty/os_window_size.py +++ b/kitty/os_window_size.py @@ -26,6 +26,7 @@ class WindowSizeData(NamedTuple): remember_window_size: bool single_window_margin_width: FloatEdges window_margin_width: FloatEdges + single_window_padding_width: FloatEdges window_padding_width: FloatEdges @@ -61,15 +62,21 @@ def initial_window_size_func(opts: WindowSizeData, cached_values: Dict[str, Any] ans = getattr(opts.window_margin_width, which) return ans + def effective_padding(which: EdgeLiteral) -> float: + ans: float = getattr(opts.single_window_padding_width, which) + if ans < 0: + ans = getattr(opts.window_padding_width, which) + return ans + if w_unit == 'cells': spacing = effective_margin('left') + effective_margin('right') - spacing += opts.window_padding_width.left + opts.window_padding_width.right + spacing += effective_padding('left') + effective_padding('right') width = cell_width * w / xscale + (dpi_x / 72) * spacing + 1 else: width = w if h_unit == 'cells': spacing = effective_margin('top') + effective_margin('bottom') - spacing += opts.window_padding_width.top + opts.window_padding_width.bottom + spacing += effective_padding('top') + effective_padding('bottom') height = cell_height * h / yscale + (dpi_y / 72) * spacing + 1 else: height = h diff --git a/kitty/session.py b/kitty/session.py index 283c734f7..85e44956b 100644 --- a/kitty/session.py +++ b/kitty/session.py @@ -26,7 +26,7 @@ def get_os_window_sizing_data(opts: Options, session: Optional['Session'] = None sizes = WindowSizes(WindowSize(*opts.initial_window_width), WindowSize(*opts.initial_window_height)) else: sizes = session.os_window_size - return WindowSizeData(sizes, opts.remember_window_size, opts.single_window_margin_width, opts.window_margin_width, opts.window_padding_width) + return WindowSizeData(sizes, opts.remember_window_size, opts.single_window_margin_width, opts.window_margin_width, opts.single_window_padding_width, opts.window_padding_width) ResizeSpec = Tuple[str, int] diff --git a/kitty/tabs.py b/kitty/tabs.py index fbf7ae853..a53b834b4 100644 --- a/kitty/tabs.py +++ b/kitty/tabs.py @@ -164,6 +164,14 @@ class Tab: # {{{ self._set_current_layout(l0) self.startup(session_tab) + def has_single_window_visible(self) -> bool: + if self.current_layout.only_active_window_visible: + return True + for i, g in enumerate(self.windows.iter_all_layoutable_groups(only_visible=True)): + if i > 0: + return False + return True + def set_enabled_layouts(self, val: Iterable[str]) -> None: self.enabled_layouts = [x.lower() for x in val] or ['tall'] if self.current_layout.name not in self.enabled_layouts: diff --git a/kitty/window.py b/kitty/window.py index 557fbd808..0b1e32f29 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -585,11 +585,13 @@ class Window: self.os_window_id = tab.os_window_id self.tabref = weakref.ref(tab) - def effective_margin(self, edge: EdgeLiteral, is_single_window: bool = False) -> int: + def effective_margin(self, edge: EdgeLiteral) -> int: q = getattr(self.margin, edge) if q is not None: return pt_to_px(q, self.os_window_id) opts = get_options() + tab = self.tabref() + is_single_window = tab is not None and tab.has_single_window_visible() if is_single_window: q = getattr(opts.single_window_margin_width, edge) if q > -0.1: @@ -601,7 +603,14 @@ class Window: q = getattr(self.padding, edge) if q is not None: return pt_to_px(q, self.os_window_id) - q = getattr(get_options().window_padding_width, edge) + opts = get_options() + tab = self.tabref() + is_single_window = tab is not None and tab.has_single_window_visible() + if is_single_window: + q = getattr(opts.single_window_padding_width, edge) + if q > -0.1: + return pt_to_px(q, self.os_window_id) + q = getattr(opts.window_padding_width, edge) return pt_to_px(q, self.os_window_id) def update_effective_padding(self) -> None: diff --git a/kitty/window_list.py b/kitty/window_list.py index 1ca4cb9e7..04db0c11b 100644 --- a/kitty/window_list.py +++ b/kitty/window_list.py @@ -101,7 +101,7 @@ class WindowGroup: if not self.windows: return 0 w = self.windows[0] - return w.effective_margin(which, is_single_window=is_single_window) + w.effective_border() * border_mult + w.effective_padding(which) + return w.effective_margin(which) + w.effective_border() * border_mult + w.effective_padding(which) def effective_padding(self, which: EdgeLiteral) -> int: if not self.windows: diff --git a/kitty_tests/layout.py b/kitty_tests/layout.py index cff3feb78..6a1edd7f0 100644 --- a/kitty_tests/layout.py +++ b/kitty_tests/layout.py @@ -31,8 +31,8 @@ class Window: def effective_padding(self, edge): return 1 - def effective_margin(self, edge, is_single_window=False): - return 0 if is_single_window else 1 + def effective_margin(self, edge): + return 1 def set_visible_in_layout(self, val): self.is_visible_in_layout = bool(val)