summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Müllner <fmuellner@gnome.org>2023-04-20 12:26:23 +0200
committerMarge Bot <marge-bot@gnome.org>2023-04-25 09:01:16 +0000
commit3f9ee9cd5e3c79cb53b7c3f759ad78fb40a4fe62 (patch)
tree865522469966cfe3df3d72030403fc206d11a2da
parenta9ba9b7a471ec09d6d76ec6abcce04aa9847a112 (diff)
downloadgnome-shell-3f9ee9cd5e3c79cb53b7c3f759ad78fb40a4fe62.tar.gz
dnd: Add addClickAction() method
The events that the draggable uses to initiate a drag operation are the same as the ones a click action consumes for clicks. It is still possible to combine the two, but it's finicky and far from being straight-forward. To make this easier, add a dedicated addClickAction() method to draggables that takes care of the setup before adding the action to the draggable actor. In the longer term, we'll want to turn DND into an action, and have something like GTK's gesture group to allow combining actions that would otherwise step on each other's toes. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2742>
-rw-r--r--js/ui/dnd.js44
-rw-r--r--js/ui/windowPreview.js47
2 files changed, 54 insertions, 37 deletions
diff --git a/js/ui/dnd.js b/js/ui/dnd.js
index 4ba724d1f..c9bce01f5 100644
--- a/js/ui/dnd.js
+++ b/js/ui/dnd.js
@@ -119,6 +119,50 @@ var _Draggable = class _Draggable extends Signals.EventEmitter {
this._dragCancellable = true;
}
+ /**
+ * addClickAction:
+ *
+ * @param {Clutter.ClickAction} action - click action to add to draggable actor
+ *
+ * Add @action to the draggable's actor, and set it up so that it does not
+ * impede drag operations.
+ */
+ addClickAction(action) {
+ action.connect('clicked', () => (this._actionClicked = true));
+ action.connect('long-press', (a, actor, state) => {
+ if (state !== Clutter.LongPressState.CANCEL)
+ return true;
+
+ const event = Clutter.get_current_event();
+ this._dragTouchSequence = event.get_event_sequence();
+
+ if (this._longPressLater)
+ return true;
+
+ // A click cancels a long-press before any click handler is
+ // run - make sure to not start a drag in that case
+ const laters = global.compositor.get_laters();
+ this._longPressLater = laters.add(Meta.LaterType.BEFORE_REDRAW, () => {
+ delete this._longPressLater;
+ if (this._actionClicked) {
+ delete this._actionClicked;
+ return GLib.SOURCE_REMOVE;
+ }
+ action.release();
+ this.startDrag(
+ ...action.get_coords(),
+ event.get_time(),
+ this._dragTouchSequence,
+ event.get_device());
+
+ return GLib.SOURCE_REMOVE;
+ });
+ return true;
+ });
+
+ this.actor.add_action(action);
+ }
+
_onButtonPress(actor, event) {
if (event.get_button() != 1)
return Clutter.EVENT_PROPAGATE;
diff --git a/js/ui/windowPreview.js b/js/ui/windowPreview.js
index ab851c6a7..599759a1b 100644
--- a/js/ui/windowPreview.js
+++ b/js/ui/windowPreview.js
@@ -98,15 +98,10 @@ var WindowPreview = GObject.registerClass({
this._updateAttachedDialogs();
- let clickAction = new Clutter.ClickAction();
- clickAction.connect('clicked', () => this._activate());
- clickAction.connect('long-press', this._onLongPress.bind(this));
- this.add_action(clickAction);
this.connect('destroy', this._onDestroy.bind(this));
this._draggable = DND.makeDraggable(this, {
restoreOnSuccess: true,
- manualMode: true,
dragActorMaxSize: WINDOW_DND_SIZE,
dragActorOpacity: DRAGGING_WINDOW_OPACITY,
});
@@ -115,7 +110,16 @@ var WindowPreview = GObject.registerClass({
this._draggable.connect('drag-end', this._onDragEnd.bind(this));
this.inDrag = false;
- this._selected = false;
+ let clickAction = new Clutter.ClickAction();
+ clickAction.connect('clicked', () => this._activate());
+ clickAction.connect('long-press', (action, actor, state) => {
+ if (state === Clutter.LongPressState.ACTIVATE)
+ this.showOverlay(true);
+ return true;
+ });
+
+ this._draggable.addClickAction(clickAction);
+
this._overlayEnabled = true;
this._overlayShown = false;
this._closeRequested = false;
@@ -545,7 +549,6 @@ var WindowPreview = GObject.registerClass({
}
_activate() {
- this._selected = true;
this.emit('selected', global.get_current_time());
}
@@ -607,36 +610,6 @@ var WindowPreview = GObject.registerClass({
return super.vfunc_key_press_event(keyEvent);
}
- _onLongPress(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) {
- let event = Clutter.get_current_event();
- this._dragTouchSequence = event.get_event_sequence();
-
- if (this._longPressLater)
- return true;
-
- // A click cancels a long-press before any click handler is
- // run - make sure to not start a drag in that case
- const laters = global.compositor.get_laters();
- this._longPressLater = laters.add(Meta.LaterType.BEFORE_REDRAW, () => {
- delete this._longPressLater;
- if (this._selected) {
- this._selected = false;
- return;
- }
- let [x, y] = action.get_coords();
- action.release();
- this._draggable.startDrag(x, y, global.get_current_time(), this._dragTouchSequence, event.get_device());
- });
- } else {
- this.showOverlay(true);
- }
- return true;
- }
-
_restack() {
// We may not have a parent if DnD completed successfully, in
// which case our clone will shortly be destroyed and replaced