From 5c9304ea86b8cfc9d0b6d7769b90bd56e5dd1313 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 30 Sep 2015 22:32:14 +0300 Subject: [PATCH] Disable some display optimizations when frames need redisplay These optimizations were previously disabled by the windows_or_buffers_changed flag, which now is not set when only some frames need to be redrawn. * src/xdisp.c (redisplay_internal): Redisplay any frame whose 'redisplay' flag is set. (try_window_reusing_current_matrix, try_window_id) (try_cursor_movement): Disable these optimizations when the frame's 'redisplay' flag is set. --- lisp/progmodes/gdb-mi.el | 28 ++++++++++++++++++++++++++++ src/xdisp.c | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index 3860c81065d..c0f995935d4 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el @@ -2315,6 +2315,34 @@ the end of the current result or async record is reached." ; list ==> ; "[]" | "[" value ( "," value )* "]" | "[" result ( "," result )* "]" +;; The idea of the following function was suggested +;; by Kenichi Handa . +;; +;; FIXME: This is fragile: it relies on the assumption that all the +;; non-ASCII strings output by GDB, including names of the source +;; files, values of string variables in the inferior, etc., are all +;; encoded in the same encoding. It also assumes that the \nnn +;; sequences are not split between chunks of GDB process output due to +;; buffering, and arrive together. When/if GDB acquires the ability +;; to not escape-protect non-ASCII characters in its MI output, this +;; kludge should be removed. +(defun gdb-mi-decode (string) + "Decode octal escapes in MI output STRING into multibyte text." + (let ((coding + (with-current-buffer + (gdb-get-buffer-create 'gdb-partial-output-buffer) + buffer-file-coding-system))) + (with-temp-buffer + (set-buffer-multibyte nil) + (insert (gdb-mi-quote string)) + (goto-char (point-min)) + ;; gdb-mi-quote quotes the octal escapes as well, which + ;; interferes with their interpretation by 'read' below. Remove + ;; the extra backslashes to countermand that. + (while (re-search-forward "\\\\\\(\\\\[2-3][0-7][0-7]\\)" nil t) + (replace-match "\\1" nil nil)) + (goto-char (point-min)) + (decode-coding-string (read (current-buffer)) coding)))) (defun gud-gdbmi-marker-filter (string) "Filter GDB/MI output." diff --git a/src/xdisp.c b/src/xdisp.c index 259c36373bf..41b84469fe3 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -13336,6 +13336,9 @@ redisplay_internal (void) /* True means redisplay has to redisplay the miniwindow. */ bool update_miniwindow_p = false; + /* True means we need to redraw frames whose 'redisplay' bit is set. */ + bool consider_some_frames_p = false; + TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p)); /* No redisplay if running in batch mode or frame is not yet fully @@ -13555,6 +13558,7 @@ redisplay_internal (void) && !FRAME_OBSCURED_P (XFRAME (w->frame)) && !XFRAME (w->frame)->cursor_type_changed && !XFRAME (w->frame)->face_change + && !XFRAME (w->frame)->redisplay /* Make sure recorded data applies to current buffer, etc. */ && this_line_buffer == current_buffer && match_p @@ -13750,13 +13754,29 @@ redisplay_internal (void) #endif /* Build desired matrices, and update the display. If - consider_all_windows_p, do it for all windows on all frames. - Otherwise do it for selected_window, only. */ + consider_all_windows_p, do it for all windows on all frames. If + a frame's 'redisplay' flag is set, do it for all windows on each + such frame. Otherwise do it for selected_window, only. */ - if (consider_all_windows_p) + if (!consider_all_windows_p) { FOR_EACH_FRAME (tail, frame) - XFRAME (frame)->updated_p = false; + { + if (XFRAME (frame)->redisplay && XFRAME (frame) != sf) + { + consider_some_frames_p = true; + break; + } + } + } + + if (consider_all_windows_p || consider_some_frames_p) + { + FOR_EACH_FRAME (tail, frame) + { + if (XFRAME (frame)->redisplay || consider_all_windows_p) + XFRAME (frame)->updated_p = false; + } propagate_buffer_redisplay (); @@ -13770,6 +13790,9 @@ redisplay_internal (void) && !EQ (FRAME_TTY (f)->top_frame, frame)) continue; + if (!consider_all_windows_p && !f->redisplay) + continue; + retry_frame: if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf) { @@ -15415,6 +15438,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, && !update_mode_lines && !windows_or_buffers_changed && !f->cursor_type_changed + && !f->redisplay && NILP (Vshow_trailing_whitespace) /* This code is not used for mini-buffer for the sake of the case of redisplaying to replace an echo area message; since in @@ -17025,6 +17049,7 @@ try_window_reusing_current_matrix (struct window *w) /* Don't try to reuse the display if windows have been split or such. */ || windows_or_buffers_changed + || f->redisplay || f->cursor_type_changed) return false; @@ -17802,7 +17827,7 @@ try_window_id (struct window *w) GIVE_UP (1); /* This flag is used to prevent redisplay optimizations. */ - if (windows_or_buffers_changed || f->cursor_type_changed) + if (windows_or_buffers_changed || f->cursor_type_changed || f->redisplay) GIVE_UP (2); /* This function's optimizations cannot be used if overlays have -- 2.39.2