all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Set-window-vscroll sometimes doesn't work
@ 2020-10-18  0:35 Yuan Fu
  2020-10-18 14:34 ` Eli Zaretskii
  0 siblings, 1 reply; 36+ messages in thread
From: Yuan Fu @ 2020-10-18  0:35 UTC (permalink / raw)
  To: help-gnu-emacs

Normally if you scroll back onto an image, the image appears completely. I want to instead only show part of the image, like what pixel scrolling would do. If everything works as expected I should only see the bottom of the image, instead I see the whole image.

It seems to be because (set-window-vscroll nil (- img-height (frame-char-height)) t) didn’t take effect, if you call that again with M-: or wrap it in (run-with-timer), then it works as expected.

Is this caused by some redisplay optimization or something?

Code:

(progn
  (switch-to-buffer (get-buffer-create "test"))
  (erase-buffer)
  (insert "\n\n")
  (insert-image (create-image "abby road.jpeg" nil nil :scale 0.1)
                "x")
  (insert "\n")
  (let ((after-img (point)))
    (set-window-start nil (point))
    (scroll-down 1)
    (let* ((img (plist-get (text-properties-at (window-start)) 'display))
           (img-height (cdr (image-size img t))))
      (set-window-vscroll nil (- img-height (frame-char-height)) t))))

Yuan

Image used in the code:






^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-18  0:35 Set-window-vscroll sometimes doesn't work Yuan Fu
@ 2020-10-18 14:34 ` Eli Zaretskii
  2020-10-18 17:24   ` Yuan Fu
  0 siblings, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2020-10-18 14:34 UTC (permalink / raw)
  To: help-gnu-emacs

> From: Yuan Fu <casouri@gmail.com>
> Date: Sat, 17 Oct 2020 20:35:00 -0400
> 
> Normally if you scroll back onto an image, the image appears completely. I want to instead only show part of the image, like what pixel scrolling would do. If everything works as expected I should only see the bottom of the image, instead I see the whole image.
> 
> It seems to be because (set-window-vscroll nil (- img-height (frame-char-height)) t) didn’t take effect, if you call that again with M-: or wrap it in (run-with-timer), then it works as expected.
> 
> Is this caused by some redisplay optimization or something?

No.  The problem is in your code.  First, you use set-window-start and
scroll-down, both of which tramp window-vscroll (as you probably
realize if you think about what those do).  And after all that, you
need one "normal" redisplay cycle before you can set the vscroll, so,
for example, a single change below should make the code work as you
expect.

(progn
  (switch-to-buffer (get-buffer-create "test"))
  (erase-buffer)
  (insert "\n\n")
  (insert-image (create-image "abby road.jpeg" nil nil :scale 0.1)
                "x")
  (insert "\n")
  (let ((after-img (point)))
    (set-window-start nil (point))
    (scroll-down 1)
    (sit-for 0)  ;; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    (let* ((img (plist-get (text-properties-at (window-start)) 'display))
           (img-height (cdr (image-size img t))))
      (set-window-vscroll nil (- img-height (frame-char-height)) t))))



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-18 14:34 ` Eli Zaretskii
@ 2020-10-18 17:24   ` Yuan Fu
  2020-10-18 17:31     ` Eli Zaretskii
  0 siblings, 1 reply; 36+ messages in thread
From: Yuan Fu @ 2020-10-18 17:24 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: help-gnu-emacs



> On Oct 18, 2020, at 10:34 AM, Eli Zaretskii <eliz@gnu.org> wrote:
> 
>> From: Yuan Fu <casouri@gmail.com>
>> Date: Sat, 17 Oct 2020 20:35:00 -0400
>> 
>> Normally if you scroll back onto an image, the image appears completely. I want to instead only show part of the image, like what pixel scrolling would do. If everything works as expected I should only see the bottom of the image, instead I see the whole image.
>> 
>> It seems to be because (set-window-vscroll nil (- img-height (frame-char-height)) t) didn’t take effect, if you call that again with M-: or wrap it in (run-with-timer), then it works as expected.
>> 
>> Is this caused by some redisplay optimization or something?
> 
> No.  The problem is in your code.  First, you use set-window-start and
> scroll-down, both of which tramp window-vscroll (as you probably
> realize if you think about what those do).  

Why is so? Is there any material that I can read about these?

