diff options
Diffstat (limited to 'src/xdisp.c')
-rw-r--r-- | src/xdisp.c | 146 |
1 files changed, 50 insertions, 96 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index dec99478ea5..5b961444384 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -9794,26 +9794,28 @@ the maximum pixel-height of all text lines. The optional argument FROM, if non-nil, specifies the first text position and defaults to the minimum accessible position of the buffer. -If FROM is t, use the minimum accessible position that is not a newline -character. TO, if non-nil, specifies the last text position and +If FROM is t, use the minimum accessible position that starts a +non-empty line. TO, if non-nil, specifies the last text position and defaults to the maximum accessible position of the buffer. If TO is t, -use the maximum accessible position that is not a newline character. +use the maximum accessible position that ends a non-empty line. The optional argument X-LIMIT, if non-nil, specifies the maximum text width that can be returned. X-LIMIT nil or omitted, means to use the -pixel-width of WINDOW's body; use this if you do not intend to change -the width of WINDOW. Use the maximum width WINDOW may assume if you -intend to change WINDOW's width. In any case, text whose x-coordinate -is beyond X-LIMIT is ignored. Since calculating the width of long lines -can take some time, it's always a good idea to make this argument as -small as possible; in particular, if the buffer contains long lines that -shall be truncated anyway. +pixel-width of WINDOW's body; use this if you want to know how high +WINDOW should be become in order to fit all of its buffer's text with +the width of WINDOW unaltered. Use the maximum width WINDOW may assume +if you intend to change WINDOW's width. In any case, text whose +x-coordinate is beyond X-LIMIT is ignored. Since calculating the width +of long lines can take some time, it's always a good idea to make this +argument as small as possible; in particular, if the buffer contains +long lines that shall be truncated anyway. The optional argument Y-LIMIT, if non-nil, specifies the maximum text -height that can be returned. Text lines whose y-coordinate is beyond -Y-LIMIT are ignored. Since calculating the text height of a large -buffer can take some time, it makes sense to specify this argument if -the size of the buffer is unknown. +height (exluding the height of the mode- or header-line, if any) that +can be returned. Text lines whose y-coordinate is beyond Y-LIMIT are +ignored. Since calculating the text height of a large buffer can take +some time, it makes sense to specify this argument if the size of the +buffer is large or unknown. Optional argument MODE-AND-HEADER-LINE nil or omitted means do not include the height of the mode- or header-line of WINDOW in the return @@ -9831,7 +9833,7 @@ include the height of both, if present, in the return value. */) ptrdiff_t start, end, pos; struct text_pos startp; void *itdata = NULL; - int c, max_y = -1, x = 0, y = 0; + int c, max_x = 0, max_y = 0, x = 0, y = 0; CHECK_BUFFER (buffer); b = XBUFFER (buffer); @@ -9876,11 +9878,13 @@ include the height of both, if present, in the return value. */) end = max (start, min (XINT (to), ZV)); } - if (!NILP (y_limit)) - { - CHECK_NUMBER (y_limit); - max_y = min (XINT (y_limit), INT_MAX); - } + if (!NILP (x_limit) && RANGED_INTEGERP (0, x_limit, INT_MAX)) + max_x = XINT (x_limit); + + if (NILP (y_limit)) + max_y = INT_MAX; + else if (RANGED_INTEGERP (0, y_limit, INT_MAX)) + max_y = XINT (y_limit); itdata = bidi_shelve_cache (); SET_TEXT_POS (startp, start, CHAR_TO_BYTE (start)); @@ -9890,27 +9894,30 @@ include the height of both, if present, in the return value. */) x = move_it_to (&it, end, -1, max_y, -1, MOVE_TO_POS | MOVE_TO_Y); else { - CHECK_NUMBER (x_limit); - it.last_visible_x = min (XINT (x_limit), INFINITY); + it.last_visible_x = max_x; /* Actually, we never want move_it_to stop at to_x. But to make sure that move_it_in_display_line_to always moves far enough, - we set it to INT_MAX and specify MOVE_TO_X. */ - x = move_it_to (&it, end, INT_MAX, max_y, -1, - MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); + we set it to INT_MAX and specify MOVE_TO_X. Also bound width + value by X-LIMIT. */ + x = min (move_it_to (&it, end, INT_MAX, max_y, -1, + MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y), + max_x); } - y = it.current_y + it.max_ascent + it.max_descent; + /* Subtract height of header-line which was counted automatically by + start_display. */ + y = min (it.current_y + it.max_ascent + it.max_descent + - WINDOW_HEADER_LINE_HEIGHT (w), + max_y); - if (!EQ (mode_and_header_line, Qheader_line) - && !EQ (mode_and_header_line, Qt)) - /* Do not count the header-line which was counted automatically by - start_display. */ - y = y - WINDOW_HEADER_LINE_HEIGHT (w); + if (EQ (mode_and_header_line, Qheader_line) + || EQ (mode_and_header_line, Qt)) + /* Re-add height of header-line as requested. */ + y = y + WINDOW_HEADER_LINE_HEIGHT (w); if (EQ (mode_and_header_line, Qmode_line) || EQ (mode_and_header_line, Qt)) - /* Do count the mode-line which is not included automatically by - start_display. */ + /* Add height of mode-line as requested. */ y = y + WINDOW_MODE_LINE_HEIGHT (w); bidi_unshelve_cache (itdata, false); @@ -11793,24 +11800,7 @@ prepare_menu_bars (void) && !XBUFFER (w->contents)->text->redisplay) continue; - /* If a window on this frame changed size, report that to - the user and clear the size-change flag. */ - if (FRAME_WINDOW_SIZES_CHANGED (f)) - { - Lisp_Object functions; - - /* Clear flag first in case we get an error below. */ - FRAME_WINDOW_SIZES_CHANGED (f) = false; - functions = Vwindow_size_change_functions; - - while (CONSP (functions)) - { - if (!EQ (XCAR (functions), Qt)) - call1 (XCAR (functions), frame); - functions = XCDR (functions); - } - } - + run_window_size_change_functions (frame); menu_bar_hooks_run = update_menu_bar (f, false, menu_bar_hooks_run); #ifdef HAVE_WINDOW_SYSTEM update_tool_bar (f, false); @@ -13606,24 +13596,12 @@ redisplay_internal (void) it's too late for the hooks in window-size-change-functions, which have been examined already in prepare_menu_bars. So in that case we call the hooks here only for the selected frame. */ - if (sf->redisplay && FRAME_WINDOW_SIZES_CHANGED (sf)) + if (sf->redisplay) { - Lisp_Object functions; ptrdiff_t count1 = SPECPDL_INDEX (); record_unwind_save_match_data (); - - /* Clear flag first in case we get an error below. */ - FRAME_WINDOW_SIZES_CHANGED (sf) = false; - functions = Vwindow_size_change_functions; - - while (CONSP (functions)) - { - if (!EQ (XCAR (functions), Qt)) - call1 (XCAR (functions), selected_frame); - functions = XCDR (functions); - } - + run_window_size_change_functions (selected_frame); unbind_to (count1, Qnil); } @@ -13645,22 +13623,10 @@ redisplay_internal (void) { if (sf->redisplay) { - Lisp_Object functions; ptrdiff_t count1 = SPECPDL_INDEX (); record_unwind_save_match_data (); - - /* Clear flag first in case we get an error below. */ - FRAME_WINDOW_SIZES_CHANGED (sf) = false; - functions = Vwindow_size_change_functions; - - while (CONSP (functions)) - { - if (!EQ (XCAR (functions), Qt)) - call1 (XCAR (functions), selected_frame); - functions = XCDR (functions); - } - + run_window_size_change_functions (selected_frame); unbind_to (count1, Qnil); } @@ -14037,9 +14003,6 @@ redisplay_internal (void) } else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf)) { - Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf); - struct frame *mini_frame; - displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents); /* Use list_of_error, not Qerror, so that we catch only errors and don't run the debugger. */ @@ -14047,8 +14010,8 @@ redisplay_internal (void) list_of_error, redisplay_window_error); if (update_miniwindow_p) - internal_condition_case_1 (redisplay_window_1, mini_window, - list_of_error, + internal_condition_case_1 (redisplay_window_1, + FRAME_MINIBUF_WINDOW (sf), list_of_error, redisplay_window_error); /* Compare desired and current matrices, perform output. */ @@ -14098,8 +14061,8 @@ redisplay_internal (void) have put text on a frame other than the selected one, so the above call to update_frame would not have caught it. Catch it here. */ - mini_window = FRAME_MINIBUF_WINDOW (sf); - mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window))); + Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf); + struct frame *mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window))); if (mini_frame != sf && FRAME_WINDOW_P (mini_frame)) { @@ -16089,6 +16052,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) bool last_line_misfit = false; ptrdiff_t beg_unchanged, end_unchanged; int frame_line_height; + bool use_desired_matrix; SET_TEXT_POS (lpoint, PT, PT_BYTE); opoint = lpoint; @@ -16811,7 +16775,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) startp = run_window_scroll_functions (window, it.current.pos); /* Redisplay the window. */ - bool use_desired_matrix = false; + use_desired_matrix = false; if (!current_matrix_up_to_date_p || windows_or_buffers_changed || f->cursor_type_changed @@ -31454,16 +31418,6 @@ If nil, disable message logging. If t, log messages but don't truncate the buffer when it becomes large. */); Vmessage_log_max = make_number (1000); - DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions, - doc: /* Functions called during redisplay, if window sizes have changed. -The value should be a list of functions that take one argument. -During the first part of redisplay, for each frame, if any of its windows -have changed size since the last redisplay, or have been split or deleted, -all the functions in the list are called, with the frame as argument. -If redisplay decides to resize the minibuffer window, it calls these -functions on behalf of that as well. */); - Vwindow_size_change_functions = Qnil; - DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions, doc: /* List of functions to call before redisplaying a window with scrolling. Each function is called with two arguments, the window and its new |