appDisplay: Only use dragMonitor for one icon at a time
Instead of adding a dragMonitor for every icon in the grid as soon as one icon is getting dragged, only add a dragMonitor for the icon that is currently being dragged over (ie. the current drag-target). With a large number of icons in the iconGrid, this should significantly reduce lags while dragging. We can do this by detecting the DnD-entering of an icon or folder using the `handleDragOver()` callback of drag-targets, adding the dragMonitor because we know an icon is hovering above the drag-target and then detecting the DnD-leaving of the drag-target by using the `dragMotion()` handler, where we remove the dragMonitor again as soon as the targetActor is no longer our actor (ie. the drag-target). https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/849
This commit is contained in:
parent
766e9034e2
commit
702417ce83
@ -1499,10 +1499,7 @@ var FolderIcon = GObject.registerClass({
|
|||||||
|
|
||||||
this.view = new FolderView(this._folder, id, parentView);
|
this.view = new FolderView(this._folder, id, parentView);
|
||||||
|
|
||||||
this._itemDragBeginId = Main.overview.connect(
|
this._iconIsHovering = false;
|
||||||
'item-drag-begin', this._onDragBegin.bind(this));
|
|
||||||
this._itemDragEndId = Main.overview.connect(
|
|
||||||
'item-drag-end', this._onDragEnd.bind(this));
|
|
||||||
|
|
||||||
this.connect('destroy', this._onDestroy.bind(this));
|
this.connect('destroy', this._onDestroy.bind(this));
|
||||||
|
|
||||||
@ -1512,9 +1509,6 @@ var FolderIcon = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
_onDestroy() {
|
_onDestroy() {
|
||||||
Main.overview.disconnect(this._itemDragBeginId);
|
|
||||||
Main.overview.disconnect(this._itemDragEndId);
|
|
||||||
|
|
||||||
if (this._dragMonitor) {
|
if (this._dragMonitor) {
|
||||||
DND.removeDragMonitor(this._dragMonitor);
|
DND.removeDragMonitor(this._dragMonitor);
|
||||||
this._dragMonitor = null;
|
this._dragMonitor = null;
|
||||||
@ -1552,29 +1546,32 @@ var FolderIcon = GObject.registerClass({
|
|||||||
return this.view.getAllItems().map(item => item.id);
|
return this.view.getAllItems().map(item => item.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onDragBegin() {
|
_setHoveringByDnd(hovering) {
|
||||||
this._dragMonitor = {
|
if (this._iconIsHovering == hovering)
|
||||||
dragMotion: this._onDragMotion.bind(this),
|
return;
|
||||||
};
|
|
||||||
DND.addDragMonitor(this._dragMonitor);
|
this._iconIsHovering = hovering;
|
||||||
|
|
||||||
|
if (hovering) {
|
||||||
|
this._dragMonitor = {
|
||||||
|
dragMotion: this._onDragMotion.bind(this),
|
||||||
|
};
|
||||||
|
DND.addDragMonitor(this._dragMonitor);
|
||||||
|
this.add_style_pseudo_class('drop');
|
||||||
|
} else {
|
||||||
|
DND.removeDragMonitor(this._dragMonitor);
|
||||||
|
this.remove_style_pseudo_class('drop');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onDragMotion(dragEvent) {
|
_onDragMotion(dragEvent) {
|
||||||
let target = dragEvent.targetActor;
|
if (!this.contains(dragEvent.targetActor) ||
|
||||||
|
!this._canAccept(dragEvent.source))
|
||||||
if (!this.contains(target) || !this._canAccept(dragEvent.source))
|
this._setHoveringByDnd(false);
|
||||||
this.remove_style_pseudo_class('drop');
|
|
||||||
else
|
|
||||||
this.add_style_pseudo_class('drop');
|
|
||||||
|
|
||||||
return DND.DragMotionResult.CONTINUE;
|
return DND.DragMotionResult.CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_onDragEnd() {
|
|
||||||
this.remove_style_pseudo_class('drop');
|
|
||||||
DND.removeDragMonitor(this._dragMonitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
_canAccept(source) {
|
_canAccept(source) {
|
||||||
if (!(source instanceof AppIcon))
|
if (!(source instanceof AppIcon))
|
||||||
return false;
|
return false;
|
||||||
@ -1593,10 +1590,14 @@ var FolderIcon = GObject.registerClass({
|
|||||||
if (!this._canAccept(source))
|
if (!this._canAccept(source))
|
||||||
return DND.DragMotionResult.NO_DROP;
|
return DND.DragMotionResult.NO_DROP;
|
||||||
|
|
||||||
|
this._setHoveringByDnd(true);
|
||||||
|
|
||||||
return DND.DragMotionResult.MOVE_DROP;
|
return DND.DragMotionResult.MOVE_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
acceptDrop(source) {
|
acceptDrop(source) {
|
||||||
|
this._setHoveringByDnd(false);
|
||||||
|
|
||||||
if (!this._canAccept(source))
|
if (!this._canAccept(source))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -2026,7 +2027,6 @@ var AppIcon = GObject.registerClass({
|
|||||||
|
|
||||||
this._delegate = this;
|
this._delegate = this;
|
||||||
|
|
||||||
this._hasDndHover = false;
|
|
||||||
this._folderPreviewId = 0;
|
this._folderPreviewId = 0;
|
||||||
|
|
||||||
// Get the isDraggable property without passing it on to the BaseIcon:
|
// Get the isDraggable property without passing it on to the BaseIcon:
|
||||||
@ -2075,11 +2075,7 @@ var AppIcon = GObject.registerClass({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this._dragMonitor = null;
|
this._otherIconIsHovering = false;
|
||||||
this._itemDragBeginId = Main.overview.connect(
|
|
||||||
'item-drag-begin', this._onDragBegin.bind(this));
|
|
||||||
this._itemDragEndId = Main.overview.connect(
|
|
||||||
'item-drag-end', this._onDragEnd.bind(this));
|
|
||||||
|
|
||||||
this._menuTimeoutId = 0;
|
this._menuTimeoutId = 0;
|
||||||
this._stateChangedId = this.app.connect('notify::state', () => {
|
this._stateChangedId = this.app.connect('notify::state', () => {
|
||||||
@ -2091,9 +2087,6 @@ var AppIcon = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
_onDestroy() {
|
_onDestroy() {
|
||||||
Main.overview.disconnect(this._itemDragBeginId);
|
|
||||||
Main.overview.disconnect(this._itemDragEndId);
|
|
||||||
|
|
||||||
if (this._folderPreviewId > 0) {
|
if (this._folderPreviewId > 0) {
|
||||||
GLib.source_remove(this._folderPreviewId);
|
GLib.source_remove(this._folderPreviewId);
|
||||||
this._folderPreviewId = 0;
|
this._folderPreviewId = 0;
|
||||||
@ -2340,7 +2333,17 @@ var AppIcon = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
_setHoveringByDnd(hovering) {
|
_setHoveringByDnd(hovering) {
|
||||||
|
if (this._otherIconIsHovering == hovering)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._otherIconIsHovering = hovering;
|
||||||
|
|
||||||
if (hovering) {
|
if (hovering) {
|
||||||
|
this._dragMonitor = {
|
||||||
|
dragMotion: this._onDragMotion.bind(this),
|
||||||
|
};
|
||||||
|
DND.addDragMonitor(this._dragMonitor);
|
||||||
|
|
||||||
if (this._folderPreviewId > 0)
|
if (this._folderPreviewId > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -2352,6 +2355,8 @@ var AppIcon = GObject.registerClass({
|
|||||||
return GLib.SOURCE_REMOVE;
|
return GLib.SOURCE_REMOVE;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
DND.removeDragMonitor(this._dragMonitor);
|
||||||
|
|
||||||
if (this._folderPreviewId > 0) {
|
if (this._folderPreviewId > 0) {
|
||||||
GLib.source_remove(this._folderPreviewId);
|
GLib.source_remove(this._folderPreviewId);
|
||||||
this._folderPreviewId = 0;
|
this._folderPreviewId = 0;
|
||||||
@ -2361,32 +2366,13 @@ var AppIcon = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onDragBegin() {
|
|
||||||
this._dragMonitor = {
|
|
||||||
dragMotion: this._onDragMotion.bind(this),
|
|
||||||
};
|
|
||||||
DND.addDragMonitor(this._dragMonitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onDragMotion(dragEvent) {
|
_onDragMotion(dragEvent) {
|
||||||
let target = dragEvent.targetActor;
|
if (!this.contains(dragEvent.targetActor))
|
||||||
let isHovering = target == this || this.contains(target);
|
this._setHoveringByDnd(false);
|
||||||
let canDrop = this._canAccept(dragEvent.source);
|
|
||||||
let hasDndHover = isHovering && canDrop;
|
|
||||||
|
|
||||||
if (this._hasDndHover != hasDndHover) {
|
|
||||||
this._setHoveringByDnd(hasDndHover);
|
|
||||||
this._hasDndHover = hasDndHover;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DND.DragMotionResult.CONTINUE;
|
return DND.DragMotionResult.CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_onDragEnd() {
|
|
||||||
this.remove_style_pseudo_class('drop');
|
|
||||||
DND.removeDragMonitor(this._dragMonitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleDragOver(source) {
|
handleDragOver(source) {
|
||||||
if (source == this)
|
if (source == this)
|
||||||
return DND.DragMotionResult.NO_DROP;
|
return DND.DragMotionResult.NO_DROP;
|
||||||
@ -2394,6 +2380,8 @@ var AppIcon = GObject.registerClass({
|
|||||||
if (!this._canAccept(source))
|
if (!this._canAccept(source))
|
||||||
return DND.DragMotionResult.CONTINUE;
|
return DND.DragMotionResult.CONTINUE;
|
||||||
|
|
||||||
|
this._setHoveringByDnd(true);
|
||||||
|
|
||||||
return DND.DragMotionResult.MOVE_DROP;
|
return DND.DragMotionResult.MOVE_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user