changeset 60177:f2c6bf193ab5

(pos_visible_p): Be sure to move to the specified position. Always get the full ascent / descent of the corresponding row, to return reliable rtop and rbot values. (back_to_previous_visible_line_start): Fix 2005-01-18 change. Must look one character back, as back_to_previous_line_start returns position after the newline. (move_it_vertically_backward): Fix heuristic for when to move further back in case line_height * 2/3 is larger than window height. (cursor_row_fully_visible_p): Rename make_cursor_line_fully_visible_p as it does not do anything anymore. Add arg current_matrix_p to use current matrix rather than desired matrix when set. (try_cursor_movement): Don't scroll to make cursor row fully visible if cursor didn't move. This avoids unexpected recentering in case of blinking cursor or accepting process output. Use current matrix to check cursor row visibility. (redisplay_window): Fix whether to recenter or move to top in case cursor line is taller than window height. (find_first_unchanged_at_end_row): Stop search if we reach a row which not enabled (instead of abort).
author Kim F. Storm <storm@cua.dk>
date Sat, 19 Feb 2005 23:30:51 +0000
parents 9440f8bb9f71
children 51f36dec1a58
files src/xdisp.c
diffstat 1 files changed, 59 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/src/xdisp.c	Sat Feb 19 23:30:29 2005 +0000
+++ b/src/xdisp.c	Sat Feb 19 23:30:51 2005 +0000
@@ -863,7 +863,7 @@
 							  Lisp_Object));
 static void extend_face_to_end_of_line P_ ((struct it *));
 static int append_space_for_newline P_ ((struct it *, int));
-static int make_cursor_line_fully_visible P_ ((struct window *, int));
+static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
 static int trailing_whitespace_p P_ ((int));
@@ -1285,8 +1285,8 @@
     }
 
   start_display (&it, w, top);
-  move_it_to (&it, charpos, 0, it.last_visible_y, -1,
-	      MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
+  move_it_to (&it, charpos, -1, it.last_visible_y, -1,
+	      MOVE_TO_POS | MOVE_TO_Y);
 
   /* Note that we may overshoot because of invisible text.  */
   if (IT_CHARPOS (it) >= charpos)
@@ -1310,12 +1310,13 @@
 	    }
 	}
     }
-  else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
+  else
     {
       struct it it2;
 
       it2 = it;
-      move_it_by_lines (&it, 1, 0);
+      if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
+	move_it_by_lines (&it, 1, 0);
       if (charpos < IT_CHARPOS (it))
 	{
 	  visible_p = 1;
@@ -1326,8 +1327,9 @@
 	      *y = it2.current_y + it2.max_ascent - it2.ascent;
 	      if (rtop)
 		{
-		  *rtop = 0;
-		  *rbot = max (0, (it2.current_y + it2.max_ascent + it2.max_descent) - it.last_visible_y);
+		  *rtop = max (0, -it2.current_y);
+		  *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
+				   - it.last_visible_y));
 		}
 	    }
 	}
@@ -4697,27 +4699,31 @@
       /* If newline has a display property that replaces the newline with something
 	 else (image or text), find start of overlay or interval and continue search
 	 from that point.  */
