]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix more toolkit scroll bar window protection issues
authorPo Lu <luangruo@yahoo.com>
Fri, 23 Sep 2022 12:41:24 +0000 (20:41 +0800)
committerPo Lu <luangruo@yahoo.com>
Fri, 23 Sep 2022 12:41:47 +0000 (20:41 +0800)
* 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'.

src/xterm.c
src/xterm.h

index 6860ef20800af1bf21a166ff8f68c2f622a06553..2d366e5511f213355ca9b61323f50760f4cb6514 100644 (file)
@@ -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
index d6ff15e40f76e52cc4af8f4fd6f39c19627c078c..d1671621c78897cc4506346e788e63a4857fea79 100644 (file)
@@ -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