From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.devel Subject: Re: The unwarranted scrolling assumption Date: Sun, 20 Jun 2010 18:24:18 +0300 Message-ID: <83eig1g21p.fsf@gnu.org> References: <87631jvpzg.fsf@gmail.com> <4C18211C.3070106@harpegolden.net> <87vd9j5neu.fsf@kfs-lx.rd.rdm> <83sk4misf2.fsf@gnu.org> <83iq5hiiin.fsf@gnu.org> <83fx0lihov.fsf@gnu.org> <838w6cixma.fsf@gnu.org> <83y6ech1oo.fsf@gnu.org> <83ocf8gx7e.fsf@gnu.org> <83fx0jgxk7.fsf@gnu.org> <83eig3gspa.fsf@gnu.org> <83bpb7gp2g.fsf@gnu.org> <837hlvglvh.fsf@gnu.org> <834ogzglaj.fsf@gnu.org> <8339wjgg8w.fsf@gnu.org> <83y6eagb7g.fsf@gnu.org> <83vd9eg9j1.fsf@gnu.org> <83r5k2g1qa.fsf@gnu.org> Reply-To: Eli Zaretskii NNTP-Posting-Host: lo.gmane.org X-Trace: dough.gmane.org 1277047681 11695 80.91.229.12 (20 Jun 2010 15:28:01 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sun, 20 Jun 2010 15:28:01 +0000 (UTC) Cc: cyd@stupidchicken.com, monnier@iro.umontreal.ca, emacs-devel@gnu.org To: Lennart Borgman Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Jun 20 17:27:59 2010 connect(): No such file or directory Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1OQMQj-0004oV-II for ged-emacs-devel@m.gmane.org; Sun, 20 Jun 2010 17:27:56 +0200 Original-Received: from localhost ([127.0.0.1]:51115 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OQMQf-0002ak-Vz for ged-emacs-devel@m.gmane.org; Sun, 20 Jun 2010 11:27:26 -0400 Original-Received: from [140.186.70.92] (port=39878 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OQMQY-0002af-PH for emacs-devel@gnu.org; Sun, 20 Jun 2010 11:27:20 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OQMQW-0002AV-JJ for emacs-devel@gnu.org; Sun, 20 Jun 2010 11:27:18 -0400 Original-Received: from mtaout22.012.net.il ([80.179.55.172]:47087) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OQMQW-0002AQ-5I for emacs-devel@gnu.org; Sun, 20 Jun 2010 11:27:16 -0400 Original-Received: from conversion-daemon.a-mtaout22.012.net.il by a-mtaout22.012.net.il (HyperSendmail v2007.08) id <0L4B00100K6JUB00@a-mtaout22.012.net.il> for emacs-devel@gnu.org; Sun, 20 Jun 2010 18:26:20 +0300 (IDT) Original-Received: from HOME-C4E4A596F7 ([84.228.178.198]) by a-mtaout22.012.net.il (HyperSendmail v2007.08) with ESMTPA id <0L4B00E6GK7VRMM0@a-mtaout22.012.net.il>; Sun, 20 Jun 2010 18:26:20 +0300 (IDT) In-reply-to: X-012-Sender: halo1@inter.net.il X-detected-operating-system: by eggs.gnu.org: Solaris 10 (beta) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:126268 Archived-At: > From: Lennart Borgman > Date: Sat, 19 Jun 2010 23:58:09 +0200 > Cc: cyd@stupidchicken.com, monnier@iro.umontreal.ca, emacs-devel@gnu.org > > Anyway the easiest way now seems that I take this trouble. I tried to > apply your patch as sent, but I could not get it to work. Maybe you > can just send me that function so I can replace that? It's a bit silly to do that, when we have a dVCS, but here you go anyway: ------------------------------------------------------------------ static int try_scrolling (window, just_this_one_p, scroll_conservatively, scroll_step, temp_scroll_step, last_line_misfit) Lisp_Object window; int just_this_one_p; EMACS_INT scroll_conservatively, scroll_step; int temp_scroll_step; int last_line_misfit; { struct window *w = XWINDOW (window); struct frame *f = XFRAME (w->frame); struct text_pos pos, startp; struct it it; int this_scroll_margin, scroll_max, rc, height; int dy = 0, amount_to_scroll = 0, scroll_down_p = 0; int extra_scroll_margin_lines = last_line_misfit ? 1 : 0; Lisp_Object aggressive; int scroll_limit = INT_MAX / FRAME_LINE_HEIGHT (f); #if GLYPH_DEBUG debug_method_add (w, "try_scrolling"); #endif SET_TEXT_POS_FROM_MARKER (startp, w->start); /* Compute scroll margin height in pixels. We scroll when point is within this distance from the top or bottom of the window. */ if (scroll_margin > 0) this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4) * FRAME_LINE_HEIGHT (f); else this_scroll_margin = 0; /* Force scroll_conservatively to have a reasonable value, to avoid overflow while computing how much to scroll. Note that the user can supply scroll-conservatively equal to `most-positive-fixnum', which can be larger than INT_MAX. */ if (scroll_conservatively > scroll_limit) { scroll_conservatively = scroll_limit; scroll_max = INT_MAX; } else if (scroll_step || scroll_conservatively || temp_scroll_step) /* Compute how much we should try to scroll maximally to bring point into view. */ scroll_max = (max (scroll_step, max (scroll_conservatively, temp_scroll_step)) * FRAME_LINE_HEIGHT (f)); else if (NUMBERP (current_buffer->scroll_down_aggressively) || NUMBERP (current_buffer->scroll_up_aggressively)) /* We're trying to scroll because of aggressive scrolling but no scroll_step is set. Choose an arbitrary one. */ scroll_max = 10 * FRAME_LINE_HEIGHT (f); else scroll_max = 0; too_near_end: /* Decide whether to scroll down. */ if (PT > CHARPOS (startp)) { int scroll_margin_y; /* Compute the pixel ypos of the scroll margin, then move it to either that ypos or PT, whichever comes first. */ start_display (&it, w, startp); scroll_margin_y = it.last_visible_y - this_scroll_margin - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines; move_it_to (&it, PT, -1, scroll_margin_y - 1, -1, (MOVE_TO_POS | MOVE_TO_Y)); if (PT > CHARPOS (it.current.pos)) { int y0 = line_bottom_y (&it); /* Compute how many pixels below window bottom to stop searching for PT. This avoids costly search for PT that is far away if the user limited scrolling by a small number of lines, but always finds PT if scroll_conservatively is set to a large number, such as most-positive-fixnum. */ int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f)); int y_to_move = slack >= INT_MAX - it.last_visible_y ? INT_MAX : it.last_visible_y + slack; /* Compute the distance from the scroll margin to PT or to the scroll limit, whichever comes first. This should include the height of the cursor line, to make that line fully visible. */ move_it_to (&it, PT, -1, y_to_move, -1, MOVE_TO_POS | MOVE_TO_Y); dy = line_bottom_y (&it) - y0; if (dy > scroll_max) return SCROLLING_FAILED; scroll_down_p = 1; } } if (scroll_down_p) { /* Point is in or below the bottom scroll margin, so move the window start down. If scrolling conservatively, move it just enough down to make point visible. If scroll_step is set, move it down by scroll_step. */ if (scroll_conservatively) amount_to_scroll = min (max (dy, FRAME_LINE_HEIGHT (f)), FRAME_LINE_HEIGHT (f) * scroll_conservatively); else if (scroll_step || temp_scroll_step) amount_to_scroll = scroll_max; else { aggressive = current_buffer->scroll_up_aggressively; height = WINDOW_BOX_TEXT_HEIGHT (w); if (NUMBERP (aggressive)) { double float_amount = XFLOATINT (aggressive) * height; amount_to_scroll = float_amount; if (amount_to_scroll == 0 && float_amount > 0) amount_to_scroll = 1; } } if (amount_to_scroll <= 0) return SCROLLING_FAILED; start_display (&it, w, startp); move_it_vertically (&it, amount_to_scroll); /* If STARTP is unchanged, move it down another screen line. */ if (CHARPOS (it.current.pos) == CHARPOS (startp)) move_it_by_lines (&it, 1, 1); startp = it.current.pos; } else { struct text_pos scroll_margin_pos = startp; /* See if point is inside the scroll margin at the top of the window. */ if (this_scroll_margin) { start_display (&it, w, startp); move_it_vertically (&it, this_scroll_margin); scroll_margin_pos = it.current.pos; } if (PT < CHARPOS (scroll_margin_pos)) { /* Point is in the scroll margin at the top of the window or above what is displayed in the window. */ int y0; /* Compute the vertical distance from PT to the scroll margin position. Give up if distance is greater than scroll_max. */ SET_TEXT_POS (pos, PT, PT_BYTE); start_display (&it, w, pos); y0 = it.current_y; move_it_to (&it, CHARPOS (scroll_margin_pos), 0, it.last_visible_y, -1, MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); dy = it.current_y - y0; if (dy > scroll_max) return SCROLLING_FAILED; /* Compute new window start. */ start_display (&it, w, startp); if (scroll_conservatively) amount_to_scroll = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step)); else if (scroll_step || temp_scroll_step) amount_to_scroll = scroll_max; else { aggressive = current_buffer->scroll_down_aggressively; height = WINDOW_BOX_TEXT_HEIGHT (w); if (NUMBERP (aggressive)) { double float_amount = XFLOATINT (aggressive) * height; amount_to_scroll = float_amount; if (amount_to_scroll == 0 && float_amount > 0) amount_to_scroll = 1; } } if (amount_to_scroll <= 0) return SCROLLING_FAILED; move_it_vertically_backward (&it, amount_to_scroll); startp = it.current.pos; } } /* Run window scroll functions. */ startp = run_window_scroll_functions (window, startp); /* Display the window. Give up if new fonts are loaded, or if point doesn't appear. */ if (!try_window (window, startp, 0)) rc = SCROLLING_NEED_LARGER_MATRICES; else if (w->cursor.vpos < 0) { clear_glyph_matrix (w->desired_matrix); rc = SCROLLING_FAILED; } else { /* Maybe forget recorded base line for line number display. */ if (!just_this_one_p || current_buffer->clip_changed || BEG_UNCHANGED < CHARPOS (startp)) w->base_line_number = Qnil; /* If cursor ends up on a partially visible line, treat that as being off the bottom of the screen. */ if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)) { clear_glyph_matrix (w->desired_matrix); ++extra_scroll_margin_lines; goto too_near_end; } rc = SCROLLING_SUCCESS; } return rc; }