mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-11 14:01:43 -08:00
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.
This commit is contained in:
parent
e2f9c27f9a
commit
be06b40ebd
2 changed files with 54 additions and 10 deletions
53
src/xmenu.c
53
src/xmenu.c
|
|
@ -299,16 +299,16 @@ popup_get_selection (XEvent *initial_event, struct x_display_info *dpyinfo,
|
|||
&& event.xgeneric.display == dpyinfo->display
|
||||
&& event.xgeneric.extension == dpyinfo->xi2_opcode)
|
||||
{
|
||||
if (!event.xcookie.data
|
||||
&& XGetEventData (dpyinfo->display, &event.xcookie))
|
||||
cookie_claimed_p = true;
|
||||
|
||||
if (event.xcookie.data)
|
||||
{
|
||||
switch (event.xgeneric.evtype)
|
||||
{
|
||||
case XI_ButtonRelease:
|
||||
{
|
||||
if (!event.xcookie.data
|
||||
&& XGetEventData (dpyinfo->display, &event.xcookie))
|
||||
cookie_claimed_p = true;
|
||||
|
||||
xev = (XIDeviceEvent *) event.xcookie.data;
|
||||
device = xi_device_from_id (dpyinfo, xev->deviceid);
|
||||
|
||||
|
|
@ -358,6 +358,10 @@ popup_get_selection (XEvent *initial_event, struct x_display_info *dpyinfo,
|
|||
{
|
||||
KeySym keysym;
|
||||
|
||||
if (!event.xcookie.data
|
||||
&& XGetEventData (dpyinfo->display, &event.xcookie))
|
||||
cookie_claimed_p = true;
|
||||
|
||||
xev = (XIDeviceEvent *) event.xcookie.data;
|
||||
|
||||
copy.xkey.type = KeyPress;
|
||||
|
|
@ -1578,26 +1582,55 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv,
|
|||
XtSetArg (av[ac], (char *) XtNgeometry, 0); ac++;
|
||||
XtSetValues (menu, av, ac);
|
||||
|
||||
#if defined HAVE_XINPUT2 && defined USE_X_TOOLKIT
|
||||
#if defined HAVE_XINPUT2
|
||||
struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
|
||||
/* Clear the XI2 grab so lwlib can set a core grab. */
|
||||
bool any_xi_grab_p = false;
|
||||
|
||||
/* Clear the XI2 grab, and if any XI2 grab was set, place a core
|
||||
grab on the frame's edit widget. */
|
||||
|
||||
if (dpyinfo->supports_xi2)
|
||||
XGrabServer (dpyinfo->display);
|
||||
|
||||
if (dpyinfo->num_devices)
|
||||
{
|
||||
for (int i = 0; i < dpyinfo->num_devices; ++i)
|
||||
{
|
||||
#ifndef USE_MOTIF
|
||||
if (dpyinfo->devices[i].grab)
|
||||
#endif
|
||||
XIUngrabDevice (dpyinfo->display, dpyinfo->devices[i].device_id,
|
||||
CurrentTime);
|
||||
{
|
||||
any_xi_grab_p = true;
|
||||
dpyinfo->devices[i].grab = 0;
|
||||
|
||||
XIUngrabDevice (dpyinfo->display,
|
||||
dpyinfo->devices[i].device_id,
|
||||
CurrentTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (any_xi_grab_p)
|
||||
XGrabPointer (dpyinfo->display,
|
||||
FRAME_X_WINDOW (f),
|
||||
False, (PointerMotionMask
|
||||
| PointerMotionHintMask
|
||||
| ButtonReleaseMask
|
||||
| ButtonPressMask),
|
||||
GrabModeSync, GrabModeAsync,
|
||||
None, None, CurrentTime);
|
||||
|
||||
if (dpyinfo->supports_xi2)
|
||||
XUngrabServer (dpyinfo->display);
|
||||
#endif
|
||||
|
||||
/* Display the menu. */
|
||||
lw_popup_menu (menu, &dummy);
|
||||
popup_activated_flag = 1;
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
if (any_xi_grab_p)
|
||||
XAllowEvents (dpyinfo->display, AsyncPointer, CurrentTime);
|
||||
#endif
|
||||
|
||||
x_activate_timeout_atimer ();
|
||||
|
||||
{
|
||||
|
|
|
|||
11
src/xterm.c
11
src/xterm.c
|
|
@ -10877,6 +10877,17 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|
|||
ev.window = leave->event;
|
||||
any = x_top_window_to_frame (dpyinfo, leave->event);
|
||||
|
||||
/* This allows us to catch LeaveNotify events generated by
|
||||
popup menu grabs. FIXME: this is right when there is a
|
||||
focus menu, but implicit focus tracking can get screwed
|
||||
up if we get this and no XI_Enter event later. */
|
||||
|
||||
#ifdef USE_X_TOOLKIT
|
||||
if (popup_activated ()
|
||||
&& leave->mode == XINotifyPassiveUngrab)
|
||||
any = x_any_window_to_frame (dpyinfo, leave->event);
|
||||
#endif
|
||||
|
||||
/* One problem behind the design of XInput 2 scrolling is
|
||||
that valuators are not unique to each window, but only
|
||||
the window that has grabbed the valuator's device or
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue