Subject: Re: bug#63187: 30.0.50; Tail of longer lines painted after end of nearby lines on macOS

From: Alan Third <[email-masked]>
Date: Tue, 2 May 2023 11:14:56 +0100

On Mon, May 01, 2023 at 06:40:15PM -0400, Aaron Jensen wrote:
> On Mon, May 1, 2023 at 1:26 PM Alan Third <[email-masked]> wrote:
> >
> > My memory of Aaron's previous bug report about this was that it looked
> > like, in some cases at least, the rectangle being copied was too wide
> > and copyRect, not being very smart, was just wrapping off the edge of
> > the buffer onto the next row of pixels, but I couldn't find any reason
> > for that to happen since afaik all the callers check the Emacs window
> > size so should never ask to copy a too-wide rectangle.
> 
> This one seems to be more about longer lines ghosting onto the tail
> end of shorter lines. You could imagine that if you had a long line
> and a short line, then scrolled such that the short line was where the
> long line was but only repainted the area there were glyphs, the new
> short line would include the tail end of the long line:
> 
> window line 2: xxxxxxxxxxxxxx
> window line 3: yyyyyyyyyy
> ->
> window 1: xxxxxxxxxxxxxx
> window 2: yyyyyyyyyyxxxx

Yeah, that's why I'm wondering if there's a timing thing where the
toolkit hasn't completed it's drawing before we copy the pixels. Emacs
might ask to clear the end of a line, then copy those "cleared" pixels
using copyRect before the initial clear has actually been completed.

This is just conjecture, though.

The other option is that it is copying too much and grabbing things it
shouldn't, but even though I think we've seen that before, I don't
know how it would happen.

Although, on reflection, your description sounds more like it's just
not clearing the end of lines correctly, which wouldn't necessarily
have anything to do with scrolling as such...

> What do you think about what I mentioned later in the thread about:
> 
> [view setNeedsDisplayInRect:srcRect];
> 
> Why would that be srcRect and not destRect? Could that cause this somehow?

I suspect that's a hang-over from the old rendering scheme where we
would have had to flag up that the source would need redrawn later.

scrollRect already marks the destination as needing updated on screen,
but iirc for whatever reason the source was never flagged as needing
redrawn, which it almost always did when scrolling.

The 10.14+ drawing scheme doesn't really require individual areas to
be marked as needing redrawn since the entire back buffer is sent to
the screen on update anyway. It could be worth replacing that with a
call to [NSView setNeedsDisplay:], or getting rid of it and making
copyRect do it instead. I don't know if it's even necessary since
I think Emacs will always do other drawing actions as part of a scroll
which will mark the view as needing sent to the screen.
-- 
Alan Third