From: Po Lu <luangruo@yahoo.com>
Date: Fri, 23 Sep 2022 12:41:24 +0000 (+0800)
Subject: Fix more toolkit scroll bar window protection issues
X-Git-Tag: emacs-29.0.90~1856^2~304
X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=e359df4217a392bb3185ff7449656c0a8953a6f4;p=emacs.git

Fix more toolkit scroll bar window protection issues

* src/xterm.c (handle_one_xevent): Ignore outdated scroll bar
events.
(x_free_frame_resources): Clear protected windows and invalidate
previous scroll bar events.
* src/xterm.h (struct x_display_info): New field
`first_valid_scroll_bar_req'.
---

diff --git a/src/xterm.c b/src/xterm.c
index 6860ef20800..2d366e5511f 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -18109,7 +18109,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 	    /* Unprotect the first window to be sent in a
 	       ClientMessage event, since it is now on the stack and
 	       thereby subject to garbage collection.  */
-	    x_unprotect_window_for_callback (dpyinfo);
+	    if (event->xclient.serial
+		>= dpyinfo->first_valid_scroll_bar_req)
+	      x_unprotect_window_for_callback (dpyinfo);
 
 	    *finish = X_EVENT_GOTO_OUT;
             goto done;
@@ -18121,7 +18123,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 	    /* Unprotect the first window to be sent in a
 	       ClientMessage event, since it is now on the stack and
 	       thereby subject to garbage collection.  */
-	    x_unprotect_window_for_callback (dpyinfo);
+	    if (event->xclient.serial
+		>= dpyinfo->first_valid_scroll_bar_req)
+	      x_unprotect_window_for_callback (dpyinfo);
 
 	    *finish = X_EVENT_GOTO_OUT;
             goto done;
@@ -27339,6 +27343,16 @@ x_free_frame_resources (struct frame *f)
 #if defined HAVE_XSYNCTRIGGERFENCE && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
       x_sync_free_fences (f);
 #endif
+
+#ifdef USE_TOOLKIT_SCROLL_BARS
+      /* Since the frame was destroyed, we can no longer guarantee
+	 that scroll bar events will be received.  Clear
+	 protected_windows, and ignore any preceding scroll bar events
+	 that happen to still be deliverable.  */
+      dpyinfo->n_protected_windows = 0;
+      dpyinfo->first_valid_scroll_bar_req
+	= XNextRequest (dpyinfo->display);
+#endif
     }
 
 #ifdef HAVE_GTK3
diff --git a/src/xterm.h b/src/xterm.h
index d6ff15e40f7..d1671621c78 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -839,6 +839,15 @@ struct x_display_info
      server_time_monotonic_p will be true).  */
   int_fast64_t server_time_offset;
 #endif
+
+#if defined USE_TOOLKIT_SCROLL_BARS
+  /* Serial number of the first scroll bar event to start listening
+     to.  This is necessary because protected_windows is display
+     local, but the destruction of a frame's edit window may cause
+     event windows to vanish before they are delivered, leading to
+     windows remaining protected indefinitely.  */
+  unsigned long first_valid_scroll_bar_req;
+#endif
 };
 
 #ifdef HAVE_X_I18N