Use a separate icon image as a drag actor instead of using the clone of the icon

Clutter no longer allows using a clone of an actor that is not a part of
the scene graph. This is what used to happen when we created a clone for
the icon of the item that was being dragged, and then closed the More panes
with the original item, removing the icon from the scene graph. This was
also when happened when the user hit Esc while dragging, which prompted the
overlay to close, removing the original icon from the scene graph.

Rename getIcon() methods to createIcon() to better reflect on the fact that
a new icon is created each time the method is called (we do use cache in
some cases).

Remove a stray log message in overlay.js

Fixes http://bugzilla.gnome.org/show_bug.cgi?id=585490
and http://bugzilla.gnome.org/show_bug.cgi?id=585489
This commit is contained in:
Marina Zhurakhinskaya 2009-06-29 15:08:48 -04:00
parent 2ae89f3b36
commit 858a82fcdd
7 changed files with 33 additions and 46 deletions

View File

@ -27,7 +27,7 @@ AppInfo.prototype = {
this._gicon = this._gAppInfo.get_icon(); this._gicon = this._gAppInfo.get_icon();
}, },
getIcon : function(size) { createIcon : function(size) {
if (this._gicon) if (this._gicon)
return Shell.TextureCache.get_default().load_gicon(this._gicon, size); return Shell.TextureCache.get_default().load_gicon(this._gicon, size);
else else

View File

@ -21,7 +21,7 @@ DocInfo.prototype = {
this.mimeType = recentInfo.get_mime_type(); this.mimeType = recentInfo.get_mime_type();
}, },
getIcon : function(size) { createIcon : function(size) {
let icon = new Clutter.Texture(); let icon = new Clutter.Texture();
let iconPixbuf; let iconPixbuf;

View File

@ -41,8 +41,7 @@ AppDisplayItem.prototype = {
GenericDisplay.GenericDisplayItem.prototype._init.call(this, availableWidth); GenericDisplay.GenericDisplayItem.prototype._init.call(this, availableWidth);
this._appInfo = appInfo; this._appInfo = appInfo;
this._setItemInfo(appInfo.name, appInfo.description, this._setItemInfo(appInfo.name, appInfo.description);
appInfo.getIcon(GenericDisplay.ITEM_DISPLAY_ICON_SIZE));
}, },
//// Public method overrides //// //// Public method overrides ////
@ -54,6 +53,11 @@ AppDisplayItem.prototype = {
//// Protected method overrides //// //// Protected method overrides ////
// Returns an icon for the item.
_createIcon : function() {
return this._appInfo.createIcon(GenericDisplay.ITEM_DISPLAY_ICON_SIZE);
},
// Ensures the preview icon is created. // Ensures the preview icon is created.
_ensurePreviewIconCreated : function() { _ensurePreviewIconCreated : function() {
if (!this._showPreview || this._previewIcon) if (!this._showPreview || this._previewIcon)
@ -447,7 +451,7 @@ WellDisplayItem.prototype = {
let draggable = DND.makeDraggable(this.actor); let draggable = DND.makeDraggable(this.actor);
this._icon = appInfo.getIcon(APP_ICON_SIZE); this._icon = appInfo.createIcon(APP_ICON_SIZE);
this.actor.append(this._icon, Big.BoxPackFlags.NONE); this.actor.append(this._icon, Big.BoxPackFlags.NONE);
@ -475,8 +479,7 @@ WellDisplayItem.prototype = {
// Draggable interface - FIXME deduplicate with GenericDisplay // Draggable interface - FIXME deduplicate with GenericDisplay
getDragActor: function(stageX, stageY) { getDragActor: function(stageX, stageY) {
this.dragActor = new Clutter.Clone({ source: this._icon }); this.dragActor = this.appInfo.createIcon(APP_ICON_SIZE);
[this.dragActor.width, this.dragActor.height] = this._icon.get_transformed_size();
// If the user dragged from the icon itself, then position // If the user dragged from the icon itself, then position
// the dragActor over the original icon. Otherwise center it // the dragActor over the original icon. Otherwise center it

View File

@ -27,8 +27,7 @@ DocDisplayItem.prototype = {
GenericDisplay.GenericDisplayItem.prototype._init.call(this, availableWidth); GenericDisplay.GenericDisplayItem.prototype._init.call(this, availableWidth);
this._docInfo = docInfo; this._docInfo = docInfo;
this._setItemInfo(docInfo.name, "", this._setItemInfo(docInfo.name, "");
docInfo.getIcon(GenericDisplay.ITEM_DISPLAY_ICON_SIZE));
}, },
//// Public methods //// //// Public methods ////
@ -42,10 +41,15 @@ DocDisplayItem.prototype = {
//// Protected method overrides //// //// Protected method overrides ////
// Returns an icon for the item.
_createIcon : function() {
return this._docInfo.createIcon(GenericDisplay.ITEM_DISPLAY_ICON_SIZE);
},
// Ensures the preview icon is created. // Ensures the preview icon is created.
_ensurePreviewIconCreated : function() { _ensurePreviewIconCreated : function() {
if (!this._previewIcon) if (!this._previewIcon)
this._previewIcon = this._docInfo.getIcon(GenericDisplay.PREVIEW_ICON_SIZE); this._previewIcon = this._docInfo.createIcon(GenericDisplay.PREVIEW_ICON_SIZE);
}, },
// Creates and returns a large preview icon, but only if this._docInfo is an image file // Creates and returns a large preview icon, but only if this._docInfo is an image file

View File

@ -126,8 +126,7 @@ GenericDisplayItem.prototype = {
// Returns a cloned texture of the item's icon to represent the item as it // Returns a cloned texture of the item's icon to represent the item as it
// is being dragged. // is being dragged.
getDragActor: function(stageX, stageY) { getDragActor: function(stageX, stageY) {
this.dragActor = new Clutter.Clone({ source: this._icon }); this.dragActor = this._createIcon();
[this.dragActor.width, this.dragActor.height] = this._icon.get_transformed_size();
// If the user dragged from the icon itself, then position // If the user dragged from the icon itself, then position
// the dragActor over the original icon. Otherwise center it // the dragActor over the original icon. Otherwise center it
@ -142,8 +141,10 @@ GenericDisplayItem.prototype = {
return this.dragActor; return this.dragActor;
}, },
// Returns the original icon that is being used as a source for the cloned texture // Returns the item icon, a separate copy of which is used to
// that represents the item as it is being dragged. // represent the item as it is being dragged. This is used to
// determine a snap-back location for the drag icon if it does
// not get accepted by any drop target.
getDragActorSource: function() { getDragActorSource: function() {
return this._icon; return this._icon;
}, },
@ -238,9 +239,8 @@ GenericDisplayItem.prototype = {
* *
* nameText - name of the item * nameText - name of the item
* descriptionText - short description of the item * descriptionText - short description of the item
* iconActor - ClutterTexture containing the icon image which should be ITEM_DISPLAY_ICON_SIZE size
*/ */
_setItemInfo: function(nameText, descriptionText, iconActor) { _setItemInfo: function(nameText, descriptionText) {
if (this._name != null) { if (this._name != null) {
// this also removes this._name from the parent container, // this also removes this._name from the parent container,
// so we don't need to call this.actor.remove_actor(this._name) directly // so we don't need to call this.actor.remove_actor(this._name) directly
@ -263,7 +263,7 @@ GenericDisplayItem.prototype = {
this._previewIcon = null; this._previewIcon = null;
} }
this._icon = iconActor; this._icon = this._createIcon();
this.actor.add_actor(this._icon); this.actor.add_actor(this._icon);
let textWidth = this._availableWidth - (ITEM_DISPLAY_ICON_SIZE + 4) - INFORMATION_BUTTON_SIZE - ITEM_DISPLAY_PADDING_RIGHT; let textWidth = this._availableWidth - (ITEM_DISPLAY_ICON_SIZE + 4) - INFORMATION_BUTTON_SIZE - ITEM_DISPLAY_PADDING_RIGHT;
@ -294,6 +294,11 @@ GenericDisplayItem.prototype = {
//// Pure virtual protected methods //// //// Pure virtual protected methods ////
// Returns an icon for the item.
_createIcon: function() {
throw new Error("Not implemented");
},
// Ensures the preview icon is created. // Ensures the preview icon is created.
_ensurePreviewIconCreated: function() { _ensurePreviewIconCreated: function() {
throw new Error("Not implemented"); throw new Error("Not implemented");
@ -588,32 +593,8 @@ GenericDisplay.prototype = {
this.selectUp(); this.selectUp();
} }
if (displayItem.dragActor) { displayItem.destroy();
// The user might be handling a dragActor when the list of items
// changes (for example, if the dragging caused us to transition
// from an expanded overlay view to the regular view). So we need
// to keep the item around so that the drag and drop action initiated
// by the user can be completed. However, we remove the item from the list.
//
// For some reason, just removing the displayItem.actor
// is not enough to get displayItem._icon.visible
// to return false, so we hide the display item and
// all its children first. (We check displayItem._icon.visible
// when deciding if a dragActor has a place to snap back to
// in case the drop was not accepted by any actor.)
displayItem.actor.hide_all();
this._grid.remove_actor(displayItem.actor);
// We should not destroy the item up-front, because that would also
// destroy the icon that was used to clone the image for the drag actor.
// We destroy it once the dragActor is destroyed instead.
displayItem.dragActor.connect('destroy',
function(item) {
displayItem.destroy();
});
} else {
displayItem.destroy();
}
delete this._displayedItems[itemId]; delete this._displayedItems[itemId];
this._displayedItemsCount--; this._displayedItemsCount--;
}, },

View File

@ -762,7 +762,6 @@ Overlay.prototype = {
// the item on any workspace. // the item on any workspace.
handleDragOver : function(source, actor, x, y, time) { handleDragOver : function(source, actor, x, y, time) {
if (source instanceof GenericDisplay.GenericDisplayItem) { if (source instanceof GenericDisplay.GenericDisplayItem) {
log("unsetting more mode");
this._dash.unsetMoreMode(); this._dash.unsetMoreMode();
return true; return true;
} }

View File

@ -182,7 +182,7 @@ LauncherWidget.prototype = {
spacing: ITEM_SPACING, spacing: ITEM_SPACING,
reactive: true }); reactive: true });
item._info = info; item._info = info;
item.append(info.getIcon(ITEM_ICON_SIZE), Big.BoxPackFlags.NONE); item.append(info.createIcon(ITEM_ICON_SIZE), Big.BoxPackFlags.NONE);
item.append(new Clutter.Text({ color: ITEM_NAME_COLOR, item.append(new Clutter.Text({ color: ITEM_NAME_COLOR,
font_name: "Sans 14px", font_name: "Sans 14px",
ellipsize: Pango.EllipsizeMode.END, ellipsize: Pango.EllipsizeMode.END,
@ -203,7 +203,7 @@ LauncherWidget.prototype = {
padding: ITEM_PADDING, padding: ITEM_PADDING,
reactive: true }); reactive: true });
item._info = info; item._info = info;
item.append(info.getIcon(COLLAPSED_WIDTH - 2 * ITEM_PADDING), item.append(info.createIcon(COLLAPSED_WIDTH - 2 * ITEM_PADDING),
Big.BoxPackFlags.NONE); Big.BoxPackFlags.NONE);
this.collapsedActor.append(item, Big.BoxPackFlags.NONE); this.collapsedActor.append(item, Big.BoxPackFlags.NONE);