emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 82626e62ab 08/14: Allow aborting redisplay stuck in 'parse-partia


From: Eli Zaretskii
Subject: master 82626e62ab 08/14: Allow aborting redisplay stuck in 'parse-partial-sexp'
Date: Fri, 24 Jun 2022 03:54:18 -0400 (EDT)

branch: master
commit 82626e62ab27b498848e4c1822f6c4c06ad53947
Author: Eli Zaretskii <eliz@gnu.org>
Commit: Eli Zaretskii <eliz@gnu.org>

    Allow aborting redisplay stuck in 'parse-partial-sexp'
    
    * src/xdisp.c (display_working_on_window_p): New global variable.
    (unwind_display_working_on_window): New function.
    * src/keyboard.c (command_loop_1): Reset
    'display_working_on_window_p' before and after executing commands.
    * src/window.c (Frecenter, window_scroll, displayed_window_lines):
    * src/indent.c (Fvertical_motion): Set
    'display_working_on_window_p' before calling 'start_display'.
    * src/syntax.c (scan_sexps_forward): Call 'update_redisplay_ticks'
    after finishing the loop.
---
 src/dispextern.h |  2 ++
 src/indent.c     |  2 ++
 src/keyboard.c   |  2 ++
 src/window.c     | 16 +++++++++++++++-
 src/xdisp.c      | 21 +++++++++++++++++++--
 5 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/src/dispextern.h b/src/dispextern.h
index 0ea3ac8b07..8bcd13dbb6 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3407,6 +3407,8 @@ int partial_line_height (struct it *it_origin);
 bool in_display_vector_p (struct it *);
 int frame_mode_line_height (struct frame *);
 extern bool redisplaying_p;
+extern bool display_working_on_window_p;
+extern void unwind_display_working_on_window (void);
 extern bool help_echo_showing_p;
 extern Lisp_Object help_echo_string, help_echo_window;
 extern Lisp_Object help_echo_object, previous_help_echo_string;
diff --git a/src/indent.c b/src/indent.c
index 51f6f414de..7d9f0fe8b0 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -2177,6 +2177,8 @@ whether or not it is currently displayed in some window.  
*/)
        line_number_display_width (w, &lnum_width, &lnum_pixel_width);
       SET_TEXT_POS (pt, PT, PT_BYTE);
       itdata = bidi_shelve_cache ();
+      record_unwind_protect_void (unwind_display_working_on_window);
+      display_working_on_window_p = true;
       start_display (&it, w, pt);
       it.lnum_width = lnum_width;
       first_x = it.first_visible_x;
diff --git a/src/keyboard.c b/src/keyboard.c
index 7d7dd2dba0..e5a991a8b2 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1505,8 +1505,10 @@ command_loop_1 (void)
               executing the command, so that we don't blame the new
               command for the sins of the previous one.  */
            update_redisplay_ticks (0, NULL);
+           display_working_on_window_p = false;
 
             call1 (Qcommand_execute, Vthis_command);
+           display_working_on_window_p = false;
 
 #ifdef HAVE_WINDOW_SYSTEM
          /* Do not check display_hourglass_p here, because
diff --git a/src/window.c b/src/window.c
index ac8408a9a9..9f0df6619a 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5568,7 +5568,11 @@ window_scroll (Lisp_Object window, EMACS_INT n, bool 
whole, bool noerror)
   /* On GUI frames, use the pixel-based version which is much slower
      than the line-based one but can handle varying line heights.  */
   if (FRAME_WINDOW_P (XFRAME (XWINDOW (window)->frame)))
-    window_scroll_pixel_based (window, n, whole, noerror);
+    {
+      record_unwind_protect_void (unwind_display_working_on_window);
+      display_working_on_window_p = true;
+      window_scroll_pixel_based (window, n, whole, noerror);
+    }
   else
     window_scroll_line_based (window, n, whole, noerror);
 
@@ -6496,9 +6500,14 @@ displayed_window_lines (struct window *w)
   CLIP_TEXT_POS_FROM_MARKER (start, w->start);
 
   itdata = bidi_shelve_cache ();
+
+  specpdl_ref count = SPECPDL_INDEX ();
+  record_unwind_protect_void (unwind_display_working_on_window);
+  display_working_on_window_p = true;
   start_display (&it, w, start);
   move_it_vertically (&it, height);
   bottom_y = line_bottom_y (&it);
+  unbind_to (count, Qnil);
   bidi_unshelve_cache (itdata, false);
 
   /* Add in empty lines at the bottom of the window.  */
@@ -6592,6 +6601,10 @@ and redisplay normally--don't erase and redraw the 
frame.  */)
      data structures might not be set up yet then.  */
   if (!FRAME_INITIAL_P (XFRAME (w->frame)))
     {
+      specpdl_ref count = SPECPDL_INDEX ();
+
+      record_unwind_protect_void (unwind_display_working_on_window);
+      display_working_on_window_p = true;
       if (center_p)
        {
          struct it it;
@@ -6708,6 +6721,7 @@ and redisplay normally--don't erase and redraw the frame. 
 */)
 
          bidi_unshelve_cache (itdata, false);
        }
+      unbind_to (count, Qnil);
     }
   else
     {
diff --git a/src/xdisp.c b/src/xdisp.c
index 1ba9132e8c..1d52bbc6c9 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -1030,6 +1030,15 @@ static struct glyph_slice null_glyph_slice = { 0, 0, 0, 
0 };
 
 bool redisplaying_p;
 
+/* True while some display-engine code is working on layout of some
+   window.
+
+   WARNING: Use sparingly, preferably only in top level of commands
+   and important functions, because using it in nested calls might
+   reset the flag when the inner call returns, behind the back of
+   the callers.  */
+bool display_working_on_window_p;
+
 /* If a string, XTread_socket generates an event to display that string.
    (The display is done in read_char.)  */
 
@@ -10961,6 +10970,7 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object 
from, Lisp_Object to,
     max_y = XFIXNUM (y_limit);
 
   itdata = bidi_shelve_cache ();
+
   start_display (&it, w, startp);
 
   int start_y = it.current_y;
@@ -16970,6 +16980,13 @@ unwind_redisplay (void)
   unblock_buffer_flips ();
 }
 
+/* Function registered with record_unwind_protect before calling
+   start_display outside of redisplay_internal.  */
+void
+unwind_display_working_on_window (void)
+{
+  display_working_on_window_p = false;
+}
 
 /* Mark the display of leaf window W as accurate or inaccurate.
    If ACCURATE_P, mark display of W as accurate.
@@ -17199,9 +17216,9 @@ update_redisplay_ticks (int ticks, struct window *w)
       cwindow = w;
       window_ticks = 0;
     }
-  /* Some callers can be run in contexts unrelated to redisplay, so
+  /* Some callers can be run in contexts unrelated to display code, so
      don't abort them and don't update the tick count in those cases.  */
-  if (!w && !redisplaying_p)
+  if (!w && !redisplaying_p && !display_working_on_window_p)
     return;
 
   if (ticks > 0)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]