[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:
Maxim Ermilov 2010-09-10 06:00:28 +04:00
parent 0e2ed0fb0b
commit 38c3422331
4 changed files with 91 additions and 24 deletions

View File

@ -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 // Draggable target interface
acceptDrop : function(source, actor, x, y, time) { acceptDrop : function(source, actor, x, y, time) {
let app = null; let app = null;

View File

@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk; const Gtk = imports.gi.Gtk;
const St = imports.gi.St; const St = imports.gi.St;
const Lang = imports.lang; const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals; const Signals = imports.signals;
const Tweener = imports.ui.tweener; const Tweener = imports.ui.tweener;
const Main = imports.ui.main; const Main = imports.ui.main;
@ -24,6 +25,12 @@ const DragMotionResult = {
CONTINUE: 3 CONTINUE: 3
}; };
const DRAG_CURSOR_MAP = {
0: Shell.Cursor.UNSUPPORTED_TARGET,
1: Shell.Cursor.COPY,
2: Shell.Cursor.MOVE
};
const DragDropResult = { const DragDropResult = {
FAILURE: 0, FAILURE: 0,
SUCCESS: 1, SUCCESS: 1,
@ -203,6 +210,7 @@ _Draggable.prototype = {
if (this._onEventId) if (this._onEventId)
this._ungrabActor(); this._ungrabActor();
this._grabEvents(); this._grabEvents();
global.set_cursor(Shell.Cursor.IN_DRAG);
this._dragX = this._dragStartX = stageX; this._dragX = this._dragStartX = stageX;
this._dragY = this._dragStartY = stageY; this._dragY = this._dragStartY = stageY;
@ -335,36 +343,38 @@ _Draggable.prototype = {
x: stageX, x: stageX,
y: stageY, y: stageY,
dragActor: this._dragActor, dragActor: this._dragActor,
source: this.actor._delegate,
targetActor: target targetActor: target
}; };
for (let i = 0; i < dragMonitors.length; i++) { for (let i = 0; i < dragMonitors.length; i++) {
let motionFunc = dragMonitors[i].dragMotion; let motionFunc = dragMonitors[i].dragMotion;
if (motionFunc) if (motionFunc) {
switch (motionFunc(dragEvent)) { let result = motionFunc(dragEvent);
case DragMotionResult.NO_DROP: if (result != DragMotionResult.CONTINUE) {
case DragMotionResult.COPY_DROP: global.set_cursor(DRAG_CURSOR_MAP[result]);
case DragMotionResult.MOVE_DROP:
// TODO: set a special cursor or something ;)
return true; return true;
case DragMotionResult.CONTINUE:
continue;
} }
} }
}
while (target) { while (target) {
if (target._delegate && target._delegate.handleDragOver) { if (target._delegate && target._delegate.handleDragOver) {
let [r, targX, targY] = target.transform_stage_point(stageX, stageY); 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 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 // 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. // to continue checking the parents.
target._delegate.handleDragOver(this.actor._delegate, let result = target._delegate.handleDragOver(this.actor._delegate,
this._dragActor, this._dragActor,
targX, targX,
targY, targY,
event.get_time()); event.get_time());
if (result != DragMotionResult.CONTINUE) {
global.set_cursor(DRAG_CURSOR_MAP[result]);
return true;
}
} }
target = target.get_parent(); target = target.get_parent();
} }
global.set_cursor(Shell.Cursor.IN_DRAG);
} }
return true; return true;
@ -418,6 +428,7 @@ _Draggable.prototype = {
} }
this._dragInProgress = false; this._dragInProgress = false;
global.unset_cursor();
this.emit('drag-end', event.get_time(), true); this.emit('drag-end', event.get_time(), true);
this._dragComplete(); this._dragComplete();
return true; return true;
@ -491,6 +502,7 @@ _Draggable.prototype = {
} else { } else {
dragActor.destroy(); dragActor.destroy();
} }
global.unset_cursor();
this.emit('drag-end', eventTime, false); this.emit('drag-end', eventTime, false);
this._animationInProgress = false; this._animationInProgress = false;

View File

