fix cursor trail not displaying in certain cases #8092
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The issue
The cursor trail will occasionally either not display when the cursor jumps, or more commonly it will initially not display, and then appear shortly after to create a glitchy-looking effect.
I found this is reproducible in vim/neovim depending on how you hold down the keys. If you do not immediately release a keypress, eg you hold '$' to go to the end of a line the trail will not appear. If you hold the key for a short while and then release, the animation will start when you release (although you are only catching the end of the animation). Under the right conditions, this can also be replicated by running a script that simply prints control codes to move the cursor (I can give more details if needed).
This may be difficult to reproduce yourself, because it is dependent on the system clock. It's reproducibility seems to be dependent on which file is open. Personally I could reproduce it 100% with a fresh vim config in kitty/cursor_trail.c.
My diagnosis
The line I have changed previously compared the
cursor_trail
config option to the time since the cursor was changed. To me this seems unintentional, ascursor_trail
is supposed to be treated like a boolean from my understanding. As a consequence if you setcursor_trail
in your config to a large value (eg 100000000) the trail will stop working altogether.Anyway, it seems it is possible for
now - WD.screen->cursor->position_changed_by_client_at
to return a negative value which will cause this condition to fail. I assume the reasoning for this is thatnow
is not actually the current time, it was measured far up the stack, and it is possible for more measurements to occur before the nextnow
is measured. If I print the value while using vim, I can see when I press a key a negative value is printed, and when I release the key a positive value is printed (hence why the animation only starts when you release).I think what the author intended here was to stop checking for updates after the cursor trail animation is finished, so in pseudocode:
OPT(cursor_trail) && sec_to_nanosec(OPT(cursor_trail_decay_slow)) < monotonic() - WD.screen->cursor->position_changed_by_client_at
As it stands though my solution should be just as performant as the master branch, as the condition was essentially never false. If we are interested in adding some performance checks as described above I will consider it. Although going up the stack to ensure the
now
variable is used correctly will likely be too difficult given my knowledge of the codebase.