GNU bug report logs - #10903
24.0.93; redisplay glitch with before-string and display overlays

Previous Next

Package: emacs;

Reported by: Stephen Berman <stephen.berman <at> gmx.net>

Date: Mon, 27 Feb 2012 22:08:02 UTC

Severity: normal

Found in version 24.0.93

Done: Eli Zaretskii <eliz <at> gnu.org>

Bug is archived. No further changes may be made.

Full log


Message #8 received at 10903 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Stephen Berman <stephen.berman <at> gmx.net>
Cc: 10903 <at> debbugs.gnu.org
Subject: Re: bug#10903: 24.0.93;
	redisplay glitch with before-string and display overlays
Date: Tue, 28 Feb 2012 22:40:17 +0200
> From: Stephen Berman <stephen.berman <at> gmx.net>
> Date: Mon, 27 Feb 2012 23:04:03 +0100
> 
> 1. emacs -Q
> 
> 2. Type `C-x b a RET' to get a fresh buffer in Fundamental mode, and  at
> (point-min) type "012".
> 
> 3. Type `M-<' so that the cursor is over (i.e. just before) `0'.
> 
> 4. Type `M-: (overlay-put (make-overlay (point) (point)) 'before-string
> "*")'.  Now you see this:
> 
> *012
> 
> 5. Type `M-: (overlay-put (make-overlay (point) (1+ (point))) 'display
> "")'.  Now you see this:
> 
> *12
> 
> 6. Type `M-: (remove-overlays)' to restore "012".
> 
> 7. Type SPC to advance the cursor and the start of "012" to column one.
> 
> 8. Repeat step 4.  Now you see this:
> 
>  *012
> 
> 9. Repeat step 5.  Now you see this:
> 
>  *112

We were hitting on an old redisplay optimization that didn't play well
with the bidi-aware display engine.

I think I fixed this.  Thanks for such a clear-cut test case.

Since Savannah is on the move, I cannot commit the fix, but perhaps
you could test it locally and see if there are any leftovers.  Here's
the patch:

=== modified file 'src/xdisp.c'
--- src/xdisp.c	2012-02-12 09:46:33 +0000
+++ src/xdisp.c	2012-02-28 20:35:41 +0000
@@ -5156,6 +5156,10 @@ next_overlay_string (struct it *it)
       it->current.overlay_string_index = -1;
       it->n_overlay_strings = 0;
       it->overlay_strings_charpos = -1;
+      /* If there's an empty display string on the stack, pop the
+	 stack, to resync the bidi iterator with IT's position.  */
+      if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
+	pop_it (it);
 
       /* If we're at the end of the buffer, record that we have
 	 processed the overlay strings there already, so that
@@ -5453,8 +5457,15 @@ get_overlay_strings_1 (struct it *it, EM
       xassert (!compute_stop_p || it->sp == 0);
 
       /* When called from handle_stop, there might be an empty display
-         string loaded.  In that case, don't bother saving it.  */
-      if (!STRINGP (it->string) || SCHARS (it->string))
+         string loaded.  In that case, don't bother saving it.  But
+         don't use this optimization with the bidi iterator, since we
+         need the corresponding pop_it call to resync the bidi
+         iterator's position with IT's position, after we are done
+         with the overlay strings.  (The corresponding call to pop_it
+         in case of an empty display string is in
+         next_overlay_string.)  */
+      if (!(!it->bidi_p
+	    && STRINGP (it->string) && !SCHARS (it->string)))
 	push_it (it, NULL);
 
       /* Set up IT to deliver display elements from the first overlay






This bug report was last modified 13 years and 84 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.