From 7906e0b96b755ca6e1b505ce88769a2b3b21d1ba Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 10 Jul 2026 02:05:57 +0000 Subject: [PATCH] Make cursor_trail_start_threshold accept two values for x and y dimensions independently --- docs/changelog.rst | 2 +- kitty/cursor_trail.c | 4 ++-- kitty/options/definition.py | 16 ++++++++++------ kitty/options/parse.py | 30 +++++++++++++++--------------- kitty/options/to-c-generated.h | 2 +- kitty/options/to-c.h | 6 ++++++ kitty/options/types.py | 2 +- kitty/options/utils.py | 10 ++++++++++ kitty/state.h | 3 ++- 9 files changed, 48 insertions(+), 27 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index b68e217e4..ce7e3512f 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -222,7 +222,7 @@ Detailed list of changes - quick-access-terminal kitten: Allow configuring the layer on which to display the terminal (:pull:`10242`) - +- :opt:`cursor_trail_start_threshold` now optionally accepts two values to set x (horizontal) and y (vertical) thresholds independently (:iss:`10246`) 0.47.4 [2026-06-15] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/kitty/cursor_trail.c b/kitty/cursor_trail.c index 8aeec4917..0d1425269 100644 --- a/kitty/cursor_trail.c +++ b/kitty/cursor_trail.c @@ -55,10 +55,10 @@ should_skip_cursor_trail_update(CursorTrail *ct, ndc_coords g, OSWindow *os_wind return true; } - if (OPT(cursor_trail_start_threshold) > 0 && !ct->needs_render) { + if ((OPT(cursor_trail_start_threshold_x) > 0 || OPT(cursor_trail_start_threshold_y) > 0) && !ct->needs_render) { int dx = (int)round((ct->corner_x[0] - EDGE(x, 1)) / g.dx); int dy = (int)round((ct->corner_y[0] - EDGE(y, 0)) / g.dy); - if (abs(dx) + abs(dy) <= OPT(cursor_trail_start_threshold)) { + if (abs(dx) <= OPT(cursor_trail_start_threshold_x) && abs(dy) <= OPT(cursor_trail_start_threshold_y)) { return true; } } diff --git a/kitty/options/definition.py b/kitty/options/definition.py index 738825fe0..3a55053e5 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -406,13 +406,17 @@ Adjust these values to control how quickly the cursor trail fades away. ''') opt('cursor_trail_start_threshold', '2', - option_type='positive_int', ctype='int', + option_type='cursor_trail_start_threshold', + ctype='!cursor_trail_start_threshold', long_text=''' -Set the distance threshold for starting the cursor trail. This option accepts a -positive integer value that represents the minimum number of cells the -cursor must move before the trail is started. When the cursor moves less than -this threshold, the trail is skipped, reducing unnecessary cursor trail -animation. +Set the distance threshold for starting the cursor trail. This option accepts +one or two positive integer values. When a single value is specified, it sets +the threshold for both horizontal (x) and vertical (y) movement. When two +values are specified, the first sets the x (horizontal) threshold and the +second sets the y (vertical) threshold. The values represent the minimum +number of cells the cursor must move in each dimension before the trail is +started. When the cursor moves less than the threshold in both dimensions, +the trail is skipped, reducing unnecessary cursor trail animation. ''') opt('cursor_trail_color', 'none', diff --git a/kitty/options/parse.py b/kitty/options/parse.py index 56e3e18b1..6f99de673 100644 --- a/kitty/options/parse.py +++ b/kitty/options/parse.py @@ -11,20 +11,20 @@ from kitty.options.utils import ( action_alias, active_tab_title_template, allow_hyperlinks, background_images, bell_on_tab, box_drawing_scale, clear_all_mouse_actions, clear_all_shortcuts, clipboard_control, clone_source_strategies, 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_scrollback_indicator_opacity, deprecated_send_text, disable_ligatures, edge_width, env, - filter_notification, font_features, hide_window_decorations, macos_option_as_alt, - macos_titlebar_color, menu_map, modify_font, mouse_hide_wait, narrow_symbols, notify_on_cmd_finish, - optional_edge_width, parse_font_spec, parse_map, parse_mouse_map, paste_actions, - pointer_shape_when_dragging, remote_control_password, resize_debounce_time, scrollback_lines, - scrollback_pager_history_size, scrollbar_color, shell_integration, show_hyperlink_targets, - store_multiple, symbol_map, tab_activity_symbol, tab_bar_edge, tab_bar_margin_height, - tab_bar_min_tabs, tab_fade, tab_font_style, tab_separator, tab_title_template, - text_fg_override_threshold, titlebar_color, to_cursor_shape, to_cursor_unfocused_shape, - to_font_size, to_layout_names, to_modifiers, transparent_background_colors, underline_exclusion, - url_prefixes, url_style, visual_bell_duration, visual_window_select_characters, window_border_width, - window_logo_scale, window_size + cursor_blink_interval, cursor_text_color, cursor_trail_decay, cursor_trail_start_threshold, + deprecated_adjust_line_height, deprecated_hide_window_decorations_aliases, + deprecated_macos_show_window_title_in_menubar_alias, deprecated_scrollback_indicator_opacity, + deprecated_send_text, disable_ligatures, edge_width, env, filter_notification, font_features, + hide_window_decorations, macos_option_as_alt, macos_titlebar_color, menu_map, modify_font, + mouse_hide_wait, narrow_symbols, notify_on_cmd_finish, optional_edge_width, parse_font_spec, + parse_map, parse_mouse_map, paste_actions, pointer_shape_when_dragging, remote_control_password, + resize_debounce_time, scrollback_lines, scrollback_pager_history_size, scrollbar_color, + shell_integration, show_hyperlink_targets, store_multiple, symbol_map, tab_activity_symbol, + tab_bar_edge, tab_bar_margin_height, tab_bar_min_tabs, tab_fade, tab_font_style, tab_separator, + tab_title_template, text_fg_override_threshold, titlebar_color, to_cursor_shape, + to_cursor_unfocused_shape, to_font_size, to_layout_names, to_modifiers, + transparent_background_colors, underline_exclusion, url_prefixes, url_style, visual_bell_duration, + visual_window_select_characters, window_border_width, window_logo_scale, window_size ) @@ -953,7 +953,7 @@ class Parser: ans['cursor_trail_decay'] = cursor_trail_decay(val) def cursor_trail_start_threshold(self, val: str, ans: dict[str, typing.Any]) -> None: - ans['cursor_trail_start_threshold'] = positive_int(val) + ans['cursor_trail_start_threshold'] = cursor_trail_start_threshold(val) def cursor_underline_thickness(self, val: str, ans: dict[str, typing.Any]) -> None: ans['cursor_underline_thickness'] = positive_float(val) diff --git a/kitty/options/to-c-generated.h b/kitty/options/to-c-generated.h index 0d7d03897..d209fb78d 100644 --- a/kitty/options/to-c-generated.h +++ b/kitty/options/to-c-generated.h @@ -228,7 +228,7 @@ convert_from_opts_cursor_trail_decay(PyObject *py_opts, Options *opts) { static void convert_from_python_cursor_trail_start_threshold(PyObject *val, Options *opts) { - opts->cursor_trail_start_threshold = PyLong_AsLong(val); + cursor_trail_start_threshold(val, opts); } static void diff --git a/kitty/options/to-c.h b/kitty/options/to-c.h index dd1ea8399..4a43e8d62 100644 --- a/kitty/options/to-c.h +++ b/kitty/options/to-c.h @@ -289,6 +289,12 @@ cursor_trail_decay(PyObject *src, Options *opts) { opts->cursor_trail_decay_slow = PyFloat_AsFloat(PyTuple_GET_ITEM(src, 1)); } +static inline void +cursor_trail_start_threshold(PyObject *src, Options *opts) { + opts->cursor_trail_start_threshold_x = (int)PyLong_AsLong(PyTuple_GET_ITEM(src, 0)); + opts->cursor_trail_start_threshold_y = (int)PyLong_AsLong(PyTuple_GET_ITEM(src, 1)); +} + static inline void cursor_trail_color(PyObject *src, Options *opts) { opts->cursor_trail_color = color_or_none_as_int(src); diff --git a/kitty/options/types.py b/kitty/options/types.py index 7569d5a45..cf7009fb1 100644 --- a/kitty/options/types.py +++ b/kitty/options/types.py @@ -567,7 +567,7 @@ class Options: cursor_trail: int = 0 cursor_trail_color: kitty.fast_data_types.Color | None = None cursor_trail_decay: tuple[float, float] = (0.1, 0.4) - cursor_trail_start_threshold: int = 2 + cursor_trail_start_threshold: tuple[int, int] = (2, 2) cursor_underline_thickness: float = 2.0 default_pointer_shape: choices_for_default_pointer_shape = 'beam' detect_urls: bool = True diff --git a/kitty/options/utils.py b/kitty/options/utils.py index 18ef6c4ab..acee2cf70 100644 --- a/kitty/options/utils.py +++ b/kitty/options/utils.py @@ -585,6 +585,16 @@ def cursor_trail_decay(x: str) -> tuple[float, float]: slow = max(slow, fast) return fast, slow + +def cursor_trail_start_threshold(x: str) -> tuple[int, int]: + parts = x.split() + if len(parts) == 1: + val = positive_int(parts[0]) + return val, val + if len(parts) == 2: + return positive_int(parts[0]), positive_int(parts[1]) + raise ValueError(f'cursor_trail_start_threshold must have 1 or 2 values, got: {x!r}') + def scrollback_lines(x: str) -> int: ans = int(x) if ans < 0: diff --git a/kitty/state.h b/kitty/state.h index 90c86bab2..86d0b5e5d 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -65,7 +65,8 @@ typedef struct Options { float cursor_trail_decay_fast; float cursor_trail_decay_slow; color_type cursor_trail_color; - float cursor_trail_start_threshold; + int cursor_trail_start_threshold_x; + int cursor_trail_start_threshold_y; unsigned int url_style; unsigned int scrollback_pager_history_size; bool scrollback_fill_enlarged_window;