[DND] change cursor when dragging
Return a DND.DragMotionResult constant from delegate _handleDragMotion methods as well as the existing return value from the drag monitor method dragMotion. https://bugzilla.gnome.org/show_bug.cgi?id=607821
This commit is contained in:
parent
0e2ed0fb0b
commit
38c3422331
@ -1035,6 +1035,29 @@ AppWell.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
handleDragOver : function(source, actor, x, y, time) {
|
||||
let app = null;
|
||||
if (source instanceof AppWellIcon)
|
||||
app = this._appSystem.get_app(source.getId());
|
||||
else if (source instanceof Workspace.WindowClone)
|
||||
app = this._tracker.get_window_app(source.metaWindow);
|
||||
|
||||
// Don't allow favoriting of transient apps
|
||||
if (app == null || app.is_transient())
|
||||
return DND.DragMotionResult.NO_DROP;
|
||||
|
||||
let id = app.get_id();
|
||||
|
||||
let favorites = AppFavorites.getAppFavorites().getFavoriteMap();
|
||||
|
||||
let srcIsFavorite = (id in favorites);
|
||||
|
||||
if (srcIsFavorite)
|
||||
return DND.DragMotionResult.NO_DROP;
|
||||
|
||||
return DND.DragMotionResult.COPY_DROP;
|
||||
},
|
||||
|
||||
// Draggable target interface
|
||||
acceptDrop : function(source, actor, x, y, time) {
|
||||
let app = null;
|
||||
|
42
js/ui/dnd.js
42
js/ui/dnd.js
@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const St = imports.gi.St;
|
||||
const Lang = imports.lang;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Main = imports.ui.main;
|
||||
@ -24,6 +25,12 @@ const DragMotionResult = {
|
||||
CONTINUE: 3
|
||||
};
|
||||
|
||||
const DRAG_CURSOR_MAP = {
|
||||
0: Shell.Cursor.UNSUPPORTED_TARGET,
|
||||
1: Shell.Cursor.COPY,
|
||||
2: Shell.Cursor.MOVE
|
||||
};
|
||||
|
||||
const DragDropResult = {
|
||||
FAILURE: 0,
|
||||
SUCCESS: 1,
|
||||
@ -203,6 +210,7 @@ _Draggable.prototype = {
|
||||
if (this._onEventId)
|
||||
this._ungrabActor();
|
||||
this._grabEvents();
|
||||
global.set_cursor(Shell.Cursor.IN_DRAG);
|
||||
|
||||
this._dragX = this._dragStartX = stageX;
|
||||
this._dragY = this._dragStartY = stageY;
|
||||
@ -335,36 +343,38 @@ _Draggable.prototype = {
|
||||
x: stageX,
|
||||
y: stageY,
|
||||
dragActor: this._dragActor,
|
||||
source: this.actor._delegate,
|
||||
targetActor: target
|
||||
};
|
||||
for (let i = 0; i < dragMonitors.length; i++) {
|
||||
let motionFunc = dragMonitors[i].dragMotion;
|
||||
if (motionFunc)
|
||||
switch (motionFunc(dragEvent)) {
|
||||
case DragMotionResult.NO_DROP:
|
||||
case DragMotionResult.COPY_DROP:
|
||||
case DragMotionResult.MOVE_DROP:
|
||||
// TODO: set a special cursor or something ;)
|
||||
return true;
|
||||
case DragMotionResult.CONTINUE:
|
||||
continue;
|
||||
if (motionFunc) {
|
||||
let result = motionFunc(dragEvent);
|
||||
if (result != DragMotionResult.CONTINUE) {
|
||||
global.set_cursor(DRAG_CURSOR_MAP[result]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (target) {
|
||||
if (target._delegate && target._delegate.handleDragOver) {
|
||||
let [r, targX, targY] = target.transform_stage_point(stageX, stageY);
|
||||
// We currently loop through all parents on drag-over even if one of the children has handled it.
|
||||
// We can check the return value of the function and break the loop if it's true if we don't want
|
||||
// to continue checking the parents.
|
||||
target._delegate.handleDragOver(this.actor._delegate,
|
||||
this._dragActor,
|
||||
targX,
|
||||
targY,
|
||||
event.get_time());
|
||||
let result = target._delegate.handleDragOver(this.actor._delegate,
|
||||
this._dragActor,
|
||||
targX,
|
||||
targY,
|
||||
event.get_time());
|
||||
if (result != DragMotionResult.CONTINUE) {
|
||||
global.set_cursor(DRAG_CURSOR_MAP[result]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
target = target.get_parent();
|
||||
}
|
||||
global.set_cursor(Shell.Cursor.IN_DRAG);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -418,6 +428,7 @@ _Draggable.prototype = {
|
||||
}
|
||||
|
||||
this._dragInProgress = false;
|
||||
global.unset_cursor();
|
||||
this.emit('drag-end', event.get_time(), true);
|
||||
this._dragComplete();
|
||||
return true;
|
||||
@ -491,6 +502,7 @@ _Draggable.prototype = {
|
||||
} else {
|
||||
dragActor.destroy();
|
||||
}
|
||||
global.unset_cursor();
|
||||
this.emit('drag-end', eventTime, false);
|
||||
|
||||
this._animationInProgress = false;
|
||||
|
@ -1586,6 +1586,15 @@ Workspace.prototype = {
|
||||
},
|
||||
|
||||
// Draggable target interface
|
||||
handleDragOver : function(source, actor, x, y, time) {
|
||||
if (source instanceof WindowClone)
|
||||
return DND.DragMotionResult.MOVE_DROP;
|
||||
if (source.shellWorkspaceLaunch)
|
||||
return DND.DragMotionResult.COPY_DROP;
|
||||
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
},
|
||||
|
||||
acceptDrop : function(source, actor, x, y, time) {
|
||||
if (source instanceof WindowClone) {
|
||||
let win = source.realWindow;
|
||||
|
@ -269,6 +269,14 @@ GenericWorkspacesView.prototype = {
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
|
||||
_handleDragOverNewWorkspace: function(source, dropActor, x, y, time) {
|
||||
if (source instanceof Workspace.WindowClone)
|
||||
return DND.DragMotionResult.MOVE_DROP;
|
||||
if (source.shellWorkspaceLaunch)
|
||||
return DND.DragMotionResult.COPY_DROP;
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
},
|
||||
|
||||
_acceptNewWorkspaceDrop: function(source, dropActor, x, y, time) {
|
||||
let ws = this.addWorkspace();
|
||||
if (ws == null)
|
||||
@ -487,14 +495,15 @@ NewWorkspaceArea.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
function WorkspaceIndicator(activateWorkspace, workspaceAcceptDrop, scrollEventCb) {
|
||||
this._init(activateWorkspace, workspaceAcceptDrop, scrollEventCb);
|
||||
function WorkspaceIndicator(activateWorkspace, workspaceAcceptDrop, workspaceHandleDragOver, scrollEventCb) {
|
||||
this._init(activateWorkspace, workspaceAcceptDrop, workspaceHandleDragOver, scrollEventCb);
|
||||
}
|
||||
|
||||
WorkspaceIndicator.prototype = {
|
||||
_init: function(activateWorkspace, workspaceAcceptDrop, scrollEventCb) {
|
||||
_init: function(activateWorkspace, workspaceAcceptDrop, workspaceHandleDragOver, scrollEventCb) {
|
||||
this._activateWorkspace = activateWorkspace;
|
||||
this._workspaceAcceptDrop = workspaceAcceptDrop;
|
||||
this._workspaceHandleDragOver = workspaceHandleDragOver;
|
||||
this._scrollEventCb = scrollEventCb;
|
||||
let actor = new St.Bin({ style_class: 'panel-button' });
|
||||
|
||||
@ -592,6 +601,9 @@ WorkspaceIndicator.prototype = {
|
||||
else
|
||||
return false;
|
||||
});
|
||||
actor._delegate.handleDragOver = Lang.bind(this, function(source, actor, x, y, time) {
|
||||
return this._workspaceHandleDragOver(i, source, actor, x, y, time);
|
||||
});
|
||||
|
||||
actor.connect('scroll-event', this._scrollEventCb);
|
||||
|
||||
@ -1187,7 +1199,7 @@ SingleView.prototype = {
|
||||
leftWorkspace.setReservedSlot(dragEvent.dragActor._delegate);
|
||||
this._dragOverLastX = leftEdge;
|
||||
|
||||
return DND.DragMotionResult.MOVE_DROP;
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
}
|
||||
let rightEdge = primary.x + primary.width - 1;
|
||||
let switchRight = (dragEvent.x >= rightEdge && rightWorkspace);
|
||||
@ -1196,15 +1208,17 @@ SingleView.prototype = {
|
||||
rightWorkspace.setReservedSlot(dragEvent.dragActor._delegate);
|
||||
this._dragOverLastX = rightEdge;
|
||||
|
||||
return DND.DragMotionResult.MOVE_DROP;
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
}
|
||||
this._dragOverLastX = dragEvent.x;
|
||||
let result = DND.DragMotionResult.CONTINUE;
|
||||
|
||||
// check hover state of new workspace area / inactive workspaces
|
||||
if (leftWorkspace) {
|
||||
if (dragEvent.targetActor == this._leftShadow) {
|
||||
hoverWorkspace = leftWorkspace;
|
||||
leftWorkspace.opacity = leftWorkspace.actor.opacity = 255;
|
||||
result = leftWorkspace.handleDragOver(dragEvent.source, dragEvent.dragActor);
|
||||
} else {
|
||||
leftWorkspace.opacity = leftWorkspace.actor.opacity = 200;
|
||||
}
|
||||
@ -1214,18 +1228,19 @@ SingleView.prototype = {
|
||||
if (dragEvent.targetActor == this._rightShadow) {
|
||||
hoverWorkspace = rightWorkspace;
|
||||
rightWorkspace.opacity = rightWorkspace.actor.opacity = 255;
|
||||
result = rightWorkspace.handleDragOver(dragEvent.source, dragEvent.dragActor);
|
||||
} else {
|
||||
rightWorkspace.opacity = rightWorkspace.actor.opacity = 200;
|
||||
}
|
||||
} else {
|
||||
let targetParent = dragEvent.targetActor.get_parent();
|
||||
if (targetParent == this._newWorkspaceArea.actor)
|
||||
if (targetParent == this._newWorkspaceArea.actor) {
|
||||
this._newWorkspaceArea.setStyle(true);
|
||||
else
|
||||
result = this._handleDragOverNewWorkspace(dragEvent.source, dragEvent.dragActor);
|
||||
} else
|
||||
this._newWorkspaceArea.setStyle(false);
|
||||
}
|
||||
|
||||
|
||||
// handle delayed workspace switches
|
||||
if (hoverWorkspace) {
|
||||
if (!this._timeoutId)
|
||||
@ -1242,7 +1257,7 @@ SingleView.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
return result;
|
||||
},
|
||||
|
||||
_dragEnd: function() {
|
||||
@ -1377,6 +1392,10 @@ SingleView.prototype = {
|
||||
if (this._workspaces[i] != undefined)
|
||||
return this._workspaces[i].acceptDrop(source, actor, x, y, time);
|
||||
return false;
|
||||
}), Lang.bind(this, function(i, source, actor, x, y, time) {
|
||||
if (this._workspaces[i] != undefined)
|
||||
return this._workspaces[i].handleDragOver(source, actor, x, y, time);
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
}), Lang.bind(this, this._onScrollEvent));
|
||||
|
||||
actor.add(indicator.actor, { expand: true, x_fill: true, y_fill: true });
|
||||
@ -1464,6 +1483,10 @@ WorkspacesControls.prototype = {
|
||||
function(source, actor, x, y, time) {
|
||||
return this._currentView._acceptNewWorkspaceDrop(source, actor, x, y, time);
|
||||
});
|
||||
this._addButton._delegate.handleDragOver = Lang.bind(this,
|
||||
function(source, actor, x, y, time) {
|
||||
return this._currentView._handleDragOverNewWorkspace(source, actor, x, y, time);
|
||||
});
|
||||
this.actor.add(this._addButton, { y_fill: false,
|
||||
y_align: St.Align.START });
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user