]> code.delx.au - gnu-emacs/blobdiff - src/xdisp.c
-
[gnu-emacs] / src / xdisp.c
index d68244e6c9d1b8405bde0c5c7d62f891c799f174..7dc99e1c283d9d2fa7543a31eebdbb1a451b9465 100644 (file)
@@ -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