aboutsummaryrefslogtreecommitdiffstats
path: root/src/xmenu.c
diff options
context:
space:
mode:
authorPo Lu2022-02-12 20:25:00 +0800
committerPo Lu2022-02-12 20:28:20 +0800
commitbe06b40ebdd6cfbd23558ce210a8a7ad2b4c7a40 (patch)
treed9e39c9ee8ff639dc65ee7df0af9aaf3ebe1ba65 /src/xmenu.c
parente2f9c27f9ac880aa321c3467c67a6c7394576781 (diff)
downloademacs-be06b40ebdd6cfbd23558ce210a8a7ad2b4c7a40.tar.gz
emacs-be06b40ebdd6cfbd23558ce210a8a7ad2b4c7a40.zip
Fix entry and exit events with XI2 grabs on X toolkit menus
* src/xmenu.c (popup_get_selection): Only claim cookie if new event will be generated. (create_and_show_popup_menu): Ungrab XI2 device, then immediately set core grab on the frame's edit widget window. * src/xterm.c (handle_one_xevent): Use x_any_window_to_frame to find exit event frame if a popup menu is active.
Diffstat (limited to 'src/xmenu.c')
-rw-r--r--src/xmenu.c53
1 files changed, 43 insertions, 10 deletions
diff --git a/src/xmenu.c b/src/xmenu.c
index eaec6efc26c..28fafa108da 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -299,16 +299,16 @@ popup_get_selection (XEvent *initial_event, struct x_display_info *dpyinfo,
299 && event.xgeneric.display == dpyinfo->display 299 && event.xgeneric.display == dpyinfo->display
300 && event.xgeneric.extension == dpyinfo->xi2_opcode) 300 && event.xgeneric.extension == dpyinfo->xi2_opcode)
301 { 301 {
302 if (!event.xcookie.data
303 && XGetEventData (dpyinfo->display, &event.xcookie))
304 cookie_claimed_p = true;
305
306 if (event.xcookie.data) 302 if (event.xcookie.data)
307 { 303 {
308 switch (event.xgeneric.evtype) 304 switch (event.xgeneric.evtype)
309 { 305 {
310 case XI_ButtonRelease: 306 case XI_ButtonRelease:
311 { 307 {
308 if (!event.xcookie.data
309 && XGetEventData (dpyinfo->display, &event.xcookie))
310 cookie_claimed_p = true;
311
312 xev = (XIDeviceEvent *) event.xcookie.data; 312 xev = (XIDeviceEvent *) event.xcookie.data;
313 device = xi_device_from_id (dpyinfo, xev->deviceid); 313 device = xi_device_from_id (dpyinfo, xev->deviceid);
314 314
@@ -358,6 +358,10 @@ popup_get_selection (XEvent *initial_event, struct x_display_info *dpyinfo,
358 { 358 {
359 KeySym keysym; 359 KeySym keysym;
360 360
361 if (!event.xcookie.data
362 && XGetEventData (dpyinfo->display, &event.xcookie))
363 cookie_claimed_p = true;
364
361 xev = (XIDeviceEvent *) event.xcookie.data; 365 xev = (XIDeviceEvent *) event.xcookie.data;
362 366
363 copy.xkey.type = KeyPress; 367 copy.xkey.type = KeyPress;
@@ -1578,26 +1582,55 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv,
1578 XtSetArg (av[ac], (char *) XtNgeometry, 0); ac++; 1582 XtSetArg (av[ac], (char *) XtNgeometry, 0); ac++;
1579 XtSetValues (menu, av, ac); 1583 XtSetValues (menu, av, ac);
1580 1584
1581#if defined HAVE_XINPUT2 && defined USE_X_TOOLKIT 1585#if defined HAVE_XINPUT2
1582 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); 1586 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
1583 /* Clear the XI2 grab so lwlib can set a core grab. */ 1587 bool any_xi_grab_p = false;
1588
1589 /* Clear the XI2 grab, and if any XI2 grab was set, place a core
1590 grab on the frame's edit widget. */
1591
1592 if (dpyinfo->supports_xi2)
1593 XGrabServer (dpyinfo->display);
1584 1594
1585 if (dpyinfo->num_devices) 1595 if (dpyinfo->num_devices)
1586 { 1596 {
1587 for (int i = 0; i < dpyinfo->num_devices; ++i) 1597 for (int i = 0; i < dpyinfo->num_devices; ++i)
1588 { 1598 {
1589#ifndef USE_MOTIF
1590 if (dpyinfo->devices[i].grab) 1599 if (dpyinfo->devices[i].grab)
1591#endif 1600 {
1592 XIUngrabDevice (dpyinfo->display, dpyinfo->devices[i].device_id, 1601 any_xi_grab_p = true;
1593 CurrentTime); 1602 dpyinfo->devices[i].grab = 0;
1603
1604 XIUngrabDevice (dpyinfo->display,
1605 dpyinfo->devices[i].device_id,
1606 CurrentTime);
1607 }
1594 } 1608 }
1595 } 1609 }
1610
1611 if (any_xi_grab_p)
1612 XGrabPointer (dpyinfo->display,
1613 FRAME_X_WINDOW (f),
1614 False, (PointerMotionMask
1615 | PointerMotionHintMask
1616 | ButtonReleaseMask
1617 | ButtonPressMask),
1618 GrabModeSync, GrabModeAsync,
1619 None, None, CurrentTime);
1620
1621 if (dpyinfo->supports_xi2)
1622 XUngrabServer (dpyinfo->display);
1596#endif 1623#endif
1597 1624
1598 /* Display the menu. */ 1625 /* Display the menu. */
1599 lw_popup_menu (menu, &dummy); 1626 lw_popup_menu (menu, &dummy);
1600 popup_activated_flag = 1; 1627 popup_activated_flag = 1;
1628
1629#ifdef HAVE_XINPUT2
1630 if (any_xi_grab_p)
1631 XAllowEvents (dpyinfo->display, AsyncPointer, CurrentTime);
1632#endif
1633
1601 x_activate_timeout_atimer (); 1634 x_activate_timeout_atimer ();
1602 1635
1603 { 1636 {