Fix bug #14567 with jumpy scrolling of tall images.
src/xdisp.c (Fline_pixel_height): New function, required for solving bug #14567. lisp/simple.el (line-move-partial): Don't jump to the next screen line as soon as it becomes visible. Instead, continue enlarging the vscroll until the portion of a tall screen line that's left on display is about the height of the frame's default font.
This commit is contained in:
parent
d1ad37b23f
commit
9583ec36c4
4 changed files with 76 additions and 17 deletions
|
@ -1,3 +1,11 @@
|
|||
2013-06-15 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* simple.el (line-move-partial): Don't jump to the next screen
|
||||
line as soon as it becomes visible. Instead, continue enlarging
|
||||
the vscroll until the portion of a tall screen line that's left on
|
||||
display is about the height of the frame's default font.
|
||||
(Bug#14567)
|
||||
|
||||
2013-06-15 Glenn Morris <rgm@gnu.org>
|
||||
|
||||
* vc/vc-dispatcher.el (vc-compilation-mode): Avoid making
|
||||
|
|
|
@ -4738,42 +4738,62 @@ lines."
|
|||
(vpos (nth 1 lh))
|
||||
(ypos (nth 2 lh))
|
||||
(rbot (nth 3 lh))
|
||||
(this-lh (window-line-height))
|
||||
(this-height (nth 0 this-lh))
|
||||
(this-ypos (nth 2 this-lh))
|
||||
(fch (frame-char-height))
|
||||
py vs)
|
||||
(when (or (null lh)
|
||||
(>= rbot (frame-char-height))
|
||||
(<= ypos (- (frame-char-height))))
|
||||
(>= rbot fch)
|
||||
(<= ypos (- fch))
|
||||
(null this-lh)
|
||||
(<= this-ypos (- fch)))
|
||||
(unless lh
|
||||
(let ((wend (pos-visible-in-window-p t nil t)))
|
||||
(setq rbot (nth 3 wend)
|
||||
vpos (nth 5 wend))))
|
||||
(unless this-lh
|
||||
(let ((wstart (pos-visible-in-window-p nil nil t)))
|
||||
(setq this-ypos (nth 2 wstart)
|
||||
this-height (nth 4 wstart))))
|
||||
(setq py
|
||||
(or (nth 1 this-lh)
|
||||
(let ((ppos (posn-at-point)))
|
||||
(cdr (or (posn-actual-col-row ppos)
|
||||
(posn-col-row ppos))))))
|
||||
(cond
|
||||
;; If last line of window is fully visible, move forward.
|
||||
((or (null rbot) (= rbot 0))
|
||||
;; If last line of window is fully visible, and vscrolling
|
||||
;; more would make this line invisible, move forward.
|
||||
((and (or (< (setq vs (window-vscroll nil t)) fch)
|
||||
(null this-height)
|
||||
(<= this-height fch))
|
||||
(or (null rbot) (= rbot 0)))
|
||||
nil)
|
||||
;; If cursor is not in the bottom scroll margin, move forward.
|
||||
((and (> vpos 0)
|
||||
(< (setq py
|
||||
(or (nth 1 (window-line-height))
|
||||
(let ((ppos (posn-at-point)))
|
||||
(cdr (or (posn-actual-col-row ppos)
|
||||
(posn-col-row ppos))))))
|
||||
;; If cursor is not in the bottom scroll margin, and the
|
||||
;; current line is is not too tall, move forward.
|
||||
((and (or (null this-height) (<= this-height fch))
|
||||
vpos
|
||||
(> vpos 0)
|
||||
(< py
|
||||
(min (- (window-text-height) scroll-margin 1) (1- vpos))))
|
||||
nil)
|
||||
;; When already vscrolled, we vscroll some more if we can,
|
||||
;; or clear vscroll and move forward at end of tall image.
|
||||
((> (setq vs (window-vscroll nil t)) 0)
|
||||
(when (> rbot 0)
|
||||
(set-window-vscroll nil (+ vs (min rbot (frame-char-height))) t)))
|
||||
((> vs 0)
|
||||
(when (or (and rbot (> rbot 0))
|
||||
(and this-height (> this-height fch)))
|
||||
(set-window-vscroll nil (+ vs fch) t)))
|
||||
;; If cursor just entered the bottom scroll margin, move forward,
|
||||
;; but also vscroll one line so redisplay won't recenter.
|
||||
((and (> vpos 0)
|
||||
((and vpos
|
||||
(> vpos 0)
|
||||
(= py (min (- (window-text-height) scroll-margin 1)
|
||||
(1- vpos))))
|
||||
(set-window-vscroll nil (frame-char-height) t)
|
||||
(line-move-1 arg noerror to-end)
|
||||
t)
|
||||
;; If there are lines above the last line, scroll-up one line.
|
||||
((> vpos 0)
|
||||
((and vpos (> vpos 0))
|
||||
(scroll-up 1)
|
||||
t)
|
||||
;; Finally, start vscroll.
|
||||
|
@ -4808,7 +4828,14 @@ lines."
|
|||
;; display-based motion doesn't make sense (because each
|
||||
;; logical line occupies exactly one screen line).
|
||||
(not (> (window-hscroll) 0)))
|
||||
(line-move-visual arg noerror)
|
||||
(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)))
|
||||
(if (and (< arg 0)
|
||||
(< (point) (window-start))
|
||||
(> lh (frame-char-height)))
|
||||
(set-window-vscroll nil (- lh (frame-char-height)) t))))
|
||||
(line-move-1 arg noerror to-end)))))
|
||||
|
||||
;; Display-based alternative to line-move-1.
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2013-06-15 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* xdisp.c (Fline_pixel_height): New function, required for solving
|
||||
bug #14567.
|
||||
|
||||
2013-06-15 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
* fns.c (Fcopy_sequence): Simplify XTYPE calculation.
|
||||
|
|
19
src/xdisp.c
19
src/xdisp.c
|
@ -1217,6 +1217,24 @@ line_bottom_y (struct it *it)
|
|||
return line_top_y + line_height;
|
||||
}
|
||||
|
||||
DEFUN ("line-pixel-height", Fline_pixel_height,
|
||||
Sline_pixel_height, 0, 0, 0,
|
||||
doc: /* Return height in pixels of text line in the selected window.
|
||||
|
||||
Value is the height in pixels of the line at point. */)
|
||||
(void)
|
||||
{
|
||||
struct it it;
|
||||
struct text_pos pt;
|
||||
struct window *w = XWINDOW (selected_window);
|
||||
|
||||
SET_TEXT_POS (pt, PT, PT_BYTE);
|
||||
start_display (&it, w, pt);
|
||||
it.vpos = it.current_y = 0;
|
||||
last_height = 0;
|
||||
return make_number (line_bottom_y (&it));
|
||||
}
|
||||
|
||||
/* Subroutine of pos_visible_p below. Extracts a display string, if
|
||||
any, from the display spec given as its argument. */
|
||||
static Lisp_Object
|
||||
|
@ -28691,6 +28709,7 @@ syms_of_xdisp (void)
|
|||
defsubr (&Stool_bar_lines_needed);
|
||||
defsubr (&Slookup_image_map);
|
||||
#endif
|
||||
defsubr (&Sline_pixel_height);
|
||||
defsubr (&Sformat_mode_line);
|
||||
defsubr (&Sinvisible_p);
|
||||
defsubr (&Scurrent_bidi_paragraph_direction);
|
||||
|
|
Loading…
Add table
Reference in a new issue