aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Antipov2013-08-07 14:32:08 +0400
committerDmitry Antipov2013-08-07 14:32:08 +0400
commit170da1ec691127471ecd118dccd79eec7c9f3699 (patch)
treeb21f37e99fdde63c2f6169c4728629ef2b302513
parent20940c206593a8e7bd4809348ff95a6f971c5528 (diff)
downloademacs-170da1ec691127471ecd118dccd79eec7c9f3699.tar.gz
emacs-170da1ec691127471ecd118dccd79eec7c9f3699.zip
Be more careful if selected window shows the buffer other than current,
use window_outdated only if this is not so. This change should also address some weird issues discussed in Bug#13012. * window.h (window_outdated): New prototype. * window.c (window_outdated): Now here. Convert from static and always assume window's buffer. (Fwindow_end, Fwindow_line_height): Use it. * xdisp.c (reconsider_clip_changes): Remove prototype, drop 2nd arg and always assume window's buffer. (redisplay_window): Adjust user. (redisplay_internal): Call to reconsider_clip_change once and check whether mode line should be updated only if selected window shows current buffer. (run_window_scroll_functions): Use eassert for debugging check. (Fmove_point_visually, note_mouse_highlight): Use window_outdated.
-rw-r--r--src/ChangeLog18
-rw-r--r--src/window.c17
-rw-r--r--src/window.h1
-rw-r--r--src/xdisp.c100
4 files changed, 71 insertions, 65 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 034926f1fae..a090e02e74a 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,21 @@
12013-08-07 Dmitry Antipov <dmantipov@yandex.ru>
2
3 Be more careful if selected window shows the buffer other than current,
4 use window_outdated only if this is not so. This change should also
5 address some weird issues discussed in Bug#13012.
6 * window.h (window_outdated): New prototype.
7 * window.c (window_outdated): Now here. Convert from static and
8 always assume window's buffer.
9 (Fwindow_end, Fwindow_line_height): Use it.
10 * xdisp.c (reconsider_clip_changes): Remove prototype, drop 2nd arg
11 and always assume window's buffer.
12 (redisplay_window): Adjust user.
13 (redisplay_internal): Call to reconsider_clip_change once and
14 check whether mode line should be updated only if selected window
15 shows current buffer.
16 (run_window_scroll_functions): Use eassert for debugging check.
17 (Fmove_point_visually, note_mouse_highlight): Use window_outdated.
18
12013-08-06 Dmitry Antipov <dmantipov@yandex.ru> 192013-08-06 Dmitry Antipov <dmantipov@yandex.ru>
2 20
3 * window.c (window_scroll, window_scroll_pixel_based) 21 * window.c (window_scroll, window_scroll_pixel_based)
diff --git a/src/window.c b/src/window.c
index 33d7dab7ec0..dff449072f5 100644
--- a/src/window.c
+++ b/src/window.c
@@ -239,6 +239,17 @@ wset_combination (struct window *w, bool horflag, Lisp_Object val)
239 w->horizontal = horflag; 239 w->horizontal = horflag;
240} 240}
241 241
242/* Nonzero if leaf window W doesn't reflect the actual state
243 of displayed buffer due to its text or overlays change. */
244
245bool
246window_outdated (struct window *w)
247{
248 struct buffer *b = XBUFFER (w->contents);
249 return (w->last_modified < BUF_MODIFF (b)
250 || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b));
251}
252
242struct window * 253struct window *
243decode_live_window (register Lisp_Object window) 254decode_live_window (register Lisp_Object window)
244{ 255{
@@ -1506,8 +1517,7 @@ if it isn't already recorded. */)
1506 || !w->window_end_valid 1517 || !w->window_end_valid
1507 || b->clip_changed 1518 || b->clip_changed
1508 || b->prevent_redisplay_optimizations_p 1519 || b->prevent_redisplay_optimizations_p
1509 || w->last_modified < BUF_MODIFF (b) 1520 || window_outdated (w))
1510 || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b))
1511 && !noninteractive) 1521 && !noninteractive)
1512 { 1522 {
1513 struct text_pos startp; 1523 struct text_pos startp;
@@ -1720,8 +1730,7 @@ Return nil if window display is not up-to-date. In that case, use
1720 || windows_or_buffers_changed 1730 || windows_or_buffers_changed
1721 || b->clip_changed 1731 || b->clip_changed
1722 || b->prevent_redisplay_optimizations_p 1732 || b->prevent_redisplay_optimizations_p
1723 || w->last_modified < BUF_MODIFF (b) 1733 || window_outdated (w))
1724 || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b))
1725 return Qnil; 1734 return Qnil;
1726 1735
1727 if (NILP (line)) 1736 if (NILP (line))
diff --git a/src/window.h b/src/window.h
index 5da6165c48d..24949e1e287 100644
--- a/src/window.h
+++ b/src/window.h
@@ -973,6 +973,7 @@ extern void replace_buffer_in_windows (Lisp_Object);
973extern void replace_buffer_in_windows_safely (Lisp_Object); 973extern void replace_buffer_in_windows_safely (Lisp_Object);
974/* This looks like a setter, but it is a bit special. */ 974/* This looks like a setter, but it is a bit special. */
975extern void wset_buffer (struct window *, Lisp_Object); 975extern void wset_buffer (struct window *, Lisp_Object);
976extern bool window_outdated (struct window *);
976extern void init_window_once (void); 977extern void init_window_once (void);
977extern void init_window (void); 978extern void init_window (void);
978extern void syms_of_window (void); 979extern void syms_of_window (void);
diff --git a/src/xdisp.c b/src/xdisp.c
index 7a1f03ce244..5e6311ed98d 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -804,7 +804,6 @@ static void pint2str (char *, int, ptrdiff_t);
804static void pint2hrstr (char *, int, ptrdiff_t); 804static void pint2hrstr (char *, int, ptrdiff_t);
805static struct text_pos run_window_scroll_functions (Lisp_Object, 805static struct text_pos run_window_scroll_functions (Lisp_Object,
806 struct text_pos); 806 struct text_pos);
807static void reconsider_clip_changes (struct window *, struct buffer *);
808static int text_outside_line_unchanged_p (struct window *, 807static int text_outside_line_unchanged_p (struct window *,
809 ptrdiff_t, ptrdiff_t); 808 ptrdiff_t, ptrdiff_t);
810static void store_mode_line_noprop_char (char); 809static void store_mode_line_noprop_char (char);
@@ -10850,17 +10849,6 @@ buffer_shared_and_changed (void)
10850 && UNCHANGED_MODIFIED < MODIFF); 10849 && UNCHANGED_MODIFIED < MODIFF);
10851} 10850}
10852 10851
10853/* Nonzero if W doesn't reflect the actual state of current buffer due
10854 to its text or overlays change. FIXME: this may be called when
10855 XBUFFER (w->contents) != current_buffer, which looks suspicious. */
10856
10857static int
10858window_outdated (struct window *w)
10859{
10860 return (w->last_modified < MODIFF
10861 || w->last_overlay_modified < OVERLAY_MODIFF);
10862}
10863
10864/* Nonzero if W's buffer was changed but not saved or Transient Mark mode 10852/* Nonzero if W's buffer was changed but not saved or Transient Mark mode
10865 is enabled and mark of W's buffer was changed since last W's update. */ 10853 is enabled and mark of W's buffer was changed since last W's update. */
10866 10854
@@ -12866,13 +12854,13 @@ check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
12866 && start < pt && end > pt); 12854 && start < pt && end > pt);
12867} 12855}
12868 12856
12869 12857/* Reconsider the clip changes of buffer which is displayed in W. */
12870/* Reconsider the setting of B->clip_changed which is displayed
12871 in window W. */
12872 12858
12873static void 12859static void
12874reconsider_clip_changes (struct window *w, struct buffer *b) 12860reconsider_clip_changes (struct window *w)
12875{ 12861{
12862 struct buffer *b = XBUFFER (w->contents);
12863
12876 if (b->clip_changed 12864 if (b->clip_changed
12877 && w->window_end_valid 12865 && w->window_end_valid
12878 && w->current_matrix->buffer == b 12866 && w->current_matrix->buffer == b
@@ -12885,24 +12873,17 @@ reconsider_clip_changes (struct window *w, struct buffer *b)
12885 we set b->clip_changed to 1 to force updating the screen. If 12873 we set b->clip_changed to 1 to force updating the screen. If
12886 b->clip_changed has already been set to 1, we can skip this 12874 b->clip_changed has already been set to 1, we can skip this
12887 check. */ 12875 check. */
12888 if (!b->clip_changed && BUFFERP (w->contents) && w->window_end_valid) 12876 if (!b->clip_changed && w->window_end_valid)
12889 { 12877 {
12890 ptrdiff_t pt; 12878 ptrdiff_t pt = (w == XWINDOW (selected_window)
12879 ? PT : marker_position (w->pointm));
12891 12880
12892 if (w == XWINDOW (selected_window)) 12881 if ((w->current_matrix->buffer != b || pt != w->last_point)
12893 pt = PT;
12894 else
12895 pt = marker_position (w->pointm);
12896
12897 if ((w->current_matrix->buffer != XBUFFER (w->contents)
12898 || pt != w->last_point)
12899 && check_point_in_composition (w->current_matrix->buffer, 12882 && check_point_in_composition (w->current_matrix->buffer,
12900 w->last_point, 12883 w->last_point, b, pt))
12901 XBUFFER (w->contents), pt))
12902 b->clip_changed = 1; 12884 b->clip_changed = 1;
12903 } 12885 }
12904} 12886}
12905
12906 12887
12907#define STOP_POLLING \ 12888#define STOP_POLLING \
12908do { if (! polling_stopped_here) stop_polling (); \ 12889do { if (! polling_stopped_here) stop_polling (); \
@@ -12923,10 +12904,10 @@ redisplay_internal (void)
12923 struct window *sw; 12904 struct window *sw;
12924 struct frame *fr; 12905 struct frame *fr;
12925 int pending; 12906 int pending;
12926 int must_finish = 0; 12907 bool must_finish = 0, match_p;
12927 struct text_pos tlbufpos, tlendpos; 12908 struct text_pos tlbufpos, tlendpos;
12928 int number_of_visible_frames; 12909 int number_of_visible_frames;
12929 ptrdiff_t count, count1; 12910 ptrdiff_t count;
12930 struct frame *sf; 12911 struct frame *sf;
12931 int polling_stopped_here = 0; 12912 int polling_stopped_here = 0;
12932 Lisp_Object tail, frame; 12913 Lisp_Object tail, frame;
@@ -12983,7 +12964,6 @@ redisplay_internal (void)
12983 sw = w; 12964 sw = w;
12984 12965
12985 pending = 0; 12966 pending = 0;
12986 reconsider_clip_changes (w, current_buffer);
12987 last_escape_glyph_frame = NULL; 12967 last_escape_glyph_frame = NULL;
12988 last_escape_glyph_face_id = (1 << FACE_ID_BITS); 12968 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
12989 last_glyphless_glyph_frame = NULL; 12969 last_glyphless_glyph_frame = NULL;
@@ -13038,10 +13018,7 @@ redisplay_internal (void)
13038 /* do_pending_window_change could change the selected_window due to 13018 /* do_pending_window_change could change the selected_window due to
13039 frame resizing which makes the selected window too small. */ 13019 frame resizing which makes the selected window too small. */
13040 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw) 13020 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
13041 { 13021 sw = w;
13042 sw = w;
13043 reconsider_clip_changes (w, current_buffer);
13044 }
13045 13022
13046 /* Clear frames marked as garbaged. */ 13023 /* Clear frames marked as garbaged. */
13047 clear_garbaged_frames (); 13024 clear_garbaged_frames ();
@@ -13053,22 +13030,31 @@ redisplay_internal (void)
13053 if (windows_or_buffers_changed) 13030 if (windows_or_buffers_changed)
13054 update_mode_lines++; 13031 update_mode_lines++;
13055 13032
13056 /* Detect case that we need to write or remove a star in the mode line. */ 13033 reconsider_clip_changes (w);
13057 if ((SAVE_MODIFF < MODIFF) != w->last_had_star) 13034
13035 /* In most cases selected window displays current buffer. */
13036 match_p = XBUFFER (w->contents) == current_buffer;
13037 if (match_p)
13058 { 13038 {
13059 w->update_mode_line = 1; 13039 ptrdiff_t count1;
13060 if (buffer_shared_and_changed ())
13061 update_mode_lines++;
13062 }
13063 13040
13064 /* Avoid invocation of point motion hooks by `current_column' below. */ 13041 /* Detect case that we need to write or remove a star in the mode line. */
13065 count1 = SPECPDL_INDEX (); 13042 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13066 specbind (Qinhibit_point_motion_hooks, Qt); 13043 {
13044 w->update_mode_line = 1;
13045 if (buffer_shared_and_changed ())
13046 update_mode_lines++;
13047 }
13067 13048
13068 if (mode_line_update_needed (w)) 13049 /* Avoid invocation of point motion hooks by `current_column' below. */
13069 w->update_mode_line = 1; 13050 count1 = SPECPDL_INDEX ();
13051 specbind (Qinhibit_point_motion_hooks, Qt);
13052
13053 if (mode_line_update_needed (w))
13054 w->update_mode_line = 1;
13070 13055
13071 unbind_to (count1, Qnil); 13056 unbind_to (count1, Qnil);
13057 }
13072 13058
13073 consider_all_windows_p = (update_mode_lines 13059 consider_all_windows_p = (update_mode_lines
13074 || buffer_shared_and_changed () 13060 || buffer_shared_and_changed ()
@@ -13167,7 +13153,7 @@ redisplay_internal (void)
13167 && !FRAME_OBSCURED_P (XFRAME (w->frame)) 13153 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13168 /* Make sure recorded data applies to current buffer, etc. */ 13154 /* Make sure recorded data applies to current buffer, etc. */
13169 && this_line_buffer == current_buffer 13155 && this_line_buffer == current_buffer
13170 && current_buffer == XBUFFER (w->contents) 13156 && match_p
13171 && !w->force_start 13157 && !w->force_start
13172 && !w->optional_new_start 13158 && !w->optional_new_start
13173 /* Point must be on the line that we have info recorded about. */ 13159 /* Point must be on the line that we have info recorded about. */
@@ -14458,8 +14444,7 @@ run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14458 struct window *w = XWINDOW (window); 14444 struct window *w = XWINDOW (window);
14459 SET_MARKER_FROM_TEXT_POS (w->start, startp); 14445 SET_MARKER_FROM_TEXT_POS (w->start, startp);
14460 14446
14461 if (current_buffer != XBUFFER (w->contents)) 14447 eassert (current_buffer == XBUFFER (w->contents));
14462 emacs_abort ();
14463 14448
14464 if (!NILP (Vwindow_scroll_functions)) 14449 if (!NILP (Vwindow_scroll_functions))
14465 { 14450 {
@@ -15360,7 +15345,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15360 eassert (XMARKER (w->pointm)->buffer == buffer); 15345 eassert (XMARKER (w->pointm)->buffer == buffer);
15361 15346
15362 restart: 15347 restart:
15363 reconsider_clip_changes (w, buffer); 15348 reconsider_clip_changes (w);
15364 frame_line_height = default_line_pixel_height (w); 15349 frame_line_height = default_line_pixel_height (w);
15365 15350
15366 /* Has the mode line to be updated? */ 15351 /* Has the mode line to be updated? */
@@ -20115,7 +20100,7 @@ Value is the new character position of point. */)
20115 (Lisp_Object direction) 20100 (Lisp_Object direction)
20116{ 20101{
20117 struct window *w = XWINDOW (selected_window); 20102 struct window *w = XWINDOW (selected_window);
20118 struct buffer *b = NULL; 20103 struct buffer *b = XBUFFER (w->contents);
20119 struct glyph_row *row; 20104 struct glyph_row *row;
20120 int dir; 20105 int dir;
20121 Lisp_Object paragraph_dir; 20106 Lisp_Object paragraph_dir;
@@ -20135,9 +20120,6 @@ Value is the new character position of point. */)
20135 else 20120 else
20136 dir = -1; 20121 dir = -1;
20137 20122
20138 if (BUFFERP (w->contents))
20139 b = XBUFFER (w->contents);
20140
20141 /* If current matrix is up-to-date, we can use the information 20123 /* If current matrix is up-to-date, we can use the information
20142 recorded in the glyphs, at least as long as the goal is on the 20124 recorded in the glyphs, at least as long as the goal is on the
20143 screen. */ 20125 screen. */
@@ -20146,8 +20128,7 @@ Value is the new character position of point. */)
20146 && b 20128 && b
20147 && !b->clip_changed 20129 && !b->clip_changed
20148 && !b->prevent_redisplay_optimizations_p 20130 && !b->prevent_redisplay_optimizations_p
20149 && w->last_modified >= BUF_MODIFF (b) 20131 && !window_outdated (w)
20150 && w->last_overlay_modified >= BUF_OVERLAY_MODIFF (b)
20151 && w->cursor.vpos >= 0 20132 && w->cursor.vpos >= 0
20152 && w->cursor.vpos < w->current_matrix->nrows 20133 && w->cursor.vpos < w->current_matrix->nrows
20153 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p) 20134 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
@@ -28142,10 +28123,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
28142 /* Are we in a window whose display is up to date? 28123 /* Are we in a window whose display is up to date?
28143 And verify the buffer's text has not changed. */ 28124 And verify the buffer's text has not changed. */
28144 b = XBUFFER (w->contents); 28125 b = XBUFFER (w->contents);
28145 if (part == ON_TEXT 28126 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
28146 && w->window_end_valid
28147 && w->last_modified == BUF_MODIFF (b)
28148 && w->last_overlay_modified == BUF_OVERLAY_MODIFF (b))
28149 { 28127 {
28150 int hpos, vpos, dx, dy, area = LAST_AREA; 28128 int hpos, vpos, dx, dy, area = LAST_AREA;
28151 ptrdiff_t pos; 28129 ptrdiff_t pos;