grabHelper: consume the press/motion/release sequence if a press dismisses the grab

The grab would previously just consume the button release, while propagating
motion events, possibly down to clients in wayland. This would produce
inconsistent streams there.

On pointer events, the inconsistency would just be having clients receiving
events with the button 1 set in the mask, with no implicit grab. When touch
events are handled, this would be more hindering as the client would receive
touch_motion events with no prior touch_down nor later touch_up, something
never supposed to happen.

https://bugzilla.gnome.org/show_bug.cgi?id=733633
This commit is contained in:
Carlos Garnacho 2014-07-22 12:50:54 +02:00
parent 7e31015ba2
commit bbfa616f27

View File

@ -283,12 +283,14 @@ const GrabHelper = new Lang.Class({
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} }
let motion = type == Clutter.EventType.MOTION;
let press = type == Clutter.EventType.BUTTON_PRESS; let press = type == Clutter.EventType.BUTTON_PRESS;
let release = type == Clutter.EventType.BUTTON_RELEASE; let release = type == Clutter.EventType.BUTTON_RELEASE;
let button = press || release; let button = press || release;
if (release && this._ignoreRelease) { if (this._ignoreUntilRelease && (motion || release)) {
this._ignoreRelease = false; if (release)
this._ignoreUntilRelease = false;
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} }
@ -299,10 +301,11 @@ const GrabHelper = new Lang.Class({
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
if (button) { if (button) {
// If we have a press event, ignore the next event, // If we have a press event, ignore the next
// which should be a release event. // motion/release events.
if (press) if (press)
this._ignoreRelease = true; this._ignoreUntilRelease = true;
let i = this._actorInGrabStack(event.get_source()) + 1; let i = this._actorInGrabStack(event.get_source()) + 1;
this.ungrab({ actor: this._grabStack[i].actor, isUser: true }); this.ungrab({ actor: this._grabStack[i].actor, isUser: true });
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;