bug-gnu-emacs
[Top][All Lists]
Advanced

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

bug#20180: Missing documentation about redisplay.


From: Alan Mackenzie
Subject: bug#20180: Missing documentation about redisplay.
Date: Mon, 23 Mar 2015 20:17:52 +0000
User-agent: Mutt/1.5.23 (2014-03-12)

On Mon, Mar 23, 2015 at 08:29:03PM +0200, Eli Zaretskii wrote:
> > Date: Mon, 23 Mar 2015 17:55:25 +0000
> > Cc: 20180@debbugs.gnu.org
> > From: Alan Mackenzie <acm@muc.de>

> > What triggered my documentation search was looking at
> > jit-lock-fontify-now.

> Note that digging into JIT Lock means going deep into the internals of
> the display engine.  It's no accident that jit-lock.el was written by
> Gerd Moellmann, who designed and implemented the current display
> engine.

OK.  I thought it was Simon Marshall who wrote jit-lock.el.  Obviously
I'm mistaken.

> IOW, it's by no means ELisp manual level stuff (although I of course
> agree that IWBN to have the display engine's internals described in
> full, along with all the other internals).

I think some of what we've been discussing would be useful to put in a
new page in the elisp manual; it wouldn't have to be a very big page.

> > There, if jit-lock suspects that properties at an
> > earlier location in the buffer have been changed, it arranges that after
> > the end of the current display cycle, some text properties at some of
> > these locations get set, thus triggering another redisplay.

> > How?

> By changing the special text property 'fontified'.

> > Why does this trigger a redisplay when the setting of the
> > properties during the previous redisplay cycle didn't?

> I don't understand the question.  What "setting of properties" during
> which "previous redisplay cycle" do you have in mind?

1. Redisplay cycle 1 starts.
2. First 500-byte chunk gets fontified through fontification-functions.
3. Second 500-byte chunk fontification starts.
4.   jit-lock-fontify-now applies face properties to a few characters of
     the first 500-byte chunk at locations 496, 497, 498, 499.
5.   jit-lock-fontify-now arranges for 10. to happen at the expiry of a 0
     second timeout.  (`run-with-timer')
6. Second 500-byte chunk is completely fontified.  It gets drawn on the
   screen.
7. Redisplay cycle 1 is now complete.

10. (At expiry of 0 second timeout), jit-lock-force-redisplay applies
   text property (fontified t) to location 496, 497, 498, 499.  496..499
   already had the property (fontified t).
11. Redisplay cycle 2 starts, having been triggered by 10.
12. ???? Redisplay draws 496, .., 499 on the screen, but no others.
13. Redisplay cycle 2 is now complete.

I think I meant to ask: why does setting text property 'fontified to t at
stage 10 trigger redisplay cycle 2, whereas setting them at stage 4.5
wouldn't have done?

> > In the new redisplay, does the whole frame/window/minibuffer get
> > redrawn (for whatever value of "redraw") or just the bits where text
> > properties were set?

> This depends on what you mean by "redraw".  A redisplay cycle has 2
> phases.  In the first phase, Emacs examines the visible portion of the
> buffer and tries to determine the minimal number of screen lines that
> might need to be redrawn; it then prepares the corresponding portions
> of the glyph matrix for those screen lines.  Normally, only the screen
> lines where the 'fontified' text property changed will be considered.

In 10. above, the `fontified' text property is set to the value it
already had.  This seems to be sufficient to trigger a redisplay.

> In the second phase of redisplay, the prepared glyph matrix is
> compared to the previous one, which describes what's on the glass, and
> only the different portions are actually redrawn.  It could be that
> nothing needs to be redrawn at all.

OK.

> > If I were to execute the command `ignore' via a key sequence, would that
> > trigger redisplay?

> Yes, redisplay is triggered each time Emacs waits for more input and
> has nothing else to do.

> > If so, how much would get redrawn?

> Nothing at all, since nothing changed.

Thanks, that's good to understand.

> > I read the "whenever" as meaning "when it's waiting for input, it tries
> > _once_ to redisplay".  Having tried once, and 0.5s
> > (jit-lock-context-time) have passed, then jit-lock-context-fontify kicks
> > in to fontify screen lines below where a buffer change happened.  Another
> > redisplay then happens.  What triggers this second redisplay, given there
> > hasn't been any more "input"?

> The JIT Lock timer.

OK.

> > Or does the expiry of the timer count as "input" here?  Or is
> > something other than input (?a buffer change) triggering this second
> > redisplay?

> Yes, timers have the same effect as input: they return to the command
> loop after the timer function is run, and the command loop enters
> redisplay if there's no input.

> > > > One clearly needs an answer to 2. if one ever wants to cause the
> > > > redisplay of a particular part of a window or frame.

> > > To do that, you need to change the text of that part or the text
> > > properties/overlays that affect how that part looks on display.  But
> > > you most probably already know that, so I'm again not sure what the
> > > question is.

To summarize: to cause a redisplay which changes what you see (without
any scrolling happening) it is necessary to (i) change some text or
"significant" property/overlay on a displayed portion of a buffer; (ii)
cause an input event of any kind.

What I'm now thinking is that jit-lock-trigger-redisplay, and its setting
of text properties to the value they already have, is a complete red
herring[*] - the same effect could have been achieved by putting `ignore'
on the run-with-timer at stage 5, it merely being the expiry of the timer
triggering the redisplay cycle 2.

[*] "Red herring": anything which diverts attention from a topic or line
of enquiry.

> > In jit-lock-fontify-now, the top half of a screen window has just been
> > redisplayed, and j-l-fontify-now is busily applying faces for the next
> > 500-byte chunk.  In so doing, it sets faces in the part of the window
> > that have already been redisplayed.  This is apparently insufficient in
> > itself to trigger another redisplay of those already displayed window
> > parts.  I would like to understand why.

> jit-lock-fontify-now can be called in 2 different ways.  One is as
> part of redisplay itself, because jit-lock-function, which calls
> jit-lock-fontify-now, is added to fontification-functions, which are
> run by the display engine when it bumps into a buffer position that
> has the 'fontified' text property whose value is nil.  When
> jit-lock-fontify-now is called by this mechanism, it fontifies
> portions that were not yet displayed.  After fontification-functions
> return, the display engine re-examines the buffer position where they
> were called, since it knows that faces could change there.  This
> constitutes "another redisplay" you were looking for, without actually
> triggering a full redisplay cycle.  Keep in mind that the display
> engine examines buffer text one character at a time, so it is only
> ever interested in the faces at the single buffer position it is
> examining.

> The other way jit-lock-fontify-now is called is from the Jit Stealth
> or deferred Jit Lock, in which case it does trigger another redisplay,
> as you expect.

> HTH

Enormously!  Thanks very much.

-- 
Alan Mackenzie (Nuremberg, Germany).





reply via email to

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