Subject: bug#18923: Alternative scrolling model

From: Eli Zaretskii <[email-masked]>
Date: Sun, 02 Nov 2014 20:22:18 +0200

> From: E Sabof <[email-masked]>
> Cc: [email-masked]
> Date: Sun, 02 Nov 2014 17:43:35 +0000
> 
> Imagine there is a buffer with which occupies 30% of the window (ex. a diagram in an org-mode buffer). It's positioned at (window-start). I (scroll-up 1). I'd end up scrolling a lot more than the usual (= (default-line-height) 20) pixels, which is what I mean by "jump".

If the problem is only with scrolling by single lines (or small
number of lines), then a very similar problem is already solved in
line-move-partial.  Try C-n in the same situation, and see if that's
what you want.  We could then use the same technique.

> >> >> (defun st-height (&optional pos)
> >> >>   "Won't report accurately, if the line is higher than window."
> >> >>   (cl-flet (( posn-y ()
> >> >>               (cdr (posn-x-y (or (posn-at-point)
> >> >>                                  (progn
> >> >>                                    (vertical-motion 0)
> >> >>                                    (set-window-start nil (point))
> >> >>                                    (posn-at-point)))))))
> >> >
> >> > Did you try using pos-visible-in-window-p?  I think it's what you
> >> > want.
> >>
> >> Reading through the documentation of `pos-visible-in-window-p' didn't suggest how it could be useful.
> >
> > Do you still not understand that?  If so, I will elaborate why I think
> > that function is what you want.
> 
> My best guess is that I'd still have to go through a similar procedure of comparing 2 return values for lines that have to be at least partially visible from some position, but I would get more information on partially visible lines. I haven't thought-through all the cases, but it might indeed always work.

The problem that you faced, as I understand it, was to get the pixel
size of a screen line even if it is only partially visible.  The RTOP
and RBOT values returned by pos-visible-in-window-p give you
information about how many pixels of the line are above the top and
below the bottom of the window.  (For a very tall image or a low
window, both RTOP and RBOT will be non-zero.)  Add those to the
visible height of the line, and AFIU you get what you wanted.  Am I
missing something?

> > IME, the most important use case is scrolling by "almost the full
> > window", in which case it is better to start with window-body-height
> > and subtract from it, instead of starting with zero and add to it.
> > The most expensive part here is vertical-motion, so I think you want
> > to call it as little as possible.
> 
> window-body-height can be very wrong if a large image is displayed in the buffer.

I meant call window-body-height with PIXELWISE non-nil.  Then the
return value doesn't depend on what is displayed, it just gives you
the height of the text area in pixels.  Subtracting from that the
pixel coordinates of point returned by pos-visible-in-window-p or
posn-at-point will give you how many pixels are there to the top and
bottom of the window.  This should eliminate the need to count pixels
by moving one screen line at a time via vertical-motion, which is less
efficient, I think.

> Still some heuristics could be used to speed-up the most common case, all lines being ~= (default-line-height).

This problem is also solved by working in pixels, which is what your
code did anyway.

> > I think we need to decide first whether the slowdown is acceptable.
> > IMO it is too significant to be ignored, if we want to replace
> > existing code.
> 
> I could define some limit (the pixel height of a window?), and if it was to be exceeded, I'd fall back on the existing or similar approach. I don't know how often people scroll several pages, but it's likely that if they do they would value speed over accuracy.

AFAIU, your method isn't more accurate than the existing one, except
in case of images.  If scrolling images by single lines is the issue,
I'm quite sure we can have that with the current C implementation.

So I think the issue of whether the slower speed is acceptable still
stands.  If it is acceptable, then the Lisp implementation should be
improved and enhanced; if it isn't, then the C implementation should
be improved.