From 7bc2573d8581560a032e829daaf2be4d93a16256 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 21 Sep 2011 02:54:06 +0200 Subject: [PATCH] window-clone: Use ClutterClickAction Right-click menus in the dash can be dismissed by clicking anywhere outside the menu. However, if a window clone is located beneath the pointer when doing so, the window is activated and the overview closed. The cause of this unexpected behavior is that window previews are activated on button-release, which is delivered to the preview after the menu releases its grab on button-press. Use a ClutterClickAction instead and let Clutter do the right thing, i.e. only trigger a 'clicked' signal when a button-release event is matched by a corresponding button-press event. https://bugzilla.gnome.org/show_bug.cgi?id=661151 --- js/ui/workspace.js | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/js/ui/workspace.js b/js/ui/workspace.js index 55e93f35e..97e784b9d 100644 --- a/js/ui/workspace.js +++ b/js/ui/workspace.js @@ -135,8 +135,11 @@ WindowClone.prototype = { this._realWindowDestroyId = this.realWindow.connect('destroy', Lang.bind(this, this._disconnectRealWindowSignals)); - this.actor.connect('button-release-event', - Lang.bind(this, this._onButtonRelease)); + let clickAction = new Clutter.ClickAction(); + clickAction.connect('clicked', Lang.bind(this, this._onClicked)); + clickAction.connect('long-press', Lang.bind(this, this._onLongPress)); + + this.actor.add_action(clickAction); this.actor.connect('scroll-event', Lang.bind(this, this._onScroll)); @@ -147,6 +150,7 @@ WindowClone.prototype = { this._draggable = DND.makeDraggable(this.actor, { restoreOnSuccess: true, + manualMode: true, dragActorMaxSize: WINDOW_DND_SIZE, dragActorOpacity: DRAGGING_WINDOW_OPACITY }); this._draggable.connect('drag-begin', Lang.bind(this, this._onDragBegin)); @@ -345,9 +349,27 @@ WindowClone.prototype = { this._zoomStep = undefined; }, - _onButtonRelease : function (actor, event) { + _onClicked: function(action, actor) { this._selected = true; - this.emit('selected', event.get_time()); + this.emit('selected', global.get_current_time()); + }, + + _onLongPress: function(action, actor, state) { + // Take advantage of the Clutter policy to consider + // a long-press canceled when the pointer movement + // exceeds dnd-drag-threshold to manually start the drag + if (state == Clutter.LongPressState.CANCEL) { + // A click cancels a long-press before any click handler is + // run - make sure to not start a drag in that case + Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, + function() { + if (this._selected) + return; + let [x, y] = action.get_coords(); + this._draggable.startDrag(x, y, global.get_current_time()); + })); + } + return true; }, _onDragBegin : function (draggable, time) {