Subject: bug#14616: 24.3.50; Excessive cursor movement on non-X Emacs

From: Eli Zaretskii <[email-masked]>
Date: Sat, 03 Aug 2013 16:32:10 +0300

> From: Lars Magne Ingebrigtsen <[email-masked]>
> Cc: [email-masked]
> Date: Sat, 03 Aug 2013 15:00:01 +0200
> 
> Hm...   Is wait_reading_process_output triggering this?

It triggers redisplay, yes, but that's not the problem.  The problem
is here:

> Hardware watchpoint 4: -location current_row->enabled_p
> 
> Old value = 1024
> New value = 0
> clear_glyph_matrix_rows (matrix=0xc16260, start=23, end=25) at dispnew.c:730
> 730	  for (; start < end; ++start)
> #0  clear_glyph_matrix_rows (matrix=0xc16260, start=23, end=25) at dispnew.c:730
> #1  0x0000000000412a60 in clear_glyph_matrix (matrix=0xc16260) at dispnew.c:749
> #2  0x0000000000412f52 in clear_current_matrices (f=0xc12be0) at dispnew.c:797
> #3  0x0000000000444c1b in clear_garbaged_frames () at xdisp.c:10726
> #4  0x00000000004497de in redisplay_internal () at xdisp.c:13047

Emacs thinks that the frame is garbaged, so it clears the enabled_p
flag of all of the screen lines on that frame, at the beginning of
each redisplay cycle.

This all sounds depressingly similar to what we found in bug #13864,
which was supposed to be fixed long ago.  Please use the technique
described in http://debbugs.gnu.org/cgi/bugreport.cgi?bug=13864#68 to
find out what code sets the frame's garbaged flag.  (The line numbers
cited in that message are different now, so be sure to use the current
ones.)

Does the recipe you use involve more than one frame, somehow?  The
problem fixed in bug #13864 was in this snippet from frame.c:

  if (FRAME_TERMCAP_P (XFRAME (frame)) || FRAME_MSDOS_P (XFRAME (frame)))
    {
      Lisp_Object top_frame = FRAME_TTY (XFRAME (frame))->top_frame;

      /* Don't mark the frame garbaged and/or obscured if we are
	 switching to the frame that is already the top frame of that
	 TTY.  */
      if (!EQ (frame, top_frame))
	{
	  if (FRAMEP (top_frame))
	    /* Mark previously displayed frame as now obscured.  */
	    SET_FRAME_VISIBLE (XFRAME (top_frame), 2);
	  SET_FRAME_VISIBLE (XFRAME (frame), 1);  <<<<<<<<<<<<<<<<<<<<
	}
      FRAME_TTY (XFRAME (frame))->top_frame = frame;
    }

The marked call to SET_FRAME_VISIBLE would set the frame's garbaged
flag.  The solution was to avoid doing that if FRAME is already the
top frame shown on that terminal (the EQ test and the comment before
it were added as part of fixing that bug).  Perhaps in your case this
logic is somehow not working?