[vim/vim] :sleep! doesn't hide the cursor in gVim (#7998)

36 views
Skip to first unread message

lkintact

unread,
Mar 22, 2021, 6:01:33 PM3/22/21
to vim/vim, Subscribed

To Reproduce

  1. Run gvim --clean
  2. Execute :sleep! 3 (the command is described at :help :sleep!). gVim sleeps for 3 seconds, but doesn't hide the cursor.

Expected behavior
The cursor should be hidden while gVim sleeps.

Environment:

  • Vim version 8.2.2632
  • OS: Windows 10 Home 1803
  • Terminal: GUI.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.

lacygoill

unread,
Mar 23, 2021, 2:14:25 PM3/23/21
to vim/vim, Subscribed

cc @jeremy-quicklearner via #7688

Also, not sure whether it's working as intended, or if it's just corner case, but the cursor is no longer hidden when a timer callback is processed:

vim -Nu NONE +'au CmdlineLeave : call timer_start(0, {-> 0})'
:sleep! 3

Jeremy Lerner

unread,
Mar 23, 2021, 4:51:28 PM3/23/21
to vim/vim, Subscribed

I don't have much insight into how Vim draws the cursor, but I can confirm that I only tested sleep! using Vim on the command-line.

After looking at the code, it seems that cursor_off() only applies to the terminal - not the GUI. It may be possible to modify update_screen() in drawscreen.c so that it calls gui_undraw_cursor() and then skips gui_update_cursor() if sleep! is ongoing. For that, we'd need some sort of ":sleep! is ongoing" flag.

As for the timer callback issue @lacygoill commented on: Looks like sleep and sleep! don't block Vim's event loop. Makes sense. I expect fixing this would require :sleep! to set some flag that later gets checked as part of the callback's event.

So to fix both of these issues, we need a flag that's accessible to both drawscreen.c and term.c. I don't know where best to put it... Perhaps someplace higher up where it can be passed down as a parameter. Maybe someone more experienced can weigh in?

Bram Moolenaar

unread,
Mar 23, 2021, 5:11:12 PM3/23/21
to vim/vim, Subscribed


Jeremy Lerner wrote:

> I don't have much insight into how Vim draws the cursor, but I can confirm that I only tested `sleep!` using Vim on the command-line.
>
> After looking at the code, it seems that `cursor_off()` only applies to the terminal - not the GUI. It may be possible to modify `update_screen()` in `drawscreen.c` so that it calls `gui_undraw_cursor()` and then skips `gui_update_cursor()` if `sleep!` is ongoing. For that, we'd need some sort of "`:sleep!` is ongoing" flag.
>
> As for the timer callback issue @lacygoill commented on: Looks like `sleep` and `sleep!` don't block Vim's event loop. Makes sense. I expect fixing this would require `:sleep!` to set some flag that later gets checked as part of the callback's event.
>
> So to fix both of these issues, we need a flag that's accessible to both `drawscreen.c` and `term.c`. I don't know where best to put it... Perhaps someplace higher up where it can be passed down as a parameter. Maybe someone more experienced can weigh in?

We already have the cursor_is_off flag in term.c. We could add a
"cursor_is_sleeping" flag there, with functions to set/reset it (making
sure reset is always used after set), and a function to get the current
value. That seems the cleanest way. Then when the cursor is displayed
anywhere, the flag can be checked by calling that function. In
cursor_on_force() the flag can be used directly.

--
Anyone who is capable of getting themselves made President should on no
account be allowed to do the job.
-- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Jeremy Lerner

unread,
Mar 24, 2021, 11:48:01 AM3/24/21
to vim/vim, Subscribed

We already have the cursor_is_off flag in term.c. We could add a "cursor_is_sleeping" flag there, with functions to set/reset it (making sure reset is always used after set), and a function to get the current value. That seems the cleanest way. Then when the cursor is displayed anywhere, the flag can be checked by calling that function. In cursor_on_force() the flag can be used directly.

Great! cursor_off() is already called by update_screen() in drawscreen.c, so I agree putting the flag in term.c with set/get functions is the clean choice. I'll give this a try within a few days.

Bram Moolenaar

unread,
Apr 11, 2021, 7:29:59 AM4/11/21
to vim/vim, Subscribed

Closed #7998 via 09f067f.

Reply all
Reply to author
Forward
0 new messages