From 463c759bfb98c12e6326b6a417093a030b4cf445 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 18 Oct 2024 11:04:13 +0530 Subject: [PATCH] Allow changing the cursor trail threshold time independently of input_delay --- kitty/child-monitor.c | 4 ++-- kitty/cursor_trail.c | 2 +- kitty/options/definition.py | 18 ++++++++++++------ kitty/options/parse.py | 6 +++--- kitty/options/to-c-generated.h | 12 ++++++------ kitty/options/types.py | 4 ++-- kitty/state.h | 2 +- 7 files changed, 27 insertions(+), 21 deletions(-) diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index d2c6707d3..a71ca63b5 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -751,7 +751,7 @@ prepare_to_render_os_window(OSWindow *os_window, monotonic_t now, unsigned int * WD.screen->cursor_render_info.is_focused = os_window->is_focused; set_os_window_title_from_window(w, os_window); *active_window_bg = window_bg; - if (OPT(enable_cursor_trail) && update_cursor_trail(&tab->cursor_trail, w, now, os_window)) { + if (OPT(cursor_trail) && update_cursor_trail(&tab->cursor_trail, w, now, os_window)) { needs_render = true; set_maximum_wait(OPT(repaint_delay)); } @@ -812,7 +812,7 @@ render_prepared_os_window(OSWindow *os_window, unsigned int active_window_id, co w->cursor_opacity_at_last_render = WD.screen->cursor_render_info.opacity; w->last_cursor_shape = WD.screen->cursor_render_info.shape; } } - if (OPT(enable_cursor_trail) && tab->cursor_trail.needs_render) draw_cursor_trail(&tab->cursor_trail); + if (OPT(cursor_trail) && tab->cursor_trail.needs_render) draw_cursor_trail(&tab->cursor_trail); if (os_window->live_resize.in_progress) draw_resizing_text(os_window); swap_window_buffers(os_window); os_window->last_active_tab = os_window->active_tab; os_window->last_num_tabs = os_window->num_tabs; os_window->last_active_window_id = active_window_id; diff --git a/kitty/cursor_trail.c b/kitty/cursor_trail.c index c90e6b6c0..47cba8fbf 100644 --- a/kitty/cursor_trail.c +++ b/kitty/cursor_trail.c @@ -56,7 +56,7 @@ update_cursor_trail(CursorTrail *ct, Window *w, monotonic_t now, OSWindow *os_wi ct->corner_y[i] = EDGE(y, ci[i][1]); } } - else if (OPT(input_delay) < now - WD.screen->cursor->updated_at && ct->updated_at < now) { + else if (OPT(cursor_trail) < now - WD.screen->cursor->updated_at && ct->updated_at < now) { float cursor_center_x = (EDGE(x, 0) + EDGE(x, 1)) * 0.5f; float cursor_center_y = (EDGE(y, 0) + EDGE(y, 1)) * 0.5f; float cursor_diag_2 = norm(EDGE(x, 1) - EDGE(x, 0), EDGE(y, 1) - EDGE(y, 0)) * 0.5f; diff --git a/kitty/options/definition.py b/kitty/options/definition.py index 7ca554e3c..b6c59706c 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -350,11 +350,17 @@ inactivity. Set to zero to never stop blinking. ''' ) -opt('enable_cursor_trail', 'no', - option_type='to_bool', ctype='bool', +opt('cursor_trail', '0', + option_type='positive_int', ctype='time-ms', long_text=''' -Enables or disables the cursor trail effect. When set to `yes`, a trailing -effect is rendered behind the cursor as it moves, creating a motion trail. +Set this to a value larger than zero to enable a "cursor trail" animation. +This is an animation that shows a "trail" following the movement of the text cursor. +It makes it easy to follow large cursor jumps and makes for a cool visual effect +of the cursor zooming around the screen. The actual value of this option +controls when the animation is trigerred. It is a number of milliseconds. The +trail animation only follows cursors that have stayed in their position for longer +than the specified number of milliseconds. This prevents trails from appearing +for cursors that rapidly change their positions during UI updates in complex applications. ''' ) @@ -362,8 +368,8 @@ opt('cursor_trail_decay', '0.1 0.3', option_type='cursor_trail_decay', ctype='!cursor_trail_decay', long_text=''' -Controls the decay times for the cursor trail effect when :code:`enable_cursor_trail` -is set to :code:`yes`. This option accepts two positive float values specifying the +Controls the decay times for the cursor trail effect when the :opt:`cursor_trail` +is enabled. This option accepts two positive float values specifying the fastest and slowest decay times in seconds. The first value corresponds to the fastest decay time (minimum), and the second value corresponds to the slowest decay time (maximum). The second value must be equal to or greater than the diff --git a/kitty/options/parse.py b/kitty/options/parse.py index a871056ab..3953912b5 100644 --- a/kitty/options/parse.py +++ b/kitty/options/parse.py @@ -931,6 +931,9 @@ class Parser: def cursor_text_color(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: ans['cursor_text_color'] = cursor_text_color(val) + def cursor_trail(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: + ans['cursor_trail'] = positive_int(val) + def cursor_trail_decay(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: ans['cursor_trail_decay'] = cursor_trail_decay(val) @@ -966,9 +969,6 @@ class Parser: def enable_audio_bell(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: ans['enable_audio_bell'] = to_bool(val) - def enable_cursor_trail(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: - ans['enable_cursor_trail'] = to_bool(val) - def enabled_layouts(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: ans['enabled_layouts'] = to_layout_names(val) diff --git a/kitty/options/to-c-generated.h b/kitty/options/to-c-generated.h index 7eb1392e5..0dd7f7345 100644 --- a/kitty/options/to-c-generated.h +++ b/kitty/options/to-c-generated.h @@ -162,15 +162,15 @@ convert_from_opts_cursor_stop_blinking_after(PyObject *py_opts, Options *opts) { } static void -convert_from_python_enable_cursor_trail(PyObject *val, Options *opts) { - opts->enable_cursor_trail = PyObject_IsTrue(val); +convert_from_python_cursor_trail(PyObject *val, Options *opts) { + opts->cursor_trail = parse_ms_long_to_monotonic_t(val); } static void -convert_from_opts_enable_cursor_trail(PyObject *py_opts, Options *opts) { - PyObject *ret = PyObject_GetAttrString(py_opts, "enable_cursor_trail"); +convert_from_opts_cursor_trail(PyObject *py_opts, Options *opts) { + PyObject *ret = PyObject_GetAttrString(py_opts, "cursor_trail"); if (ret == NULL) return; - convert_from_python_enable_cursor_trail(ret, opts); + convert_from_python_cursor_trail(ret, opts); Py_DECREF(ret); } @@ -1149,7 +1149,7 @@ convert_opts_from_python_opts(PyObject *py_opts, Options *opts) { if (PyErr_Occurred()) return false; convert_from_opts_cursor_stop_blinking_after(py_opts, opts); if (PyErr_Occurred()) return false; - convert_from_opts_enable_cursor_trail(py_opts, opts); + convert_from_opts_cursor_trail(py_opts, opts); if (PyErr_Occurred()) return false; convert_from_opts_cursor_trail_decay(py_opts, opts); if (PyErr_Occurred()) return false; diff --git a/kitty/options/types.py b/kitty/options/types.py index 0bb9f0c99..0b35668c0 100644 --- a/kitty/options/types.py +++ b/kitty/options/types.py @@ -334,6 +334,7 @@ option_names = ( # {{{ 'cursor_shape_unfocused', 'cursor_stop_blinking_after', 'cursor_text_color', + 'cursor_trail', 'cursor_trail_decay', 'cursor_underline_thickness', 'default_pointer_shape', @@ -344,7 +345,6 @@ option_names = ( # {{{ 'dynamic_background_opacity', 'editor', 'enable_audio_bell', - 'enable_cursor_trail', 'enabled_layouts', 'env', 'exe_search_path', @@ -512,6 +512,7 @@ class Options: cursor_shape_unfocused: int = 4 cursor_stop_blinking_after: float = 15.0 cursor_text_color: typing.Optional[kitty.fast_data_types.Color] = Color(17, 17, 17) + cursor_trail: int = 0 cursor_trail_decay: typing.Tuple[float, float] = (0.1, 0.3) cursor_underline_thickness: float = 2.0 default_pointer_shape: choices_for_default_pointer_shape = 'beam' @@ -522,7 +523,6 @@ class Options: dynamic_background_opacity: bool = False editor: str = '.' enable_audio_bell: bool = True - enable_cursor_trail: bool = False enabled_layouts: typing.List[str] = ['fat', 'grid', 'horizontal', 'splits', 'stack', 'tall', 'vertical'] file_transfer_confirmation_bypass: str = '' focus_follows_mouse: bool = False diff --git a/kitty/state.h b/kitty/state.h index 19a5d4b72..08a592001 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -46,7 +46,7 @@ typedef struct { CursorShape cursor_shape, cursor_shape_unfocused; float cursor_beam_thickness; float cursor_underline_thickness; - bool enable_cursor_trail; + monotonic_t cursor_trail; float cursor_trail_decay_fast; float cursor_trail_decay_slow; unsigned int url_style;