[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Question about display engine

From: Ergus
Subject: Re: Question about display engine
Date: Wed, 7 Aug 2019 17:32:20 +0200
User-agent: NeoMutt/20180716

On Wed, Aug 07, 2019 at 06:01:12PM +0300, Eli Zaretskii wrote:
Date: Wed, 7 Aug 2019 02:54:11 +0200
From: Ergus <address@hidden>
Cc: address@hidden

Sorry to bother with this.

Sorry for not answering sooner: I needed to find time to re-read the
relevant code and recollect the consequences.

Fixing the issue 36858 in text mode I found that the
extend_face_to_end_of_line uses the same face for the last char in the


This is useful to extend selection face the whole line, but this created
a difference with gui emacs when the last face was underlined or
overlined because in tui the underline is extended for the entire line.

The issue is more general, and not limited to the underline
attribute.  See below.

To fix this I need to create a new face to extend until the end of the
line that has the same properties than it->face_id except that the
underline and overline properties will be disabled.

Why only underline and overline?  And why do you think you can reset
these attributes at will in this case?  Suppose someone defines the
'region' face to use underline -- we definitely cannot reset this
attribute in that case, because then the region will appear
non-contiguous, right?

I can produce the desired effect doing:

(defface my_new_face
  '((t :weight normal :slant normal
       :underline nil :overline nil :strike-through nil
       :box nil :inverse-video nil :stipple nil)))

DEFSYM (my_new_face, "my-new-face");

it->face_id = merge_faces (it->w, my-new-face, 0, it->face_id)

But this seems very dirty.

How can I produce the same effect in the right way? (I mean create a new
face_id based on it->face_id but with :underline nil :overline
nil... etc?) And only with C code.

You need to call realize_face after copying the attributes of the
default face and resetting some of the attributes to Qunspecified.
But this is the mechanical part of the issue; I think the conceptual
part is more problematic.

First, we indeed behave inconsistently in GUI and TTY frames regarding
faces that straddle the newline.  On GUI frames, some attributes, such
as colors and the box attribute, extend all the way to the window's
edge; others, like underline, overline, and strike-through only affect
the single glyph that stands for the newline (which the display engine
adds so it will have a place to display the cursor).  By contrast, on
TTY frames, every attribute we support in text mode extends to the
window's edge.

Emacs behaved like that since v21.

The question is: which of the 2 is the correct display, if there is a
correct one?  When trying to answer this question, please keep in mind
two special use cases: the use case with the region, and the use case
where the same attribute continues on the next screen line.  Maybe
there are other relevant use cases as well.

I myself don't have a definitive answer.  The TTY behavior makes more
sense to me, but people frequently complain about it saying it's ugly,
so I guess "makes sense" doesn't necessarily cut it.


I am not sure about what will be the community opinion; so I'll wait for
some comments (and the usual complains) before implementing anything.

Maybe it makes some sense to consider the region as a corner case
here. So a possible solution is just to add a condition to reset the
underline (and other attributes) when the last glyph was not in the
active region.

The actual TUI behavior is annoying in some modes; so maybe the best is
to reproduce the gui behavior as it is now in TUI too.


After thinking on that a little bit more since yesterday; maybe it is
possible to add another basic face for the rest of the line. That face
will be merged with the previous face as in the example code, so if it
specifies :underline then merging should work as specified; else, it
will just use the :underline from the latest glyph.

So the user could potentially customize the desired behavior. The
arguments will come about what the defaults should be, but at least we
don't limit that.

Does it makes sense?

reply via email to

[Prev in Thread] Current Thread [Next in Thread]