]> code.delx.au - gnu-emacs/blobdiff - src/xdisp.c
Merge from origin/emacs-25
[gnu-emacs] / src / xdisp.c
index 78fddd60fc09c13de1a264bac72587f0c1babc88..b9d496ed556d96e2f48065a16260d455775c432f 100644 (file)
@@ -825,6 +825,7 @@ static Lisp_Object redisplay_window_1 (Lisp_Object);
 static bool set_cursor_from_row (struct window *, struct glyph_row *,
                                 struct glyph_matrix *, ptrdiff_t, ptrdiff_t,
                                 int, int);
+static bool cursor_row_fully_visible_p (struct window *, bool, bool);
 static bool update_menu_bar (struct frame *, bool, bool);
 static bool try_window_reusing_current_matrix (struct window *);
 static int try_window_id (struct window *);
@@ -7234,14 +7235,23 @@ get_next_display_element (struct it *it)
                     buffer position is stored in the 'position'
                     member of the iteration stack slot below the
                     current one, see handle_single_display_spec.  By
-                    contrast, it->current.pos was is not yet updated
+                    contrast, it->current.pos was not yet updated
                     to point to that buffer position; that will
                     happen in pop_it, after we finish displaying the
                     current string.  Note that we already checked
                     above that it->sp is positive, so subtracting one
                     from it is safe.  */
                  if (it->from_disp_prop_p)
-                   pos = (it->stack + it->sp - 1)->position;
+                   {
+                     int stackp = it->sp - 1;
+
+                     /* Find the stack level with data from buffer.  */
+                     while (stackp >= 0
+                            && STRINGP ((it->stack + stackp)->string))
+                       stackp--;
+                     eassert (stackp >= 0);
+                     pos = (it->stack + stackp)->position;
+                   }
                  else
                    INC_TEXT_POS (pos, it->multibyte_p);
 
@@ -11222,6 +11232,7 @@ clear_garbaged_frames (void)
   if (frame_garbaged)
     {
       Lisp_Object tail, frame;
+      struct frame *sf = SELECTED_FRAME ();
 
       FOR_EACH_FRAME (tail, frame)
        {
@@ -11229,7 +11240,13 @@ clear_garbaged_frames (void)
 
          if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
            {
-             if (f->resized_p)
+             if (f->resized_p
+                 /* It makes no sense to redraw a non-selected TTY
+                    frame, since that will actually clear the
+                    selected frame, and might leave the selected
+                    frame with corrupted display, if it happens not
+                    to be marked garbaged.  */
+                 && !(f != sf && (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))))
                redraw_frame (f);
              else
                clear_current_matrices (f);
@@ -11776,24 +11793,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);
@@ -13589,24 +13589,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);
        }
 
@@ -13628,22 +13616,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);
        }
 
@@ -13872,11 +13848,16 @@ redisplay_internal (void)
              eassert (this_line_vpos == it.vpos);
              eassert (this_line_y == it.current_y);
              set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
+             if (cursor_row_fully_visible_p (w, false, true))
+               {
 #ifdef GLYPH_DEBUG
-             *w->desired_matrix->method = 0;
-             debug_method_add (w, "optimization 3");
+                 *w->desired_matrix->method = 0;
+                 debug_method_add (w, "optimization 3");
 #endif
-             goto update;
+                 goto update;
+               }
+             else
+               goto cancel;
            }
          else
            goto cancel;
@@ -14015,9 +13996,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.  */
@@ -14025,8 +14003,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.  */
@@ -14076,8 +14054,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))
        {
@@ -16067,6 +16045,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;
@@ -16789,7 +16768,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
@@ -16905,7 +16884,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
       if (scroll_conservatively > SCROLL_LIMIT)
        {
          int window_total_lines
-           = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) * frame_line_height;
+           = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
          int margin =
            scroll_margin > 0
            ? min (scroll_margin, window_total_lines / 4)
@@ -31432,16 +31411,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