summaryrefslogtreecommitdiff
path: root/src/xterm.c
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2022-08-27 09:54:16 +0800
committerPo Lu <luangruo@yahoo.com>2022-08-27 09:54:19 +0800
commit4015d561c39d29200bf1ac542844fd5f3ba99426 (patch)
tree9b57c8a8957040d42e41bd9355264dee8ec05f41 /src/xterm.c
parent6edff5ac331236f817032d6744a0855e5cc3d48d (diff)
downloademacs-4015d561c39d29200bf1ac542844fd5f3ba99426.tar.gz
Fix crash when handling "swallowed" generic events
* src/xmenu.c (x_menu_translate_generic_event, x_menu_show): Pass through more events, correctly. * src/xterm.c (handle_one_xevent): Don't abort if must_free_data and xi_event is NULL; this is an Xlib bug.
Diffstat (limited to 'src/xterm.c')
-rw-r--r--src/xterm.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/src/xterm.c b/src/xterm.c
index b91d3a95173..c716d07adaf 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -20626,11 +20626,14 @@ handle_one_xevent (struct x_display_info *dpyinfo,
bool must_free_data = false;
XIEvent *xi_event = (XIEvent *) event->xcookie.data;
+
/* Sometimes the event is already claimed by GTK, which
will free its data in due course. */
- if (!xi_event && XGetEventData (dpyinfo->display, &event->xcookie))
+ if (!xi_event)
{
- must_free_data = true;
+ if (XGetEventData (dpyinfo->display, &event->xcookie))
+ must_free_data = true;
+
xi_event = (XIEvent *) event->xcookie.data;
}
@@ -20638,7 +20641,25 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (!xi_event)
{
- eassert (!must_free_data);
+ /* It may turn out that the event data has already been
+ implicitly freed for various reasons up to and
+ including XMenuActivate pushing some other event onto
+ the foreign-event queue, or x_menu_wait_for_events
+ calling XNextEvent through a timer that tries to wait
+ for input.
+
+ In that case, XGetEventData will return True, but
+ cookie->data will be NULL. Since handling such input
+ events is not really important, we can afford to
+ discard them.
+
+ The way Xlib is currently implemented makes calling
+ XFreeEventData unnecessary in this case, but call it
+ anyway, since not doing so may lead to a memory leak in
+ the future. */
+
+ if (must_free_data)
+ XFreeEventData (dpyinfo->display, &event->xcookie);
goto OTHER;
}