From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.bugs Subject: bug#14567: Scrolling of large images Date: Sat, 08 Jun 2013 17:19:32 +0300 Message-ID: <83vc5osn0r.fsf@gnu.org> References: <83ppvzur6i.fsf@gnu.org> <83obbjuov4.fsf@gnu.org> Reply-To: Eli Zaretskii NNTP-Posting-Host: plane.gmane.org X-Trace: ger.gmane.org 1370701263 17829 80.91.229.3 (8 Jun 2013 14:21:03 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 8 Jun 2013 14:21:03 +0000 (UTC) Cc: 14567@debbugs.gnu.org To: thomas.wiecki@gmail.com Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sat Jun 08 16:21:03 2013 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1UlK0s-00086I-N4 for geb-bug-gnu-emacs@m.gmane.org; Sat, 08 Jun 2013 16:21:02 +0200 Original-Received: from localhost ([::1]:34151 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UlK0s-0004Zj-3A for geb-bug-gnu-emacs@m.gmane.org; Sat, 08 Jun 2013 10:21:02 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:36990) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UlK0o-0004Ze-5W for bug-gnu-emacs@gnu.org; Sat, 08 Jun 2013 10:20:59 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UlK0m-0000Kx-Dj for bug-gnu-emacs@gnu.org; Sat, 08 Jun 2013 10:20:58 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:41839) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UlK0m-0000Kt-2y for bug-gnu-emacs@gnu.org; Sat, 08 Jun 2013 10:20:56 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.72) (envelope-from ) id 1UlK0r-0000Dv-N5 for bug-gnu-emacs@gnu.org; Sat, 08 Jun 2013 10:21:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Eli Zaretskii Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 08 Jun 2013 14:21:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 14567 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 14567-submit@debbugs.gnu.org id=B14567.1370701226742 (code B ref 14567); Sat, 08 Jun 2013 14:21:01 +0000 Original-Received: (at 14567) by debbugs.gnu.org; 8 Jun 2013 14:20:26 +0000 Original-Received: from localhost ([127.0.0.1]:58429 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1UlK0H-0000Bp-CE for submit@debbugs.gnu.org; Sat, 08 Jun 2013 10:20:25 -0400 Original-Received: from mtaout22.012.net.il ([80.179.55.172]:64324) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1UlK0D-0000B8-S2 for 14567@debbugs.gnu.org; Sat, 08 Jun 2013 10:20:23 -0400 Original-Received: from conversion-daemon.a-mtaout22.012.net.il by a-mtaout22.012.net.il (HyperSendmail v2007.08) id <0MO200D00V2AGE00@a-mtaout22.012.net.il> for 14567@debbugs.gnu.org; Sat, 08 Jun 2013 17:19:44 +0300 (IDT) Original-Received: from HOME-C4E4A596F7 ([87.69.4.28]) by a-mtaout22.012.net.il (HyperSendmail v2007.08) with ESMTPA id <0MO200DULVSW27B0@a-mtaout22.012.net.il>; Sat, 08 Jun 2013 17:19:44 +0300 (IDT) In-reply-to: <83obbjuov4.fsf@gnu.org> X-012-Sender: halo1@inter.net.il X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:74892 Archived-At: > Date: Thu, 06 Jun 2013 20:32:15 +0300 > From: Eli Zaretskii > Cc: 14567@debbugs.gnu.org > > > From: Thomas Wiecki > > Date: Thu, 6 Jun 2013 13:16:43 -0400 > > Cc: 14567@debbugs.gnu.org > > > > 1. Download a large image (e.g. > > http://cdn.urbanislandz.com/wp-content/uploads/2011/10/MMSposter-large.jpg) > > and save it as /tmp/test.jpg > > 2. In an emacs buffer type "(insert-image (create-image "/tmp/test.jpg"))" > > 3. Type some arbitrary lines of text below this line. > > 4. In first line (containing insert-image), type C-x C-e at end of line to > > load the image. > > 5. Image should appear in buffer. > > 6. Scroll down repeatedly until past the image. > > > > Expected behavior: Scrolls down smoothly even once scrolled past image. > > Observed behavior: Scrolls down smoothly until end of image is reached. At > > end of image, the next scroll causes a huge jump in the window so that and > > only the text is shown but not any of the residual image. > > > > 7. scroll back up > > > > Expected behavior: Scrolls upwards over image. > > Observed behavior: Jumps over complete image and shows beginning of buffer. > > Perfect, thanks. I will take a look. Can you try the changes below and see if they give good results, including in the real-life use cases where you bumped into this? Note that you will have to rebuild Emacs to try this. Thanks. === modified file 'lisp/simple.el' --- lisp/simple.el 2013-06-05 18:10:27 +0000 +++ lisp/simple.el 2013-06-08 14:14:39 +0000 @@ -4738,20 +4738,35 @@ 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)))) (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) + (<= this-height fch)) + (or (null rbot) (= rbot 0))) nil) - ;; If cursor is not in the bottom scroll margin, move forward. - ((and (> vpos 0) + ;; If cursor is not in the bottom scroll margin, and the + ;; current line is is not too tall, move forward. + ((and (<= this-height fch) + (> vpos 0) (< (setq py (or (nth 1 (window-line-height)) (let ((ppos (posn-at-point))) @@ -4761,9 +4776,10 @@ lines." 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 (> rbot 0) + (> 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) @@ -4808,7 +4824,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. === modified file 'src/xdisp.c' --- src/xdisp.c 2013-06-06 16:35:31 +0000 +++ src/xdisp.c 2013-06-08 14:02:28 +0000 @@ -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 @@ -28665,6 +28683,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);