emacs-devel
[Top][All Lists]
Advanced

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

Re: move_it_vertically_backward question


From: Eli Zaretskii
Subject: Re: move_it_vertically_backward question
Date: Mon, 13 Dec 2021 16:50:12 +0200

> From: Po Lu <luangruo@yahoo.com>
> Date: Mon, 13 Dec 2021 10:47:48 +0800
> 
> I've been trying to introduce a new redisplay primitive to speed up
> precision pixel scrolling

I'm not sure this is the way to go, judging by what you told on
help-gnu-emacs.  The main reason is that window-text-pixel-size, which
you said doesn't do what you want, uses exactly the same technique as
you are trying to do in this new primitive, and so whatever problems
you have with window-text-pixel-size, you will bump into them (or
similar problems) with your new primitive as well.  This stuff is
always extremely tricky when advanced display features are used, like
display and overlay strings with embedded newlines, line-prefix, line
numbers, etc.  There's no easy way around this complexity.

Instead, we should understand better why window-text-pixel-size
doesn't fit your bill, and then extend it so that it does what you
want in your use cases.

That said, to answer your question:

> If there are 3 lines above window start, all of which are 17 pixels
> tall, calling this new primitive with PIXELS anything between 18 and 33
> will result in the start and height of the first line being returned,
> while I would have expected it to move onto the second line, as anything
> between 18 and 33 pixels above window start should be inside the second
> line.

The commentary to the function doesn't tell the whole story.  In fact,
it always undershoots first, because of this:

  /* Estimate how many newlines we must move back.  */
  nlines = max (1, dy / default_line_pixel_height (it->w));

This is integer division, so it truncates the number of lines.  E.g.,
in your case, with DY between 17 and 33 you get 1 line, not more.
Then it moves back by that number of physical lines, which is why you
get the line before window-start.

And then it can move farther back, but only if the undershoot is
"large enough":

      /* If we did not reach target_y, try to move further backward if
         we can.  If we moved too far backward, try to move forward.  */
      if (target_y < it->current_y
          /* This is heuristic.  In a window that's 3 lines high, with
             a line height of 13 pixels each, recentering with point
             on the bottom line will try to move -39/2 = 19 pixels
             backward.  Try to avoid moving into the first line.  */
          && (it->current_y - target_y
              > min (window_box_height (it->w), line_height * 2 / 3))
          && IT_CHARPOS (*it) > BEGV)
        {
          move_trace ("  not far enough -> move_vert %d\n",
                      target_y - it->current_y);
          dy = it->current_y - target_y;
          goto move_further_back;
        }

That "2/3rd of line height" threshold heuristic is the reason why it
not always moves one more line back.  On my system, the default pixel
height of a line is 16, so it moves to the second line before
window-start for DY >= 27, since 2/3rd of 16 is 10.



reply via email to

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