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._itemDragBeginId = Main.overview.connect(
|
||||
'item-drag-begin', this._onDragBegin.bind(this));
|
||||
this._itemDragEndId = Main.overview.connect(
|
||||
'item-drag-end', this._onDragEnd.bind(this));
|
||||
this._iconIsHovering = false;
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
|
||||
@ -1512,9 +1509,6 @@ var FolderIcon = GObject.registerClass({
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
Main.overview.disconnect(this._itemDragBeginId);
|
||||
Main.overview.disconnect(this._itemDragEndId);
|
||||
|
||||
if (this._dragMonitor) {
|
||||
DND.removeDragMonitor(this._dragMonitor);
|
||||
this._dragMonitor = null;
|
||||
@ -1552,29 +1546,32 @@ var FolderIcon = GObject.registerClass({
|
||||
return this.view.getAllItems().map(item => item.id);
|
||||
}
|
||||
|
||||
_onDragBegin() {
|
||||
_setHoveringByDnd(hovering) {
|
||||
if (this._iconIsHovering == hovering)
|
||||
return;
|
||||
|
||||
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) {
|
||||
let target = dragEvent.targetActor;
|
||||
|
||||
if (!this.contains(target) || !this._canAccept(dragEvent.source))
|
||||
this.remove_style_pseudo_class('drop');
|
||||
else
|
||||
this.add_style_pseudo_class('drop');
|
||||
if (!this.contains(dragEvent.targetActor) ||
|
||||
!this._canAccept(dragEvent.source))
|
||||
this._setHoveringByDnd(false);
|
||||
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
}
|
||||
|
||||
_onDragEnd() {
|
||||
this.remove_style_pseudo_class('drop');
|
||||
DND.removeDragMonitor(this._dragMonitor);
|
||||
}
|
||||
|
||||
_canAccept(source) {
|
||||
if (!(source instanceof AppIcon))
|
||||
return false;
|
||||
@ -1593,10 +1590,14 @@ var FolderIcon = GObject.registerClass({
|
||||
if (!this._canAccept(source))
|
||||
return DND.DragMotionResult.NO_DROP;
|
||||
|
||||
this._setHoveringByDnd(true);
|
||||
|
||||
return DND.DragMotionResult.MOVE_DROP;
|
||||
}
|
||||
|
||||
acceptDrop(source) {
|
||||
this._setHoveringByDnd(false);
|
||||
|
||||
if (!this._canAccept(source))
|
||||
return false;
|
||||
|
||||
@ -2026,7 +2027,6 @@ var AppIcon = GObject.registerClass({
|
||||
|
||||
this._delegate = this;
|
||||
|
||||
this._hasDndHover = false;
|
||||
this._folderPreviewId = 0;
|
||||
|
||||
// Get the isDraggable property without passing it on to the BaseIcon:
|
||||
@ -2075,11 +2075,7 @@ var AppIcon = GObject.registerClass({
|
||||
});
|
||||
}
|
||||
|
||||
this._dragMonitor = null;
|
||||
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._otherIconIsHovering = false;
|
||||
|
||||
this._menuTimeoutId = 0;
|
||||
this._stateChangedId = this.app.connect('notify::state', () => {
|
||||
@ -2091,9 +2087,6 @@ var AppIcon = GObject.registerClass({
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
Main.overview.disconnect(this._itemDragBeginId);
|
||||
Main.overview.disconnect(this._itemDragEndId);
|
||||
|
||||
if (this._folderPreviewId > 0) {
|
||||
GLib.source_remove(this._folderPreviewId);
|
||||
this._folderPreviewId = 0;
|
||||
@ -2340,7 +2333,17 @@ var AppIcon = GObject.registerClass({
|
||||
}
|
||||
|
||||
_setHoveringByDnd(hovering) {
|
||||
if (this._otherIconIsHovering == hovering)
|
||||
return;
|
||||
|
||||
this._otherIconIsHovering = hovering;
|
||||
|
||||
if (hovering) {
|
||||
this._dragMonitor = {
|
||||
dragMotion: this._onDragMotion.bind(this),
|
||||
};
|
||||
DND.addDragMonitor(this._dragMonitor);
|
||||
|
||||
if (this._folderPreviewId > 0)
|
||||
return;
|
||||
|
||||
@ -2352,6 +2355,8 @@ var AppIcon = GObject.registerClass({
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
} else {
|
||||
DND.removeDragMonitor(this._dragMonitor);
|
||||
|
||||
if (this._folderPreviewId > 0) {
|
||||
GLib.source_remove(this._folderPreviewId);
|
||||
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) {
|
||||
let target = dragEvent.targetActor;
|
||||
let isHovering = target == this || this.contains(target);
|
||||
let canDrop = this._canAccept(dragEvent.source);
|
||||
let hasDndHover = isHovering && canDrop;
|
||||
|
||||
if (this._hasDndHover != hasDndHover) {
|
||||
this._setHoveringByDnd(hasDndHover);
|
||||
this._hasDndHover = hasDndHover;
|
||||
}
|
||||
if (!this.contains(dragEvent.targetActor))
|
||||
this._setHoveringByDnd(false);
|
||||
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
}
|
||||
|
||||
_onDragEnd() {
|
||||
this.remove_style_pseudo_class('drop');
|
||||
DND.removeDragMonitor(this._dragMonitor);
|
||||
}
|
||||
|
||||
handleDragOver(source) {
|
||||
if (source == this)
|
||||
return DND.DragMotionResult.NO_DROP;
|
||||
@ -2394,6 +2380,8 @@ var AppIcon = GObject.registerClass({
|
||||
if (!this._canAccept(source))
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
|
||||
this._setHoveringByDnd(true);
|
||||
|
||||
return DND.DragMotionResult.MOVE_DROP;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user