diff options
| author | Dmitry Antipov | 2013-08-07 14:32:08 +0400 |
|---|---|---|
| committer | Dmitry Antipov | 2013-08-07 14:32:08 +0400 |
| commit | 170da1ec691127471ecd118dccd79eec7c9f3699 (patch) | |
| tree | b21f37e99fdde63c2f6169c4728629ef2b302513 /src | |
| parent | 20940c206593a8e7bd4809348ff95a6f971c5528 (diff) | |
| download | emacs-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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 18 | ||||
| -rw-r--r-- | src/window.c | 17 | ||||
| -rw-r--r-- | src/window.h | 1 | ||||
| -rw-r--r-- | src/xdisp.c | 100 |
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 @@ | |||
| 1 | 2013-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 | |||
| 1 | 2013-08-06 Dmitry Antipov <dmantipov@yandex.ru> | 19 | 2013-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 | |||
| 245 | bool | ||
| 246 | window_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 | |||
| 242 | struct window * | 253 | struct window * |
| 243 | decode_live_window (register Lisp_Object window) | 254 | decode_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); | |||
| 973 | extern void replace_buffer_in_windows_safely (Lisp_Object); | 973 | extern 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. */ |
| 975 | extern void wset_buffer (struct window *, Lisp_Object); | 975 | extern void wset_buffer (struct window *, Lisp_Object); |
| 976 | extern bool window_outdated (struct window *); | ||
| 976 | extern void init_window_once (void); | 977 | extern void init_window_once (void); |
| 977 | extern void init_window (void); | 978 | extern void init_window (void); |
| 978 | extern void syms_of_window (void); | 979 | extern 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); | |||
| 804 | static void pint2hrstr (char *, int, ptrdiff_t); | 804 | static void pint2hrstr (char *, int, ptrdiff_t); |
| 805 | static struct text_pos run_window_scroll_functions (Lisp_Object, | 805 | static struct text_pos run_window_scroll_functions (Lisp_Object, |
| 806 | struct text_pos); | 806 | struct text_pos); |
| 807 | static void reconsider_clip_changes (struct window *, struct buffer *); | ||
| 808 | static int text_outside_line_unchanged_p (struct window *, | 807 | static int text_outside_line_unchanged_p (struct window *, |
| 809 | ptrdiff_t, ptrdiff_t); | 808 | ptrdiff_t, ptrdiff_t); |
| 810 | static void store_mode_line_noprop_char (char); | 809 | static 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 | |||
| 10857 | static int | ||
| 10858 | window_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 | ||
| 12873 | static void | 12859 | static void |
| 12874 | reconsider_clip_changes (struct window *w, struct buffer *b) | 12860 | reconsider_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 \ |
| 12908 | do { if (! polling_stopped_here) stop_polling (); \ | 12889 | do { 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; |