emacs-devel
[Top][All Lists]
Advanced

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

Re: Aborting display. Is this possible?


From: Eli Zaretskii
Subject: Re: Aborting display. Is this possible?
Date: Mon, 20 Oct 2014 18:12:05 +0300

> Date: Mon, 20 Oct 2014 11:09:49 +0000
> Cc: address@hidden
> From: Alan Mackenzie <address@hidden>
> 
> On a large C Mode buffer (such as xdisp.c), hold down the PageDown key
> for, say, 10 seconds.
> 
> What is seen: The screen freezes.  After releasing the key, it takes many
> seconds (~10) before the current buffer position is displayed on the
> screen.
> 
> What I'd like to see: The screen continuously updating with (not
> necessarily contiguous) parts of the buffer, the updating being frequent
> enough to give the illusion of continuous scrolling.  On releasing the
> key, the screen "instantly" displaying the new buffer position.

I understand the desire, and I'm not saying it isn't reasonable.  So
please don't take what's below as a rebuttal; I'm just trying to
explain how the current Emacs design works against your wishes, and
what could/should be changed for your wishes to maybe become reality.

I will probably say some (or many) things that you already know, so
please bear with me.

First, Emacs's basic design is that it processes all the available
input before it enters redisplay.  As long as there's input in the
input queue, Emacs will not call redisplay.  (There are 2 exceptions
to this rule: processing input could indirectly call the 'redisplay'
function; and messages in the echo area produced while processing
input require a kind of "partial" redisplay to show the echo area.)
Why? because processing input allows to avoid showing the user a
screen that is outdated from the user's POV, given that input more
often than not changes what should be displayed.

Another part of this puzzle is that redisplay includes fontification
of the visible portion of the buffer.  Emacs applies the font-lock
faces (and any other faces) during the 1st stage of its redisplay
cycle, when it computes the so-called "glyph matrices", which are data
structures maintained for each window that describe what the updated
screen should look like.  As David points out, it is impossible to
compute the glyph matrices without applying the faces, because faces
change the metrics of each character, and thus affect the layout,
which is what glyph matrices are all about.

The final part of the puzzle is what the scroll-up-command does when
Emacs processes a single PageDown keypress.  It computes the new
starting point for the window, which (if we neglect complications) is
simply the beginning of line N screen lines below the original window
start, where N is almost the height of the window.  (Note that I wrote
"screen lines", not "physical lines", so this is not entirely trivial
when there are continuation lines and variable-size fonts.)  Then it
determines whether this change of the window-start requires to move
point to bring it into the view, and if so, moves point as well.

So, after processing a single PageDown key, the window has a new
starting point, and point in that window's buffer has been moved.

If, after processing this single PageDown key, the input queue is
empty (as it is when you lean on the key, because Emacs finishes the
above processing in less time than the auto-repeat interval), Emacs
enters redisplay.  Redisplay computes the glyph matrix of the window
given its start point as set by scroll-up-command; as part of this
matrix computation, the display engine applies all the font-lock
properties to the text, and sets the 'fontified' property on that
text.  Then, just before it is about to redraw the window given the
new glyph matrix, it checks for input.  If there's input available,
and redisplay-dont-pause is nil, the window will not be redrawn,
i.e. this redisplay cycle will be aborted.

Then the same will happen again for the next PageDown key.  The result
is a frozen window display, because all the attempts to redisplay are
aborted due to input rate that is high enough to preempt redisplay,
but not high enough to prevent Emacs from entering redisplay after
every (or almost every) PageDown key.  To see more frequent updates
that give an illusion of scrolling, we would need a feature that
ignores the input availability, or maybe dynamically changes the
number of input events that could be ignored when redisplay falls
behind.  We don't have such a feature.

Now, what happens when you release the key?  The input queue is still
full of unprocessed PageDown keys.  As I explained above, Emacs will
drain the entire input queue before it enters redisplay; thus the long
delay you see after releasing the key.

You want Emacs to "immediately" display the new buffer position, but
this is impossible without some code that would quickly scan the input
queue, analyze what's there, and "understand" that 100 PageDown
keystrokes can be "optimized" by executing a single scroll-up-command
with a suitable argument.  IOW, we would need some input preprocessing
stage that could "optimize" input by replacing a series of commands
with a single command, and do that cheaply.  We don't have such a
feature; patches to add it will probably be welcome.



reply via email to

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