diff options
| author | Gerd Möllmann | 2024-11-16 13:52:17 +0100 |
|---|---|---|
| committer | Gerd Möllmann | 2024-11-16 13:52:17 +0100 |
| commit | e7359fbbc40bbf714fb5b4bffc256b455fbe9a6c (patch) | |
| tree | 0339ad3723caba83d7630fce95a936290a3cc56d | |
| parent | e5a2bc740dc43de63acb6e9603ad1905fac1e2c6 (diff) | |
| download | emacs-e7359fbbc40bbf714fb5b4bffc256b455fbe9a6c.tar.gz emacs-e7359fbbc40bbf714fb5b4bffc256b455fbe9a6c.zip | |
Revert "Don't pause display for pending input"
This reverts commit f62d70f52f4f6b7ed158d618bf790df21f171172.
| -rw-r--r-- | lisp/subr.el | 1 | ||||
| -rw-r--r-- | src/dispextern.h | 9 | ||||
| -rw-r--r-- | src/dispnew.c | 543 | ||||
| -rw-r--r-- | src/keyboard.c | 3 | ||||
| -rw-r--r-- | src/minibuf.c | 4 | ||||
| -rw-r--r-- | src/xdisp.c | 199 |
6 files changed, 497 insertions, 262 deletions
diff --git a/lisp/subr.el b/lisp/subr.el index 648e6f0f38f..6472c9d6916 100644 --- a/lisp/subr.el +++ b/lisp/subr.el | |||
| @@ -1990,6 +1990,7 @@ be a list of the form returned by `event-start' and `event-end'." | |||
| 1990 | ;; It's been announced as obsolete in NEWS and in the docstring since Emacs-25, | 1990 | ;; It's been announced as obsolete in NEWS and in the docstring since Emacs-25, |
| 1991 | ;; but it's only been marked for compilation warnings since Emacs-29. | 1991 | ;; but it's only been marked for compilation warnings since Emacs-29. |
| 1992 | "25.1") | 1992 | "25.1") |
| 1993 | (make-obsolete-variable 'redisplay-dont-pause nil "24.5") | ||
| 1993 | (make-obsolete-variable 'operating-system-release nil "28.1") | 1994 | (make-obsolete-variable 'operating-system-release nil "28.1") |
| 1994 | (make-obsolete-variable 'inhibit-changing-match-data 'save-match-data "29.1") | 1995 | (make-obsolete-variable 'inhibit-changing-match-data 'save-match-data "29.1") |
| 1995 | 1996 | ||
diff --git a/src/dispextern.h b/src/dispextern.h index 47afc48bb60..cb43d330b86 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -1322,6 +1322,9 @@ struct glyph_row *matrix_row (struct glyph_matrix *, int); | |||
| 1322 | 1322 | ||
| 1323 | extern struct glyph space_glyph; | 1323 | extern struct glyph space_glyph; |
| 1324 | 1324 | ||
| 1325 | /* True means last display completed. False means it was preempted. */ | ||
| 1326 | |||
| 1327 | extern bool display_completed; | ||
| 1325 | 1328 | ||
| 1326 | /************************************************************************ | 1329 | /************************************************************************ |
| 1327 | Glyph Strings | 1330 | Glyph Strings |
| @@ -3803,7 +3806,7 @@ extern Lisp_Object marginal_area_string (struct window *, enum window_part, | |||
| 3803 | Lisp_Object *, | 3806 | Lisp_Object *, |
| 3804 | int *, int *, int *, int *); | 3807 | int *, int *, int *, int *); |
| 3805 | extern void redraw_frame (struct frame *); | 3808 | extern void redraw_frame (struct frame *); |
| 3806 | void update_frame (struct frame *, bool); | 3809 | extern bool update_frame (struct frame *, bool, bool); |
| 3807 | extern void update_frame_with_menu (struct frame *, int, int); | 3810 | extern void update_frame_with_menu (struct frame *, int, int); |
| 3808 | extern int update_mouse_position (struct frame *, int, int); | 3811 | extern int update_mouse_position (struct frame *, int, int); |
| 3809 | extern void bitch_at_user (void); | 3812 | extern void bitch_at_user (void); |
| @@ -3922,8 +3925,8 @@ Lisp_Object frames_in_reverse_z_order (struct frame *f, bool visible); | |||
| 3922 | bool is_tty_frame (struct frame *f); | 3925 | bool is_tty_frame (struct frame *f); |
| 3923 | bool is_tty_child_frame (struct frame *f); | 3926 | bool is_tty_child_frame (struct frame *f); |
| 3924 | bool is_tty_root_frame (struct frame *f); | 3927 | bool is_tty_root_frame (struct frame *f); |
| 3925 | void combine_updates (Lisp_Object root_frames, bool inhibit_id_p); | 3928 | bool combine_updates (Lisp_Object root_frames, bool force_p, bool inhibit_id_p); |
| 3926 | void combine_updates_for_frame (struct frame *f, bool inhibit_id_p); | 3929 | bool combine_updates_for_frame (struct frame *f, bool force_p, bool inhibit_id_p); |
| 3927 | void tty_raise_lower_frame (struct frame *f, bool raise); | 3930 | void tty_raise_lower_frame (struct frame *f, bool raise); |
| 3928 | int max_child_z_order (struct frame *parent); | 3931 | int max_child_z_order (struct frame *parent); |
| 3929 | 3932 | ||
diff --git a/src/dispnew.c b/src/dispnew.c index 37ec37b752e..d473a77e3ad 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -93,10 +93,10 @@ static void check_matrix_pointers (struct glyph_matrix *, | |||
| 93 | struct glyph_matrix *); | 93 | struct glyph_matrix *); |
| 94 | #endif | 94 | #endif |
| 95 | static void mirror_line_dance (struct window *, int, int, int *, char *); | 95 | static void mirror_line_dance (struct window *, int, int, int *, char *); |
| 96 | static void update_window_tree (struct window *); | 96 | static bool update_window_tree (struct window *, bool); |
| 97 | static void update_window (struct window *); | 97 | static bool update_window (struct window *, bool); |
| 98 | static void write_matrix (struct frame *, bool, bool, bool); | 98 | static bool write_matrix (struct frame *, bool, bool, bool, bool); |
| 99 | static void scrolling (struct frame *); | 99 | static bool scrolling (struct frame *); |
| 100 | static void set_window_cursor_after_update (struct window *); | 100 | static void set_window_cursor_after_update (struct window *); |
| 101 | static void adjust_frame_glyphs_for_window_redisplay (struct frame *); | 101 | static void adjust_frame_glyphs_for_window_redisplay (struct frame *); |
| 102 | static void adjust_frame_glyphs_for_frame_redisplay (struct frame *); | 102 | static void adjust_frame_glyphs_for_frame_redisplay (struct frame *); |
| @@ -116,6 +116,10 @@ check_rows (struct frame *f) | |||
| 116 | } | 116 | } |
| 117 | #endif | 117 | #endif |
| 118 | 118 | ||
| 119 | /* True means last display completed. False means it was preempted. */ | ||
| 120 | |||
| 121 | bool display_completed; | ||
| 122 | |||
| 119 | /* True means SIGWINCH happened when not safe. */ | 123 | /* True means SIGWINCH happened when not safe. */ |
| 120 | 124 | ||
| 121 | static bool delayed_size_change; | 125 | static bool delayed_size_change; |
| @@ -171,10 +175,11 @@ static uintmax_t history_tick; | |||
| 171 | 175 | ||
| 172 | /* Add to the redisplay history how window W has been displayed. | 176 | /* Add to the redisplay history how window W has been displayed. |
| 173 | MSG is a trace containing the information how W's glyph matrix | 177 | MSG is a trace containing the information how W's glyph matrix |
| 174 | has been constructed. */ | 178 | has been constructed. PAUSED_P means that the update |
| 179 | has been interrupted for pending input. */ | ||
| 175 | 180 | ||
| 176 | static void | 181 | static void |
| 177 | add_window_display_history (struct window *w, const char *msg) | 182 | add_window_display_history (struct window *w, const char *msg, bool paused_p) |
| 178 | { | 183 | { |
| 179 | char *buf; | 184 | char *buf; |
| 180 | void *ptr = w; | 185 | void *ptr = w; |
| @@ -185,13 +190,14 @@ add_window_display_history (struct window *w, const char *msg) | |||
| 185 | ++history_idx; | 190 | ++history_idx; |
| 186 | 191 | ||
| 187 | snprintf (buf, sizeof redisplay_history[0].trace, | 192 | snprintf (buf, sizeof redisplay_history[0].trace, |
| 188 | "%"PRIuMAX": window %p %s\n%s", | 193 | "%"PRIuMAX": window %p (%s)%s\n%s", |
| 189 | history_tick++, | 194 | history_tick++, |
| 190 | ptr, | 195 | ptr, |
| 191 | ((BUFFERP (w->contents) | 196 | ((BUFFERP (w->contents) |
| 192 | && STRINGP (BVAR (XBUFFER (w->contents), name))) | 197 | && STRINGP (BVAR (XBUFFER (w->contents), name))) |
| 193 | ? SSDATA (BVAR (XBUFFER (w->contents), name)) | 198 | ? SSDATA (BVAR (XBUFFER (w->contents), name)) |
| 194 | : "???"), | 199 | : "???"), |
| 200 | paused_p ? " ***paused***" : "", | ||
| 195 | msg); | 201 | msg); |
| 196 | } | 202 | } |
| 197 | 203 | ||
| @@ -2130,7 +2136,8 @@ adjust_frame_glyphs_for_frame_redisplay (struct frame *f) | |||
| 2130 | current matrix over a call to adjust_glyph_matrix, we must | 2136 | current matrix over a call to adjust_glyph_matrix, we must |
| 2131 | make a copy of the current glyphs, and restore the current | 2137 | make a copy of the current glyphs, and restore the current |
| 2132 | matrix' contents from that copy. */ | 2138 | matrix' contents from that copy. */ |
| 2133 | if (!FRAME_GARBAGED_P (f) | 2139 | if (display_completed |
| 2140 | && !FRAME_GARBAGED_P (f) | ||
| 2134 | && matrix_dim.width == f->current_matrix->matrix_w | 2141 | && matrix_dim.width == f->current_matrix->matrix_w |
| 2135 | && matrix_dim.height == f->current_matrix->matrix_h | 2142 | && matrix_dim.height == f->current_matrix->matrix_h |
| 2136 | /* For some reason, the frame glyph matrix gets corrupted if | 2143 | /* For some reason, the frame glyph matrix gets corrupted if |
| @@ -2675,7 +2682,7 @@ build_frame_matrix_from_leaf_window (struct glyph_matrix *frame_matrix, struct w | |||
| 2675 | frame and window share glyphs. */ | 2682 | frame and window share glyphs. */ |
| 2676 | 2683 | ||
| 2677 | strcpy (w->current_matrix->method, w->desired_matrix->method); | 2684 | strcpy (w->current_matrix->method, w->desired_matrix->method); |
| 2678 | add_window_display_history (w, w->current_matrix->method); | 2685 | add_window_display_history (w, w->current_matrix->method, 0); |
| 2679 | #endif | 2686 | #endif |
| 2680 | } | 2687 | } |
| 2681 | 2688 | ||
| @@ -3771,7 +3778,7 @@ update_bar_window (Lisp_Object window, Lisp_Object *current, | |||
| 3771 | struct window *w = XWINDOW (window); | 3778 | struct window *w = XWINDOW (window); |
| 3772 | if (w->must_be_updated_p) | 3779 | if (w->must_be_updated_p) |
| 3773 | { | 3780 | { |
| 3774 | update_window (w); | 3781 | update_window (w, true); |
| 3775 | w->must_be_updated_p = false; | 3782 | w->must_be_updated_p = false; |
| 3776 | Lisp_Object tem = *current; | 3783 | Lisp_Object tem = *current; |
| 3777 | *current = *desired; | 3784 | *current = *desired; |
| @@ -3801,8 +3808,8 @@ update_tool_bar (struct frame *f) | |||
| 3801 | #endif | 3808 | #endif |
| 3802 | } | 3809 | } |
| 3803 | 3810 | ||
| 3804 | static void | 3811 | static bool |
| 3805 | update_window_frame (struct frame *f) | 3812 | update_window_frame (struct frame *f, bool force_p) |
| 3806 | { | 3813 | { |
| 3807 | eassert (FRAME_WINDOW_P (f)); | 3814 | eassert (FRAME_WINDOW_P (f)); |
| 3808 | update_begin (f); | 3815 | update_begin (f); |
| @@ -3810,17 +3817,19 @@ update_window_frame (struct frame *f) | |||
| 3810 | update_tab_bar (f); | 3817 | update_tab_bar (f); |
| 3811 | update_tool_bar (f); | 3818 | update_tool_bar (f); |
| 3812 | struct window *root_window = XWINDOW (f->root_window); | 3819 | struct window *root_window = XWINDOW (f->root_window); |
| 3813 | update_window_tree (root_window); | 3820 | bool paused_p = update_window_tree (root_window, force_p); |
| 3814 | update_end (f); | 3821 | update_end (f); |
| 3815 | set_window_update_flags (root_window, false); | 3822 | set_window_update_flags (root_window, false); |
| 3823 | return paused_p; | ||
| 3816 | } | 3824 | } |
| 3817 | 3825 | ||
| 3818 | static void | 3826 | static bool |
| 3819 | update_initial_frame (struct frame *f) | 3827 | update_initial_frame (struct frame *f, bool force_p) |
| 3820 | { | 3828 | { |
| 3821 | build_frame_matrix (f); | 3829 | build_frame_matrix (f); |
| 3822 | struct window *root_window = XWINDOW (f->root_window); | 3830 | struct window *root_window = XWINDOW (f->root_window); |
| 3823 | set_window_update_flags (root_window, false); | 3831 | set_window_update_flags (root_window, false); |
| 3832 | return false; | ||
| 3824 | } | 3833 | } |
| 3825 | 3834 | ||
| 3826 | static void | 3835 | static void |
| @@ -3831,10 +3840,11 @@ flush_terminal (struct frame *f) | |||
| 3831 | fflush (FRAME_TTY (f)->output); | 3840 | fflush (FRAME_TTY (f)->output); |
| 3832 | } | 3841 | } |
| 3833 | 3842 | ||
| 3834 | static void | 3843 | static bool |
| 3835 | update_tty_frame (struct frame *f) | 3844 | update_tty_frame (struct frame *f, bool force_p) |
| 3836 | { | 3845 | { |
| 3837 | build_frame_matrix (f); | 3846 | build_frame_matrix (f); |
| 3847 | return false; | ||
| 3838 | } | 3848 | } |
| 3839 | 3849 | ||
| 3840 | /* Return the cursor position of the selected window of frame F, in | 3850 | /* Return the cursor position of the selected window of frame F, in |
| @@ -3942,8 +3952,8 @@ terminal_cursor_magic (struct frame *root, struct frame *topmost_child) | |||
| 3942 | } | 3952 | } |
| 3943 | } | 3953 | } |
| 3944 | 3954 | ||
| 3945 | void | 3955 | bool |
| 3946 | combine_updates_for_frame (struct frame *f, bool inhibit_scrolling) | 3956 | combine_updates_for_frame (struct frame *f, bool force_p, bool inhibit_scrolling) |
| 3947 | { | 3957 | { |
| 3948 | struct frame *root = root_frame (f); | 3958 | struct frame *root = root_frame (f); |
| 3949 | eassert (FRAME_VISIBLE_P (root)); | 3959 | eassert (FRAME_VISIBLE_P (root)); |
| @@ -3959,12 +3969,13 @@ combine_updates_for_frame (struct frame *f, bool inhibit_scrolling) | |||
| 3959 | } | 3969 | } |
| 3960 | 3970 | ||
| 3961 | update_begin (root); | 3971 | update_begin (root); |
| 3962 | write_matrix (root, inhibit_scrolling, 1, false); | 3972 | bool paused = write_matrix (root, force_p, inhibit_scrolling, 1, false); |
| 3963 | make_matrix_current (root); | 3973 | if (!paused) |
| 3974 | make_matrix_current (root); | ||
| 3964 | update_end (root); | 3975 | update_end (root); |
| 3965 | 3976 | ||
| 3966 | /* If a child is displayed, and the cursor is displayed in another | 3977 | /* If a child is displayed, and the cursor is displayed in another |
| 3967 | frame, the child might lay above the cursor, so that it appears to | 3978 | frame, the child might lay above the cursor, so that it appers to |
| 3968 | "shine through" the child. Avoid that because it's confusing. */ | 3979 | "shine through" the child. Avoid that because it's confusing. */ |
| 3969 | if (topmost_child) | 3980 | if (topmost_child) |
| 3970 | terminal_cursor_magic (root, topmost_child); | 3981 | terminal_cursor_magic (root, topmost_child); |
| @@ -3981,33 +3992,66 @@ combine_updates_for_frame (struct frame *f, bool inhibit_scrolling) | |||
| 3981 | add_frame_display_history (f, false); | 3992 | add_frame_display_history (f, false); |
| 3982 | #endif | 3993 | #endif |
| 3983 | } | 3994 | } |
| 3995 | |||
| 3996 | return paused; | ||
| 3984 | } | 3997 | } |
| 3985 | 3998 | ||
| 3986 | /* Update on the screen all root frames ROOTS. Called from | 3999 | /* Update on the screen all root frames ROOTS. Called from |
| 3987 | redisplay_internal as the last step of redisplaying. */ | 4000 | redisplay_internal as the last step of redisplaying. */ |
| 3988 | 4001 | ||
| 3989 | void | 4002 | bool |
| 3990 | combine_updates (Lisp_Object roots, bool inhibit_scrolling) | 4003 | combine_updates (Lisp_Object roots, bool force_p, bool inhibit_scrolling) |
| 3991 | { | 4004 | { |
| 4005 | if (redisplay_dont_pause) | ||
| 4006 | force_p = true; | ||
| 4007 | |||
| 3992 | for (; CONSP (roots); roots = XCDR (roots)) | 4008 | for (; CONSP (roots); roots = XCDR (roots)) |
| 3993 | { | 4009 | { |
| 3994 | struct frame *root = XFRAME (XCAR (roots)); | 4010 | struct frame *root = XFRAME (XCAR (roots)); |
| 3995 | combine_updates_for_frame (root, inhibit_scrolling); | 4011 | if (combine_updates_for_frame (root, force_p, inhibit_scrolling)) |
| 4012 | { | ||
| 4013 | display_completed = false; | ||
| 4014 | return true; | ||
| 4015 | } | ||
| 3996 | } | 4016 | } |
| 4017 | |||
| 4018 | display_completed = true; | ||
| 4019 | return false; | ||
| 3997 | } | 4020 | } |
| 3998 | 4021 | ||
| 3999 | /* Update frame F based on the data in desired matrices. | 4022 | /* Update frame F based on the data in desired matrices. |
| 4000 | If INHIBIT_SCROLLING, don't try scrolling. */ | ||
| 4001 | 4023 | ||
| 4002 | void | 4024 | If FORCE_P, don't let redisplay be stopped by detecting pending input. |
| 4003 | update_frame (struct frame *f, bool inhibit_scrolling) | 4025 | If INHIBIT_SCROLLING, don't try scrolling. |
| 4026 | |||
| 4027 | Value is true if redisplay was stopped due to pending input. */ | ||
| 4028 | |||
| 4029 | bool | ||
| 4030 | update_frame (struct frame *f, bool force_p, bool inhibit_scrolling) | ||
| 4004 | { | 4031 | { |
| 4032 | struct window *root_window = XWINDOW (f->root_window); | ||
| 4033 | |||
| 4034 | if (redisplay_dont_pause) | ||
| 4035 | force_p = true; | ||
| 4036 | else if (!force_p && detect_input_pending_ignore_squeezables ()) | ||
| 4037 | { | ||
| 4038 | /* Reset flags indicating that a window should be updated. */ | ||
| 4039 | set_window_update_flags (root_window, false); | ||
| 4040 | display_completed = false; | ||
| 4041 | return true; | ||
| 4042 | } | ||
| 4043 | |||
| 4044 | bool paused; | ||
| 4005 | if (FRAME_WINDOW_P (f)) | 4045 | if (FRAME_WINDOW_P (f)) |
| 4006 | update_window_frame (f); | 4046 | paused = update_window_frame (f, force_p); |
| 4007 | else if (FRAME_INITIAL_P (f)) | 4047 | else if (FRAME_INITIAL_P (f)) |
| 4008 | update_initial_frame (f); | 4048 | paused = update_initial_frame (f, force_p); |
| 4009 | else | 4049 | else |
| 4010 | update_tty_frame (f); | 4050 | paused = update_tty_frame (f, force_p); |
| 4051 | |||
| 4052 | if (paused) | ||
| 4053 | display_completed = false; | ||
| 4054 | return paused; | ||
| 4011 | } | 4055 | } |
| 4012 | 4056 | ||
| 4013 | /* Update a TTY frame F that has a menu dropped down over some of its | 4057 | /* Update a TTY frame F that has a menu dropped down over some of its |
| @@ -4033,7 +4077,7 @@ update_frame_with_menu (struct frame *f, int row, int col) | |||
| 4033 | cursor_at_point_p = !(row >= 0 && col >= 0); | 4077 | cursor_at_point_p = !(row >= 0 && col >= 0); |
| 4034 | /* Do not stop due to pending input, and do not try scrolling. This | 4078 | /* Do not stop due to pending input, and do not try scrolling. This |
| 4035 | means that write_glyphs will always return false. */ | 4079 | means that write_glyphs will always return false. */ |
| 4036 | write_matrix (f, 1, cursor_at_point_p, true); | 4080 | write_matrix (f, 1, 1, cursor_at_point_p, true); |
| 4037 | make_matrix_current (f); | 4081 | make_matrix_current (f); |
| 4038 | clear_desired_matrices (f); | 4082 | clear_desired_matrices (f); |
| 4039 | /* ROW and COL tell us where in the menu to position the cursor, so | 4083 | /* ROW and COL tell us where in the menu to position the cursor, so |
| @@ -4056,6 +4100,7 @@ update_frame_with_menu (struct frame *f, int row, int col) | |||
| 4056 | 4100 | ||
| 4057 | /* Reset flags indicating that a window should be updated. */ | 4101 | /* Reset flags indicating that a window should be updated. */ |
| 4058 | set_window_update_flags (root_window, false); | 4102 | set_window_update_flags (root_window, false); |
| 4103 | display_completed = true; | ||
| 4059 | } | 4104 | } |
| 4060 | 4105 | ||
| 4061 | /* Update the mouse position for a frame F. This handles both | 4106 | /* Update the mouse position for a frame F. This handles both |
| @@ -4111,24 +4156,30 @@ properties or updating the help echo text. */) | |||
| 4111 | Window-based updates | 4156 | Window-based updates |
| 4112 | ************************************************************************/ | 4157 | ************************************************************************/ |
| 4113 | 4158 | ||
| 4114 | /* Perform updates in window tree rooted at W. */ | 4159 | /* Perform updates in window tree rooted at W. |
| 4160 | If FORCE_P, don't stop updating if input is pending. */ | ||
| 4115 | 4161 | ||
| 4116 | static void | 4162 | static bool |
| 4117 | update_window_tree (struct window *w) | 4163 | update_window_tree (struct window *w, bool force_p) |
| 4118 | { | 4164 | { |
| 4119 | while (w) | 4165 | bool paused_p = 0; |
| 4166 | |||
| 4167 | while (w && !paused_p) | ||
| 4120 | { | 4168 | { |
| 4121 | if (WINDOWP (w->contents)) | 4169 | if (WINDOWP (w->contents)) |
| 4122 | update_window_tree (XWINDOW (w->contents)); | 4170 | paused_p |= update_window_tree (XWINDOW (w->contents), force_p); |
| 4123 | else if (w->must_be_updated_p) | 4171 | else if (w->must_be_updated_p) |
| 4124 | update_window (w); | 4172 | paused_p |= update_window (w, force_p); |
| 4125 | 4173 | ||
| 4126 | w = NILP (w->next) ? 0 : XWINDOW (w->next); | 4174 | w = NILP (w->next) ? 0 : XWINDOW (w->next); |
| 4127 | } | 4175 | } |
| 4176 | |||
| 4177 | return paused_p; | ||
| 4128 | } | 4178 | } |
| 4129 | 4179 | ||
| 4130 | 4180 | ||
| 4131 | /* Update window W if its flag must_be_updated_p is set. */ | 4181 | /* Update window W if its flag must_be_updated_p is set. |
| 4182 | If FORCE_P, don't stop updating if input is pending. */ | ||
| 4132 | 4183 | ||
| 4133 | void | 4184 | void |
| 4134 | update_single_window (struct window *w) | 4185 | update_single_window (struct window *w) |
| @@ -4139,7 +4190,7 @@ update_single_window (struct window *w) | |||
| 4139 | 4190 | ||
| 4140 | /* Update W. */ | 4191 | /* Update W. */ |
| 4141 | update_begin (f); | 4192 | update_begin (f); |
| 4142 | update_window (w); | 4193 | update_window (w, true); |
| 4143 | update_end (f); | 4194 | update_end (f); |
| 4144 | 4195 | ||
| 4145 | /* Reset flag in W. */ | 4196 | /* Reset flag in W. */ |
| @@ -4279,12 +4330,15 @@ check_current_matrix_flags (struct window *w) | |||
| 4279 | #endif /* GLYPH_DEBUG */ | 4330 | #endif /* GLYPH_DEBUG */ |
| 4280 | 4331 | ||
| 4281 | 4332 | ||
| 4282 | /* Update display of window W. */ | 4333 | /* Update display of window W. |
| 4334 | If FORCE_P, don't stop updating when input is pending. */ | ||
| 4283 | 4335 | ||
| 4284 | static void | 4336 | static bool |
| 4285 | update_window (struct window *w) | 4337 | update_window (struct window *w, bool force_p) |
| 4286 | { | 4338 | { |
| 4287 | struct glyph_matrix *desired_matrix = w->desired_matrix; | 4339 | struct glyph_matrix *desired_matrix = w->desired_matrix; |
| 4340 | bool paused_p; | ||
| 4341 | int preempt_count = clip_to_bounds (1, baud_rate / 2400 + 1, INT_MAX); | ||
| 4288 | #ifdef HAVE_WINDOW_SYSTEM | 4342 | #ifdef HAVE_WINDOW_SYSTEM |
| 4289 | struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); | 4343 | struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); |
| 4290 | #endif | 4344 | #endif |
| @@ -4293,200 +4347,224 @@ update_window (struct window *w) | |||
| 4293 | eassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w)))); | 4347 | eassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w)))); |
| 4294 | #endif | 4348 | #endif |
| 4295 | 4349 | ||
| 4350 | /* Check pending input the first time so that we can quickly return. */ | ||
| 4351 | if (!force_p) | ||
| 4352 | detect_input_pending_ignore_squeezables (); | ||
| 4353 | |||
| 4296 | /* If forced to complete the update, no input is pending, or we are | 4354 | /* If forced to complete the update, no input is pending, or we are |
| 4297 | tracking the mouse, do the update. */ | 4355 | tracking the mouse, do the update. */ |
| 4298 | struct glyph_row *row, *end; | 4356 | if (force_p || !input_pending || !NILP (track_mouse)) |
| 4299 | struct glyph_row *mode_line_row; | 4357 | { |
| 4300 | struct glyph_row *tab_line_row; | 4358 | struct glyph_row *row, *end; |
| 4301 | struct glyph_row *header_line_row; | 4359 | struct glyph_row *mode_line_row; |
| 4302 | int yb; | 4360 | struct glyph_row *tab_line_row; |
| 4303 | bool changed_p = 0, mouse_face_overwritten_p = 0; | 4361 | struct glyph_row *header_line_row; |
| 4304 | bool invisible_rows_marked = false; | 4362 | int yb; |
| 4363 | bool changed_p = 0, mouse_face_overwritten_p = 0; | ||
| 4364 | int n_updated = 0; | ||
| 4365 | bool invisible_rows_marked = false; | ||
| 4305 | 4366 | ||
| 4306 | #ifdef HAVE_WINDOW_SYSTEM | 4367 | #ifdef HAVE_WINDOW_SYSTEM |
| 4307 | gui_update_window_begin (w); | 4368 | gui_update_window_begin (w); |
| 4308 | #else | 4369 | #else |
| 4309 | (void) changed_p; | 4370 | (void) changed_p; |
| 4310 | #endif | 4371 | #endif |
| 4311 | yb = window_text_bottom_y (w); | 4372 | yb = window_text_bottom_y (w); |
| 4312 | row = MATRIX_ROW (desired_matrix, 0); | 4373 | row = MATRIX_ROW (desired_matrix, 0); |
| 4313 | end = MATRIX_MODE_LINE_ROW (desired_matrix); | 4374 | end = MATRIX_MODE_LINE_ROW (desired_matrix); |
| 4314 | |||
| 4315 | /* Take note of the tab line, if there is one. We will | ||
| 4316 | update it below, after updating all of the window's lines. */ | ||
| 4317 | if (row->mode_line_p && row->tab_line_p) | ||
| 4318 | { | ||
| 4319 | tab_line_row = row; | ||
| 4320 | ++row; | ||
| 4321 | } | ||
| 4322 | else | ||
| 4323 | tab_line_row = NULL; | ||
| 4324 | 4375 | ||
| 4325 | /* Take note of the header line, if there is one. We will | 4376 | /* Take note of the tab line, if there is one. We will |
| 4326 | update it below, after updating all of the window's lines. */ | 4377 | update it below, after updating all of the window's lines. */ |
| 4327 | if (row->mode_line_p) | 4378 | if (row->mode_line_p && row->tab_line_p) |
| 4328 | { | 4379 | { |
| 4329 | header_line_row = row; | 4380 | tab_line_row = row; |
| 4330 | ++row; | 4381 | ++row; |
| 4331 | } | 4382 | } |
| 4332 | else | 4383 | else |
| 4333 | header_line_row = NULL; | 4384 | tab_line_row = NULL; |
| 4334 | |||
| 4335 | /* Update the mode line, if necessary. */ | ||
| 4336 | mode_line_row = MATRIX_MODE_LINE_ROW (desired_matrix); | ||
| 4337 | if (mode_line_row->mode_line_p && mode_line_row->enabled_p) | ||
| 4338 | { | ||
| 4339 | mode_line_row->y = yb + WINDOW_SCROLL_BAR_AREA_HEIGHT (w); | ||
| 4340 | update_window_line (w, MATRIX_ROW_VPOS (mode_line_row, | ||
| 4341 | desired_matrix), | ||
| 4342 | &mouse_face_overwritten_p); | ||
| 4343 | } | ||
| 4344 | 4385 | ||
| 4345 | /* Find first enabled row. Optimizations in redisplay_internal | 4386 | /* Take note of the header line, if there is one. We will |
| 4346 | may lead to an update with only one row enabled. There may | 4387 | update it below, after updating all of the window's lines. */ |
| 4347 | be also completely empty matrices. */ | 4388 | if (row->mode_line_p) |
| 4348 | while (row < end && !row->enabled_p) | 4389 | { |
| 4349 | ++row; | 4390 | header_line_row = row; |
| 4391 | ++row; | ||
| 4392 | } | ||
| 4393 | else | ||
| 4394 | header_line_row = NULL; | ||
| 4350 | 4395 | ||
| 4351 | /* Try reusing part of the display by copying. */ | 4396 | /* Update the mode line, if necessary. */ |
| 4352 | if (row < end && !desired_matrix->no_scrolling_p) | 4397 | mode_line_row = MATRIX_MODE_LINE_ROW (desired_matrix); |
| 4353 | { | 4398 | if (mode_line_row->mode_line_p && mode_line_row->enabled_p) |
| 4354 | int rc = scrolling_window (w, (tab_line_row != NULL ? 1 : 0) | ||
| 4355 | + (header_line_row != NULL ? 1 : 0)); | ||
| 4356 | if (rc < 0) | ||
| 4357 | { | 4399 | { |
| 4358 | /* All rows were found to be equal. */ | 4400 | mode_line_row->y = yb + WINDOW_SCROLL_BAR_AREA_HEIGHT (w); |
| 4359 | goto set_cursor; | 4401 | update_window_line (w, MATRIX_ROW_VPOS (mode_line_row, |
| 4402 | desired_matrix), | ||
| 4403 | &mouse_face_overwritten_p); | ||
| 4360 | } | 4404 | } |
| 4361 | else if (rc > 0) | 4405 | |
| 4406 | /* Find first enabled row. Optimizations in redisplay_internal | ||
| 4407 | may lead to an update with only one row enabled. There may | ||
| 4408 | be also completely empty matrices. */ | ||
| 4409 | while (row < end && !row->enabled_p) | ||
| 4410 | ++row; | ||
| 4411 | |||
| 4412 | /* Try reusing part of the display by copying. */ | ||
| 4413 | if (row < end && !desired_matrix->no_scrolling_p) | ||
| 4362 | { | 4414 | { |
| 4363 | /* We've scrolled the display. */ | 4415 | int rc = scrolling_window (w, (tab_line_row != NULL ? 1 : 0) |
| 4364 | changed_p = 1; | 4416 | + (header_line_row != NULL ? 1 : 0)); |
| 4417 | if (rc < 0) | ||
| 4418 | { | ||
| 4419 | /* All rows were found to be equal. */ | ||
| 4420 | paused_p = 0; | ||
| 4421 | goto set_cursor; | ||
| 4422 | } | ||
| 4423 | else if (rc > 0) | ||
| 4424 | { | ||
| 4425 | /* We've scrolled the display. */ | ||
| 4426 | force_p = 1; | ||
| 4427 | changed_p = 1; | ||
| 4428 | } | ||
| 4365 | } | 4429 | } |
| 4366 | } | ||
| 4367 | 4430 | ||
| 4368 | /* Update the rest of the lines. */ | 4431 | /* Update the rest of the lines. */ |
| 4369 | for (; row < end; ++row) | 4432 | for (; row < end && (force_p || !input_pending); ++row) |
| 4370 | /* scrolling_window resets the enabled_p flag of the rows it | 4433 | /* scrolling_window resets the enabled_p flag of the rows it |
| 4371 | reuses from current_matrix. */ | 4434 | reuses from current_matrix. */ |
| 4372 | if (row->enabled_p) | 4435 | if (row->enabled_p) |
| 4373 | { | ||
| 4374 | int vpos = MATRIX_ROW_VPOS (row, desired_matrix); | ||
| 4375 | int i; | ||
| 4376 | |||
| 4377 | changed_p |= update_window_line (w, vpos, | ||
| 4378 | &mouse_face_overwritten_p); | ||
| 4379 | |||
| 4380 | /* Mark all rows below the last visible one in the current | ||
| 4381 | matrix as invalid. This is necessary because of | ||
| 4382 | variable line heights. Consider the case of three | ||
| 4383 | successive redisplays, where the first displays 5 | ||
| 4384 | lines, the second 3 lines, and the third 5 lines again. | ||
| 4385 | If the second redisplay wouldn't mark rows in the | ||
| 4386 | current matrix invalid, the third redisplay might be | ||
| 4387 | tempted to optimize redisplay based on lines displayed | ||
| 4388 | in the first redisplay. */ | ||
| 4389 | if (MATRIX_ROW_BOTTOM_Y (row) >= yb) | ||
| 4390 | { | 4436 | { |
| 4391 | for (i = vpos + 1; i < w->current_matrix->nrows - 1; ++i) | 4437 | int vpos = MATRIX_ROW_VPOS (row, desired_matrix); |
| 4392 | SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false); | 4438 | int i; |
| 4393 | invisible_rows_marked = true; | 4439 | |
| 4440 | /* We'll have to play a little bit with when to | ||
| 4441 | detect_input_pending. If it's done too often, | ||
| 4442 | scrolling large windows with repeated scroll-up | ||
| 4443 | commands will too quickly pause redisplay. */ | ||
| 4444 | if (!force_p && ++n_updated % preempt_count == 0) | ||
| 4445 | detect_input_pending_ignore_squeezables (); | ||
| 4446 | changed_p |= update_window_line (w, vpos, | ||
| 4447 | &mouse_face_overwritten_p); | ||
| 4448 | |||
| 4449 | /* Mark all rows below the last visible one in the current | ||
| 4450 | matrix as invalid. This is necessary because of | ||
| 4451 | variable line heights. Consider the case of three | ||
| 4452 | successive redisplays, where the first displays 5 | ||
| 4453 | lines, the second 3 lines, and the third 5 lines again. | ||
| 4454 | If the second redisplay wouldn't mark rows in the | ||
| 4455 | current matrix invalid, the third redisplay might be | ||
| 4456 | tempted to optimize redisplay based on lines displayed | ||
| 4457 | in the first redisplay. */ | ||
| 4458 | if (MATRIX_ROW_BOTTOM_Y (row) >= yb) | ||
| 4459 | { | ||
| 4460 | for (i = vpos + 1; i < w->current_matrix->nrows - 1; ++i) | ||
| 4461 | SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false); | ||
| 4462 | invisible_rows_marked = true; | ||
| 4463 | } | ||
| 4394 | } | 4464 | } |
| 4395 | } | ||
| 4396 | 4465 | ||
| 4397 | /* If the window doesn't display its mode line, make sure the | 4466 | /* If the window doesn't display its mode line, make sure the |
| 4398 | corresponding row of the current glyph matrix is disabled, so | 4467 | corresponding row of the current glyph matrix is disabled, so |
| 4399 | that if and when the mode line is displayed again, it will be | 4468 | that if and when the mode line is displayed again, it will be |
| 4400 | cleared and completely redrawn. */ | 4469 | cleared and completely redrawn. */ |
| 4401 | if (!window_wants_mode_line (w)) | 4470 | if (!window_wants_mode_line (w)) |
| 4402 | SET_MATRIX_ROW_ENABLED_P (w->current_matrix, | 4471 | SET_MATRIX_ROW_ENABLED_P (w->current_matrix, |
| 4403 | w->current_matrix->nrows - 1, false); | 4472 | w->current_matrix->nrows - 1, false); |
| 4404 | 4473 | ||
| 4405 | if (!invisible_rows_marked) | 4474 | /* Was display preempted? */ |
| 4406 | { | 4475 | paused_p = row < end; |
| 4407 | /* If we didn't mark the invisible rows in the current | 4476 | |
| 4408 | matrix as invalid above, do that now. This can happen if | 4477 | if (!paused_p && !invisible_rows_marked) |
| 4409 | scrolling_window updates the last visible rows of the | ||
| 4410 | current matrix, in which case the above loop doesn't get | ||
| 4411 | to examine the last visible row. */ | ||
| 4412 | int i; | ||
| 4413 | for (i = 0; i < w->current_matrix->nrows - 1; ++i) | ||
| 4414 | { | 4478 | { |
| 4415 | struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, i); | 4479 | /* If we didn't mark the invisible rows in the current |
| 4416 | if (current_row->enabled_p | 4480 | matrix as invalid above, do that now. This can happen if |
| 4417 | && MATRIX_ROW_BOTTOM_Y (current_row) >= yb) | 4481 | scrolling_window updates the last visible rows of the |
| 4482 | current matrix, in which case the above loop doesn't get | ||
| 4483 | to examine the last visible row. */ | ||
| 4484 | int i; | ||
| 4485 | for (i = 0; i < w->current_matrix->nrows - 1; ++i) | ||
| 4418 | { | 4486 | { |
| 4419 | for (++i ; i < w->current_matrix->nrows - 1; ++i) | 4487 | struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, i); |
| 4420 | SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false); | 4488 | if (current_row->enabled_p |
| 4489 | && MATRIX_ROW_BOTTOM_Y (current_row) >= yb) | ||
| 4490 | { | ||
| 4491 | for (++i ; i < w->current_matrix->nrows - 1; ++i) | ||
| 4492 | SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false); | ||
| 4493 | } | ||
| 4421 | } | 4494 | } |
| 4422 | } | 4495 | } |
| 4423 | } | ||
| 4424 | 4496 | ||
| 4425 | set_cursor: | 4497 | set_cursor: |
| 4426 | 4498 | ||
| 4427 | /* Update the tab line after scrolling because a new tab | 4499 | /* Update the tab line after scrolling because a new tab |
| 4428 | line would otherwise overwrite lines at the top of the window | 4500 | line would otherwise overwrite lines at the top of the window |
| 4429 | that can be scrolled. */ | 4501 | that can be scrolled. */ |
| 4430 | if (tab_line_row && tab_line_row->enabled_p) | 4502 | if (tab_line_row && tab_line_row->enabled_p) |
| 4431 | { | 4503 | { |
| 4432 | tab_line_row->y = 0; | 4504 | tab_line_row->y = 0; |
| 4433 | update_window_line (w, 0, &mouse_face_overwritten_p); | 4505 | update_window_line (w, 0, &mouse_face_overwritten_p); |
| 4434 | } | 4506 | } |
| 4435 | |||
| 4436 | /* Update the header line after scrolling because a new header | ||
| 4437 | line would otherwise overwrite lines at the top of the window | ||
| 4438 | that can be scrolled. */ | ||
| 4439 | if (header_line_row && header_line_row->enabled_p) | ||
| 4440 | { | ||
| 4441 | header_line_row->y = tab_line_row ? CURRENT_TAB_LINE_HEIGHT (w) : 0; | ||
| 4442 | update_window_line (w, tab_line_row ? 1 : 0, &mouse_face_overwritten_p); | ||
| 4443 | } | ||
| 4444 | 4507 | ||
| 4445 | /* Fix the appearance of overlapping/overlapped rows. */ | 4508 | /* Update the header line after scrolling because a new header |
| 4446 | if (!w->pseudo_window_p) | 4509 | line would otherwise overwrite lines at the top of the window |
| 4447 | { | 4510 | that can be scrolled. */ |
| 4448 | #ifdef HAVE_WINDOW_SYSTEM | 4511 | if (header_line_row && header_line_row->enabled_p) |
| 4449 | if (changed_p && rif->fix_overlapping_area) | ||
| 4450 | { | 4512 | { |
| 4451 | redraw_overlapped_rows (w, yb); | 4513 | header_line_row->y = tab_line_row ? CURRENT_TAB_LINE_HEIGHT (w) : 0; |
| 4452 | redraw_overlapping_rows (w, yb); | 4514 | update_window_line (w, tab_line_row ? 1 : 0, &mouse_face_overwritten_p); |
| 4453 | } | 4515 | } |
| 4516 | |||
| 4517 | /* Fix the appearance of overlapping/overlapped rows. */ | ||
| 4518 | if (!paused_p && !w->pseudo_window_p) | ||
| 4519 | { | ||
| 4520 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 4521 | if (changed_p && rif->fix_overlapping_area) | ||
| 4522 | { | ||
| 4523 | redraw_overlapped_rows (w, yb); | ||
| 4524 | redraw_overlapping_rows (w, yb); | ||
| 4525 | } | ||
| 4454 | #endif | 4526 | #endif |
| 4455 | 4527 | ||
| 4456 | /* Make cursor visible at cursor position of W. */ | 4528 | /* Make cursor visible at cursor position of W. */ |
| 4457 | set_window_cursor_after_update (w); | 4529 | set_window_cursor_after_update (w); |
| 4458 | 4530 | ||
| 4459 | #if 0 /* Check that current matrix invariants are satisfied. This is | 4531 | #if 0 /* Check that current matrix invariants are satisfied. This is |
| 4460 | for debugging only. See the comment of check_matrix_invariants. */ | 4532 | for debugging only. See the comment of check_matrix_invariants. */ |
| 4461 | IF_DEBUG (check_matrix_invariants (w)); | 4533 | IF_DEBUG (check_matrix_invariants (w)); |
| 4462 | #endif | 4534 | #endif |
| 4463 | } | 4535 | } |
| 4464 | 4536 | ||
| 4465 | #ifdef GLYPH_DEBUG | 4537 | #ifdef GLYPH_DEBUG |
| 4466 | /* Remember the redisplay method used to display the matrix. */ | 4538 | /* Remember the redisplay method used to display the matrix. */ |
| 4467 | strcpy (w->current_matrix->method, w->desired_matrix->method); | 4539 | strcpy (w->current_matrix->method, w->desired_matrix->method); |
| 4468 | #endif | 4540 | #endif |
| 4469 | 4541 | ||
| 4470 | #ifdef HAVE_WINDOW_SYSTEM | 4542 | #ifdef HAVE_WINDOW_SYSTEM |
| 4471 | update_window_fringes (w, 0); | 4543 | update_window_fringes (w, 0); |
| 4472 | 4544 | ||
| 4473 | /* End the update of window W. Don't set the cursor if we | 4545 | /* End the update of window W. Don't set the cursor if we |
| 4474 | paused updating the display because in this case, | 4546 | paused updating the display because in this case, |
| 4475 | set_window_cursor_after_update hasn't been called, and | 4547 | set_window_cursor_after_update hasn't been called, and |
| 4476 | W->output_cursor doesn't contain the cursor location. */ | 4548 | W->output_cursor doesn't contain the cursor location. */ |
| 4477 | gui_update_window_end (w, true, mouse_face_overwritten_p); | 4549 | gui_update_window_end (w, !paused_p, mouse_face_overwritten_p); |
| 4478 | #endif | 4550 | #endif |
| 4479 | /* If the update wasn't interrupted, this window has been | 4551 | /* If the update wasn't interrupted, this window has been |
| 4480 | completely updated. */ | 4552 | completely updated. */ |
| 4481 | w->must_be_updated_p = false; | 4553 | if (!paused_p) |
| 4554 | w->must_be_updated_p = false; | ||
| 4555 | } | ||
| 4556 | else | ||
| 4557 | paused_p = 1; | ||
| 4482 | 4558 | ||
| 4483 | #ifdef GLYPH_DEBUG | 4559 | #ifdef GLYPH_DEBUG |
| 4484 | /* check_current_matrix_flags (w); */ | 4560 | /* check_current_matrix_flags (w); */ |
| 4485 | add_window_display_history (w, w->current_matrix->method); | 4561 | add_window_display_history (w, w->current_matrix->method, paused_p); |
| 4486 | #endif | 4562 | #endif |
| 4487 | 4563 | ||
| 4488 | xwidget_end_redisplay (w, w->current_matrix); | 4564 | xwidget_end_redisplay (w, w->current_matrix); |
| 4489 | clear_glyph_matrix (desired_matrix); | 4565 | clear_glyph_matrix (desired_matrix); |
| 4566 | |||
| 4567 | return paused_p; | ||
| 4490 | } | 4568 | } |
| 4491 | 4569 | ||
| 4492 | #ifdef HAVE_WINDOW_SYSTEM | 4570 | #ifdef HAVE_WINDOW_SYSTEM |
| @@ -5619,13 +5697,20 @@ tty_set_cursor (void) | |||
| 5619 | } | 5697 | } |
| 5620 | 5698 | ||
| 5621 | /* Write desired matix of tty frame F and make it current. | 5699 | /* Write desired matix of tty frame F and make it current. |
| 5700 | |||
| 5701 | FORCE_P means that the update should not be stopped by pending input. | ||
| 5622 | INHIBIT_ID_P means that scrolling by insert/delete should not be tried. | 5702 | INHIBIT_ID_P means that scrolling by insert/delete should not be tried. |
| 5623 | SET_CURSOR_P false means do not set cursor at point in selected window. */ | 5703 | SET_CURSOR_P false means do not set cursor at point in selected window. |
| 5624 | 5704 | ||
| 5625 | static void | 5705 | Value is true if update was stopped due to pending input. */ |
| 5626 | write_matrix (struct frame *f, bool inhibit_id_p, | 5706 | |
| 5707 | static bool | ||
| 5708 | write_matrix (struct frame *f, bool force_p, bool inhibit_id_p, | ||
| 5627 | bool set_cursor_p, bool updating_menu_p) | 5709 | bool set_cursor_p, bool updating_menu_p) |
| 5628 | { | 5710 | { |
| 5711 | if (!force_p && detect_input_pending_ignore_squeezables ()) | ||
| 5712 | return true; | ||
| 5713 | |||
| 5629 | /* If we cannot insert/delete lines, it's no use trying it. */ | 5714 | /* If we cannot insert/delete lines, it's no use trying it. */ |
| 5630 | if (!FRAME_LINE_INS_DEL_OK (f)) | 5715 | if (!FRAME_LINE_INS_DEL_OK (f)) |
| 5631 | inhibit_id_p = true; | 5716 | inhibit_id_p = true; |
| @@ -5637,7 +5722,7 @@ write_matrix (struct frame *f, bool inhibit_id_p, | |||
| 5637 | i/d line if just want cursor motion. */ | 5722 | i/d line if just want cursor motion. */ |
| 5638 | int first_row = first_enabled_row (f->desired_matrix); | 5723 | int first_row = first_enabled_row (f->desired_matrix); |
| 5639 | if (!inhibit_id_p && first_row >= 0) | 5724 | if (!inhibit_id_p && first_row >= 0) |
| 5640 | scrolling (f); | 5725 | force_p |= scrolling (f); |
| 5641 | 5726 | ||
| 5642 | /* Update the individual lines as needed. Do bottom line first. This | 5727 | /* Update the individual lines as needed. Do bottom line first. This |
| 5643 | is done so that messages are made visible when pausing. */ | 5728 | is done so that messages are made visible when pausing. */ |
| @@ -5645,19 +5730,36 @@ write_matrix (struct frame *f, bool inhibit_id_p, | |||
| 5645 | if (MATRIX_ROW_ENABLED_P (f->desired_matrix, last_row)) | 5730 | if (MATRIX_ROW_ENABLED_P (f->desired_matrix, last_row)) |
| 5646 | write_row (f, last_row, updating_menu_p); | 5731 | write_row (f, last_row, updating_menu_p); |
| 5647 | 5732 | ||
| 5733 | bool pause_p = false; | ||
| 5648 | if (first_row >= 0) | 5734 | if (first_row >= 0) |
| 5649 | for (int i = first_row; i < last_row; ++i) | 5735 | { |
| 5650 | if (MATRIX_ROW_ENABLED_P (f->desired_matrix, i)) | 5736 | const int preempt_count = clip_to_bounds (1, baud_rate / 2400 + 1, INT_MAX); |
| 5651 | write_row (f, i, updating_menu_p); | 5737 | |
| 5738 | for (int i = first_row, n = 0; i < last_row; ++i) | ||
| 5739 | if (MATRIX_ROW_ENABLED_P (f->desired_matrix, i)) | ||
| 5740 | { | ||
| 5741 | if (!force_p && n % preempt_count == 0 | ||
| 5742 | && detect_input_pending_ignore_squeezables ()) | ||
| 5743 | { | ||
| 5744 | pause_p = true; | ||
| 5745 | break; | ||
| 5746 | } | ||
| 5747 | |||
| 5748 | write_row (f, i, updating_menu_p); | ||
| 5749 | ++n; | ||
| 5750 | } | ||
| 5751 | } | ||
| 5652 | 5752 | ||
| 5653 | /* Now just clean up termcap drivers and set cursor, etc. */ | 5753 | /* Now just clean up termcap drivers and set cursor, etc. */ |
| 5654 | if (set_cursor_p) | 5754 | if (!pause_p && set_cursor_p) |
| 5655 | tty_set_cursor (); | 5755 | tty_set_cursor (); |
| 5756 | |||
| 5757 | return pause_p; | ||
| 5656 | } | 5758 | } |
| 5657 | 5759 | ||
| 5658 | /* Do line insertions/deletions on frame F for frame-based redisplay. */ | 5760 | /* Do line insertions/deletions on frame F for frame-based redisplay. */ |
| 5659 | 5761 | ||
| 5660 | static void | 5762 | static bool |
| 5661 | scrolling (struct frame *frame) | 5763 | scrolling (struct frame *frame) |
| 5662 | { | 5764 | { |
| 5663 | /* In fact this code should never be reached at all under | 5765 | /* In fact this code should never be reached at all under |
| @@ -5694,7 +5796,7 @@ scrolling (struct frame *frame) | |||
| 5694 | if (!MATRIX_ROW_ENABLED_P (current_matrix, i)) | 5796 | if (!MATRIX_ROW_ENABLED_P (current_matrix, i)) |
| 5695 | { | 5797 | { |
| 5696 | SAFE_FREE (); | 5798 | SAFE_FREE (); |
| 5697 | return; | 5799 | return false; |
| 5698 | } | 5800 | } |
| 5699 | old_hash[i] = line_hash_code (frame, MATRIX_ROW (current_matrix, i)); | 5801 | old_hash[i] = line_hash_code (frame, MATRIX_ROW (current_matrix, i)); |
| 5700 | if (! MATRIX_ROW_ENABLED_P (desired_matrix, i)) | 5802 | if (! MATRIX_ROW_ENABLED_P (desired_matrix, i)) |
| @@ -5725,7 +5827,7 @@ scrolling (struct frame *frame) | |||
| 5725 | || unchanged_at_bottom == height) | 5827 | || unchanged_at_bottom == height) |
| 5726 | { | 5828 | { |
| 5727 | SAFE_FREE (); | 5829 | SAFE_FREE (); |
| 5728 | return; | 5830 | return true; |
| 5729 | } | 5831 | } |
| 5730 | 5832 | ||
| 5731 | window_size = (height - unchanged_at_top | 5833 | window_size = (height - unchanged_at_top |
| @@ -5755,6 +5857,7 @@ scrolling (struct frame *frame) | |||
| 5755 | 5857 | ||
| 5756 | SAFE_FREE (); | 5858 | SAFE_FREE (); |
| 5757 | #endif | 5859 | #endif |
| 5860 | return false; | ||
| 5758 | } | 5861 | } |
| 5759 | 5862 | ||
| 5760 | 5863 | ||
| @@ -6886,18 +6989,27 @@ sit_for (Lisp_Object timeout, bool reading, int display_option) | |||
| 6886 | 6989 | ||
| 6887 | 6990 | ||
| 6888 | DEFUN ("redisplay", Fredisplay, Sredisplay, 0, 1, 0, | 6991 | DEFUN ("redisplay", Fredisplay, Sredisplay, 0, 1, 0, |
| 6889 | doc : /* Perform redisplay. | 6992 | doc: /* Perform redisplay. |
| 6890 | Optional arg FORCE exists for historical reasons and is ignored. | 6993 | Optional arg FORCE, if non-nil, prevents redisplay from being |
| 6891 | Value is t if redisplay has been performed, nil if executing a | 6994 | preempted by arriving input, even if `redisplay-dont-pause' is nil. |
| 6892 | keyboard macro. */) | 6995 | If `redisplay-dont-pause' is non-nil (the default), redisplay is never |
| 6996 | preempted by arriving input, so FORCE does nothing. | ||
| 6997 | |||
| 6998 | Return t if redisplay was performed, nil if redisplay was preempted | ||
| 6999 | immediately by pending input. */) | ||
| 6893 | (Lisp_Object force) | 7000 | (Lisp_Object force) |
| 6894 | { | 7001 | { |
| 6895 | swallow_events (true); | 7002 | swallow_events (true); |
| 6896 | if (!NILP (Vexecuting_kbd_macro)) | 7003 | if ((detect_input_pending_run_timers (1) |
| 7004 | && NILP (force) && !redisplay_dont_pause) | ||
| 7005 | || !NILP (Vexecuting_kbd_macro)) | ||
| 6897 | return Qnil; | 7006 | return Qnil; |
| 6898 | 7007 | ||
| 7008 | specpdl_ref count = SPECPDL_INDEX (); | ||
| 7009 | if (!NILP (force) && !redisplay_dont_pause) | ||
| 7010 | specbind (Qredisplay_dont_pause, Qt); | ||
| 6899 | redisplay_preserve_echo_area (2); | 7011 | redisplay_preserve_echo_area (2); |
| 6900 | return Qt; | 7012 | return unbind_to (count, Qt); |
| 6901 | } | 7013 | } |
| 6902 | 7014 | ||
| 6903 | 7015 | ||
| @@ -7350,6 +7462,8 @@ syms_of_display (void) | |||
| 7350 | /* This is the "purpose" slot of a display table. */ | 7462 | /* This is the "purpose" slot of a display table. */ |
| 7351 | DEFSYM (Qdisplay_table, "display-table"); | 7463 | DEFSYM (Qdisplay_table, "display-table"); |
| 7352 | DEFSYM (Qframe__z_order_lessp, "frame--z-order-lessp"); | 7464 | DEFSYM (Qframe__z_order_lessp, "frame--z-order-lessp"); |
| 7465 | |||
| 7466 | DEFSYM (Qredisplay_dont_pause, "redisplay-dont-pause"); | ||
| 7353 | DEFSYM (Qtty_non_selected_cursor, "tty-non-selected-cursor"); | 7467 | DEFSYM (Qtty_non_selected_cursor, "tty-non-selected-cursor"); |
| 7354 | 7468 | ||
| 7355 | DEFVAR_INT ("baud-rate", baud_rate, | 7469 | DEFVAR_INT ("baud-rate", baud_rate, |
| @@ -7431,6 +7545,17 @@ It is also used for standard output and error streams. | |||
| 7431 | See `buffer-display-table' for more information. */); | 7545 | See `buffer-display-table' for more information. */); |
| 7432 | Vstandard_display_table = Qnil; | 7546 | Vstandard_display_table = Qnil; |
| 7433 | 7547 | ||
| 7548 | DEFVAR_BOOL ("redisplay-dont-pause", redisplay_dont_pause, | ||
| 7549 | doc: /* Nil means display update is paused when input is detected. */); | ||
| 7550 | /* Contrary to expectations, a value of "false" can be detrimental to | ||
| 7551 | responsiveness since aborting a redisplay throws away some of the | ||
| 7552 | work already performed. It's usually more efficient (and gives | ||
| 7553 | more prompt feedback to the user) to let the redisplay terminate, | ||
| 7554 | and just completely skip the next command's redisplay (which is | ||
| 7555 | done regardless of this setting if there's pending input at the | ||
| 7556 | beginning of the next redisplay). */ | ||
| 7557 | redisplay_dont_pause = true; | ||
| 7558 | |||
| 7434 | DEFVAR_LISP ("x-show-tooltip-timeout", Vx_show_tooltip_timeout, | 7559 | DEFVAR_LISP ("x-show-tooltip-timeout", Vx_show_tooltip_timeout, |
| 7435 | doc: /* The default timeout (in seconds) for `x-show-tip'. */); | 7560 | doc: /* The default timeout (in seconds) for `x-show-tip'. */); |
| 7436 | Vx_show_tooltip_timeout = make_fixnum (5); | 7561 | Vx_show_tooltip_timeout = make_fixnum (5); |
diff --git a/src/keyboard.c b/src/keyboard.c index fe485a3efd6..bfb5fd3592b 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -2663,7 +2663,8 @@ read_char (int commandflag, Lisp_Object map, | |||
| 2663 | swallow_events (false); /* May clear input_pending. */ | 2663 | swallow_events (false); /* May clear input_pending. */ |
| 2664 | 2664 | ||
| 2665 | /* Redisplay if no pending input. */ | 2665 | /* Redisplay if no pending input. */ |
| 2666 | while (!(input_pending && input_was_pending)) | 2666 | while (!(input_pending |
| 2667 | && (input_was_pending || !redisplay_dont_pause))) | ||
| 2667 | { | 2668 | { |
| 2668 | input_was_pending = input_pending; | 2669 | input_was_pending = input_pending; |
| 2669 | if (help_echo_showing_p && !BASE_EQ (selected_window, minibuf_window)) | 2670 | if (help_echo_showing_p && !BASE_EQ (selected_window, minibuf_window)) |
diff --git a/src/minibuf.c b/src/minibuf.c index 390db0d31fa..c8267045397 100644 --- a/src/minibuf.c +++ b/src/minibuf.c | |||
| @@ -914,9 +914,9 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, | |||
| 914 | XWINDOW (minibuf_window)->cursor.x = 0; | 914 | XWINDOW (minibuf_window)->cursor.x = 0; |
| 915 | XWINDOW (minibuf_window)->must_be_updated_p = true; | 915 | XWINDOW (minibuf_window)->must_be_updated_p = true; |
| 916 | struct frame *sf = XFRAME (selected_frame); | 916 | struct frame *sf = XFRAME (selected_frame); |
| 917 | update_frame (sf, true); | 917 | update_frame (sf, true, true); |
| 918 | if (is_tty_frame (sf)) | 918 | if (is_tty_frame (sf)) |
| 919 | combine_updates_for_frame (sf, true); | 919 | combine_updates_for_frame (sf, true, true); |
| 920 | 920 | ||
| 921 | #ifndef HAVE_NTGUI | 921 | #ifndef HAVE_NTGUI |
| 922 | flush_frame (XFRAME (XWINDOW (minibuf_window)->frame)); | 922 | flush_frame (XFRAME (XWINDOW (minibuf_window)->frame)); |
diff --git a/src/xdisp.c b/src/xdisp.c index 3364c6870cf..8196d1236ba 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -1116,6 +1116,7 @@ static void set_iterator_to_next (struct it *, bool); | |||
| 1116 | static void mark_window_display_accurate_1 (struct window *, bool); | 1116 | static void mark_window_display_accurate_1 (struct window *, bool); |
| 1117 | static bool row_for_charpos_p (struct glyph_row *, ptrdiff_t); | 1117 | static bool row_for_charpos_p (struct glyph_row *, ptrdiff_t); |
| 1118 | static bool cursor_row_p (struct glyph_row *); | 1118 | static bool cursor_row_p (struct glyph_row *); |
| 1119 | static int redisplay_mode_lines (Lisp_Object, bool); | ||
| 1119 | 1120 | ||
| 1120 | static void handle_line_prefix (struct it *); | 1121 | static void handle_line_prefix (struct it *); |
| 1121 | 1122 | ||
| @@ -13510,6 +13511,24 @@ echo_area_display (bool update_frame_p) | |||
| 13510 | here could cause confusion. */ | 13511 | here could cause confusion. */ |
| 13511 | if (update_frame_p && !redisplaying_p) | 13512 | if (update_frame_p && !redisplaying_p) |
| 13512 | { | 13513 | { |
| 13514 | int n = 0; | ||
| 13515 | |||
| 13516 | /* If the display update has been interrupted by pending | ||
| 13517 | input, update mode lines in the frame. Due to the | ||
| 13518 | pending input, it might have been that redisplay hasn't | ||
| 13519 | been called, so that mode lines above the echo area are | ||
| 13520 | garbaged. This looks odd, so we prevent it here. */ | ||
| 13521 | if (!display_completed) | ||
| 13522 | { | ||
| 13523 | n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), false); | ||
| 13524 | |||
| 13525 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 13526 | if (FRAME_WINDOW_P (f) | ||
| 13527 | && FRAME_RIF (f)->clear_under_internal_border) | ||
| 13528 | FRAME_RIF (f)->clear_under_internal_border (f); | ||
| 13529 | #endif | ||
| 13530 | } | ||
| 13531 | |||
| 13513 | if (window_height_changed_p | 13532 | if (window_height_changed_p |
| 13514 | /* Don't do this if Emacs is shutting down. Redisplay | 13533 | /* Don't do this if Emacs is shutting down. Redisplay |
| 13515 | needs to run hooks. */ | 13534 | needs to run hooks. */ |
| @@ -13518,10 +13537,13 @@ echo_area_display (bool update_frame_p) | |||
| 13518 | /* Must update other windows. Likewise as in other | 13537 | /* Must update other windows. Likewise as in other |
| 13519 | cases, don't let this update be interrupted by | 13538 | cases, don't let this update be interrupted by |
| 13520 | pending input. */ | 13539 | pending input. */ |
| 13540 | specpdl_ref count = SPECPDL_INDEX (); | ||
| 13541 | specbind (Qredisplay_dont_pause, Qt); | ||
| 13521 | fset_redisplay (f); | 13542 | fset_redisplay (f); |
| 13522 | redisplay_internal (); | 13543 | redisplay_internal (); |
| 13544 | unbind_to (count, Qnil); | ||
| 13523 | } | 13545 | } |
| 13524 | else if (FRAME_WINDOW_P (f)) | 13546 | else if (FRAME_WINDOW_P (f) && n == 0) |
| 13525 | { | 13547 | { |
| 13526 | /* Window configuration is the same as before. | 13548 | /* Window configuration is the same as before. |
| 13527 | Can do with a display update of the echo area, | 13549 | Can do with a display update of the echo area, |
| @@ -13531,9 +13553,9 @@ echo_area_display (bool update_frame_p) | |||
| 13531 | } | 13553 | } |
| 13532 | else | 13554 | else |
| 13533 | { | 13555 | { |
| 13534 | update_frame (f, true); | 13556 | update_frame (f, true, true); |
| 13535 | if (is_tty_frame (f)) | 13557 | if (is_tty_frame (f)) |
| 13536 | combine_updates_for_frame (f, true); | 13558 | combine_updates_for_frame (f, true, true); |
| 13537 | } | 13559 | } |
| 13538 | 13560 | ||
| 13539 | /* If cursor is in the echo area, make sure that the next | 13561 | /* If cursor is in the echo area, make sure that the next |
| @@ -16916,6 +16938,7 @@ redisplay_internal (void) | |||
| 16916 | struct window *w = XWINDOW (selected_window); | 16938 | struct window *w = XWINDOW (selected_window); |
| 16917 | struct window *sw; | 16939 | struct window *sw; |
| 16918 | struct frame *fr; | 16940 | struct frame *fr; |
| 16941 | bool pending; | ||
| 16919 | bool must_finish = false, match_p; | 16942 | bool must_finish = false, match_p; |
| 16920 | struct text_pos tlbufpos, tlendpos; | 16943 | struct text_pos tlbufpos, tlendpos; |
| 16921 | int number_of_visible_frames; | 16944 | int number_of_visible_frames; |
| @@ -17001,6 +17024,7 @@ redisplay_internal (void) | |||
| 17001 | /* Remember the currently selected window. */ | 17024 | /* Remember the currently selected window. */ |
| 17002 | sw = w; | 17025 | sw = w; |
| 17003 | 17026 | ||
| 17027 | pending = false; | ||
| 17004 | forget_escape_and_glyphless_faces (); | 17028 | forget_escape_and_glyphless_faces (); |
| 17005 | 17029 | ||
| 17006 | inhibit_free_realized_faces = false; | 17030 | inhibit_free_realized_faces = false; |
| @@ -17566,7 +17590,7 @@ redisplay_internal (void) | |||
| 17566 | unrequest_sigio (); | 17590 | unrequest_sigio (); |
| 17567 | STOP_POLLING; | 17591 | STOP_POLLING; |
| 17568 | 17592 | ||
| 17569 | update_frame (f, false); | 17593 | pending |= update_frame (f, false, false); |
| 17570 | /* On some platforms (at least MS-Windows), the | 17594 | /* On some platforms (at least MS-Windows), the |
| 17571 | scroll_run_hook called from scrolling_window | 17595 | scroll_run_hook called from scrolling_window |
| 17572 | called from update_frame could set the frame's | 17596 | called from update_frame could set the frame's |
| @@ -17588,24 +17612,27 @@ redisplay_internal (void) | |||
| 17588 | } | 17612 | } |
| 17589 | 17613 | ||
| 17590 | if (CONSP (tty_root_frames)) | 17614 | if (CONSP (tty_root_frames)) |
| 17591 | combine_updates (tty_root_frames, false); | 17615 | pending |= combine_updates (tty_root_frames, false, false); |
| 17592 | 17616 | ||
| 17593 | eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window)); | 17617 | eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window)); |
| 17594 | 17618 | ||
| 17595 | /* Do the mark_window_display_accurate after all windows have | 17619 | if (!pending) |
| 17596 | been redisplayed because this call resets flags in buffers | ||
| 17597 | which are needed for proper redisplay. */ | ||
| 17598 | FOR_EACH_FRAME (tail, frame) | ||
| 17599 | { | 17620 | { |
| 17600 | struct frame *f = XFRAME (frame); | 17621 | /* Do the mark_window_display_accurate after all windows have |
| 17601 | if (f->updated_p) | 17622 | been redisplayed because this call resets flags in buffers |
| 17602 | { | 17623 | which are needed for proper redisplay. */ |
| 17603 | f->redisplay = false; | 17624 | FOR_EACH_FRAME (tail, frame) |
| 17604 | f->garbaged = false; | 17625 | { |
| 17605 | mark_window_display_accurate (f->root_window, true); | 17626 | struct frame *f = XFRAME (frame); |
| 17606 | if (FRAME_TERMINAL (f)->frame_up_to_date_hook) | 17627 | if (f->updated_p) |
| 17607 | FRAME_TERMINAL (f)->frame_up_to_date_hook (f); | 17628 | { |
| 17608 | } | 17629 | f->redisplay = false; |
| 17630 | f->garbaged = false; | ||
| 17631 | mark_window_display_accurate (f->root_window, true); | ||
| 17632 | if (FRAME_TERMINAL (f)->frame_up_to_date_hook) | ||
| 17633 | FRAME_TERMINAL (f)->frame_up_to_date_hook (f); | ||
| 17634 | } | ||
| 17635 | } | ||
| 17609 | } | 17636 | } |
| 17610 | } | 17637 | } |
| 17611 | else if (FRAME_REDISPLAY_P (sf)) | 17638 | else if (FRAME_REDISPLAY_P (sf)) |
| @@ -17669,10 +17696,10 @@ redisplay_internal (void) | |||
| 17669 | } | 17696 | } |
| 17670 | 17697 | ||
| 17671 | XWINDOW (selected_window)->must_be_updated_p = true; | 17698 | XWINDOW (selected_window)->must_be_updated_p = true; |
| 17672 | update_frame (sf, false); | 17699 | pending = update_frame (sf, false, false); |
| 17673 | 17700 | ||
| 17674 | if (is_tty_frame (sf)) | 17701 | if (is_tty_frame (sf)) |
| 17675 | combine_updates_for_frame (sf, false); | 17702 | pending |= combine_updates_for_frame (sf, false, false); |
| 17676 | 17703 | ||
| 17677 | sf->cursor_type_changed = false; | 17704 | sf->cursor_type_changed = false; |
| 17678 | sf->inhibit_clear_image_cache = false; | 17705 | sf->inhibit_clear_image_cache = false; |
| @@ -17689,11 +17716,11 @@ redisplay_internal (void) | |||
| 17689 | if (mini_frame != sf) | 17716 | if (mini_frame != sf) |
| 17690 | { | 17717 | { |
| 17691 | XWINDOW (mini_window)->must_be_updated_p = true; | 17718 | XWINDOW (mini_window)->must_be_updated_p = true; |
| 17692 | update_frame (mini_frame, false); | 17719 | pending |= update_frame (mini_frame, false, false); |
| 17693 | if (is_tty_frame (mini_frame)) | 17720 | if (is_tty_frame (mini_frame)) |
| 17694 | combine_updates_for_frame (mini_frame, false); | 17721 | pending |= combine_updates_for_frame (mini_frame, false, false); |
| 17695 | mini_frame->cursor_type_changed = false; | 17722 | mini_frame->cursor_type_changed = false; |
| 17696 | if (hscroll_retries <= MAX_HSCROLL_RETRIES | 17723 | if (!pending && hscroll_retries <= MAX_HSCROLL_RETRIES |
| 17697 | && hscroll_windows (mini_window)) | 17724 | && hscroll_windows (mini_window)) |
| 17698 | { | 17725 | { |
| 17699 | hscroll_retries++; | 17726 | hscroll_retries++; |
| @@ -17702,26 +17729,47 @@ redisplay_internal (void) | |||
| 17702 | } | 17729 | } |
| 17703 | } | 17730 | } |
| 17704 | 17731 | ||
| 17705 | if (!consider_all_windows_p) | 17732 | /* If display was paused because of pending input, make sure we do a |
| 17733 | thorough update the next time. */ | ||
| 17734 | if (pending) | ||
| 17706 | { | 17735 | { |
| 17707 | /* This has already been done above if | 17736 | /* Prevent the optimization at the beginning of |
| 17708 | consider_all_windows_p is set. */ | 17737 | redisplay_internal that tries a single-line update of the |
| 17709 | if (XBUFFER (w->contents)->text->redisplay | 17738 | line containing the cursor in the selected window. */ |
| 17710 | && buffer_window_count (XBUFFER (w->contents)) > 1) | 17739 | CHARPOS (this_line_start_pos) = 0; |
| 17711 | /* This can happen if b->text->redisplay was set during | ||
| 17712 | jit-lock. */ | ||
| 17713 | propagate_buffer_redisplay (); | ||
| 17714 | mark_window_display_accurate_1 (w, true); | ||
| 17715 | 17740 | ||
| 17716 | /* Say overlay arrows are up to date. */ | 17741 | /* Let the overlay arrow be updated the next time. */ |
| 17717 | update_overlay_arrows (1); | 17742 | update_overlay_arrows (0); |
| 17718 | 17743 | ||
| 17719 | if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0) | 17744 | /* If we pause after scrolling, some rows in the current |
| 17720 | FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf); | 17745 | matrices of some windows are not valid. */ |
| 17746 | if (!WINDOW_FULL_WIDTH_P (w) | ||
| 17747 | && !FRAME_WINDOW_P (XFRAME (w->frame))) | ||
| 17748 | update_mode_lines = 36; | ||
| 17721 | } | 17749 | } |
| 17750 | else | ||
| 17751 | { | ||
| 17752 | if (!consider_all_windows_p) | ||
| 17753 | { | ||
| 17754 | /* This has already been done above if | ||
| 17755 | consider_all_windows_p is set. */ | ||
| 17756 | if (XBUFFER (w->contents)->text->redisplay | ||
| 17757 | && buffer_window_count (XBUFFER (w->contents)) > 1) | ||
| 17758 | /* This can happen if b->text->redisplay was set during | ||
| 17759 | jit-lock. */ | ||
| 17760 | propagate_buffer_redisplay (); | ||
| 17761 | mark_window_display_accurate_1 (w, true); | ||
| 17722 | 17762 | ||
| 17723 | update_mode_lines = 0; | 17763 | /* Say overlay arrows are up to date. */ |
| 17724 | windows_or_buffers_changed = 0; | 17764 | update_overlay_arrows (1); |
| 17765 | |||
| 17766 | if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0) | ||
| 17767 | FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf); | ||
| 17768 | } | ||
| 17769 | |||
| 17770 | update_mode_lines = 0; | ||
| 17771 | windows_or_buffers_changed = 0; | ||
| 17772 | } | ||
| 17725 | 17773 | ||
| 17726 | /* Start SIGIO interrupts coming again. Having them off during the | 17774 | /* Start SIGIO interrupts coming again. Having them off during the |
| 17727 | code above makes it less likely one will discard output, but not | 17775 | code above makes it less likely one will discard output, but not |
| @@ -17737,23 +17785,26 @@ redisplay_internal (void) | |||
| 17737 | redisplay constructing glyphs, so simply exposing a frame won't | 17785 | redisplay constructing glyphs, so simply exposing a frame won't |
| 17738 | display anything in this case. So, we have to display these | 17786 | display anything in this case. So, we have to display these |
| 17739 | frames here explicitly. */ | 17787 | frames here explicitly. */ |
| 17740 | int new_count = 0; | 17788 | if (!pending) |
| 17741 | |||
| 17742 | FOR_EACH_FRAME (tail, frame) | ||
| 17743 | { | 17789 | { |
| 17744 | if (FRAME_REDISPLAY_P (XFRAME (frame))) | 17790 | int new_count = 0; |
| 17745 | new_count++; | 17791 | |
| 17746 | } | 17792 | FOR_EACH_FRAME (tail, frame) |
| 17793 | { | ||
| 17794 | if (FRAME_REDISPLAY_P (XFRAME (frame))) | ||
| 17795 | new_count++; | ||
| 17796 | } | ||
| 17747 | 17797 | ||
| 17748 | if (new_count != number_of_visible_frames) | 17798 | if (new_count != number_of_visible_frames) |
| 17749 | windows_or_buffers_changed = 52; | 17799 | windows_or_buffers_changed = 52; |
| 17800 | } | ||
| 17750 | 17801 | ||
| 17751 | /* Change frame size now if a change is pending. */ | 17802 | /* Change frame size now if a change is pending. */ |
| 17752 | do_pending_window_change (true); | 17803 | do_pending_window_change (true); |
| 17753 | 17804 | ||
| 17754 | /* If we just did a pending size change, or have additional | 17805 | /* If we just did a pending size change, or have additional |
| 17755 | visible frames, or selected_window changed, redisplay again. */ | 17806 | visible frames, or selected_window changed, redisplay again. */ |
| 17756 | if (windows_or_buffers_changed | 17807 | if ((windows_or_buffers_changed && !pending) |
| 17757 | || (WINDOWP (selected_window) | 17808 | || (WINDOWP (selected_window) |
| 17758 | && (w = XWINDOW (selected_window)) != sw)) | 17809 | && (w = XWINDOW (selected_window)) != sw)) |
| 17759 | goto retry; | 17810 | goto retry; |
| @@ -27343,6 +27394,60 @@ display_tty_menu_item (const char *item_text, int width, int face_id, | |||
| 27343 | Mode Line | 27394 | Mode Line |
| 27344 | ***********************************************************************/ | 27395 | ***********************************************************************/ |
| 27345 | 27396 | ||
| 27397 | /* Redisplay mode lines in the window tree whose root is WINDOW. | ||
| 27398 | If FORCE, redisplay mode lines unconditionally. | ||
| 27399 | Otherwise, redisplay only mode lines that are garbaged. Value is | ||
| 27400 | the number of windows whose mode lines were redisplayed. */ | ||
| 27401 | |||
| 27402 | static int | ||
| 27403 | redisplay_mode_lines (Lisp_Object window, bool force) | ||
| 27404 | { | ||
| 27405 | int nwindows = 0; | ||
| 27406 | |||
| 27407 | while (!NILP (window)) | ||
| 27408 | { | ||
| 27409 | struct window *w = XWINDOW (window); | ||
| 27410 | |||
| 27411 | if (WINDOWP (w->contents)) | ||
| 27412 | nwindows += redisplay_mode_lines (w->contents, force); | ||
| 27413 | else if (force | ||
| 27414 | || FRAME_GARBAGED_P (XFRAME (w->frame)) | ||
| 27415 | || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p) | ||
| 27416 | { | ||
| 27417 | struct text_pos lpoint; | ||
| 27418 | struct buffer *old = current_buffer; | ||
| 27419 | |||
| 27420 | /* Set the window's buffer for the mode line display. */ | ||
| 27421 | SET_TEXT_POS (lpoint, PT, PT_BYTE); | ||
| 27422 | set_buffer_internal_1 (XBUFFER (w->contents)); | ||
| 27423 | |||
| 27424 | /* Point refers normally to the selected window. For any | ||
| 27425 | other window, set up appropriate value. */ | ||
| 27426 | if (!EQ (window, selected_window)) | ||
| 27427 | { | ||
| 27428 | struct text_pos pt; | ||
| 27429 | |||
| 27430 | CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm); | ||
| 27431 | TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt)); | ||
| 27432 | } | ||
| 27433 | |||
| 27434 | /* Display mode lines. */ | ||
| 27435 | clear_glyph_matrix (w->desired_matrix); | ||
| 27436 | if (display_mode_lines (w)) | ||
| 27437 | ++nwindows; | ||
| 27438 | |||
| 27439 | /* Restore old settings. */ | ||
| 27440 | set_buffer_internal_1 (old); | ||
| 27441 | TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint)); | ||
| 27442 | } | ||
| 27443 | |||
| 27444 | window = w->next; | ||
| 27445 | } | ||
| 27446 | |||
| 27447 | return nwindows; | ||
| 27448 | } | ||
| 27449 | |||
| 27450 | |||
| 27346 | /* Display the mode line, the header line, and the tab-line of window | 27451 | /* Display the mode line, the header line, and the tab-line of window |
| 27347 | W. Value is the sum number of mode lines, header lines, and tab | 27452 | W. Value is the sum number of mode lines, header lines, and tab |
| 27348 | lines actually displayed. */ | 27453 | lines actually displayed. */ |