x11: Discard the LeaveNotify for off-stage ButtonRelease
If the user presses a button on a pointer device and then moves out the Stage X11 will emit the following events: LeaveNotify ➔ MotionNotify ... ➔ ButtonRelease ➔ LeaveNotify The second LeaveNotify differs from the first by the state field. Unfortunately, ClutterCrossingEvent doesn't have a modifier_state field like other events, so we cannot provide a way for programmatically distinguishing them from a Clutter perspective. This is also an X11-ism we might not even want to replicate on every backend with sane enter/leave semantics. For this reason we should check inside the X11 event processing if the pointer device has already left the Stage and ignore the second LeaveNotify.
This commit is contained in:
parent
8736b53d7c
commit
25c6ebbb2c
@ -417,6 +417,7 @@ event_translate (ClutterBackend *backend,
|
||||
gboolean res, not_yet_handled = FALSE;
|
||||
Window xwindow, stage_xwindow;
|
||||
ClutterDeviceManager *manager;
|
||||
ClutterInputDevice *device;
|
||||
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
|
||||
@ -674,12 +675,11 @@ event_translate (ClutterBackend *backend,
|
||||
{
|
||||
if (!clutter_x11_has_xinput ())
|
||||
{
|
||||
device = clutter_device_manager_get_device (manager, 0);
|
||||
|
||||
/* Regular X event */
|
||||
switch (xevent->type)
|
||||
{
|
||||
/* KeyPress / KeyRelease should reside here if XInput
|
||||
* worked properly
|
||||
*/
|
||||
case ButtonPress:
|
||||
switch (xevent->xbutton.button)
|
||||
{
|
||||
@ -702,8 +702,7 @@ event_translate (ClutterBackend *backend,
|
||||
event->scroll.x = xevent->xbutton.x;
|
||||
event->scroll.y = xevent->xbutton.y;
|
||||
event->scroll.modifier_state = xevent->xbutton.state;
|
||||
event->scroll.device =
|
||||
clutter_device_manager_get_device (manager, 0);
|
||||
event->scroll.device = device;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -713,8 +712,7 @@ event_translate (ClutterBackend *backend,
|
||||
event->button.y = xevent->xbutton.y;
|
||||
event->button.modifier_state = xevent->xbutton.state;
|
||||
event->button.button = xevent->xbutton.button;
|
||||
event->button.device =
|
||||
clutter_device_manager_get_device (manager, 0);
|
||||
event->button.device = device;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -738,8 +736,7 @@ event_translate (ClutterBackend *backend,
|
||||
event->button.y = xevent->xbutton.y;
|
||||
event->button.modifier_state = xevent->xbutton.state;
|
||||
event->button.button = xevent->xbutton.button;
|
||||
event->button.device =
|
||||
clutter_device_manager_get_device (manager, 0);
|
||||
event->button.device = device;
|
||||
break;
|
||||
|
||||
case MotionNotify:
|
||||
@ -748,8 +745,7 @@ event_translate (ClutterBackend *backend,
|
||||
event->motion.x = xevent->xmotion.x;
|
||||
event->motion.y = xevent->xmotion.y;
|
||||
event->motion.modifier_state = xevent->xmotion.state;
|
||||
event->motion.device =
|
||||
clutter_device_manager_get_device (manager, 0);
|
||||
event->motion.device = device;
|
||||
break;
|
||||
|
||||
case EnterNotify:
|
||||
@ -760,25 +756,35 @@ event_translate (ClutterBackend *backend,
|
||||
event->motion.x = xevent->xcrossing.x;
|
||||
event->motion.y = xevent->xcrossing.y;
|
||||
event->motion.modifier_state = xevent->xcrossing.state;
|
||||
event->motion.device =
|
||||
clutter_device_manager_get_device (manager, 0);
|
||||
event->motion.source = CLUTTER_ACTOR (stage);
|
||||
event->motion.device = device;
|
||||
|
||||
/* we know that we are entering the stage here */
|
||||
_clutter_input_device_set_stage (event->motion.device, stage);
|
||||
_clutter_input_device_set_stage (device, stage);
|
||||
CLUTTER_NOTE (EVENT, "Entering the stage");
|
||||
break;
|
||||
|
||||
case LeaveNotify:
|
||||
if (device->stage == NULL)
|
||||
{
|
||||
CLUTTER_NOTE (EVENT,
|
||||
"Discarding LeaveNotify for ButtonRelease "
|
||||
"event off-stage");
|
||||
res = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
event->crossing.type = event->type = CLUTTER_LEAVE;
|
||||
event->crossing.time = xevent->xcrossing.time;
|
||||
event->crossing.x = xevent->xcrossing.x;
|
||||
event->crossing.y = xevent->xcrossing.y;
|
||||
event->crossing.device =
|
||||
clutter_device_manager_get_device (manager, 0);
|
||||
event->crossing.source = CLUTTER_ACTOR (stage);
|
||||
event->crossing.device = device;
|
||||
|
||||
/* we know that we are leaving the stage here */
|
||||
_clutter_input_device_set_stage (event->crossing.device, NULL);
|
||||
CLUTTER_NOTE (EVENT, "Leaving the stage");
|
||||
_clutter_input_device_set_stage (device, NULL);
|
||||
CLUTTER_NOTE (EVENT, "Leaving the stage (time:%u)",
|
||||
event->crossing.time);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -804,6 +810,8 @@ event_translate (ClutterBackend *backend,
|
||||
{
|
||||
XDeviceButtonEvent *xbev = (XDeviceButtonEvent *) xevent;
|
||||
|
||||
device = _clutter_x11_get_device_for_xid (xbev->deviceid);
|
||||
|
||||
CLUTTER_NOTE (EVENT,
|
||||
"XINPUT Button press event for %li at %d, %d",
|
||||
xbev->deviceid,
|
||||
@ -831,8 +839,7 @@ event_translate (ClutterBackend *backend,
|
||||
event->scroll.x = xbev->x;
|
||||
event->scroll.y = xbev->y;
|
||||
event->scroll.modifier_state = xbev->state;
|
||||
event->scroll.device =
|
||||
_clutter_x11_get_device_for_xid (xbev->deviceid);
|
||||
event->scroll.device = device;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -842,8 +849,7 @@ event_translate (ClutterBackend *backend,
|
||||
event->button.y = xbev->y;
|
||||
event->button.modifier_state = xbev->state;
|
||||
event->button.button = xbev->button;
|
||||
event->button.device =
|
||||
_clutter_x11_get_device_for_xid (xbev->deviceid);
|
||||
event->button.device = device;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -853,6 +859,8 @@ event_translate (ClutterBackend *backend,
|
||||
{
|
||||
XDeviceButtonEvent *xbev = (XDeviceButtonEvent *)xevent;
|
||||
|
||||
device = _clutter_x11_get_device_for_xid (xbev->deviceid);
|
||||
|
||||
CLUTTER_NOTE (EVENT, "XINPUT Button release event for %li at %d, %d",
|
||||
xbev->deviceid,
|
||||
xbev->x,
|
||||
@ -873,12 +881,14 @@ event_translate (ClutterBackend *backend,
|
||||
event->button.y = xbev->y;
|
||||
event->button.modifier_state = xbev->state;
|
||||
event->button.button = xbev->button;
|
||||
event->button.device = _clutter_x11_get_device_for_xid (xbev->deviceid);
|
||||
event->button.device = device;
|
||||
}
|
||||
else if (xevent->type == motion_notify)
|
||||
{
|
||||
XDeviceMotionEvent *xmev = (XDeviceMotionEvent *)xevent;
|
||||
|
||||
device = _clutter_x11_get_device_for_xid (xmev->deviceid);
|
||||
|
||||
CLUTTER_NOTE(EVENT, "XINPUT Motion event for %li at %d, %d",
|
||||
xmev->deviceid,
|
||||
xmev->x,
|
||||
@ -889,7 +899,7 @@ event_translate (ClutterBackend *backend,
|
||||
event->motion.x = xmev->x;
|
||||
event->motion.y = xmev->y;
|
||||
event->motion.modifier_state = xmev->state;
|
||||
event->motion.device = _clutter_x11_get_device_for_xid (xmev->deviceid);
|
||||
event->motion.device = device;
|
||||
}
|
||||
#if 0
|
||||
/* the Xinput handling of key presses/releases disabled for now since
|
||||
|
Loading…
Reference in New Issue
Block a user