]> code.delx.au - gnu-emacs/blobdiff - src/xdisp.c
Merge from origin/emacs-25
[gnu-emacs] / src / xdisp.c
index 89385c0e17267f5c2cb64da807d3f482d0d8dbff..b9d496ed556d96e2f48065a16260d455775c432f 100644 (file)
@@ -314,13 +314,11 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "font.h"
 #include "fontset.h"
 #include "blockinput.h"
+#include "xwidget.h"
 #ifdef HAVE_WINDOW_SYSTEM
 #include TERM_HEADER
 #endif /* HAVE_WINDOW_SYSTEM */
 
-#ifdef HAVE_XWIDGETS
-# include "xwidget.h"
-#endif
 #ifndef FRAME_X_OUTPUT
 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
 #endif
@@ -827,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 *);
@@ -857,9 +856,7 @@ static bool next_element_from_buffer (struct it *);
 static bool next_element_from_composition (struct it *);
 static bool next_element_from_image (struct it *);
 static bool next_element_from_stretch (struct it *);
-#ifdef HAVE_XWIDGETS
 static bool next_element_from_xwidget (struct it *);
-#endif
 static void load_overlay_strings (struct it *, ptrdiff_t);
 static bool get_next_display_element (struct it *);
 static enum move_it_result
@@ -5147,11 +5144,8 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
                      && valid_image_p (value))
 #endif /* not HAVE_WINDOW_SYSTEM */
              || (CONSP (value) && EQ (XCAR (value), Qspace))
-#ifdef HAVE_XWIDGETS
              || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
-                && valid_xwidget_spec_p (value))
-#endif
-             );
+                && valid_xwidget_spec_p (value)));
 
   if (valid_p && display_replaced == 0)
     {
@@ -5226,17 +5220,15 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
          *position = it->position = start_pos;
          retval = 1 + (it->area == TEXT_AREA);
        }
-#ifdef HAVE_XWIDGETS
-      else if (valid_xwidget_spec_p(value))
+      else if (valid_xwidget_spec_p (value))
        {
           it->what = IT_XWIDGET;
           it->method = GET_FROM_XWIDGET;
           it->position = start_pos;
          it->object = NILP (object) ? it->w->contents : object;
          *position = start_pos;
-          it->xwidget = lookup_xwidget(value);
+          it->xwidget = lookup_xwidget (value);
        }
-#endif
 #ifdef HAVE_WINDOW_SYSTEM
       else
        {
@@ -5989,11 +5981,9 @@ push_it (struct it *it, struct text_pos *position)
     case GET_FROM_STRETCH:
       p->u.stretch.object = it->object;
       break;
-#ifdef HAVE_XWIDGETS
     case GET_FROM_XWIDGET:
       p->u.xwidget.object = it->object;
       break;
-#endif
     case GET_FROM_BUFFER:
     case GET_FROM_DISPLAY_VECTOR:
     case GET_FROM_STRING:
@@ -6095,11 +6085,9 @@ pop_it (struct it *it)
       it->object = p->u.image.object;
       it->slice = p->u.image.slice;
       break;
-#ifdef HAVE_XWIDGETS
     case GET_FROM_XWIDGET:
       it->object = p->u.xwidget.object;
       break;
-#endif
     case GET_FROM_STRETCH:
       it->object = p->u.stretch.object;
       break;
@@ -6775,9 +6763,7 @@ static next_element_function const get_next_element[NUM_IT_METHODS] =
   next_element_from_c_string,
   next_element_from_image,
   next_element_from_stretch,
-#ifdef HAVE_XWIDGETS
   next_element_from_xwidget,
-#endif
 };
 
 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
@@ -7249,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);
 
@@ -7638,9 +7633,7 @@ set_iterator_to_next (struct it *it, bool reseat_p)
 
     case GET_FROM_IMAGE:
     case GET_FROM_STRETCH:
-#ifdef HAVE_XWIDGETS
     case GET_FROM_XWIDGET:
-#endif
 
       /* The position etc with which we have to proceed are on
         the stack.  The position may be at the end of a string,
@@ -8103,14 +8096,12 @@ next_element_from_image (struct it *it)
   return true;
 }
 
-#ifdef HAVE_XWIDGETS
 static bool
 next_element_from_xwidget (struct it *it)
 {
   it->what = IT_XWIDGET;
   return true;
 }
-#endif
 
 
 /* Fill iterator IT with next display element from a stretch glyph
@@ -11241,6 +11232,7 @@ clear_garbaged_frames (void)
   if (frame_garbaged)
     {
       Lisp_Object tail, frame;
+      struct frame *sf = SELECTED_FRAME ();
 
       FOR_EACH_FRAME (tail, frame)
        {
@@ -11248,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);
@@ -11795,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);
@@ -13158,7 +13139,7 @@ text_outside_line_unchanged_p (struct window *w,
         beginning of a paragraph, before the first strong directional
         character, can change the base direction of the paragraph (unless
         the buffer specifies a fixed paragraph direction), which will
-        require to redisplay the whole paragraph.  It might be worthwhile
+        require redisplaying the whole paragraph.  It might be worthwhile
         to find the paragraph limits and widen the range of redisplayed
         lines to that, but for now just give up this optimization.  */
       if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
