From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.devel Subject: Re: Unfreezing the display during auto-repeated scrolling. [ Was: Aborting display. Is this possible? ] Date: Sun, 26 Oct 2014 20:03:13 +0000 Message-ID: <20141026200313.GE4397@acm.acm> References: <83lhoabl2x.fsf@gnu.org> <20141020210819.GE2947@acm.acm> <87y4s9rgi9.fsf@fencepost.gnu.org> <83zjcpa11g.fsf@gnu.org> <20141021171403.GB3035@acm.acm> <83oat59ucc.fsf@gnu.org> <20141021183807.GD3035@acm.acm> <20141026124333.GA4397@acm.acm> <83h9yq4w5g.fsf@gnu.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1414353869 8080 80.91.229.3 (26 Oct 2014 20:04:29 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 26 Oct 2014 20:04:29 +0000 (UTC) Cc: monnier@IRO.UMontreal.CA, emacs-devel@gnu.org To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Oct 26 21:04:22 2014 Return-path: Envelope-to: ged-emacs-devel@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 1XiU34-00039N-2S for ged-emacs-devel@m.gmane.org; Sun, 26 Oct 2014 21:04:22 +0100 Original-Received: from localhost ([::1]:58250 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XiU33-0002VQ-2n for ged-emacs-devel@m.gmane.org; Sun, 26 Oct 2014 16:04:21 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:48362) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XiU2j-0002VG-4m for emacs-devel@gnu.org; Sun, 26 Oct 2014 16:04:05 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XiU2e-0005Zz-DV for emacs-devel@gnu.org; Sun, 26 Oct 2014 16:04:01 -0400 Original-Received: from colin.muc.de ([193.149.48.1]:20507 helo=mail.muc.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XiU2d-0005Zo-VJ for emacs-devel@gnu.org; Sun, 26 Oct 2014 16:03:56 -0400 Original-Received: (qmail 26095 invoked by uid 3782); 26 Oct 2014 20:03:54 -0000 Original-Received: from acm.muc.de (pD951867E.dip0.t-ipconnect.de [217.81.134.126]) by colin.muc.de (tmda-ofmipd) with ESMTP; Sun, 26 Oct 2014 21:03:52 +0100 Original-Received: (qmail 11748 invoked by uid 1000); 26 Oct 2014 20:03:13 -0000 Content-Disposition: inline In-Reply-To: <83h9yq4w5g.fsf@gnu.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Delivery-Agent: TMDA/1.1.12 (Macallan) X-Primary-Address: acm@muc.de X-detected-operating-system: by eggs.gnu.org: FreeBSD 8.x X-Received-From: 193.149.48.1 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:175874 Archived-At: Hello, Eli. Thanks for such a quick reply. On Sun, Oct 26, 2014 at 06:45:47PM +0200, Eli Zaretskii wrote: > > Date: Sun, 26 Oct 2014 12:43:33 +0000 > > From: Alan Mackenzie > > Cc: monnier@IRO.UMontreal.CA, emacs-devel@gnu.org > > Here's what I've done: Conceptually, ITs (i.e. "struct it"s, the > > iterators in xdisp.c) are used for two different purposes: > > (i) display; > > (ii) calculation of displayed character sizes, positions etc. > > I've distinguished these two cases by adding an extra boolean flag to IT, > > called `not_for_display'. The functions `init_iterator' and > > `start_display' have got this as an extra boolean parameter. > > Some of the ITs in window.c and xdisp.c are now designated > > `not_for_display'. > > `handle_fontified_prop' now checks this flag in IT. If both the flag and > > `use-default-face-for-fast-scrolling' are set, then fontification is not > > done. The existing face (usually default) is simply left there. The > > code doesn't also check for the event queue being non-empty - in > > practice, this didn't work very well. > > Here's the code. Comments and criticism would be welcome. > I'm afraid this is a non-starter. Even if this feature is accepted > (and I don't like it), it cannot be controlled on such a low level. > You cannot possibly know, on this low level, which code will use the > "not for display" functions, even if today they are only used in a > context where ignoring font-lock faces might be OK. The contract of xdisp.c says explicitly that the only visible display function is redisplay, and this has no IT parameters. So any IT with not_for_display set should be "safe" if it is defined outside of xdisp.c > You already marked as "not for display" line-pixel-height, which must > be accurate in the results it returns, since otherwise it will violate > its contract. Likewise in resize_mini_window (which is definitely "for > display"), redisplay_internal (likewise), etc. OTOH, displaying > strings (e.g., as part of mode-line display) will never bump into > font-lock faces, so setting this flag there is not useful. Sorry, I'd left unnecessary not_for_display's set. I've cleared out xdisp.c, such that the only function which sets not_for_display is pos_visible_p. The rest are not needed. The other functions which set not_for_display are (i) window_scroll_pixel_based (window.c); (ii) Fvertical_motion (indent.c). > So if we go this way, we are digging a hole for ourselves -- it is an > impossible maintenance burden to have functions that don't exactly do > what they say they do under some circumstances. Yes. But the current implementation doesn't work very well. I'm trying to fix it, because it's irritating. I think I've made good progress. I can't see any other approach to fixing it at the moment. > You should only make changes in window_scroll_* functions, ... I honestly can't see how I could achieve what's wanted if I restrict myself to window.c. > ... and do that only under control of the > use-default-face-for-fast-scrolling variable, so that the Lisp > application that binds this variable to a non-nil value is the sole > source of this behavior, and holds all the responsibility for binding > it where it wants. No code should disregard font-lock faces, except > when this variable is non-nil. The new feature I've added remains inactive when use-default-face-for-fast-scrolling is nil. The single effect when it is set is to inhibit fontification when an IT.not_for_display flag is also set. I had in mind that use-default-face-for-fast-scrolling should be a user option rather than something to be set by a major mode. Something that could upset exact scrolling should be turned on by a user, rather thaan by a major mode. > And I still don't understand why writing a simple "fast-scroll" > function in Lisp, which just moves point N lines forward or backward, > is not a better solution. It's certainly easier and has exactly zero > impact on our infrastructure. That's precisely how Fscroll_up and Fscroll_down work. I'd merely be reinventing the wheel, and I'd face all the difficulties and special cases which other hackers have long ago overcome. To reiterate what I want: it is for an auto-repeated PageUp or PageDown not to freeze the screen, either whilst depressed or after being released. I don't see how writing a new scroll command for these keys would help. Anyhow, I've now got the feature working for GUI windows. It wasn't difficult. Here's the updated patch: === modified file 'src/dispextern.h' --- src/dispextern.h 2014-10-15 10:22:15 +0000 +++ src/dispextern.h 2014-10-26 10:32:37 +0000 @@ -2275,6 +2275,12 @@ /* True means cursor shouldn't be displayed here. */ bool_bf avoid_cursor_p : 1; + /* True means it is known that IT is only for calculating screen + occupancy, not for actually drawing elements on a screen. This + suppresses fontification when user option + `use-default-face-for-fast-scrolling' is set. */ + bool_bf not_for_display : 1; + /* Display table in effect or null for none. */ struct Lisp_Char_Table *dp; @@ -3204,10 +3210,10 @@ void mark_window_display_accurate (Lisp_Object, int); void redisplay_preserve_echo_area (int); void init_iterator (struct it *, struct window *, ptrdiff_t, - ptrdiff_t, struct glyph_row *, enum face_id); + ptrdiff_t, struct glyph_row *, enum face_id, bool); void init_iterator_to_row_start (struct it *, struct window *, struct glyph_row *); -void start_display (struct it *, struct window *, struct text_pos); +void start_display (struct it *, struct window *, struct text_pos, bool); void move_it_vertically (struct it *, int); void move_it_vertically_backward (struct it *, int); void move_it_by_lines (struct it *, ptrdiff_t); === modified file 'src/dispnew.c' --- src/dispnew.c 2014-10-14 12:45:41 +0000 +++ src/dispnew.c 2014-10-22 11:15:50 +0000 @@ -5131,7 +5131,7 @@ Fset_buffer (w->contents); itdata = bidi_shelve_cache (); CLIP_TEXT_POS_FROM_MARKER (startp, w->start); - start_display (&it, w, startp); + start_display (&it, w, startp, 0); x0 = *x; /* First, move to the beginning of the row corresponding to *Y. We === modified file 'src/indent.c' --- src/indent.c 2014-08-28 01:59:29 +0000 +++ src/indent.c 2014-10-22 11:17:10 +0000 @@ -2009,7 +2009,7 @@ itdata = bidi_shelve_cache (); SET_TEXT_POS (pt, PT, PT_BYTE); - start_display (&it, w, pt); + start_display (&it, w, pt, 1); first_x = it.first_visible_x; it_start = IT_CHARPOS (it); === modified file 'src/window.c' --- src/window.c 2014-10-04 08:20:24 +0000 +++ src/window.c 2014-10-26 15:15:07 +0000 @@ -1799,7 +1799,7 @@ CLIP_TEXT_POS_FROM_MARKER (startp, w->start); itdata = bidi_shelve_cache (); - start_display (&it, w, startp); + start_display (&it, w, startp, 0); move_it_vertically (&it, window_box_height (w)); if (it.current_y < it.last_visible_y) move_it_past_eol (&it); @@ -4923,7 +4923,7 @@ /* Move backward half the height of the window. Performance note: vmotion used here is about 10% faster, but would give wrong results for variable height lines. */ - init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); + init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID, 1); it.current_y = it.last_visible_y; move_it_vertically_backward (&it, window_box_height (w) / 2); @@ -4934,7 +4934,7 @@ start of the line containing PT in this case. */ if (it.current_y <= 0) { - init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); + init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID, 1); move_it_vertically_backward (&it, 0); it.current_y = 0; } @@ -5015,7 +5015,7 @@ || !SYMBOLP (KVAR (current_kboard, Vlast_command)) || NILP (Fget (KVAR (current_kboard, Vlast_command), Qscroll_command))) { - start_display (&it, w, start); + start_display (&it, w, start, 1); move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); window_scroll_pixel_based_preserve_y = it.current_y; window_scroll_pixel_based_preserve_x = it.current_x; @@ -5027,7 +5027,7 @@ /* Move iterator it from start the specified distance forward or backward. The result is the new window start. */ - start_display (&it, w, start); + start_display (&it, w, start, 1); if (whole) { ptrdiff_t start_pos = IT_CHARPOS (it); @@ -5252,7 +5252,7 @@ else if (window_scroll_pixel_based_preserve_y >= 0) { SET_TEXT_POS_FROM_MARKER (start, w->start); - start_display (&it, w, start); + start_display (&it, w, start, 1); /* It would be wrong to subtract CURRENT_HEADER_LINE_HEIGHT here because we called start_display again and did not alter it.current_y this time. */ @@ -5310,6 +5310,20 @@ bool adjust_old_pointm = !NILP (Fequal (Fwindow_point (window), Fwindow_old_point (window))); +#if 0 + Lisp_Object Fhighest_fontified = intern ("highest-fontified"); + Lisp_Object Flowest_fontified = intern ("lowest-fontified"); + Lisp_Object Fdump_fontification_diags = intern ("dump-fontification-diags"); + Lisp_Object pre_point = Fpoint (), post_point, pre_low_f, post_low_f, pre_high_f, post_high_f; + + Lisp_Object dfd_array [7]; + struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; + GCPRO6 (Fhighest_fontified, Fdump_fontification_diags, + pre_point, post_point, pre_high_f, post_high_f); + pre_low_f = Ffuncall (1, (Lisp_Object []){Flowest_fontified}); + pre_high_f = Ffuncall (0, (Lisp_Object []){Fhighest_fontified}); +#endif + /* If scrolling screen-fulls, compute the number of lines to scroll from the window's height. */ if (whole) @@ -5355,7 +5369,12 @@ if (lose) { if (noerror) - return; + { +#if 0 + UNGCPRO; +#endif + return; + } else xsignal0 (Qbeginning_of_buffer); } @@ -5436,7 +5455,12 @@ else { if (noerror) - return; + { +#if 0 + UNGCPRO; +#endif + return; + } else xsignal0 (Qend_of_buffer); } @@ -5447,6 +5471,21 @@ ? make_number (BUF_PT (XBUFFER (w->contents))) : Fmarker_position (w->pointm)), w->contents); + +#if 0 + post_low_f = Ffuncall (1, (Lisp_Object []){Flowest_fontified}); + post_high_f = Ffuncall (1, (Lisp_Object []){Fhighest_fontified}); + post_point = Fpoint (); + dfd_array [0] = Fdump_fontification_diags; + dfd_array [1] = pre_low_f; + dfd_array [2] = pre_high_f; + dfd_array [3] = pre_point; + dfd_array [4] = post_low_f; + dfd_array [5] = post_high_f; + dfd_array [6] = post_point; + Ffuncall (7, dfd_array); + UNGCPRO; +#endif } @@ -5694,7 +5733,7 @@ CLIP_TEXT_POS_FROM_MARKER (start, w->start); itdata = bidi_shelve_cache (); - start_display (&it, w, start); + start_display (&it, w, start, 0); move_it_vertically (&it, height); bottom_y = line_bottom_y (&it); bidi_unshelve_cache (itdata, 0); @@ -5798,7 +5837,7 @@ void *itdata = bidi_shelve_cache (); SET_TEXT_POS (pt, PT, PT_BYTE); - start_display (&it, w, pt); + start_display (&it, w, pt, 0); move_it_vertically_backward (&it, window_box_height (w) / 2); charpos = IT_CHARPOS (it); bytepos = IT_BYTEPOS (it); @@ -5816,7 +5855,7 @@ iarg = - max (-iarg, this_scroll_margin); SET_TEXT_POS (pt, PT, PT_BYTE); - start_display (&it, w, pt); + start_display (&it, w, pt, 0); /* Be sure we have the exact height of the full line containing PT. */ move_it_by_lines (&it, 0); @@ -5855,7 +5894,7 @@ } /* Now find the new top line (starting position) of the window. */ - start_display (&it, w, pt); + start_display (&it, w, pt, 0); it.current_y = 0; move_it_vertically_backward (&it, h); === modified file 'src/xdisp.c' --- src/xdisp.c 2014-10-24 09:58:43 +0000 +++ src/xdisp.c 2014-10-26 18:48:23 +0000 @@ -1289,7 +1289,7 @@ set_buffer_internal_1 (XBUFFER (w->contents)); } SET_TEXT_POS (pt, PT, PT_BYTE); - start_display (&it, w, pt); + start_display (&it, w, pt, 0); it.vpos = it.current_y = 0; last_height = 0; result = make_number (line_bottom_y (&it)); @@ -1434,7 +1434,7 @@ = display_mode_line (w, HEADER_LINE_FACE_ID, BVAR (current_buffer, header_line_format)); - start_display (&it, w, top); + start_display (&it, w, top, 1); move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1, (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y); @@ -1508,7 +1508,7 @@ the previous buffer position is also displayed from a display vector, we need to consume all of the glyphs from that display vector. */ - start_display (&it2, w, top); + start_display (&it2, w, top, 1); move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS); /* If we didn't get to CHARPOS - 1, there's some replacing display property at that position, and @@ -1590,7 +1590,7 @@ end = XFASTINT (endpos); /* Move to the last buffer position before the display property. */ - start_display (&it3, w, top); + start_display (&it3, w, top, 1); if (start > CHARPOS (top)) move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS); /* Move forward one more line if the position before @@ -1625,7 +1625,7 @@ display string could be _after_ the display property in the logical order. Use the smallest vertical position of these two. */ - start_display (&it3, w, top); + start_display (&it3, w, top, 1); move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS); if (it3.current_y < top_y) top_y = it3.current_y; @@ -1633,7 +1633,7 @@ /* Move from the top of the window to the beginning of the display line where the display string begins. */ - start_display (&it3, w, top); + start_display (&it3, w, top, 1); move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y); /* If it3_moved stays zero after the 'while' loop below, that means we already were at a newline @@ -2795,12 +2795,18 @@ If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID, MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator will be initialized to use the corresponding mode line glyph row of - the desired matrix of W. */ + the desired matrix of W. + + NOT_FOR_DISPLAY can be set to true if it is known the iterator will + not be used for display. This optimization prevents this iterator + from performing fontification when the user option + USE-DEFAULT-FACE-FOR-FAST-SCROLLING is enabled. */ void init_iterator (struct it *it, struct window *w, ptrdiff_t charpos, ptrdiff_t bytepos, - struct glyph_row *row, enum face_id base_face_id) + struct glyph_row *row, enum face_id base_face_id, + bool not_for_display) { enum face_id remapped_base_face_id = base_face_id; @@ -2840,6 +2846,7 @@ it->current.overlay_string_index = -1; it->current.dpvec_index = -1; it->base_face_id = remapped_base_face_id; + it->not_for_display = not_for_display; it->string = Qnil; IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1; it->paragraph_embedding = L2R; @@ -3097,13 +3104,15 @@ /* Initialize IT for the display of window W with window start POS. */ void -start_display (struct it *it, struct window *w, struct text_pos pos) +start_display (struct it *it, struct window *w, struct text_pos pos, + bool not_for_display) { struct glyph_row *row; int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0; row = w->desired_matrix->rows + first_vpos; - init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID); + init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID, + not_for_display); it->first_vpos = first_vpos; /* Don't reseat to previous visible line start if current start @@ -3243,7 +3252,7 @@ newline before the row start, such a POS will not be in a string, but the call to init_iterator below will move us to the after-string. */ - init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID); + init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID, 0); /* This only scans the current chunk -- it should scan all chunks. However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1 @@ -3867,7 +3876,10 @@ prop = Fget_char_property (pos, Qfontified, Qnil), /* Ignore the special cased nil value always present at EOB since no amount of fontifying will be able to change it. */ - NILP (prop) && IT_CHARPOS (*it) < Z)) + NILP (prop) && IT_CHARPOS (*it) < Z) + && (NILP (Vuse_default_face_for_fast_scrolling) + || !it->not_for_display + /* || NILP (Finput_pending_p (Qnil)) */)) { ptrdiff_t count = SPECPDL_INDEX (); Lisp_Object val; @@ -9866,7 +9878,7 @@ itdata = bidi_shelve_cache (); SET_TEXT_POS (startp, start, CHAR_TO_BYTE (start)); - start_display (&it, w, startp); + start_display (&it, w, startp, 0); if (NILP (x_limit)) x = move_it_to (&it, end, -1, max_y, -1, MOVE_TO_POS | MOVE_TO_Y); @@ -10915,7 +10927,7 @@ set_buffer_internal (XBUFFER (w->contents)); } - init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID); + init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID, 0); /* Compute the max. number of lines specified by the user. */ if (FLOATP (Vmax_mini_window_height)) @@ -10946,7 +10958,7 @@ if (height > max_height) { height = (max_height / unit) * unit; - init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID); + init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID, 0); move_it_vertically_backward (&it, height - unit); start = it.current.pos; } @@ -11626,7 +11638,7 @@ mode_line_target = MODE_LINE_TITLE; title_start = MODE_LINE_NOPROP_LEN (0); init_iterator (&it, XWINDOW (f->selected_window), -1, -1, - NULL, DEFAULT_FACE_ID); + NULL, DEFAULT_FACE_ID, 0); display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0); len = MODE_LINE_NOPROP_LEN (title_start); title = mode_line_noprop_buf + title_start; @@ -12355,7 +12367,7 @@ /* Initialize an iterator for iteration over F->desired_tool_bar_string in the tool-bar window of frame F. */ - init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID); + init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID, 0); temp_row->reversed_p = false; it.first_visible_x = 0; it.last_visible_x = WINDOW_PIXEL_WIDTH (w); @@ -12437,7 +12449,7 @@ return 0; /* Set up an iterator for the tool-bar window. */ - init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID); + init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID, 0); it.first_visible_x = 0; it.last_visible_x = WINDOW_PIXEL_WIDTH (w); row = it.glyph_row; @@ -13709,7 +13721,7 @@ /* Note that start_display will handle the case that the line starting at tlbufpos is a continuation line. */ - start_display (&it, w, tlbufpos); + start_display (&it, w, tlbufpos, 0); /* Implementation note: It this still necessary? */ if (it.current_x != this_line_start_x) @@ -13825,7 +13837,7 @@ PT may be in invisible text. If so, we will end at the next visible position. */ init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos), - NULL, DEFAULT_FACE_ID); + NULL, DEFAULT_FACE_ID, 0); it.current_x = this_line_start_x; it.current_y = this_line_y; it.vpos = this_line_vpos; @@ -15138,7 +15150,7 @@ /* 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); + start_display (&it, w, startp, 0); scroll_margin_y = it.last_visible_y - this_scroll_margin - frame_line_height * extra_scroll_margin_lines; move_it_to (&it, PT, -1, scroll_margin_y - 1, -1, @@ -15208,7 +15220,7 @@ if (amount_to_scroll <= 0) return SCROLLING_FAILED; - start_display (&it, w, startp); + start_display (&it, w, startp, 0); if (arg_scroll_conservatively <= scroll_limit) move_it_vertically (&it, amount_to_scroll); else @@ -15250,7 +15262,7 @@ { int y_start; - start_display (&it, w, startp); + start_display (&it, w, startp, 0); y_start = it.current_y; move_it_vertically (&it, this_scroll_margin); scroll_margin_pos = it.current.pos; @@ -15274,7 +15286,7 @@ Give up if distance is greater than scroll_max or if we didn't reach the scroll margin position. */ SET_TEXT_POS (pos, PT, PT_BYTE); - start_display (&it, w, pos); + start_display (&it, w, pos, 0); y0 = it.current_y; y_to_move = max (it.last_visible_y, max (scroll_max, 10 * frame_line_height)); @@ -15290,7 +15302,7 @@ dy += y_offset; /* Compute new window start. */ - start_display (&it, w, startp); + start_display (&it, w, startp, 0); if (arg_scroll_conservatively) amount_to_scroll = max (dy, frame_line_height * @@ -15399,7 +15411,7 @@ because find_newline is fast (newline cache). */ row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0); init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos), - row, DEFAULT_FACE_ID); + row, DEFAULT_FACE_ID, 0); reseat_at_previous_visible_line_start (&it); /* If the line start is "too far" away from the window start, @@ -15871,7 +15883,7 @@ } SET_TEXT_POS_FROM_MARKER (startp, w->start); - start_display (&it, w, startp); + start_display (&it, w, startp, 0); it.last_visible_x = INT_MAX; whole = move_it_to (&it, -1, INT_MAX, window_box_height (w), -1, MOVE_TO_X | MOVE_TO_Y); @@ -16184,7 +16196,7 @@ ptrdiff_t it_charpos; w->optional_new_start = 0; - start_display (&it, w, startp); + start_display (&it, w, startp, 0); move_it_to (&it, PT, 0, it.last_visible_y, -1, MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); /* Record IT's position now, since line_bottom_y might change @@ -16577,7 +16589,7 @@ w->base_line_number = 0; /* Determine the window start relative to point. */ - init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); + init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID, 0); it.current_y = it.last_visible_y; if (centering_position < 0) { @@ -16606,7 +16618,7 @@ void *it1data = NULL; SAVE_IT (it1, it, it1data); - start_display (&it1, w, startp); + start_display (&it1, w, startp, 0); move_it_vertically (&it1, margin * frame_line_height); margin_pos = IT_CHARPOS (it1); RESTORE_IT (&it, &it, it1data); @@ -16669,7 +16681,7 @@ containing PT in this case. */ if (it.current_y <= 0) { - init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); + init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID, 0); move_it_vertically_backward (&it, 0); it.current_y = 0; } @@ -17013,7 +17025,7 @@ overlay_arrow_seen = 0; /* Initialize iterator and info to start at POS. */ - start_display (&it, w, pos); + start_display (&it, w, pos, 0); it.glyph_row->reversed_p = false; /* Display all lines of W. */ @@ -17161,7 +17173,7 @@ last_text_row is set to the last row displayed that displays text. Note that it.vpos == 0 if or if not there is a header-line; it's not the same as the MATRIX_ROW_VPOS! */ - start_display (&it, w, new_start); + start_display (&it, w, new_start, 0); w->cursor.vpos = -1; last_text_row = last_reused_text_row = NULL; @@ -18142,7 +18154,7 @@ { /* There are no reusable lines at the start of the window. Start displaying in the first text line. */ - start_display (&it, w, start); + start_display (&it, w, start, 0); it.vpos = it.first_vpos; start_pos = it.current.pos; } @@ -18932,7 +18944,7 @@ int n_glyphs_before; set_buffer_temp (buffer); - init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID); + init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID, 0); scratch_glyph_row.reversed_p = false; it.glyph_row->used[TEXT_AREA] = 0; SET_TEXT_POS (it.position, 0, 0); @@ -21228,7 +21240,7 @@ /* Setup the arena. */ SET_TEXT_POS (pt, PT, PT_BYTE); - start_display (&it, w, pt); + start_display (&it, w, pt, 0); if (it.cmp_it.id < 0 && it.method == GET_FROM_STRING @@ -21319,7 +21331,7 @@ { if (pt_x > 0) { - start_display (&it, w, pt); + start_display (&it, w, pt, 0); reseat_at_previous_visible_line_start (&it); it.current_x = it.current_y = it.hpos = 0; if (pt_vpos != 0) @@ -21622,7 +21634,7 @@ #if defined (USE_X_TOOLKIT) || defined (USE_GTK) eassert (!FRAME_WINDOW_P (f)); - init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID); + init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID, 0); it.first_visible_x = 0; it.last_visible_x = FRAME_PIXEL_WIDTH (f); #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */ @@ -21633,7 +21645,7 @@ struct window *menu_w; menu_w = XWINDOW (f->menu_bar_window); init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows, - MENU_FACE_ID); + MENU_FACE_ID, 0); it.first_visible_x = 0; it.last_visible_x = FRAME_PIXEL_WIDTH (f); } @@ -21643,7 +21655,7 @@ /* This is a TTY frame, i.e. character hpos/vpos are used as pixel x/y. */ init_iterator (&it, w, -1, -1, f->desired_matrix->rows, - MENU_FACE_ID); + MENU_FACE_ID, 0); it.first_visible_x = 0; it.last_visible_x = FRAME_COLS (f); } @@ -21759,7 +21771,7 @@ if (y >= f->desired_matrix->nrows) return; - init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID); + init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID, 0); it.first_visible_x = 0; it.last_visible_x = FRAME_COLS (f) - 1; row = it.glyph_row; @@ -21932,7 +21944,7 @@ struct face *face; ptrdiff_t count = SPECPDL_INDEX (); - init_iterator (&it, w, -1, -1, NULL, face_id); + init_iterator (&it, w, -1, -1, NULL, face_id, 0); /* Don't extend on a previously drawn mode-line. This may happen if called from pos_visible_p. */ it.glyph_row->enabled_p = false; @@ -22651,7 +22663,7 @@ Fselect_window (window, Qt); set_buffer_internal_1 (XBUFFER (buffer)); - init_iterator (&it, w, -1, -1, NULL, face_id); + init_iterator (&it, w, -1, -1, NULL, face_id, 0); if (no_props) { @@ -31056,6 +31068,18 @@ doc: /* */); Vredisplay__mode_lines_cause = Fmake_vector (make_number (100), make_number (0)); + + DEFVAR_LISP ("use-default-face-for-fast-scrolling", + Vuse_default_face_for_fast_scrolling, + doc: /* When non-nil, accelerate repeated scrolling operations. +This comes into play when scrolling rapidly over previously +unfontified buffer regions. Only those portions of the buffer which +are actually going to be displayed get fontified. + +Note that this optimization can cause the portion of the buffer displayed to +be slightly different. */); + + Vuse_default_face_for_fast_scrolling = Qnil; } > Thanks. -- Alan Mackenzie (Nuremberg, Germany).