Subject: bug#20285: 25.0.50; blink-cursor-mode sometimes stops blinking

From: Tassilo Horn <[email-masked]>
Date: Sat, 11 Apr 2015 07:54:52 +0200

Stefan Monnier <[email-masked]> writes:

>> I can at least confirm that `blink-cursor-timer-function' runs every 0.5
>> seconds and toggles the visibility state of the cursor.  When that state
>> doesn't appear on the screen, then what else can it be except for a
>> skipped redisplay.
>
> Of course, I don't know what it is, but it could be many other things,
> such as a successful redisplay which somehow just didn't think the
> relevant window needed to be refreshed.
> Or a misinterpretation of the state of the cursor?
> Or maybe the cursor state is indeed changed, but not in the right window?

That happens also when there is just one window (except the minibuffer
window).  And when there are more, the cursors in the other windows stay
hollow boxes.  I haven't noticed that one of them disappeared completely
yet.

>> Maybe the interval is 0.8 seconds sometimes when emacs is under heavy
>> load.  But the timer not being run is definitely not the cause for not
>> blinking for up to 10 seconds here.
>>> Have you tried to call `redisplay' explicitly from the blink-cursor
>>> timer?
>> Yes, then it blinks fine even under stress.
>
> Great, so that would hint at redisplay being skipped, indeed.
> Revision 9e77c1b7bcfd0807be7fe67daf73c2320e864309 changed the way we
> decide when to skip a redisplay recently.  The change should make us
> skip redisplay strictly less often rather than more often, but maybe
> there's a problem in that change.
>
> You could also use a pre-redisplay-function to count how many times
> redisplay happensin that particular window.

Ok, I used the following code (add-function because there's already a
pre-redisplay function which I didn't want to replace):

--8<---------------cut here---------------start------------->8---
(defvar th/redisplay-count 0)

(defun th/count-redisplays (windows)
  (when (or (null windows)
            (eq windows t)
            (memq (selected-window) windows))
    (incf th/redisplay-count)))

(add-function :before pre-redisplay-function #'th/count-redisplays)
--8<---------------cut here---------------end--------------->8---

Then I switched to some large latex buffer, did M-: (setq
th/redisplay-count 0), and then started compiling that document to
generate some load.  Then I waited for exactly one minute in which there
has been at least one phase of almost 10 seconds with the cursor being
invisible on the screen before getting the value of th/redisplay-count.

And the value is seven hundred something every time I test.  That's more
than 10 redisplays of the selected window per second!  I didn't do
anything in that one minute so there shouldn't have been a reason for
redisplay to kick in except for the blinking cursor.  And that would
suggest 120 redisplays.

Of course, it's still possible that during the 10 seconds where the
cursor was invisible on the screen there hasn't been a redisplay of the
selected window, but how can I know?

Bye,
Tassilo