mirror of
https://github.com/brl/mutter.git
synced 2024-11-23 00:20:42 -05:00
event: Unify the off-stage motion events delivery behaviour
When we disable the per-actor events delivery Clutter replicates the X11 implicit soft grab for motion events with off-stage. The implicit grab is done whenever the pointer of a device leaves a window with a button still pressed; with the implicit grab in place the window still receives motion events even after the LeaveNotify - until the button is released. The implicit grab is not honoured in the per-actor event deliver case, though, so we have a mismatch between two in theory equivalent cases. Luckily, the fix is pretty trivial: when we check for a motion event with a stage set but without an actor set, and that has off-stage coordinates, we arbitrarily set the source to be the stage of the event and emit the pointer event.
This commit is contained in:
parent
46d6697b91
commit
521d71d4bc
@ -2240,6 +2240,17 @@ emit_keyboard_event (ClutterEvent *event)
|
|||||||
clutter_actor_event (context->keyboard_grab_actor, event, FALSE);
|
clutter_actor_event (context->keyboard_grab_actor, event, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_off_stage (ClutterActor *stage,
|
||||||
|
gfloat x,
|
||||||
|
gfloat y)
|
||||||
|
{
|
||||||
|
return (x < 0 ||
|
||||||
|
y < 0 ||
|
||||||
|
x >= clutter_actor_get_width (stage) ||
|
||||||
|
y >= clutter_actor_get_height (stage));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_do_event
|
* clutter_do_event
|
||||||
* @event: a #ClutterEvent.
|
* @event: a #ClutterEvent.
|
||||||
@ -2360,10 +2371,14 @@ _clutter_process_event_details (ClutterActor *stage,
|
|||||||
*/
|
*/
|
||||||
if (event->any.source == NULL)
|
if (event->any.source == NULL)
|
||||||
{
|
{
|
||||||
/* Handle release off stage */
|
/* emulate X11 the implicit soft grab; the implicit soft grab
|
||||||
if ((x >= clutter_actor_get_width (stage) ||
|
* keeps relaying motion events when the stage is left with a
|
||||||
y >= clutter_actor_get_height (stage) ||
|
* pointer button pressed. since this is what happens when we
|
||||||
x < 0 || y < 0))
|
* disable per-actor motion events we need to maintain the same
|
||||||
|
* behaviour when the per-actor motion events are enabled as
|
||||||
|
* well
|
||||||
|
*/
|
||||||
|
if (is_off_stage (stage, x, y))
|
||||||
{
|
{
|
||||||
if (event->type == CLUTTER_BUTTON_RELEASE)
|
if (event->type == CLUTTER_BUTTON_RELEASE)
|
||||||
{
|
{
|
||||||
@ -2373,8 +2388,20 @@ _clutter_process_event_details (ClutterActor *stage,
|
|||||||
|
|
||||||
event->button.source = stage;
|
event->button.source = stage;
|
||||||
event->button.click_count = 1;
|
event->button.click_count = 1;
|
||||||
|
|
||||||
emit_pointer_event (event, device);
|
emit_pointer_event (event, device);
|
||||||
}
|
}
|
||||||
|
else if (event->type == CLUTTER_MOTION)
|
||||||
|
{
|
||||||
|
CLUTTER_NOTE (EVENT,
|
||||||
|
"Motion off stage received at %.2f, %2.f",
|
||||||
|
x, y);
|
||||||
|
|
||||||
|
event->motion.source = stage;
|
||||||
|
|
||||||
|
emit_pointer_event (event, device);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2393,9 +2420,10 @@ _clutter_process_event_details (ClutterActor *stage,
|
|||||||
CLUTTER_PICK_REACTIVE);
|
CLUTTER_PICK_REACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
event->any.source = actor;
|
if (actor == NULL)
|
||||||
if (event->any.source == NULL)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
event->any.source = actor;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user