[gnome-shell/workspace-thumbnails: 1/13] Save enter/leave events and deliver them after DND
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/workspace-thumbnails: 1/13] Save enter/leave events and deliver them after DND
- Date: Mon, 31 Jan 2011 04:13:41 +0000 (UTC)
commit e6ec9cabdf2cd4be3a8f54c4c50916825c2f8df7
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Sun Jan 30 17:39:50 2011 -0500
Save enter/leave events and deliver them after DND
During a drag-and-drop, our pointer grab keeps enter/leave events from
being delivered. That means that after the DND ends, whatever actor is
under the pointer won't have received the enter event it should have,
and any state or hover effect dependent on that won't work right.
So, save the first-leave and last-enter and deliver them at the end
of the drag to get things into a consistent state for the current
pointer position.
https://bugzilla.gnome.org/show_bug.cgi?id=640974
js/ui/dnd.js | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 56 insertions(+), 0 deletions(-)
---
diff --git a/js/ui/dnd.js b/js/ui/dnd.js
index 71d8c04..eb1b958 100644
--- a/js/ui/dnd.js
+++ b/js/ui/dnd.js
@@ -101,6 +101,12 @@ _Draggable.prototype = {
this._dragInProgress = false; // The drag has been started, and has not been dropped or cancelled yet.
this._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting).
+ // During the drag, we eat enter/leave events so that actors don't prelight or show
+ // tooltips. We then deliver the relevant events (first leave, last enter) after
+ // the drag ends.
+ this._firstLeaveEvent = null;
+ this._lastEnterEvent = null;
+
this._eventsGrabbed = false;
},
@@ -198,6 +204,11 @@ _Draggable.prototype = {
this._cancelDrag(event.get_time());
return true;
}
+ } else if (event.type() == Clutter.EventType.LEAVE) {
+ if (this._firstLeaveEvent == null)
+ this._firstLeaveEvent = event;
+ } else if (event.type() == Clutter.EventType.ENTER) {
+ this._lastEnterEvent = event;
}
return false;
@@ -542,12 +553,57 @@ _Draggable.prototype = {
this._dragComplete();
},
+ _deliverPointerEvent: function(event) {
+ // When we are emitting the enter/leave events that were saved up
+ // during the grab, we have to emulate the Clutter event delivery
+ // logic so that, for example, the event capturing logic used for
+ // our hover tracking works correctly.
+ //
+ // Based on code in clutter/clutter/clutter-main.c:emit_event()
+
+ let eventTree = [];
+
+ let actor = event.get_source();
+ while (actor) {
+ let parent = actor.get_parent();
+ if (actor.get_reactive() ||
+ parent == null) // Stage gets all events
+ eventTree.push(actor);
+
+ actor = parent;
+ }
+
+ let i;
+
+ // Capture
+ for (i = eventTree.length - 1; i >= 0; i--) {
+ if (eventTree[i].event(event, true))
+ return;
+ }
+
+ // Bubble
+ for (i = 0; i < eventTree.length; i++) {
+ if (eventTree[i].event(event, false))
+ return;
+ }
+ },
+
_dragComplete: function() {
Shell.util_set_hidden_from_pick(this._dragActor, false);
this._dragActor = undefined;
currentDraggable = null;
this._ungrabEvents();
+
+ if (this._firstLeaveEvent) {
+ this._deliverPointerEvent(this._firstLeaveEvent);
+ this._firstLeaveEvent = null;
+ }
+
+ if (this._lastEnterEvent) {
+ this._deliverPointerEvent(this._lastEnterEvent);
+ this._lastEnterEvent = null;
+ }
}
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]