summaryrefslogtreecommitdiff
path: root/src/xdisp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xdisp.c')
-rw-r--r--src/xdisp.c146
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