appDisplay: Use a drag monitor to check for out-of-dialog drags
When the app folder dialog handles a drag hover, it starts a timeout to popdown if dragging outside the "real" dialog area. However, when dragging inside it, BaseAppView handles all drag hover events which would disarm the popdown timeout. In cases like this, it's almost impossible to prevent the timeout from triggering, which always pops down the dialog. Add a drag monitor when handling any drag hover (which only happens when dragging outside the folder's icon grid); and eventually disarm the popdown timeout from the monitor's motion event. Remove the drag monitor when dragging over the folder dialog again. https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
This commit is contained in:
parent
730a68dffc
commit
d93b51e135
@ -2011,6 +2011,7 @@ var AppFolderDialog = GObject.registerClass({
|
||||
this._grabHelper.addActor(Main.layoutManager.overviewGroup);
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
|
||||
this._dragMonitor = null;
|
||||
this._sourceMappedId = 0;
|
||||
this._popdownTimeoutId = 0;
|
||||
this._needsZoomAndFade = false;
|
||||
@ -2224,6 +2225,22 @@ var AppFolderDialog = GObject.registerClass({
|
||||
this._needsZoomAndFade = false;
|
||||
}
|
||||
|
||||
_removeDragMonitor() {
|
||||
if (!this._dragMonitor)
|
||||
return;
|
||||
|
||||
DND.removeDragMonitor(this._dragMonitor);
|
||||
this._dragMonitor = null;
|
||||
}
|
||||
|
||||
_removePopdownTimeout() {
|
||||
if (this._popdownTimeoutId === 0)
|
||||
return;
|
||||
|
||||
GLib.source_remove(this._popdownTimeoutId);
|
||||
this._popdownTimeoutId = 0;
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
if (this._isOpen) {
|
||||
this._isOpen = false;
|
||||
@ -2236,10 +2253,8 @@ var AppFolderDialog = GObject.registerClass({
|
||||
this._sourceMappedId = 0;
|
||||
}
|
||||
|
||||
if (this._popdownTimeoutId > 0) {
|
||||
GLib.source_remove(this._popdownTimeoutId);
|
||||
this._popdownTimeoutId = 0;
|
||||
}
|
||||
this._removePopdownTimeout();
|
||||
this._removeDragMonitor();
|
||||
}
|
||||
|
||||
vfunc_allocate(box) {
|
||||
@ -2306,19 +2321,41 @@ var AppFolderDialog = GObject.registerClass({
|
||||
y < childAllocation.y2;
|
||||
}
|
||||
|
||||
_setupDragMonitor() {
|
||||
if (this._dragMonitor)
|
||||
return;
|
||||
|
||||
this._dragMonitor = {
|
||||
dragMotion: dragEvent => {
|
||||
if (this._withinDialog(dragEvent.x, dragEvent.y)) {
|
||||
this._removePopdownTimeout();
|
||||
this._removeDragMonitor();
|
||||
}
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
},
|
||||
};
|
||||
DND.addDragMonitor(this._dragMonitor);
|
||||
}
|
||||
|
||||
_setupPopdownTimeout() {
|
||||
if (this._popdownTimeoutId > 0)
|
||||
return;
|
||||
|
||||
this._popdownTimeoutId =
|
||||
GLib.timeout_add(GLib.PRIORITY_DEFAULT, POPDOWN_DIALOG_TIMEOUT, () => {
|
||||
this._popdownTimeoutId = 0;
|
||||
this.popdown();
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
}
|
||||
|
||||
handleDragOver(source, actor, x, y) {
|
||||
if (this._withinDialog(x, y)) {
|
||||
if (this._popdownTimeoutId > 0) {
|
||||
GLib.source_remove(this._popdownTimeoutId);
|
||||
this._popdownTimeoutId = 0;
|
||||
}
|
||||
} else if (this._popdownTimeoutId === 0) {
|
||||
this._popdownTimeoutId =
|
||||
GLib.timeout_add(GLib.PRIORITY_DEFAULT, POPDOWN_DIALOG_TIMEOUT, () => {
|
||||
this._popdownTimeoutId = 0;
|
||||
this.popdown();
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
this._removePopdownTimeout();
|
||||
this._removeDragMonitor();
|
||||
} else {
|
||||
this._setupPopdownTimeout();
|
||||
this._setupDragMonitor();
|
||||
}
|
||||
|
||||
return DND.DragMotionResult.NO_DROP;
|
||||
|
Loading…
Reference in New Issue
Block a user