@ -1586,6 +1586,15 @@ Workspace.prototype = {
}, },
// Draggable target interface // 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) { acceptDrop : function(source, actor, x, y, time) {
if (source instanceof WindowClone) { if (source instanceof WindowClone) {
let win = source.realWindow; let win = source.realWindow;

View File

@ -269,6 +269,14 @@ GenericWorkspacesView.prototype = {
throw new Error('Not implemented'); 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) { _acceptNewWorkspaceDrop: function(source, dropActor, x, y, time) {
let ws = this.addWorkspace(); let ws = this.addWorkspace();
if (ws == null) if (ws == null)
@ -487,14 +495,15 @@ NewWorkspaceArea.prototype = {
} }
}; };
function WorkspaceIndicator(activateWorkspace, workspaceAcceptDrop, scrollEventCb) { function WorkspaceIndicator(activateWorkspace, workspaceAcceptDrop, workspaceHandleDragOver, scrollEventCb) {
this._init(activateWorkspace, workspaceAcceptDrop, scrollEventCb); this._init(activateWorkspace, workspaceAcceptDrop, workspaceHandleDragOver, scrollEventCb);
} }
WorkspaceIndicator.prototype = { WorkspaceIndicator.prototype = {
_init: function(activateWorkspace, workspaceAcceptDrop, scrollEventCb) { _init: function(activateWorkspace, workspaceAcceptDrop, workspaceHandleDragOver, scrollEventCb) {
this._activateWorkspace = activateWorkspace; this._activateWorkspace = activateWorkspace;
this._workspaceAcceptDrop = workspaceAcceptDrop; this._workspaceAcceptDrop = workspaceAcceptDrop;
this._workspaceHandleDragOver = workspaceHandleDragOver;
this._scrollEventCb = scrollEventCb; this._scrollEventCb = scrollEventCb;
let actor = new St.Bin({ style_class: 'panel-button' }); let actor = new St.Bin({ style_class: 'panel-button' });
@ -592,6 +601,9 @@ WorkspaceIndicator.prototype = {
else else
return false; 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); actor.connect('scroll-event', this._scrollEventCb);
@ -1187,7 +1199,7 @@ SingleView.prototype = {
leftWorkspace.setReservedSlot(dragEvent.dragActor._delegate); leftWorkspace.setReservedSlot(dragEvent.dragActor._delegate);
this._dragOverLastX = leftEdge; this._dragOverLastX = leftEdge;
return DND.DragMotionResult.MOVE_DROP; return DND.DragMotionResult.CONTINUE;
} }
let rightEdge = primary.x + primary.width - 1; let rightEdge = primary.x + primary.width - 1;
let switchRight = (dragEvent.x >= rightEdge && rightWorkspace); let switchRight = (dragEvent.x >= rightEdge && rightWorkspace);
@ -1196,15 +1208,17 @@ SingleView.prototype = {
rightWorkspace.setReservedSlot(dragEvent.dragActor._delegate); rightWorkspace.setReservedSlot(dragEvent.dragActor._delegate);
this._dragOverLastX = rightEdge; this._dragOverLastX = rightEdge;
return DND.DragMotionResult.MOVE_DROP; return DND.DragMotionResult.CONTINUE;
} }
this._dragOverLastX = dragEvent.x; this._dragOverLastX = dragEvent.x;
let result = DND.DragMotionResult.CONTINUE;
// check hover state of new workspace area / inactive workspaces // check hover state of new workspace area / inactive workspaces
if (leftWorkspace) { if (leftWorkspace) {
if (dragEvent.targetActor == this._leftShadow) { if (dragEvent.targetActor == this._leftShadow) {
hoverWorkspace = leftWorkspace; hoverWorkspace = leftWorkspace;
leftWorkspace.opacity = leftWorkspace.actor.opacity = 255; leftWorkspace.opacity = leftWorkspace.actor.opacity = 255;
result = leftWorkspace.handleDragOver(dragEvent.source, dragEvent.dragActor);
} else { } else {
leftWorkspace.opacity = leftWorkspace.actor.opacity = 200; leftWorkspace.opacity = leftWorkspace.actor.opacity = 200;
} }
@ -1214,18 +1228,19 @@ SingleView.prototype = {
if (dragEvent.targetActor == this._rightShadow) { if (dragEvent.targetActor == this._rightShadow) {
hoverWorkspace = rightWorkspace; hoverWorkspace = rightWorkspace;
rightWorkspace.opacity = rightWorkspace.actor.opacity = 255; rightWorkspace.opacity = rightWorkspace.actor.opacity = 255;
result = rightWorkspace.handleDragOver(dragEvent.source, dragEvent.dragActor);
} else { } else {
rightWorkspace.opacity = rightWorkspace.actor.opacity = 200; rightWorkspace.opacity = rightWorkspace.actor.opacity = 200;
} }
} else { } else {
let targetParent = dragEvent.targetActor.get_parent(); let targetParent = dragEvent.targetActor.get_parent();
if (targetParent == this._newWorkspaceArea.actor) if (targetParent == this._newWorkspaceArea.actor) {
this._newWorkspaceArea.setStyle(true); this._newWorkspaceArea.setStyle(true);
else result = this._handleDragOverNewWorkspace(dragEvent.source, dragEvent.dragActor);
} else
this._newWorkspaceArea.setStyle(false); this._newWorkspaceArea.setStyle(false);
} }
// handle delayed workspace switches // handle delayed workspace switches
if (hoverWorkspace) { if (hoverWorkspace) {
if (!this._timeoutId) if (!this._timeoutId)
@ -1242,7 +1257,7 @@ SingleView.prototype = {
} }
} }
return DND.DragMotionResult.CONTINUE; return result;
}, },
_dragEnd: function() { _dragEnd: function() {
@ -1377,6 +1392,10 @@ SingleView.prototype = {
if (this._workspaces[i] != undefined) if (this._workspaces[i] != undefined)
return this._workspaces[i].acceptDrop(source, actor, x, y, time); return this._workspaces[i].acceptDrop(source, actor, x, y, time);
return false; 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)); }), Lang.bind(this, this._onScrollEvent));
actor.add(indicator.actor, { expand: true, x_fill: true, y_fill: true }); actor.add(indicator.actor, { expand: true, x_fill: true, y_fill: true });
@ -1464,6 +1483,10 @@ WorkspacesControls.prototype = {
function(source, actor, x, y, time) { function(source, actor, x, y, time) {
return this._currentView._acceptNewWorkspaceDrop(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, this.actor.add(this._addButton, { y_fill: false,
y_align: St.Align.START }); y_align: St.Align.START });