-      {
-	struct it it2 = *it;
-	int pos = IT_CHARPOS (*it);
-	int beg, end;
-	Lisp_Object val, overlay;
-
-	it2.sp = 0;
-	if (handle_display_prop (&it2) == HANDLED_RETURN
-	    && !NILP (val = get_char_property_and_overlay
-		      (make_number (pos), Qdisplay, Qnil, &overlay))
-	    && (OVERLAYP (overlay)
-		? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
-		: get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
-	  {
-	    if (beg < BEGV)
-	      beg = BEGV;
-	    IT_CHARPOS (*it) = beg;
-	    IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
-	    continue;
-	  }
-      }
+      if (IT_CHARPOS (*it) > BEGV)
+	{
+	  struct it it2 = *it;
+	  int pos;
+	  int beg, end;
+	  Lisp_Object val, overlay;
+
+	  pos = --IT_CHARPOS (it2);
+	  --IT_BYTEPOS (it2);
+	  it2.sp = 0;
+	  if (handle_display_prop (&it2) == HANDLED_RETURN
+	      && !NILP (val = get_char_property_and_overlay
+			(make_number (pos), Qdisplay, Qnil, &overlay))
+	      && (OVERLAYP (overlay)
+		  ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
+		  : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
+	    {
+	      if (beg < BEGV)
+		beg = BEGV;
+	      IT_CHARPOS (*it) = beg;
+	      IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
+	      continue;
+	    }
+	}
+
       break;
     }
 
@@ -6330,7 +6336,8 @@
 	     a line height of 13 pixels each, recentering with point
 	     on the bottom line will try to move -39/2 = 19 pixels
 	     backward.  Try to avoid moving into the first line.  */
-	  && it->current_y - target_y > line_height * 2 / 3
+	  && (it->current_y - target_y
+	      > min (window_box_height (it->w), line_height * 2 / 3))
 	  && IT_CHARPOS (*it) > BEGV)
 	{
 	  TRACE_MOVE ((stderr, "  not far enough -> move_vert %d\n",
@@ -11088,7 +11095,7 @@
    as if point had gone off the screen.  */
 
 static int
-make_cursor_line_fully_visible (w, force_p)
+cursor_row_fully_visible_p (w, force_p, current_matrix_p)
      struct window *w;
      int force_p;
 {
@@ -11104,7 +11111,7 @@
   if (w->cursor.vpos < 0)
     return 1;
 
-  matrix = w->desired_matrix;
+  matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
   row = MATRIX_ROW (matrix, w->cursor.vpos);
 
   /* If the cursor row is not partially visible, there's nothing to do.  */
@@ -11409,7 +11416,7 @@
 
       /* If cursor ends up on a partially visible line,
 	 treat that as being off the bottom of the screen.  */
-      if (! make_cursor_line_fully_visible (w, extra_scroll_margin_lines <= 1))
+      if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
 	{
 	  clear_glyph_matrix (w->desired_matrix);
 	  ++extra_scroll_margin_lines;
@@ -11679,6 +11686,12 @@
 		  && CHARPOS (startp) != BEGV)
 		scroll_p = 1;
 	    }
+	  else
+	    {
+	      /* Cursor did not move.  So don't scroll even if cursor line
+		 is partially visible, as it was so before.  */
+		 rc = CURSOR_MOVEMENT_SUCCESS;
+	    }
 
 	  if (PT < MATRIX_ROW_START_CHARPOS (row)
 	      || PT > MATRIX_ROW_END_CHARPOS (row))
@@ -11686,7 +11699,8 @@
 	      /* if PT is not in the glyph row, give up.  */
 	      rc = CURSOR_MOVEMENT_MUST_SCROLL;
 	    }
-	  else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
+	  else if (rc != CURSOR_MOVEMENT_SUCCESS
+		   && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
 		   && make_cursor_line_fully_visible_p)
 	    {
 	      if (PT == MATRIX_ROW_END_CHARPOS (row)
@@ -11705,7 +11719,7 @@
 	      else
 		{
 		  set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
-		  if (!make_cursor_line_fully_visible (w, 0))
+		  if (!cursor_row_fully_visible_p (w, 0, 1))
 		    rc = CURSOR_MOVEMENT_MUST_SCROLL;
 		  else
 		    rc = CURSOR_MOVEMENT_SUCCESS;
@@ -11790,7 +11804,7 @@
   int temp_scroll_step = 0;
   int count = SPECPDL_INDEX ();
   int rc;
-  int centering_position;
+  int centering_position = -1;
   int last_line_misfit = 0;
 
   SET_TEXT_POS (lpoint, PT, PT_BYTE);
@@ -12036,7 +12050,7 @@
 	  new_vpos = window_box_height (w) / 2;
 	}
 
-      if (!make_cursor_line_fully_visible (w, 0))
+      if (!cursor_row_fully_visible_p (w, 0, 0))
 	{
 	  /* Point does appear, but on a line partly visible at end of window.
 	     Move it back to a fully-visible line.  */
@@ -12173,7 +12187,7 @@
 	    /* Forget any recorded base line for line number display.  */
 	    w->base_line_number = Qnil;
 
-	  if (!make_cursor_line_fully_visible (w, 1))
+	  if (!cursor_row_fully_visible_p (w, 1, 0))
 	    {
 	      clear_glyph_matrix (w->desired_matrix);
 	      last_line_misfit = 1;
@@ -12233,10 +12247,8 @@
   /* Finally, just choose place to start which centers point */
 
  recenter:
-  centering_position = window_box_height (w) / 2;
-
- point_at_top:
-  /* Jump here with centering_position already set to 0.  */
+  if (centering_position < 0)
+    centering_position = window_box_height (w) / 2;
 
 #if GLYPH_DEBUG
   debug_method_add (w, "recenter");
@@ -12333,7 +12345,7 @@
       set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
     }
 
-  if (!make_cursor_line_fully_visible (w, centering_position > 0))
+  if (!cursor_row_fully_visible_p (w, 0, 0))
     {
       /* If vscroll is enabled, disable it and try again.  */
       if (w->vscroll)
@@ -12348,9 +12360,10 @@
 	 visible, if it can be done.  */
       if (centering_position == 0)
 	goto done;
+
       clear_glyph_matrix (w->desired_matrix);
       centering_position = 0;
-      goto point_at_top;
+      goto recenter;
     }
 
  done:
@@ -13135,8 +13148,10 @@
 	 starts at a minimum position >= last_unchanged_pos_old.  */
       for (; row > first_text_row; --row)
 	{
+	  /* This used to abort, but it can happen.
+	     It is ok to just stop the search instead here.  KFS.  */
 	  if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
-	    abort ();
+	    break;
 
 	  if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
 	    row_found = row;