Subject: Re: bug#42552: 28.0.50; Overlay 'face' property doesn't set the "underlying face" for 'after-string'

From: Eli Zaretskii <[email-masked]>
Date: Wed, 05 Aug 2020 17:58:53 +0300

> Cc: [email-masked]
> From: Dmitry Gutov <[email-masked]>
> Date: Wed, 5 Aug 2020 02:55:59 +0300
> 
> > When the underlying face has the :extend attribute set, we must obey
> > it.  So what you see in that case is the expected behavior.
> 
> Should the "overlay string" obey the underlying face, though? It doesn't 
> obey the 'face' property, like you explained. Seems inconsistent.

Emacs always worked this way, so changing it now is probably a big
deal.  AFAIU, the reason for this behavior is so that overlay strings
which specify no faces use the same face as the surrounding text.
Which sounds reasonable.

> > Emacs 26 and before simply extended the face of the last character of
> > the line.  Emacs 27 doesn't do that, it examines the faces in effect
> > anew, filtering out those which don't have the :extend attribute set,
> > so the result is different.  This is exactly the change in behavior
> > that was intended, not a bug.
> 
> But it should obey :extend set to nil, shouldn't it?

It does, but :extend nil doesn't override :extend t, it just says that
the face with a nil :extend attribute should not be considered when
computing the face for the empty space past EOL.

> Even if I replace 'default' in there with a custom face that sets 
> ':extend' to nil, the result is the same.

Right, as expected.  The nil value of :extend doesn't override the
non-nil value.

> I suppose you mean the custom face must have :extend set to t, and have 
> a :background value computed right before it is used (otherwise the user 
> might customize the faces mid-session, leading to bad visuals).

Yes, that's what I meant.

> That seems to work. It also has the significant benefit on working in 
> Emacs 27, so if that's the approach you recommend in the end, the fix 
> you already pushed to master might be unnecessary.

The fix I pushed might not be necessary for company's sake, but it is
necessary for other use cases, because without it we don't behave as
documented when :extend attribute is not present: we extend using the
wrong background color.

> >> Furthermore, in Emacs 26.3 I can propertize the newlines in the overlay
> >> string with '(face region) and see the "extend" effect. Or keep them
> >> with 'default' face and see no "extend" effect on those lines.
> > 
> > You are saying that this doesn't work in Emacs >= 27?
> 
> One works, the other doesn't.

Well, that's because you expected :extend nil to do something that it
isn't supposed to do.

> > It works with display strings, yes.  You now want to switch to overlay
> > strings, and the rules of collecting faces are subtly different there.
> 
> Hmm, so 'after-string' and 'before-string' are overlay strings, but 
> 'display' set on an overlay is not an overlay string. Okay then.

Yes, the latter is alluded to as "display string", since the string
comes from the 'display' property.