@@ -13608,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);
        }
 
@@ -13647,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);
        }
 
@@ -13891,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;
@@ -14034,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.  */
@@ -14044,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.  */
@@ -14095,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))
        {
@@ -16086,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;
@@ -16808,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
@@ -16924,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)
@@ -18086,7 +18046,7 @@ try_window_id (struct window *w)
      beginning of a paragraph, before the first strong directional
      character, can change the base direction of the paragraph (unless
      the buffer specifies a fixed paragraph direction), which will
-     require to redisplay the whole paragraph.  It might be worthwhile
+     require redisplaying the whole paragraph.  It might be worthwhile
      to find the paragraph limits and widen the range of redisplayed
      lines to that, but for now just give up this optimization and
      redisplay from scratch.  */
@@ -18844,9 +18804,11 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
               glyph->left_box_line_p,
               glyph->right_box_line_p);
     }
-#ifdef HAVE_XWIDGETS
   else if (glyph->type == XWIDGET_GLYPH)
     {
+#ifndef HAVE_XWIDGETS
+      eassume (false);
+#else
       fprintf (stderr,
               "  %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
               glyph - row->glyphs[TEXT_AREA],
@@ -18863,9 +18825,8 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
               glyph->face_id,
               glyph->left_box_line_p,
               glyph->right_box_line_p);
-
-    }
 #endif
+    }
 }
 
 
@@ -24364,13 +24325,11 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
 
              return OK_PIXELS (width_p ? img->width : img->height);
            }
-# ifdef HAVE_XWIDGETS
          if (FRAME_WINDOW_P (it->f) && valid_xwidget_spec_p (prop))
            {
               // TODO: Don't return dummy size.
               return OK_PIXELS (100);
             }
-# endif
 #endif
          if (EQ (car, Qplus) || EQ (car, Qminus))
            {
@@ -25273,8 +25232,11 @@ compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
        }                                                               \
      while (false)
 
-#ifdef HAVE_XWIDGETS
-#define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
+#ifndef HAVE_XWIDGETS
+# define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
+     eassume (false)
+#else
+# define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
      do                                                                        \
        {                                                               \
         s = alloca (sizeof *s);                                        \
@@ -25287,7 +25249,6 @@ compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
      while (false)
 #endif
 
-
 /* Add a glyph string for a sequence of character glyphs to the list
    of strings between HEAD and TAIL.  START is the index of the first
    glyph in row area AREA of glyph row ROW that is part of the new
@@ -25441,13 +25402,11 @@ compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
                                        HL, X, LAST_X);                 \
              break;
 
-#ifdef HAVE_XWIDGETS
-# define BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
+#define BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X)  \
             case XWIDGET_GLYPH:                                         \
               BUILD_XWIDGET_GLYPH_STRING (START, END, HEAD, TAIL,       \
                                           HL, X, LAST_X);               \
               break;
-#endif
 
 #define BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)   \
            case GLYPHLESS_GLYPH:                                       \
@@ -25456,7 +25415,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
              break;                                                    \
                                                                        \
            default:                                                    \
-             emacs_abort ();                                                   \
+             emacs_abort ();                                           \
            }                                                           \
                                                                        \
          if (s)                                                        \
@@ -25468,16 +25427,10 @@ compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
     } while (false)
 
 
-#ifdef HAVE_XWIDGETS
-# define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X)    \
+#define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X)     \
     BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X)       \
     BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X)      \
     BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)
-#else
-# define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X)    \
-    BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X)       \
-    BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)
-#endif
 
 
 /* Draw glyphs between START and END in AREA of ROW on window W,
@@ -26118,10 +26071,10 @@ produce_image_glyph (struct it *it)
     }
 }
 
-#ifdef HAVE_XWIDGETS
 static void
 produce_xwidget_glyph (struct it *it)
 {
+#ifdef HAVE_XWIDGETS
   struct xwidget *xw;
   int glyph_ascent, crop;
   eassert (it->what == IT_XWIDGET);
@@ -26219,8 +26172,8 @@ produce_xwidget_glyph (struct it *it)
       else
        IT_EXPAND_MATRIX_WIDTH (it, area);
     }
-}
 #endif
+}
 
 /* Append a stretch glyph to IT->glyph_row.  OBJECT is the source
    of the glyph, WIDTH and HEIGHT are the width and height of the
@@ -27631,10 +27584,8 @@ x_produce_glyphs (struct it *it)
     produce_image_glyph (it);
   else if (it->what == IT_STRETCH)
     produce_stretch_glyph (it);
-#ifdef HAVE_XWIDGETS
   else if (it->what == IT_XWIDGET)
     produce_xwidget_glyph (it);
-#endif
 
  done:
   /* Accumulate dimensions.  Note: can't assume that it->descent > 0
@@ -28004,10 +27955,8 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
   /* Use normal cursor if not blinked off.  */
   if (!w->cursor_off_p)
     {
-#ifdef HAVE_XWIDGETS
       if (glyph != NULL && glyph->type == XWIDGET_GLYPH)
         return NO_CURSOR;
-#endif
       if (glyph != NULL && glyph->type == IMAGE_GLYPH)
        {
          if (cursor_type == FILLED_BOX_CURSOR)
@@ -31462,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