> And after all that, you
> need one "normal" redisplay cycle before you can set the vscroll, so,
> for example, a single change below should make the code work as you
> expect.
> 
> (progn
>  (switch-to-buffer (get-buffer-create "test"))
>  (erase-buffer)
>  (insert "\n\n")
>  (insert-image (create-image "abby road.jpeg" nil nil :scale 0.1)
>                "x")
>  (insert "\n")
>  (let ((after-img (point)))
>    (set-window-start nil (point))
>    (scroll-down 1)
>    (sit-for 0)  ;; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>    (let* ((img (plist-get (text-properties-at (window-start)) 'display))
>           (img-height (cdr (image-size img t))))
>      (set-window-vscroll nil (- img-height (frame-char-height)) t))))

This works, but brings flickers: the image first shows completely then the vscroll takes effect, which is reasonable but not preferred. I found that using (set-window-start nil (point) t) with the third argument non-nil gives me the desired effect. My guess is that, as the doctoring said, setting that to non-nil prevents redisplay to try to make point completely visible, so redisplay doesn’t modify vscroll, so my vscroll value survived. Is that right?

Thanks,
Yuan

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-18 17:24   ` Yuan Fu
@ 2020-10-18 17:31     ` Eli Zaretskii
  2020-10-18 17:51       ` Yuan Fu
  0 siblings, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2020-10-18 17:31 UTC (permalink / raw)
  To: help-gnu-emacs

> From: Yuan Fu <casouri@gmail.com>
> Date: Sun, 18 Oct 2020 13:24:25 -0400
> Cc: help-gnu-emacs@gnu.org
> 
>  No.  The problem is in your code.  First, you use set-window-start and
>  scroll-down, both of which tramp window-vscroll (as you probably
>  realize if you think about what those do).  
> 
> Why is so? Is there any material that I can read about these?

These two functions force Emacs to display the buffer starting at a
particular position, so vscroll is zeroed out.  Otherwise, how could
Emacs obey the forced start point?

> This works, but brings flickers: the image first shows completely then the vscroll takes effect, which is
> reasonable but not preferred.

It was just an example to explain to you what should be done.  E.g.,
when you scroll a tall image with C-n there's no flickering.  You just
cannot mix vscroll with other code that affects the window display,
that's all.

> I found that using (set-window-start nil (point) t) with the third argument non-nil
> gives me the desired effect. My guess is that, as the doctoring said, setting that to non-nil prevents redisplay
> to try to make point completely visible, so redisplay doesn’t modify vscroll, so my vscroll value survived. Is
> that right?

NOFORCE non-nil means Emacs doesn't have to display the window
starting at the position if there are valid reasons, so yes.  But my
suggestion is not to use set-window-start when you want to vscroll,
it's unsafe.  You in effect create a conflict for the display engine,
and have no control on how it will resolve that conflict.




^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-18 17:31     ` Eli Zaretskii
@ 2020-10-18 17:51       ` Yuan Fu
  2020-10-18 17:55         ` Eli Zaretskii
  0 siblings, 1 reply; 36+ messages in thread
From: Yuan Fu @ 2020-10-18 17:51 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: help-gnu-emacs



> On Oct 18, 2020, at 1:31 PM, Eli Zaretskii <eliz@gnu.org> wrote:
> 
>> From: Yuan Fu <casouri@gmail.com>
>> Date: Sun, 18 Oct 2020 13:24:25 -0400
>> Cc: help-gnu-emacs@gnu.org
>> 
>> No.  The problem is in your code.  First, you use set-window-start and
>> scroll-down, both of which tramp window-vscroll (as you probably
>> realize if you think about what those do).  
>> 
>> Why is so? Is there any material that I can read about these?
> 
> These two functions force Emacs to display the buffer starting at a
> particular position, so vscroll is zeroed out.  Otherwise, how could
> Emacs obey the forced start point?
> 
>> This works, but brings flickers: the image first shows completely then the vscroll takes effect, which is
>> reasonable but not preferred.
> 
> It was just an example to explain to you what should be done.  E.g.,
> when you scroll a tall image with C-n there's no flickering.  You just
> cannot mix vscroll with other code that affects the window display,
> that's all.
> 
>> I found that using (set-window-start nil (point) t) with the third argument non-nil
>> gives me the desired effect. My guess is that, as the doctoring said, setting that to non-nil prevents redisplay
>> to try to make point completely visible, so redisplay doesn’t modify vscroll, so my vscroll value survived. Is
>> that right?
> 
> NOFORCE non-nil means Emacs doesn't have to display the window
> starting at the position if there are valid reasons, so yes.  But my
> suggestion is not to use set-window-start when you want to vscroll,
> it's unsafe.  You in effect create a conflict for the display engine,
> and have no control on how it will resolve that conflict.

Thanks. I see what you mean. What I want to do is to scroll over images as if it is made of several lines (like sliced images). Which requires scrolling over logical lines by set-window-start and scrolling over images by set-window-vscroll. Do you think I would be better off implementing this in, say, window_scroll_pixel_based rather than in Lisp?

Yuan




^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-18 17:51       ` Yuan Fu
@ 2020-10-18 17:55         ` Eli Zaretskii
  2020-10-18 18:02           ` Yuan Fu
  2020-10-18 19:12           ` Yuan Fu
  0 siblings, 2 replies; 36+ messages in thread
From: Eli Zaretskii @ 2020-10-18 17:55 UTC (permalink / raw)
  To: help-gnu-emacs

> From: Yuan Fu <casouri@gmail.com>
> Date: Sun, 18 Oct 2020 13:51:14 -0400
> Cc: help-gnu-emacs@gnu.org
> 
> > NOFORCE non-nil means Emacs doesn't have to display the window
> > starting at the position if there are valid reasons, so yes.  But my
> > suggestion is not to use set-window-start when you want to vscroll,
> > it's unsafe.  You in effect create a conflict for the display engine,
> > and have no control on how it will resolve that conflict.
> 
> Thanks. I see what you mean. What I want to do is to scroll over images as if it is made of several lines (like sliced images). Which requires scrolling over logical lines by set-window-start and scrolling over images by set-window-vscroll. Do you think I would be better off implementing this in, say, window_scroll_pixel_based rather than in Lisp?

It sounds like you want to do what we already have implemented in
next-line and previous-line and their subroutines.  Typing C-n on a
tall image scrolls the image the number of pixels that is equal to the
line height.  Maybe you can just use that code?



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-18 17:55         ` Eli Zaretskii
@ 2020-10-18 18:02           ` Yuan Fu
  2020-10-18 19:12           ` Yuan Fu
  1 sibling, 0 replies; 36+ messages in thread
From: Yuan Fu @ 2020-10-18 18:02 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: help-gnu-emacs



> On Oct 18, 2020, at 1:55 PM, Eli Zaretskii <eliz@gnu.org> wrote:
> 
>> From: Yuan Fu <casouri@gmail.com>
>> Date: Sun, 18 Oct 2020 13:51:14 -0400
>> Cc: help-gnu-emacs@gnu.org
>> 
>>> NOFORCE non-nil means Emacs doesn't have to display the window
>>> starting at the position if there are valid reasons, so yes.  But my
>>> suggestion is not to use set-window-start when you want to vscroll,
>>> it's unsafe.  You in effect create a conflict for the display engine,
>>> and have no control on how it will resolve that conflict.
>> 
>> Thanks. I see what you mean. What I want to do is to scroll over images as if it is made of several lines (like sliced images). Which requires scrolling over logical lines by set-window-start and scrolling over images by set-window-vscroll. Do you think I would be better off implementing this in, say, window_scroll_pixel_based rather than in Lisp?
> 
> It sounds like you want to do what we already have implemented in
> next-line and previous-line and their subroutines.  Typing C-n on a
> tall image scrolls the image the number of pixels that is equal to the
> line height.  Maybe you can just use that code?
> 

You might be right. Currently that (scroll by pixels) only happens if this tall line is taller than the window, maybe I can modify it so that it also do that (scroll by pixels) when the first line of the window is taller than, say 3x normal line height. I’ll dig deeper into this.

Yuan


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-18 17:55         ` Eli Zaretskii
  2020-10-18 18:02           ` Yuan Fu
@ 2020-10-18 19:12           ` Yuan Fu
  2020-10-18 19:19             ` Eli Zaretskii
  1 sibling, 1 reply; 36+ messages in thread
From: Yuan Fu @ 2020-10-18 19:12 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: help-gnu-emacs



> On Oct 18, 2020, at 1:55 PM, Eli Zaretskii <eliz@gnu.org> wrote:
> 
>> From: Yuan Fu <casouri@gmail.com>
>> Date: Sun, 18 Oct 2020 13:51:14 -0400
>> Cc: help-gnu-emacs@gnu.org
>> 
>>> NOFORCE non-nil means Emacs doesn't have to display the window
>>> starting at the position if there are valid reasons, so yes.  But my
>>> suggestion is not to use set-window-start when you want to vscroll,
>>> it's unsafe.  You in effect create a conflict for the display engine,
>>> and have no control on how it will resolve that conflict.
>> 
>> Thanks. I see what you mean. What I want to do is to scroll over images as if it is made of several lines (like sliced images). Which requires scrolling over logical lines by set-window-start and scrolling over images by set-window-vscroll. Do you think I would be better off implementing this in, say, window_scroll_pixel_based rather than in Lisp?
> 
> It sounds like you want to do what we already have implemented in
> next-line and previous-line and their subroutines.  Typing C-n on a
> tall image scrolls the image the number of pixels that is equal to the
> line height.  Maybe you can just use that code?
> 

Some questions:

1. Is it true that move_it_by_lines regards an image as one display line?
2. It seems that when I move focus out of the window, the vscroll setting is nullified, why is that?

Yuan


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-18 19:12           ` Yuan Fu
@ 2020-10-18 19:19             ` Eli Zaretskii
  2020-10-18 20:06               ` Yuan Fu
  0 siblings, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2020-10-18 19:19 UTC (permalink / raw)
  To: help-gnu-emacs

> From: Yuan Fu <casouri@gmail.com>
> Date: Sun, 18 Oct 2020 15:12:10 -0400
> Cc: help-gnu-emacs@gnu.org
> 
> 1. Is it true that move_it_by_lines regards an image as one display line?

Yes.  That's why we need vscroll in the first place.

> 2. It seems that when I move focus out of the window, the vscroll setting is nullified, why is that?

I don't know.  It doesn't happen here when I display a tall image and
scroll it with C-n/C-p.



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-18 19:19             ` Eli Zaretskii
@ 2020-10-18 20:06               ` Yuan Fu
  2020-10-19  2:23                 ` Eli Zaretskii
  0 siblings, 1 reply; 36+ messages in thread
From: Yuan Fu @ 2020-10-18 20:06 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: help-gnu-emacs



> On Oct 18, 2020, at 3:19 PM, Eli Zaretskii <eliz@gnu.org> wrote:
> 
>> From: Yuan Fu <casouri@gmail.com>
>> Date: Sun, 18 Oct 2020 15:12:10 -0400
>> Cc: help-gnu-emacs@gnu.org
>> 
>> 1. Is it true that move_it_by_lines regards an image as one display line?
> 
> Yes.  That's why we need vscroll in the first place.

Cool. I’m thinking about wrapping move_it_by_lines in window_scroll_pixel_based with a version that regards images (and tall lines) as several lines. Do you see some potential problems with that?

> 
>> 2. It seems that when I move focus out of the window, the vscroll setting is nullified, why is that?
> 
> I don't know.  It doesn't happen here when I display a tall image and
> scroll it with C-n/C-p.

I restarted Emacs and it's gone. I’ll try to find what’s the cause.

Yuan


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-18 20:06               ` Yuan Fu
@ 2020-10-19  2:23                 ` Eli Zaretskii
       [not found]                   ` <B1D235FE-49B8-4F0A-9C02-78B7E3244C47@gmail.com>
  0 siblings, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2020-10-19  2:23 UTC (permalink / raw)
  To: help-gnu-emacs

> From: Yuan Fu <casouri@gmail.com>
> Date: Sun, 18 Oct 2020 16:06:11 -0400
> Cc: help-gnu-emacs@gnu.org
> 
> >> 1. Is it true that move_it_by_lines regards an image as one display line?
> > 
> > Yes.  That's why we need vscroll in the first place.
> 
> Cool. I’m thinking about wrapping move_it_by_lines in window_scroll_pixel_based with a version that regards images (and tall lines) as several lines. Do you see some potential problems with that?

What is the problem with the existing code that you are trying to
solve?  Whatever it is, it is highly likely that the solution already
exists, and no new code is needed.



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
       [not found]                   ` <B1D235FE-49B8-4F0A-9C02-78B7E3244C47@gmail.com>
@ 2020-10-19  6:00                     ` Yuan Fu
  2020-10-19 16:24                     ` Eli Zaretskii
  1 sibling, 0 replies; 36+ messages in thread
From: Yuan Fu @ 2020-10-19  6:00 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: help-gnu-emacs



> On Oct 19, 2020, at 12:59 AM, Yuan Fu <casouri@gmail.com> wrote:
> 
> 
> 
>> On Oct 18, 2020, at 10:23 PM, Eli Zaretskii <eliz@gnu.org> wrote:
>> 
>>> From: Yuan Fu <casouri@gmail.com>
>>> Date: Sun, 18 Oct 2020 16:06:11 -0400
>>> Cc: help-gnu-emacs@gnu.org
>>> 
>>>>> 1. Is it true that move_it_by_lines regards an image as one display line?
>>>> 
>>>> Yes.  That's why we need vscroll in the first place.
>>> 
>>> Cool. I’m thinking about wrapping move_it_by_lines in window_scroll_pixel_based with a version that regards images (and tall lines) as several lines. Do you see some potential problems with that?
>> 
>> What is the problem with the existing code that you are trying to
>> solve?  Whatever it is, it is highly likely that the solution already
>> exists, and no new code is needed.
> 
> The problem I have is that when I scroll over images they jumps in and out of the window: (bad-scrolling.mp4)
> 
> <bad-scrolling.mp4>
> 
> What I want is to have the images smoothly scrolls in and out: (good-scrolling.mp4)
> 
> <good-scrolling.mp4>
> 
> Is there already a mean to do that?
> 
> Yuan
> 

Before you ask, I am aware of pixel-scroll-mode, but 1) it doesn’t handle the case when moving point instead of scrolling, 2) it’s performance is not very good, 3) scrolling by pixels isn’t really necessary, scrolling by single lines are fine enough.

Yuan


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
       [not found]                   ` <B1D235FE-49B8-4F0A-9C02-78B7E3244C47@gmail.com>
  2020-10-19  6:00                     ` Yuan Fu
@ 2020-10-19 16:24                     ` Eli Zaretskii
  2020-10-19 16:56                       ` Yuan Fu
  1 sibling, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2020-10-19 16:24 UTC (permalink / raw)
  To: help-gnu-emacs

> From: Yuan Fu <casouri@gmail.com>
> Date: Mon, 19 Oct 2020 00:59:33 -0400
> Cc: help-gnu-emacs@gnu.org
> 
> >> Cool. I’m thinking about wrapping move_it_by_lines in window_scroll_pixel_based with a version that regards images (and tall lines) as several lines. Do you see some potential problems with that?
> > 
> > What is the problem with the existing code that you are trying to
> > solve?  Whatever it is, it is highly likely that the solution already
> > exists, and no new code is needed.
> 
> The problem I have is that when I scroll over images they jumps in and out of the window: (bad-scrolling.mp4)

AFAICT, you are trying to scroll an image that is smaller than the
window?  That's not supported by the current code, you will need to
modify the criteria for entering the vscroll mode there.

But in any case, I don't see how move_it_by_lines can have anything to
do with this: whatever you do, an image must always remain a single
"display element", and the only way we currently have to scroll
partial images is via vscroll.  Which works, so I don't understand why
you need any changes in window_scroll_pixel_based.



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-19 16:24                     ` Eli Zaretskii
@ 2020-10-19 16:56                       ` Yuan Fu
  2020-10-19 17:23                         ` Eli Zaretskii
  0 siblings, 1 reply; 36+ messages in thread
From: Yuan Fu @ 2020-10-19 16:56 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: help-gnu-emacs



> On Oct 19, 2020, at 12:24 PM, Eli Zaretskii <eliz@gnu.org> wrote:
> 
>> From: Yuan Fu <casouri@gmail.com>
>> Date: Mon, 19 Oct 2020 00:59:33 -0400
>> Cc: help-gnu-emacs@gnu.org
>> 
>>>> Cool. I’m thinking about wrapping move_it_by_lines in window_scroll_pixel_based with a version that regards images (and tall lines) as several lines. Do you see some potential problems with that?
>>> 
>>> What is the problem with the existing code that you are trying to
>>> solve?  Whatever it is, it is highly likely that the solution already
>>> exists, and no new code is needed.
>> 
>> The problem I have is that when I scroll over images they jumps in and out of the window: (bad-scrolling.mp4)
> 
> AFAICT, you are trying to scroll an image that is smaller than the
> window?  That's not supported by the current code, you will need to
> modify the criteria for entering the vscroll mode there.
> 
> But in any case, I don't see how move_it_by_lines can have anything to
> do with this: whatever you do, an image must always remain a single
> "display element", and the only way we currently have to scroll
> partial images is via vscroll.  Which works, so I don't understand why
> you need any changes in window_scroll_pixel_based.
> 

What I came up with is this:

For (scroll-up 1):

1. If the first row is a normal line (i.e., with normal height), scroll up normally by one display line.
2. If the first row is an image, adjust vscroll += frame-default-pixel-line-height
3. If the first row is an image and we have scrolled to the bottom of the image, i.e., vscroll = image-height, scroll up one display line and set vscroll to 0.

In other words, sometimes we are not really scrolling, but faking a scroll by adjusting vscroll. IIUC window_scroll_pixel_based moves it by move_it_by_lines and set window-start to it. That’s not what we want when we want to fake scroll by adjusting vscroll: in that case we don’t want to change window-start.

Some questions:
1. Is there a way to get the line-height that an it is on? 
2. Where is the code that ensures point is always fully visible? When I move point around Emacs adjusts scrolling to keep the point fully visible, but I don’t know who’s doing that work.

Yuan







^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-19 16:56                       ` Yuan Fu
@ 2020-10-19 17:23                         ` Eli Zaretskii
  2020-10-19 20:39                           ` Yuan Fu
  0 siblings, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2020-10-19 17:23 UTC (permalink / raw)
  To: help-gnu-emacs

> From: Yuan Fu <casouri@gmail.com>
> Date: Mon, 19 Oct 2020 12:56:38 -0400
> Cc: help-gnu-emacs <help-gnu-emacs@gnu.org>
> 
> > But in any case, I don't see how move_it_by_lines can have anything to
> > do with this: whatever you do, an image must always remain a single
> > "display element", and the only way we currently have to scroll
> > partial images is via vscroll.  Which works, so I don't understand why
> > you need any changes in window_scroll_pixel_based.
> > 
> 
> What I came up with is this:
> 
> For (scroll-up 1):

That's your problem, right there: scroll-up is not the right command
for this.  Scroll commands work by setting window-start, and you don't
want that with large images.  They also move by window-full, again
something that is not appropriate for scrolling images.  You'd need a
different command for your use case.

Please read the code in simple.el, the functions line-move,
line-move-1, and line-move-partial -- those perform scrolling of tall
images when needed.  You will find there how to decide when to set
vscroll and to what value; I suggest to use a similar strategy.

> 
> 1. If the first row is a normal line (i.e., with normal height), scroll up normally by one display line.
> 2. If the first row is an image, adjust vscroll += frame-default-pixel-line-height
> 3. If the first row is an image and we have scrolled to the bottom of the image, i.e., vscroll = image-height, scroll up one display line and set vscroll to 0.

You can do it this way, but I think it will be confusing because
scroll-up is rarely used with an argument of 1.

But if you insist on doing this inside scroll-up, then items 2 and 3
should do what line-move-visual etc. in simple.el do when they need to
scroll a tall image.  They do exactly what you describe above (they
also do other stuff, which you can remove if you want).

> In other words, sometimes we are not really scrolling, but faking a scroll by adjusting vscroll. IIUC window_scroll_pixel_based moves it by move_it_by_lines and set window-start to it. That’s not what we want when we want to fake scroll by adjusting vscroll: in that case we don’t want to change window-start.

Indeed, that's not what we want.  Which is why scroll commands are not
the right starting point for what you want to do.

> 1. Is there a way to get the line-height that an it is on? 

Yes, use line-pixel-height.  Again, see the functions in simple.el I
pointed to, they do it already.

> 2. Where is the code that ensures point is always fully visible? When I move point around Emacs adjusts scrolling to keep the point fully visible, but I don’t know who’s doing that work.

It's in the display engine (xdisp.c).  Many places there check whether
the screen line of point is fully visible and retry redisplay if not.



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-19 17:23                         ` Eli Zaretskii
@ 2020-10-19 20:39                           ` Yuan Fu
  2020-10-20 16:04                             ` Eli Zaretskii
  0 siblings, 1 reply; 36+ messages in thread
From: Yuan Fu @ 2020-10-19 20:39 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: help-gnu-emacs


>> 
>> What I came up with is this:
>> 
>> For (scroll-up 1):
> 
> That's your problem, right there: scroll-up is not the right command
> for this.  Scroll commands work by setting window-start, and you don't
> want that with large images.  They also move by window-full, again
> something that is not appropriate for scrolling images.  You'd need a
> different command for your use case.
> 
> Please read the code in simple.el, the functions line-move,
> line-move-1, and line-move-partial -- those perform scrolling of tall
> images when needed.  You will find there how to decide when to set
> vscroll and to what value; I suggest to use a similar strategy.

Sorry for the confusion, I didn't mean to use scroll-up directly, I meant “(my-scroll-up 1)”.

These functions only handle the case where the line is taller than the window, so they either adjust vscroll or scroll with scroll-up/down but never both, which isn’t too helpful. Because in my use case I sometimes need to scroll and adjust vscroll in the same time. Suppose I have a line followed by an image in my buffer:

+------------------------------------+
|        first line                  |
+------------------------------------+
|        image                       |
|                                    |
|                                    |
|                                    |
|                                    |
|                                    |
|                                    |
+------------------------------------+


And I want to “scroll 3 lines up", then with my strategy I need to scroll up one display line and adjust vscroll to 2x default-line-height. In other word:

(set-window-start nil point-of-image t)
(set-window-vscroll nil (* 2 (default-line-height)) t)

> 
>> 
>> 1. If the first row is a normal line (i.e., with normal height), scroll up normally by one display line.
>> 2. If the first row is an image, adjust vscroll += frame-default-pixel-line-height
>> 3. If the first row is an image and we have scrolled to the bottom of the image, i.e., vscroll = image-height, scroll up one display line and set vscroll to 0.
> 
> You can do it this way, but I think it will be confusing because
> scroll-up is rarely used with an argument of 1.
> 
> But if you insist on doing this inside scroll-up, then items 2 and 3
> should do what line-move-visual etc. in simple.el do when they need to
> scroll a tall image.  They do exactly what you describe above (they
> also do other stuff, which you can remove if you want).

The strategy also works with an argument larger than 1. Again, those functions never need to scroll and adjust vscroll in the same time.

> 
>> In other words, sometimes we are not really scrolling, but faking a scroll by adjusting vscroll. IIUC window_scroll_pixel_based moves it by move_it_by_lines and set window-start to it. That’s not what we want when we want to fake scroll by adjusting vscroll: in that case we don’t want to change window-start.
> 
> Indeed, that's not what we want.  Which is why scroll commands are not
> the right starting point for what you want to do.

Maybe I should state what I want to do clearly: I want to achieve the smooth scrolling when both scrolling and moving point, i.e., both scroll-up/down and next/previous-line, that ensures I never have annoying jumpy images.

With my limited knowledge, setting window-start (aka scroll) and setting vscroll in the same time is the only way to to get what I want. But it is against the design of the display engine. Is there anyway out of this?


Thanks,
Yuan




^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-19 20:39                           ` Yuan Fu
@ 2020-10-20 16:04                             ` Eli Zaretskii
  2020-10-20 18:00                               ` Yuan Fu
  2020-10-20 18:19                               ` Yuan Fu
  0 siblings, 2 replies; 36+ messages in thread
From: Eli Zaretskii @ 2020-10-20 16:04 UTC (permalink / raw)
  To: help-gnu-emacs

> From: Yuan Fu <casouri@gmail.com>
> Date: Mon, 19 Oct 2020 16:39:11 -0400
> Cc: help-gnu-emacs@gnu.org
> 
> These functions only handle the case where the line is taller than the window, so they either adjust vscroll or scroll with scroll-up/down but never both, which isn’t too helpful. Because in my use case I sometimes need to scroll and adjust vscroll in the same time. Suppose I have a line followed by an image in my buffer:
> 
> +------------------------------------+
> |        first line                  |
> +------------------------------------+
> |        image                       |
> |                                    |
> |                                    |
> |                                    |
> |                                    |
> |                                    |
> |                                    |
> +------------------------------------+
> 
> 
> And I want to “scroll 3 lines up", then with my strategy I need to scroll up one display line and adjust vscroll to 2x default-line-height. In other word:

You could write a function that scrolls by 1 screen line, either by
scroll-up/down or with vscroll, then call that function 3 times, and
let it do its job each of these 3 times.  Then you'd still be able to
reuse most of the code that already exists, by following the same
convention: either scroll-up/down or set vscroll.

> > Indeed, that's not what we want.  Which is why scroll commands are not
> > the right starting point for what you want to do.
> 
> Maybe I should state what I want to do clearly: I want to achieve the smooth scrolling when both scrolling and moving point, i.e., both scroll-up/down and next/previous-line, that ensures I never have annoying jumpy images.

Once again: scroll-up/down normally scroll by whole window, or by its
large fraction.  It is not a good idea to mix that with pixel-wise
scrolling of images.

> With my limited knowledge, setting window-start (aka scroll) and setting vscroll in the same time is the only way to to get what I want. But it is against the design of the display engine. Is there anyway out of this?

Not without rewriting significant parts of the display code.  Forcing
window-start and setting vscroll conceptually contradict each other,
so your interpretation of avoiding the contradiction by doing one and
then the other is bound to cause problems in other use cases.

That is why I suggest to stick to the code in simple.el as much as
possible: it is well tested and works, AFAIU you need to change it
very little to be able to scroll images that are smaller than the
window height -- that test is in a small number of places and can be
replaced by something else.



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-20 16:04                             ` Eli Zaretskii
@ 2020-10-20 18:00                               ` Yuan Fu
  2020-10-20 18:19                               ` Yuan Fu
  1 sibling, 0 replies; 36+ messages in thread
From: Yuan Fu @ 2020-10-20 18:00 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: help-gnu-emacs



> On Oct 20, 2020, at 12:04 PM, Eli Zaretskii <eliz@gnu.org> wrote:
> 
> 



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-20 16:04                             ` Eli Zaretskii
  2020-10-20 18:00                               ` Yuan Fu
@ 2020-10-20 18:19                               ` Yuan Fu
  2020-10-21 16:25                                 ` Eli Zaretskii
  1 sibling, 1 reply; 36+ messages in thread
From: Yuan Fu @ 2020-10-20 18:19 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: help-gnu-emacs

> 
> You could write a function that scrolls by 1 screen line, either by
> scroll-up/down or with vscroll, then call that function 3 times, and
> let it do its job each of these 3 times.  Then you'd still be able to
> reuse most of the code that already exists, by following the same
> convention: either scroll-up/down or set vscroll.

So that’s conceptually equivalent of inserting normal redisplays in between set-window-start and set-window-vscroll, right?

> 
>>> Indeed, that's not what we want.  Which is why scroll commands are not
>>> the right starting point for what you want to do.
>> 
>> Maybe I should state what I want to do clearly: I want to achieve the smooth scrolling when both scrolling and moving point, i.e., both scroll-up/down and next/previous-line, that ensures I never have annoying jumpy images.
> 
> Once again: scroll-up/down normally scroll by whole window, or by its
> large fraction.  It is not a good idea to mix that with pixel-wise
> scrolling of images.

AFAICT mouse wheel scrolling uses scroll-up/down, so a smooth scrolling behavior for scroll-up/down is not unreasonable.

> 
>> With my limited knowledge, setting window-start (aka scroll) and setting vscroll in the same time is the only way to to get what I want. But it is against the design of the display engine. Is there anyway out of this?
> 
> Not without rewriting significant parts of the display code.  Forcing
> window-start and setting vscroll conceptually contradict each other,
> so your interpretation of avoiding the contradiction by doing one and
> then the other is bound to cause problems in other use cases.

I’d love to know more about this part. For me, window-start and vscroll seem to be unrelated: changing vscroll doesn’t really affect window-start. Couldn’t the redisplay do something like “move window to start at window-start then scroll down vscroll pixels”?

> 
> That is why I suggest to stick to the code in simple.el as much as
> possible: it is well tested and works, AFAIU you need to change it
> very little to be able to scroll images that are smaller than the
> window height -- that test is in a small number of places and can be
> replaced by something else.
> 

next-line and friends only vscroll when scroll-conservatively=0 and ARG=1, which allows it to get away from the problem I face (set-window-start and set-window-vscroll in the same time). I either implements smooth scrolling to only work when ARG=1 or I need to set both value at the same time.

Yuan




^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-20 18:19                               ` Yuan Fu
@ 2020-10-21 16:25                                 ` Eli Zaretskii
  2020-10-21 19:05                                   ` Yuan Fu
  0 siblings, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2020-10-21 16:25 UTC (permalink / raw)
  To: help-gnu-emacs

> From: Yuan Fu <casouri@gmail.com>
> Date: Tue, 20 Oct 2020 14:19:46 -0400
> Cc: help-gnu-emacs@gnu.org
> 
> > You could write a function that scrolls by 1 screen line, either by
> > scroll-up/down or with vscroll, then call that function 3 times, and
> > let it do its job each of these 3 times.  Then you'd still be able to
> > reuse most of the code that already exists, by following the same
> > convention: either scroll-up/down or set vscroll.
> 
> So that’s conceptually equivalent of inserting normal redisplays in between set-window-start and set-window-vscroll, right?

I don't understand what you mean.  If you mean that you need to insert
sit-for, then no: try "C-u 10 C-n" when displaying a tall image, and
you will see that it scrolls the image by 10 screen lines.

> > Once again: scroll-up/down normally scroll by whole window, or by its
> > large fraction.  It is not a good idea to mix that with pixel-wise
> > scrolling of images.
> 
> AFAICT mouse wheel scrolling uses scroll-up/down, so a smooth scrolling behavior for scroll-up/down is not unreasonable.

Mouse-wheel scrolling doesn't set window-start, it sets vscroll
instead.  So you indeed can use that paradigm as well, as long as you
make sure the argument to scroll-up/down is a small number.

But my point was that you shouldn't set window-start if you need to
use a non-zero vscroll.

> >> With my limited knowledge, setting window-start (aka scroll) and setting vscroll in the same time is the only way to to get what I want. But it is against the design of the display engine. Is there anyway out of this?
> > 
> > Not without rewriting significant parts of the display code.  Forcing
> > window-start and setting vscroll conceptually contradict each other,
> > so your interpretation of avoiding the contradiction by doing one and
> > then the other is bound to cause problems in other use cases.
> 
> I’d love to know more about this part. For me, window-start and vscroll seem to be unrelated: changing vscroll doesn’t really affect window-start. Couldn’t the redisplay do something like “move window to start at window-start then scroll down vscroll pixels”?

The idea behind the current design is that if you set window-start,
you want to see the stuff at that position in its entirety.  Having
non-zero vscroll would prevent that, because some of the tall image is
not visible.

It is, of course, possible to use some other concept, but the current
concept is assumed in several places, and you will have to change them
all.

> > That is why I suggest to stick to the code in simple.el as much as
> > possible: it is well tested and works, AFAIU you need to change it
> > very little to be able to scroll images that are smaller than the
> > window height -- that test is in a small number of places and can be
> > replaced by something else.
> > 
> 
> next-line and friends only vscroll when scroll-conservatively=0 and ARG=1, which allows it to get away from the problem I face (set-window-start and set-window-vscroll in the same time). I either implements smooth scrolling to only work when ARG=1 or I need to set both value at the same time.

I don't understand why you say this.  First, C-n works on tall images
with arguments greater than 1.  And second, I still don't understand
why you need to set window-start, because vscroll should be enough for
your needs, as far as I understand.



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-21 16:25                                 ` Eli Zaretskii
@ 2020-10-21 19:05                                   ` Yuan Fu
  2020-10-22  4:16                                     ` Yuan Fu
  2020-10-22 16:05                                     ` Eli Zaretskii
  0 siblings, 2 replies; 36+ messages in thread
From: Yuan Fu @ 2020-10-21 19:05 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: help-gnu-emacs

> 
>>> Once again: scroll-up/down normally scroll by whole window, or by its
>>> large fraction.  It is not a good idea to mix that with pixel-wise
>>> scrolling of images.
>> 
>> AFAICT mouse wheel scrolling uses scroll-up/down, so a smooth scrolling behavior for scroll-up/down is not unreasonable.
> 
> Mouse-wheel scrolling doesn't set window-start, it sets vscroll
> instead.  So you indeed can use that paradigm as well, as long as you
> make sure the argument to scroll-up/down is a small number.
> 
> But my point was that you shouldn't set window-start if you need to
> use a non-zero vscroll.

It does: mwheel-scroll calls scroll-down/up, which calls window_scroll_pixel_based, which sets w->start (and it sets vscroll for tall image).

> 
>>>> With my limited knowledge, setting window-start (aka scroll) and setting vscroll in the same time is the only way to to get what I want. But it is against the design of the display engine. Is there anyway out of this?
>>> 
>>> Not without rewriting significant parts of the display code.  Forcing
>>> window-start and setting vscroll conceptually contradict each other,
>>> so your interpretation of avoiding the contradiction by doing one and
>>> then the other is bound to cause problems in other use cases.
>> 
>> I’d love to know more about this part. For me, window-start and vscroll seem to be unrelated: changing vscroll doesn’t really affect window-start. Couldn’t the redisplay do something like “move window to start at window-start then scroll down vscroll pixels”?
> 
> The idea behind the current design is that if you set window-start,
> you want to see the stuff at that position in its entirety.  Having
> non-zero vscroll would prevent that, because some of the tall image is
> not visible.
> 
> It is, of course, possible to use some other concept, but the current
> concept is assumed in several places, and you will have to change them
> all.
> 

I see.

>>> That is why I suggest to stick to the code in simple.el as much as
>>> possible: it is well tested and works, AFAIU you need to change it
>>> very little to be able to scroll images that are smaller than the
>>> window height -- that test is in a small number of places and can be
>>> replaced by something else.
>>> 
>> 
>> next-line and friends only vscroll when scroll-conservatively=0 and ARG=1, which allows it to get away from the problem I face (set-window-start and set-window-vscroll in the same time). I either implements smooth scrolling to only work when ARG=1 or I need to set both value at the same time.
> 
> I don't understand why you say this.  First, C-n works on tall images
> with arguments greater than 1.  And second, I still don't understand
> why you need to set window-start, because vscroll should be enough for
> your needs, as far as I understand.

C-n doesn’t smooth scroll on tall images when ARG > 1: The code checks for ARG = 1, if not, it doesn’t do line-move-partial. I also tried C-2 C-n, no smooth scrolling.

I thought vscroll is a relative measure and is measured against window-start. And it kind of makes sense to set a window start as the basis and set vscroll based on that. So I kind of assumed that window-start is always at least partially visible and vscroll is always less than the height of the first line. Now, if I throw away window-start and scrolls entirely by vscroll, will there be any problems? Like, does anyone relies on window-start being visible? I felt like that’s what people uses to get the first line displayed in the window.

Yuan



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-21 19:05                                   ` Yuan Fu
@ 2020-10-22  4:16                                     ` Yuan Fu
  2020-10-22 16:08                                       ` Eli Zaretskii
  2020-10-22 16:05                                     ` Eli Zaretskii
  1 sibling, 1 reply; 36+ messages in thread
From: Yuan Fu @ 2020-10-22  4:16 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: help-gnu-emacs

> 
>>>> That is why I suggest to stick to the code in simple.el as much as
>>>> possible: it is well tested and works, AFAIU you need to change it
>>>> very little to be able to scroll images that are smaller than the
>>>> window height -- that test is in a small number of places and can be
>>>> replaced by something else.
>>>> 
>>> 
>>> next-line and friends only vscroll when scroll-conservatively=0 and ARG=1, which allows it to get away from the problem I face (set-window-start and set-window-vscroll in the same time). I either implements smooth scrolling to only work when ARG=1 or I need to set both value at the same time.
>> 
>> I don't understand why you say this.  First, C-n works on tall images
>> with arguments greater than 1.  And second, I still don't understand
>> why you need to set window-start, because vscroll should be enough for
>> your needs, as far as I understand.
> 
> C-n doesn’t smooth scroll on tall images when ARG > 1: The code checks for ARG = 1, if not, it doesn’t do line-move-partial. I also tried C-2 C-n, no smooth scrolling.
> 
> I thought vscroll is a relative measure and is measured against window-start. And it kind of makes sense to set a window start as the basis and set vscroll based on that. So I kind of assumed that window-start is always at least partially visible and vscroll is always less than the height of the first line. Now, if I throw away window-start and scrolls entirely by vscroll, will there be any problems? Like, does anyone relies on window-start being visible? I felt like that’s what people uses to get the first line displayed in the window.
> 

Ok, I looked at redisplay_window, and it zeros out vscroll if force_start is true, that explains my initial question. After reading the function, it seems that setting window-start is the primary way to scroll and to produce the glyph matrix to display. IIUC this is how window-start and vscroll works together in window redisplay: we have a window-start -> try window -> start_display on window-start -> it_initialize on window-start -> it->current-y adjusted according to vscroll -> back to try window -> while (it.current_y < it.last_visible_y): produce glyph rows. This doesn’t seem to be too contradictory, and scrolling by setting window-start and add sub-line adjustment with vscroll seems to be complaint with the redisplay logic. What am I missing?

Yuan



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-21 19:05                                   ` Yuan Fu
  2020-10-22  4:16                                     ` Yuan Fu
@ 2020-10-22 16:05                                     ` Eli Zaretskii
  1 sibling, 0 replies; 36+ messages in thread
From: Eli Zaretskii @ 2020-10-22 16:05 UTC (permalink / raw)
  To: help-gnu-emacs

> From: Yuan Fu <casouri@gmail.com>
> Date: Wed, 21 Oct 2020 15:05:26 -0400
> Cc: help-gnu-emacs@gnu.org
> 
>  But my point was that you shouldn't set window-start if you need to
>  use a non-zero vscroll.
> 
> It does: mwheel-scroll calls scroll-down/up, which calls window_scroll_pixel_based, which sets w->start
> (and it sets vscroll for tall image).

If you examine the code in window_scroll_pixel_based carefully, you
will see that it either sets vscroll or w->start, but never both.

>  next-line and friends only vscroll when scroll-conservatively=0 and ARG=1, which allows it to get
>  away from the problem I face (set-window-start and set-window-vscroll in the same time). I either
>  implements smooth scrolling to only work when ARG=1 or I need to set both value at the same
>  time.
> 
>  I don't understand why you say this.  First, C-n works on tall images
>  with arguments greater than 1.  And second, I still don't understand
>  why you need to set window-start, because vscroll should be enough for
>  your needs, as far as I understand.
> 
> C-n doesn’t smooth scroll on tall images when ARG > 1: The code checks for ARG = 1, if not, it doesn’t do
> line-move-partial. I also tried C-2 C-n, no smooth scrolling.

What do you mean by "smooth scrolling" here?  If I invoke C-2 C-n" on
a large image, the image gets scrolled by the amount of pixels that is
equivalent to 2 screen lines.  Isn't that what you see?

> I thought vscroll is a relative measure and is measured against window-start. And it kind of makes sense to
> set a window start as the basis and set vscroll based on that. So I kind of assumed that window-start is
> always at least partially visible and vscroll is always less than the height of the first line. Now, if I throw away
> window-start and scrolls entirely by vscroll, will there be any problems? Like, does anyone relies on
> window-start being visible? I felt like that’s what people uses to get the first line displayed in the window.

When vscroll is so large that the window-start point is entirely not
visible, you should move window-start so it becomes visible.  But that
shouldn't be a problem, because it means you've scrolled the entire
image off-screen.



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-22  4:16                                     ` Yuan Fu
@ 2020-10-22 16:08                                       ` Eli Zaretskii
  2020-10-22 16:50                                         ` Yuan Fu
  0 siblings, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2020-10-22 16:08 UTC (permalink / raw)
  To: help-gnu-emacs

> From: Yuan Fu <casouri@gmail.com>
> Date: Thu, 22 Oct 2020 00:16:04 -0400
> Cc: help-gnu-emacs@gnu.org
> 
> Ok, I looked at redisplay_window, and it zeros out vscroll if force_start is true, that explains my initial
> question. After reading the function, it seems that setting window-start is the primary way to scroll and to
> produce the glyph matrix to display. IIUC this is how window-start and vscroll works together in window
> redisplay: we have a window-start -> try window -> start_display on window-start -> it_initialize on
> window-start -> it->current-y adjusted according to vscroll -> back to try window -> while (it.current_y <
> it.last_visible_y): produce glyph rows. This doesn’t seem to be too contradictory, and scrolling by setting
> window-start and add sub-line adjustment with vscroll seems to be complaint with the redisplay logic. What
> am I missing?

You are missing the use cases where the display element that is taller
than the normal text is not an image, but something else.  For
example, text displayed with a very large font.  In this other use
case, starting display with a non-zero vscroll when the Lisp program
forced window-start will produce text part of which cannot be read,
because too much of the characters is off-screen.

This is why setting window-start zeroes out vscroll: Emacs wants to
make sure that in this case the entire screen line that starts at
window-start will be fully visible.



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-22 16:08                                       ` Eli Zaretskii
@ 2020-10-22 16:50                                         ` Yuan Fu
  2020-10-22 17:09                                           ` Eli Zaretskii
  0 siblings, 1 reply; 36+ messages in thread
From: Yuan Fu @ 2020-10-22 16:50 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: help-gnu-emacs

> What do you mean by "smooth scrolling" here?  If I invoke C-2 C-n" on
> a large image, the image gets scrolled by the amount of pixels that is
> equivalent to 2 screen lines.  Isn't that what you see?

With emacs -Q? On my machine emacs -Q doesn’t to that. Instead of moving two line’s height, it just jumps to the next logical line.

> When vscroll is so large that the window-start point is entirely not
> visible, you should move window-start so it becomes visible.  But that
> shouldn't be a problem, because it means you've scrolled the entire
> image off-screen.

> On Oct 22, 2020, at 12:08 PM, Eli Zaretskii <eliz@gnu.org> wrote:
> 
>> From: Yuan Fu <casouri@gmail.com>
>> Date: Thu, 22 Oct 2020 00:16:04 -0400
>> Cc: help-gnu-emacs@gnu.org
>> 
>> Ok, I looked at redisplay_window, and it zeros out vscroll if force_start is true, that explains my initial
>> question. After reading the function, it seems that setting window-start is the primary way to scroll and to
>> produce the glyph matrix to display. IIUC this is how window-start and vscroll works together in window
>> redisplay: we have a window-start -> try window -> start_display on window-start -> it_initialize on
>> window-start -> it->current-y adjusted according to vscroll -> back to try window -> while (it.current_y <
>> it.last_visible_y): produce glyph rows. This doesn’t seem to be too contradictory, and scrolling by setting
>> window-start and add sub-line adjustment with vscroll seems to be complaint with the redisplay logic. What
>> am I missing?
> 
> You are missing the use cases where the display element that is taller
> than the normal text is not an image, but something else.  For
> example, text displayed with a very large font.  In this other use
> case, starting display with a non-zero vscroll when the Lisp program
> forced window-start will produce text part of which cannot be read,
> because too much of the characters is off-screen.
> 
> This is why setting window-start zeroes out vscroll: Emacs wants to
> make sure that in this case the entire screen line that starts at
> window-start will be fully visible.
> 

That’s a fair point. But what about scrolling down into an image? I’ll need to set window-start on the image then set vscroll to image height - line height so it only displays the bottom strip. That’s what line-move does, too:

(prog1 (line-move-visual arg noerror)
	    ;; If we moved into a tall line, set vscroll to make
	    ;; scrolling through tall images more smooth.
	    (let ((lh (line-pixel-height))
		  (edges (window-inside-pixel-edges))
		  (dlh (default-line-height))
		  winh)
	      (setq winh (- (nth 3 edges) (nth 1 edges) 1))
	      (if (and (< arg 0)
		       (< (point) (window-start))
		       (> lh winh))
		  (set-window-vscroll
		   nil
		   (- lh dlh) t))))

Yuan

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-22 16:50                                         ` Yuan Fu
@ 2020-10-22 17:09                                           ` Eli Zaretskii
  2020-10-22 19:33                                             ` Yuan Fu
  0 siblings, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2020-10-22 17:09 UTC (permalink / raw)
  To: help-gnu-emacs

> From: Yuan Fu <casouri@gmail.com>
> Date: Thu, 22 Oct 2020 12:50:23 -0400
> Cc: help-gnu-emacs@gnu.org
> 
>  What do you mean by "smooth scrolling" here?  If I invoke C-2 C-n" on
>  a large image, the image gets scrolled by the amount of pixels that is
>  equivalent to 2 screen lines.  Isn't that what you see?
> 
> With emacs -Q? On my machine emacs -Q doesn’t to that. Instead of moving two line’s height, it just jumps
> to the next logical line.

That can only happen if the image fits in the window in its entirety.
Enlarge it so it's taller than the window, and then try again.



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-22 17:09                                           ` Eli Zaretskii
@ 2020-10-22 19:33                                             ` Yuan Fu
  2020-10-23  6:05                                               ` Eli Zaretskii
  0 siblings, 1 reply; 36+ messages in thread
From: Yuan Fu @ 2020-10-22 19:33 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: help-gnu-emacs



> On Oct 22, 2020, at 1:09 PM, Eli Zaretskii <eliz@gnu.org> wrote:
> 
>> From: Yuan Fu <casouri@gmail.com>
>> Date: Thu, 22 Oct 2020 12:50:23 -0400
>> Cc: help-gnu-emacs@gnu.org
>> 
>> What do you mean by "smooth scrolling" here?  If I invoke C-2 C-n" on
>> a large image, the image gets scrolled by the amount of pixels that is
>> equivalent to 2 screen lines.  Isn't that what you see?
>> 
>> With emacs -Q? On my machine emacs -Q doesn’t to that. Instead of moving two line’s height, it just jumps
>> to the next logical line.
> 
> That can only happen if the image fits in the window in its entirety.
> Enlarge it so it's taller than the window, and then try again.

In the video I first pressed C-n a couple times, then C-u 2 C-n. It really doesn’t smooth scroll here (I’m on master).

Yuan



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-22 19:33                                             ` Yuan Fu
@ 2020-10-23  6:05                                               ` Eli Zaretskii
  2020-10-23 16:48                                                 ` Yuan Fu
  0 siblings, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2020-10-23  6:05 UTC (permalink / raw)
  To: help-gnu-emacs

> From: Yuan Fu <casouri@gmail.com>
> Date: Thu, 22 Oct 2020 15:33:40 -0400
> Cc: help-gnu-emacs@gnu.org
> 
> >> With emacs -Q? On my machine emacs -Q doesn’t to that. Instead of moving two line’s height, it just jumps
> >> to the next logical line.
> > 
> > That can only happen if the image fits in the window in its entirety.
> > Enlarge it so it's taller than the window, and then try again.
> 
> In the video I first pressed C-n a couple times, then C-u 2 C-n. It really doesn’t smooth scroll here (I’m on master).

Please submit a full bug report, with the image to use, the Lisp code
to create the buffer you used, and anything else required to reproduce
the problem.

FTR, in my testing, I just visited an image file, enlarged it to be
larger than the window, and then invoked C-n with a numeric argument.
Your buffer has more stuff, which might make a difference.



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-23  6:05                                               ` Eli Zaretskii
@ 2020-10-23 16:48                                                 ` Yuan Fu
  2020-10-23 18:11                                                   ` Eli Zaretskii
  0 siblings, 1 reply; 36+ messages in thread
From: Yuan Fu @ 2020-10-23 16:48 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: help-gnu-emacs



> On Oct 23, 2020, at 2:05 AM, Eli Zaretskii <eliz@gnu.org> wrote:
> 
>> From: Yuan Fu <casouri@gmail.com>
>> Date: Thu, 22 Oct 2020 15:33:40 -0400
>> Cc: help-gnu-emacs@gnu.org
>> 
>>>> With emacs -Q? On my machine emacs -Q doesn’t to that. Instead of moving two line’s height, it just jumps
>>>> to the next logical line.
>>> 
>>> That can only happen if the image fits in the window in its entirety.
>>> Enlarge it so it's taller than the window, and then try again.
>> 
>> In the video I first pressed C-n a couple times, then C-u 2 C-n. It really doesn’t smooth scroll here (I’m on master).
> 
> Please submit a full bug report, with the image to use, the Lisp code
> to create the buffer you used, and anything else required to reproduce
> the problem.
> 
> FTR, in my testing, I just visited an image file, enlarged it to be
> larger than the window, and then invoked C-n with a numeric argument.
> Your buffer has more stuff, which might make a difference.
> 

In image-mode, C-n is bound to image-next-line, not next-line.

Yuan


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-23 16:48                                                 ` Yuan Fu
@ 2020-10-23 18:11                                                   ` Eli Zaretskii
  2020-10-23 20:30                                                     ` Yuan Fu
  0 siblings, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2020-10-23 18:11 UTC (permalink / raw)
  To: help-gnu-emacs

> From: Yuan Fu <casouri@gmail.com>
> Date: Fri, 23 Oct 2020 12:48:54 -0400
> Cc: help-gnu-emacs <help-gnu-emacs@gnu.org>
> 
> > FTR, in my testing, I just visited an image file, enlarged it to be
> > larger than the window, and then invoked C-n with a numeric argument.
> > Your buffer has more stuff, which might make a difference.
> > 
> 
> In image-mode, C-n is bound to image-next-line, not next-line.

OK, but how does this change anything in the context of the discussion
we are having?



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-23 18:11                                                   ` Eli Zaretskii
@ 2020-10-23 20:30                                                     ` Yuan Fu
  2020-10-24  7:17                                                       ` Eli Zaretskii
  0 siblings, 1 reply; 36+ messages in thread
From: Yuan Fu @ 2020-10-23 20:30 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: help-gnu-emacs



> On Oct 23, 2020, at 2:11 PM, Eli Zaretskii <eliz@gnu.org> wrote:
> 
>> From: Yuan Fu <casouri@gmail.com>
>> Date: Fri, 23 Oct 2020 12:48:54 -0400
>> Cc: help-gnu-emacs <help-gnu-emacs@gnu.org>
>> 
>>> FTR, in my testing, I just visited an image file, enlarged it to be
>>> larger than the window, and then invoked C-n with a numeric argument.
>>> Your buffer has more stuff, which might make a difference.
>>> 
>> 
>> In image-mode, C-n is bound to image-next-line, not next-line.
> 
> OK, but how does this change anything in the context of the discussion
> we are having?
> 

I was just mentioning that current implementation of next-line and friends only handle a limited use case (ARG=1) and what they do doesn’t provide enough inspiration to solve my problem. They never set window-start and vscroll in the same time because they don’t need to.

Technically my problem isn’t a real problem, since it works, but of course I want to do the right thing. Again, judging by my reading of the code in xdisp.c, setting window-start and vscroll doesn’t seem to harm too much.

I really need to set them in the same time because when I scroll down, and stopped at a tall image (or tall line), I don’t want to scroll to the top of that image immediately. Instead, I want to scroll just enough to show the bottom of it. This requires setting window-start to that image and set vscroll = image height - line height.

So maybe setting both window-start and vscroll should be considered as a valid thing to do?

Yuan


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-23 20:30                                                     ` Yuan Fu
@ 2020-10-24  7:17                                                       ` Eli Zaretskii
  2020-10-26  8:38                                                         ` Jens C. Jensen
  2020-10-27 18:10                                                         ` Yuan Fu
  0 siblings, 2 replies; 36+ messages in thread
From: Eli Zaretskii @ 2020-10-24  7:17 UTC (permalink / raw)
  To: help-gnu-emacs

> From: Yuan Fu <casouri@gmail.com>
> Date: Fri, 23 Oct 2020 16:30:40 -0400
> Cc: help-gnu-emacs@gnu.org
> 
> I really need to set them in the same time because when I scroll down, and stopped at a tall image (or tall line), I don’t want to scroll to the top of that image immediately. Instead, I want to scroll just enough to show the bottom of it. This requires setting window-start to that image and set vscroll = image height - line height.

This makes no sense to me, because you want to deliberately deny the
user from showing the entire screen line or its important parts.  The
bottom of a large image will generally not show anything important,
and most of the screen line with the surrounding text could remain
undisplayed.  Why is that a good idea? just because some other editor
behaves like that?

> So maybe setting both window-start and vscroll should be considered as a valid thing to do?

You can still do that as I've shown before, by inserting (sit-for 0)
in the middle, right?  But I urge you not to do that because it makes
no sense when text is mixed with images.



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-24  7:17                                                       ` Eli Zaretskii
@ 2020-10-26  8:38                                                         ` Jens C. Jensen
  2020-10-26 15:18                                                           ` Eli Zaretskii
  2020-10-27 18:10                                                         ` Yuan Fu
  1 sibling, 1 reply; 36+ messages in thread
From: Jens C. Jensen @ 2020-10-26  8:38 UTC (permalink / raw)
  To: Eli Zaretskii, help-gnu-emacs

On Sat, Oct 24 2020, Eli Zaretskii <eliz@gnu.org> wrote:

>> I really need to set them in the same time because when I scroll down, and stopped at a tall image (or tall line), I don’t want to scroll to the top of that image immediately. Instead, I want to scroll just enough to show the bottom of it. This requires setting window-start to that image and set vscroll = image height - line height.
>
> This makes no sense to me, because you want to deliberately deny the
> user from showing the entire screen line or its important parts.  The
> bottom of a large image will generally not show anything important,
> and most of the screen line with the surrounding text could remain
> undisplayed.  Why is that a good idea? just because some other editor
> behaves like that?

Just to have another data-point, I also prefer the behaviour that Yuan is describing, it has
been a pet-peeve for me that images seems to pop into (and out of) existence when scrolling in a
buffer with inline-images. Smoothly scrolling over images seem to be how many other things
behave, PDF viewers, websites, etc.




^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-26  8:38                                                         ` Jens C. Jensen
@ 2020-10-26 15:18                                                           ` Eli Zaretskii
  0 siblings, 0 replies; 36+ messages in thread
From: Eli Zaretskii @ 2020-10-26 15:18 UTC (permalink / raw)
  To: help-gnu-emacs

> From: Jens C. Jensen <jensecj@gmail.com>
> Date: Mon, 26 Oct 2020 09:38:26 +0100
> 
> On Sat, Oct 24 2020, Eli Zaretskii <eliz@gnu.org> wrote:
> 
> >> I really need to set them in the same time because when I scroll down, and stopped at a tall image (or tall line), I don’t want to scroll to the top of that image immediately. Instead, I want to scroll just enough to show the bottom of it. This requires setting window-start to that image and set vscroll = image height - line height.
> >
> > This makes no sense to me, because you want to deliberately deny the
> > user from showing the entire screen line or its important parts.  The
> > bottom of a large image will generally not show anything important,
> > and most of the screen line with the surrounding text could remain
> > undisplayed.  Why is that a good idea? just because some other editor
> > behaves like that?
> 
> Just to have another data-point, I also prefer the behaviour that Yuan is describing, it has
> been a pet-peeve for me that images seems to pop into (and out of) existence when scrolling in a
> buffer with inline-images. Smoothly scrolling over images seem to be how many other things
> behave, PDF viewers, websites, etc.

This is a misunderstanding: I have nothing against making image
scrolling more smooth.  The disagreement between us is not about the
user-facing feature, it is about low-level details of the
implementation, and how the display engine interprets certain flags.
(Actually, such a discussion should be held on emacs-devel or the
issue tracker, not here, precisely because it might confuse people who
dwell here.)



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-24  7:17                                                       ` Eli Zaretskii
  2020-10-26  8:38                                                         ` Jens C. Jensen
@ 2020-10-27 18:10                                                         ` Yuan Fu
  2020-10-27 18:32                                                           ` Eli Zaretskii
  1 sibling, 1 reply; 36+ messages in thread
From: Yuan Fu @ 2020-10-27 18:10 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: help-gnu-emacs



> On Oct 24, 2020, at 3:17 AM, Eli Zaretskii <eliz@gnu.org> wrote:
> 
>> From: Yuan Fu <casouri@gmail.com>
>> Date: Fri, 23 Oct 2020 16:30:40 -0400
>> Cc: help-gnu-emacs@gnu.org
>> 
>> I really need to set them in the same time because when I scroll down, and stopped at a tall image (or tall line), I don’t want to scroll to the top of that image immediately. Instead, I want to scroll just enough to show the bottom of it. This requires setting window-start to that image and set vscroll = image height - line height.
> 
> This makes no sense to me, because you want to deliberately deny the
> user from showing the entire screen line or its important parts.  

Only when the line is a tall image, which will break smooth scrolling if I try to show it completely. Instead, I want to reveal the image a bit at a time, so there is no surprise when scrolling through them. If the user wants to see the entire line they can press C-l.

> The
> bottom of a large image will generally not show anything important,
> and most of the screen line with the surrounding text could remain
> undisplayed.  Why is that a good idea? just because some other editor
> behaves like that?
> 

This is not about other editors, really. The main motivation is that with the current behavior, if I have images and text in the same buffer and I scroll down/up, the display jumps up and down and I get lost: I kind of lost track of where I am in the buffer. The desired behavior is, of course, a stable, smooth, unsurprised scrolling.

Maybe you (and many) scroll by half-screen, but I bet a large chunk of people using Emacs scrolls by 1 line, and expects a smooth scrolling behavior.


>> So maybe setting both window-start and vscroll should be considered as a valid thing to do?
> 
> You can still do that as I've shown before, by inserting (sit-for 0)
> in the middle, right?  But I urge you not to do that because it makes
> no sense when text is mixed with images.
> 

Will that make sense if the image is on a line by itself (which is often the case)? Inserting (sit-for 0) gives me flickers, Emacs will show the full image for like 0.1 second and scroll to the desired vscroll.

> This is a misunderstanding: I have nothing against making image
> scrolling more smooth.  The disagreement between us is not about the
> user-facing feature, it is about low-level details of the
> implementation, and how the display engine interprets certain flags.
> (Actually, such a discussion should be held on emacs-devel or the
> issue tracker, not here, precisely because it might confuse people who
> dwell here.)

How should I move the discussion to emacs-devel? Should I post a new thread and explain the disagreement/confusion?

I think it does make sense for window-start and vscroll to work together, and the implementation of redisplay seems to suggest that. Could you explain how is inserting sit-for makes sense but setting both flags at the same time doesn’t?

Yuan




^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Set-window-vscroll sometimes doesn't work
  2020-10-27 18:10                                                         ` Yuan Fu
@ 2020-10-27 18:32                                                           ` Eli Zaretskii
  0 siblings, 0 replies; 36+ messages in thread
From: Eli Zaretskii @ 2020-10-27 18:32 UTC (permalink / raw)
  To: help-gnu-emacs

> From: Yuan Fu <casouri@gmail.com>
> Date: Tue, 27 Oct 2020 14:10:58 -0400
> Cc: help-gnu-emacs <help-gnu-emacs@gnu.org>
> 
> This is not about other editors, really. The main motivation is that with the current behavior, if I have images and text in the same buffer and I scroll down/up, the display jumps up and down and I get lost: I kind of lost track of where I am in the buffer. The desired behavior is, of course, a stable, smooth, unsurprised scrolling.

And you can have that, just don't use any functions that set the
window's start point.  E.g., scroll by setting vscroll, and when that
is about to scroll past the last portion of the image, move point to
the next/previous line and set vscroll to a suitable value.  More or
less like image-mode.el does.

Scroll commands via scroll-up/down are for different use cases, so
they don't do what you want.

> How should I move the discussion to emacs-devel? Should I post a new thread and explain the disagreement/confusion?

Start new thread, yes.  What to discuss there is up to you.  I still
have no clear idea what are you looking for.  AFAIU, the problem you
are trying to solve doesn't need any change in how window-start and
vscroll are handled, so I don't understand why you insist on changing
that.

> I think it does make sense for window-start and vscroll to work together, and the implementation of redisplay seems to suggest that. Could you explain how is inserting sit-for makes sense but setting both flags at the same time doesn’t?

You don't need sit-for if you just set vscroll, I think.  The need for
sit-for in your original code was because you set window-start,
something you shouldn't do to solve your problem.



^ permalink raw reply	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2020-10-27 18:32 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-10-18  0:35 Set-window-vscroll sometimes doesn't work Yuan Fu
2020-10-18 14:34 ` Eli Zaretskii
2020-10-18 17:24   ` Yuan Fu
2020-10-18 17:31     ` Eli Zaretskii
2020-10-18 17:51       ` Yuan Fu
2020-10-18 17:55         ` Eli Zaretskii
2020-10-18 18:02           ` Yuan Fu
2020-10-18 19:12           ` Yuan Fu
2020-10-18 19:19             ` Eli Zaretskii
2020-10-18 20:06               ` Yuan Fu
2020-10-19  2:23                 ` Eli Zaretskii
     [not found]                   ` <B1D235FE-49B8-4F0A-9C02-78B7E3244C47@gmail.com>
2020-10-19  6:00                     ` Yuan Fu
2020-10-19 16:24                     ` Eli Zaretskii
2020-10-19 16:56                       ` Yuan Fu
2020-10-19 17:23                         ` Eli Zaretskii
2020-10-19 20:39                           ` Yuan Fu
2020-10-20 16:04                             ` Eli Zaretskii
2020-10-20 18:00                               ` Yuan Fu
2020-10-20 18:19                               ` Yuan Fu
2020-10-21 16:25                                 ` Eli Zaretskii
2020-10-21 19:05                                   ` Yuan Fu
2020-10-22  4:16                                     ` Yuan Fu
2020-10-22 16:08                                       ` Eli Zaretskii
2020-10-22 16:50                                         ` Yuan Fu
2020-10-22 17:09                                           ` Eli Zaretskii
2020-10-22 19:33                                             ` Yuan Fu
2020-10-23  6:05                                               ` Eli Zaretskii
2020-10-23 16:48                                                 ` Yuan Fu
2020-10-23 18:11                                                   ` Eli Zaretskii
2020-10-23 20:30                                                     ` Yuan Fu
2020-10-24  7:17                                                       ` Eli Zaretskii
2020-10-26  8:38                                                         ` Jens C. Jensen
2020-10-26 15:18                                                           ` Eli Zaretskii
2020-10-27 18:10                                                         ` Yuan Fu
2020-10-27 18:32                                                           ` Eli Zaretskii
2020-10-22 16:05                                     ` Eli Zaretskii

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.