merge in ics-mr1-release history after reset to ics-mr1
diff --git a/res/drawable-hdpi/ic_home_all_apps_holo_dark.png b/res/drawable-hdpi/ic_home_all_apps_holo_dark.png
index a0bfc0f..1533a15 100644
--- a/res/drawable-hdpi/ic_home_all_apps_holo_dark.png
+++ b/res/drawable-hdpi/ic_home_all_apps_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_launcher_clear_active_holo.png b/res/drawable-hdpi/ic_launcher_clear_active_holo.png
new file mode 100644
index 0000000..cdd0052
--- /dev/null
+++ b/res/drawable-hdpi/ic_launcher_clear_active_holo.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_launcher_clear_normal_holo.png b/res/drawable-hdpi/ic_launcher_clear_normal_holo.png
new file mode 100644
index 0000000..84549ff
--- /dev/null
+++ b/res/drawable-hdpi/ic_launcher_clear_normal_holo.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_home_all_apps_holo_dark.png b/res/drawable-mdpi/ic_home_all_apps_holo_dark.png
index ffc3020..ebbc792 100644
--- a/res/drawable-mdpi/ic_home_all_apps_holo_dark.png
+++ b/res/drawable-mdpi/ic_home_all_apps_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher_clear_active_holo.png b/res/drawable-mdpi/ic_launcher_clear_active_holo.png
new file mode 100644
index 0000000..2683bea
--- /dev/null
+++ b/res/drawable-mdpi/ic_launcher_clear_active_holo.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher_clear_normal_holo.png b/res/drawable-mdpi/ic_launcher_clear_normal_holo.png
new file mode 100644
index 0000000..219f3e5
--- /dev/null
+++ b/res/drawable-mdpi/ic_launcher_clear_normal_holo.png
Binary files differ
diff --git a/res/drawable-sw600dp-hdpi/overscroll_glow_left.9.png b/res/drawable-sw600dp-hdpi/overscroll_glow_left.9.png
new file mode 100644
index 0000000..3928e2c
--- /dev/null
+++ b/res/drawable-sw600dp-hdpi/overscroll_glow_left.9.png
Binary files differ
diff --git a/res/drawable-sw600dp-hdpi/overscroll_glow_right.9.png b/res/drawable-sw600dp-hdpi/overscroll_glow_right.9.png
new file mode 100644
index 0000000..e34de34
--- /dev/null
+++ b/res/drawable-sw600dp-hdpi/overscroll_glow_right.9.png
Binary files differ
diff --git a/res/drawable-sw600dp-mdpi/overscroll_glow_left.9.png b/res/drawable-sw600dp-mdpi/overscroll_glow_left.9.png
new file mode 100644
index 0000000..58ec10c
--- /dev/null
+++ b/res/drawable-sw600dp-mdpi/overscroll_glow_left.9.png
Binary files differ
diff --git a/res/drawable-sw600dp-mdpi/overscroll_glow_right.9.png b/res/drawable-sw600dp-mdpi/overscroll_glow_right.9.png
new file mode 100644
index 0000000..a986fd3
--- /dev/null
+++ b/res/drawable-sw600dp-mdpi/overscroll_glow_right.9.png
Binary files differ
diff --git a/res/drawable-sw600dp-xhdpi/overscroll_glow_left.9.png b/res/drawable-sw600dp-xhdpi/overscroll_glow_left.9.png
new file mode 100644
index 0000000..b66dd2f
--- /dev/null
+++ b/res/drawable-sw600dp-xhdpi/overscroll_glow_left.9.png
Binary files differ
diff --git a/res/drawable-sw600dp-xhdpi/overscroll_glow_right.9.png b/res/drawable-sw600dp-xhdpi/overscroll_glow_right.9.png
new file mode 100644
index 0000000..3ccce33
--- /dev/null
+++ b/res/drawable-sw600dp-xhdpi/overscroll_glow_right.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_home_all_apps_holo_dark.png b/res/drawable-xhdpi/ic_home_all_apps_holo_dark.png
index 21a51ab..61d9b55 100644
--- a/res/drawable-xhdpi/ic_home_all_apps_holo_dark.png
+++ b/res/drawable-xhdpi/ic_home_all_apps_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_launcher_clear_active_holo.png b/res/drawable-xhdpi/ic_launcher_clear_active_holo.png
new file mode 100644
index 0000000..1a7e53d
--- /dev/null
+++ b/res/drawable-xhdpi/ic_launcher_clear_active_holo.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_launcher_clear_normal_holo.png b/res/drawable-xhdpi/ic_launcher_clear_normal_holo.png
new file mode 100644
index 0000000..d4965d9
--- /dev/null
+++ b/res/drawable-xhdpi/ic_launcher_clear_normal_holo.png
Binary files differ
diff --git a/res/drawable/remove_target_selector.xml b/res/drawable/remove_target_selector.xml
new file mode 100644
index 0000000..5e071fb
--- /dev/null
+++ b/res/drawable/remove_target_selector.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<transition xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/ic_launcher_clear_normal_holo"  />
+    <item android:drawable="@drawable/ic_launcher_clear_active_holo"  />
+</transition>
diff --git a/res/drawable/delete_target_selector.xml b/res/drawable/uninstall_target_selector.xml
similarity index 100%
rename from res/drawable/delete_target_selector.xml
rename to res/drawable/uninstall_target_selector.xml
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index 084b163..a74eb14 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -66,6 +66,11 @@
         <include android:id="@+id/cell5" layout="@layout/workspace_screen" />
     </com.android.launcher2.Workspace>
 
+    <include layout="@layout/hotseat"
+        android:id="@+id/hotseat"
+        android:layout_width="@dimen/button_bar_height_plus_padding"
+        android:layout_height="match_parent"
+        android:layout_gravity="right" />
     <include
         android:id="@+id/qsb_bar"
         layout="@layout/qsb_bar" />
@@ -76,12 +81,6 @@
         android:layout_height="match_parent"
         android:visibility="invisible" />
 
-    <include layout="@layout/hotseat"
-        android:id="@+id/hotseat"
-        android:layout_width="@dimen/button_bar_height_plus_padding"
-        android:layout_height="match_parent"
-        android:layout_gravity="right" />
-
     <include layout="@layout/workspace_cling"
         android:id="@+id/workspace_cling"
         android:layout_width="match_parent"
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index b8df2ee..062656f 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -60,16 +60,16 @@
         <include android:id="@+id/cell5" layout="@layout/workspace_screen" />
     </com.android.launcher2.Workspace>
 
-    <include
-        android:id="@+id/qsb_bar"
-        layout="@layout/qsb_bar" />
-
     <include layout="@layout/hotseat"
         android:id="@+id/hotseat"
         android:layout_width="match_parent"
         android:layout_height="@dimen/button_bar_height_plus_padding"
         android:layout_gravity="bottom" />
 
+    <include
+        android:id="@+id/qsb_bar"
+        layout="@layout/qsb_bar" />
+
     <include layout="@layout/apps_customize_pane"
         android:id="@+id/apps_customize_pane"
         android:layout_width="match_parent"
diff --git a/res/layout-sw600dp/search_bar.xml b/res/layout-sw600dp/search_bar.xml
index b852632..ebaf960 100644
--- a/res/layout-sw600dp/search_bar.xml
+++ b/res/layout-sw600dp/search_bar.xml
@@ -56,10 +56,9 @@
         android:contentDescription="@string/accessibility_voice_search_button" />
 
     <!-- AppsCustomize icon -->
-    <com.android.launcher2.StrokedTextView
+    <com.android.launcher2.HolographicImageView
         android:id="@+id/all_apps_button"
         android:onClick="onClickAllAppsButton"
-        android:drawableLeft="@drawable/ic_home_all_apps_holo_dark"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentRight="true"
@@ -69,20 +68,7 @@
         android:paddingRight="@dimen/toolbar_button_horizontal_padding"
         android:paddingTop="@dimen/all_apps_button_vertical_padding"
         android:paddingBottom="@dimen/all_apps_button_vertical_padding"
-        android:background="?android:attr/selectableItemBackground"
-
-        android:gravity="center"
-        android:textColor="#CCFFFFFF"
-        android:textSize="18sp"
-
-        launcher:strokeColor="#991e3157"
-        launcher:strokeTextColor="#DDFFFFFF"
-        launcher:strokeWidth="2.5"
-
-        android:shadowColor="#DA000000"
-        android:shadowDx="0.0"
-        android:shadowDy="0.0"
-        android:shadowRadius="2.5"
+        android:src="@drawable/ic_home_all_apps_holo_dark"
 
         android:focusable="true"
         android:clickable="true"
diff --git a/res/layout/apps_customize_pane.xml b/res/layout/apps_customize_pane.xml
index aaca695..af87653 100644
--- a/res/layout/apps_customize_pane.xml
+++ b/res/layout/apps_customize_pane.xml
@@ -65,10 +65,11 @@
                 launcher:clingFocusedX="@integer/apps_customize_cling_focused_x"
                 launcher:clingFocusedY="@integer/apps_customize_cling_focused_y"
                 launcher:maxGap="@dimen/workspace_max_gap" />
-            <ImageView
+            <FrameLayout
                 android:id="@+id/animation_buffer"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
+                android:background="#FF000000"
                 android:visibility="gone" />
 
             <include
diff --git a/res/layout/apps_customize_widget.xml b/res/layout/apps_customize_widget.xml
index 704401a..90883c5 100644
--- a/res/layout/apps_customize_widget.xml
+++ b/res/layout/apps_customize_widget.xml
@@ -63,7 +63,7 @@
     </LinearLayout>
 
     <!-- The icon of the widget. -->
-    <ImageView
+    <com.android.launcher2.PagedViewWidgetImageView
         android:id="@+id/widget_preview"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
diff --git a/res/layout/qsb_bar.xml b/res/layout/qsb_bar.xml
index c2179ce..9daf7bf 100644
--- a/res/layout/qsb_bar.xml
+++ b/res/layout/qsb_bar.xml
@@ -37,7 +37,7 @@
                 style="@style/DropTargetButton"
                 android:id="@+id/delete_target_text"
                 android:text="@string/delete_zone_label_workspace"
-                android:drawableLeft="@drawable/delete_target_selector" />
+                android:drawableLeft="@drawable/remove_target_selector" />
         </FrameLayout>
 
         <FrameLayout
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index 6667f7c..af5141f 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -31,13 +31,13 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
 import android.graphics.Canvas;
 import android.graphics.MaskFilter;
 import android.graphics.Paint;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.RectF;
-import android.graphics.Bitmap.Config;
 import android.graphics.TableMaskFilter;
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
@@ -48,10 +48,10 @@
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
 import android.widget.GridLayout;
 import android.widget.ImageView;
 import android.widget.Toast;
@@ -86,18 +86,17 @@
         items = l;
         sourceImages = si;
         generatedImages = new ArrayList<Bitmap>();
-        cellWidth = cellHeight = -1;
+        maxImageWidth = maxImageHeight = -1;
         doInBackgroundCallback = bgR;
         postExecuteCallback = postR;
     }
-    AsyncTaskPageData(int p, ArrayList<Object> l, int cw, int ch, int ccx, AsyncTaskCallback bgR,
+    AsyncTaskPageData(int p, ArrayList<Object> l, int cw, int ch, AsyncTaskCallback bgR,
             AsyncTaskCallback postR) {
         page = p;
         items = l;
         generatedImages = new ArrayList<Bitmap>();
-        cellWidth = cw;
-        cellHeight = ch;
-        cellCountX = ccx;
+        maxImageWidth = cw;
+        maxImageHeight = ch;
         doInBackgroundCallback = bgR;
         postExecuteCallback = postR;
     }
@@ -124,9 +123,8 @@
     ArrayList<Object> items;
     ArrayList<Bitmap> sourceImages;
     ArrayList<Bitmap> generatedImages;
-    int cellWidth;
-    int cellHeight;
-    int cellCountX;
+    int maxImageWidth;
+    int maxImageHeight;
     AsyncTaskCallback doInBackgroundCallback;
     AsyncTaskCallback postExecuteCallback;
 }
@@ -460,7 +458,14 @@
             AppWidgetManager.getInstance(mLauncher).getInstalledProviders();
         Intent shortcutsIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
         List<ResolveInfo> shortcuts = mPackageManager.queryIntentActivities(shortcutsIntent, 0);
-        mWidgets.addAll(widgets);
+        for (AppWidgetProviderInfo widget : widgets) {
+            if (widget.minWidth > 0 && widget.minHeight > 0) {
+                mWidgets.add(widget);
+            } else {
+                Log.e(LOG_TAG, "Widget " + widget.provider + " has invalid dimensions (" +
+                        widget.minWidth + ", " + widget.minHeight + ")");
+            }
+        }
         mWidgets.addAll(shortcuts);
         Collections.sort(mWidgets,
                 new LauncherModel.WidgetAndShortcutNameComparator(mPackageManager));
@@ -530,26 +535,23 @@
 
         // Compose the drag image
         Bitmap b;
-        Drawable preview = image.getDrawable();
-        RectF mTmpScaleRect = new RectF(0f,0f,1f,1f);
-        image.getImageMatrix().mapRect(mTmpScaleRect);
-        float scale = mTmpScaleRect.right;
-        int w = (int) (preview.getIntrinsicWidth() * scale);
-        int h = (int) (preview.getIntrinsicHeight() * scale);
         if (createItemInfo instanceof PendingAddWidgetInfo) {
             PendingAddWidgetInfo createWidgetInfo = (PendingAddWidgetInfo) createItemInfo;
             int[] spanXY = mLauncher.getSpanForWidget(createWidgetInfo, null);
             createItemInfo.spanX = spanXY[0];
             createItemInfo.spanY = spanXY[1];
 
-            b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
-            renderDrawableToBitmap(preview, b, 0, 0, w, h, scale, mDragViewMultiplyColor);
+            int[] maxSize = mLauncher.getWorkspace().estimateItemSize(spanXY[0], spanXY[1],
+                    createWidgetInfo, true);
+            b = getWidgetPreview(createWidgetInfo.componentName, createWidgetInfo.previewImage,
+                    createWidgetInfo.icon, spanXY[0], spanXY[1], maxSize[0], maxSize[1]);
         } else {
             // Workaround for the fact that we don't keep the original ResolveInfo associated with
             // the shortcut around.  To get the icon, we just render the preview image (which has
             // the shortcut icon) to a new drag bitmap that clips the non-icon space.
             b = Bitmap.createBitmap(mWidgetPreviewIconPaddedDimension,
                     mWidgetPreviewIconPaddedDimension, Bitmap.Config.ARGB_8888);
+            Drawable preview = image.getDrawable();
             mCanvas.setBitmap(b);
             mCanvas.save();
             preview.draw(mCanvas);
@@ -562,7 +564,7 @@
         // We use a custom alpha clip table for the default widget previews
         Paint alphaClipPaint = null;
         if (createItemInfo instanceof PendingAddWidgetInfo) {
-            if (((PendingAddWidgetInfo) createItemInfo).hasDefaultPreview) {
+            if (((PendingAddWidgetInfo) createItemInfo).previewImage != 0) {
                 MaskFilter alphaClipTable = TableMaskFilter.CreateClipTable(0, 255);
                 alphaClipPaint = new Paint();
                 alphaClipPaint.setMaskFilter(alphaClipTable);
@@ -571,8 +573,7 @@
 
         // Start the drag
         mLauncher.lockScreenOrientationOnLargeUI();
-        mLauncher.getWorkspace().onDragStartedWithItemSpans(createItemInfo.spanX,
-                createItemInfo.spanY, b, alphaClipPaint);
+        mLauncher.getWorkspace().onDragStartedWithItem(createItemInfo, b, alphaClipPaint);
         mDragController.startDrag(image, b, this, createItemInfo,
                 DragController.DRAG_ACTION_COPY, null);
         b.recycle();
@@ -783,7 +784,7 @@
         // We introduce a slight delay to order the loading of side pages so that we don't thrash
         final int sleepMs = getSleepForPage(page + mNumAppsPages);
         AsyncTaskPageData pageData = new AsyncTaskPageData(page, widgets, cellWidth, cellHeight,
-            cellCountX, new AsyncTaskCallback() {
+            new AsyncTaskCallback() {
                 @Override
                 public void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data) {
                     try {
@@ -929,7 +930,7 @@
             c.setBitmap(null);
         }
     }
-    private Bitmap getShortcutPreview(ResolveInfo info, int cellWidth, int cellHeight) {
+    private Bitmap getShortcutPreview(ResolveInfo info) {
         // Render the background
         int offset = 0;
         int bitmapSize = mAppIconSize;
@@ -940,74 +941,71 @@
         renderDrawableToBitmap(icon, preview, offset, offset, mAppIconSize, mAppIconSize);
         return preview;
     }
-    private Bitmap getWidgetPreview(AppWidgetProviderInfo info,
-            int cellHSpan, int cellVSpan, int cellWidth, int cellHeight) {
 
+    private Bitmap getWidgetPreview(ComponentName provider, int previewImage, int iconId,
+            int cellHSpan, int cellVSpan, int maxWidth, int maxHeight) {
         // Load the preview image if possible
-        String packageName = info.provider.getPackageName();
-        Drawable drawable = null;
-        Bitmap preview = null;
-        if (info.previewImage != 0) {
-            drawable = mPackageManager.getDrawable(packageName, info.previewImage, null);
-            if (drawable == null) {
-                Log.w(LOG_TAG, "Can't load icon drawable 0x" + Integer.toHexString(info.icon)
-                        + " for provider: " + info.provider);
-            } else {
-                // Map the target width/height to the cell dimensions
-                int targetWidth = mWidgetSpacingLayout.estimateCellWidth(cellHSpan);
-                int targetHeight = mWidgetSpacingLayout.estimateCellHeight(cellVSpan);
-                int targetCellWidth;
-                int targetCellHeight;
-                if (targetWidth >= targetHeight) {
-                    targetCellWidth = Math.min(targetWidth, cellWidth);
-                    targetCellHeight = (int) (cellHeight * ((float) targetCellWidth / cellWidth));
-                } else {
-                    targetCellHeight = Math.min(targetHeight, cellHeight);
-                    targetCellWidth = (int) (cellWidth * ((float) targetCellHeight / cellHeight));
-                }
-                // Map the preview to the target cell dimensions
-                int bitmapWidth = Math.min(targetCellWidth, drawable.getIntrinsicWidth());
-                int bitmapHeight = (int) (drawable.getIntrinsicHeight() *
-                        ((float) bitmapWidth / drawable.getIntrinsicWidth()));
+        String packageName = provider.getPackageName();
+        if (maxWidth < 0) maxWidth = Integer.MAX_VALUE;
+        if (maxHeight < 0) maxHeight = Integer.MAX_VALUE;
 
-                preview = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Config.ARGB_8888);
-                renderDrawableToBitmap(drawable, preview, 0, 0, bitmapWidth, bitmapHeight);
+        Drawable drawable = null;
+        if (previewImage != 0) {
+            drawable = mPackageManager.getDrawable(packageName, previewImage, null);
+            if (drawable == null) {
+                Log.w(LOG_TAG, "Can't load widget preview drawable 0x" +
+                        Integer.toHexString(previewImage) + " for provider: " + provider);
             }
         }
 
-        // Generate a preview image if we couldn't load one
-        if (drawable == null) {
-            Resources resources = mLauncher.getResources();
+        int bitmapWidth;
+        int bitmapHeight;
+        boolean widgetPreviewExists = (drawable != null);
+        if (widgetPreviewExists) {
+            bitmapWidth = drawable.getIntrinsicWidth();
+            bitmapHeight = drawable.getIntrinsicHeight();
+
+            // Cap the size so widget previews don't appear larger than the actual widget
+            maxWidth = Math.min(maxWidth, mWidgetSpacingLayout.estimateCellWidth(cellHSpan));
+            maxHeight = Math.min(maxHeight, mWidgetSpacingLayout.estimateCellHeight(cellVSpan));
+        } else {
+            // Determine the size of the bitmap for the preview image we will generate
             // TODO: This actually uses the apps customize cell layout params, where as we make want
             // the Workspace params for more accuracy.
-            int targetWidth = mWidgetSpacingLayout.estimateCellWidth(cellHSpan);
-            int targetHeight = mWidgetSpacingLayout.estimateCellHeight(cellVSpan);
-            int bitmapWidth = targetWidth;
-            int bitmapHeight = targetHeight;
-            int minOffset = (int) (mAppIconSize * sWidgetPreviewIconPaddingPercentage);
-            float iconScale = 1f;
-
-            // Determine the size of the bitmap we want to draw
+            bitmapWidth = mWidgetSpacingLayout.estimateCellWidth(cellHSpan);
+            bitmapHeight = mWidgetSpacingLayout.estimateCellHeight(cellVSpan);
             if (cellHSpan == cellVSpan) {
                 // For square widgets, we just have a fixed size for 1x1 and larger-than-1x1
+                int minOffset = (int) (mAppIconSize * sWidgetPreviewIconPaddingPercentage);
                 if (cellHSpan <= 1) {
                     bitmapWidth = bitmapHeight = mAppIconSize + 2 * minOffset;
                 } else {
                     bitmapWidth = bitmapHeight = mAppIconSize + 4 * minOffset;
                 }
-            } else {
-                // Otherwise, ensure that we are properly sized within the cellWidth/Height
-                if (targetWidth >= targetHeight) {
-                    bitmapWidth = Math.min(targetWidth, cellWidth);
-                    bitmapHeight = (int) (targetHeight * ((float) bitmapWidth / targetWidth));
-                    iconScale = Math.min((float) bitmapHeight / (mAppIconSize + 2 * minOffset), 1f);
-                } else {
-                    bitmapHeight = Math.min(targetHeight, cellHeight);
-                    bitmapWidth = (int) (targetWidth * ((float) bitmapHeight / targetHeight));
-                    iconScale = Math.min((float) bitmapWidth / (mAppIconSize + 2 * minOffset), 1f);
-                }
             }
-            preview = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Config.ARGB_8888);
+        }
+
+        float scale = 1f;
+        if (bitmapWidth > maxWidth) {
+            scale = maxWidth / (float) bitmapWidth;
+        }
+        if (bitmapHeight * scale > maxHeight) {
+            scale = maxHeight / (float) bitmapHeight;
+        }
+        if (scale != 1f) {
+            bitmapWidth = (int) (scale * bitmapWidth);
+            bitmapHeight = (int) (scale * bitmapHeight);
+        }
+
+        Bitmap preview = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Config.ARGB_8888);
+
+        if (widgetPreviewExists) {
+            renderDrawableToBitmap(drawable, preview, 0, 0, bitmapWidth, bitmapHeight);
+        } else {
+            // Generate a preview image if we couldn't load one
+            int minOffset = (int) (mAppIconSize * sWidgetPreviewIconPaddingPercentage);
+            int smallestSide = Math.min(bitmapWidth, bitmapHeight);
+            float iconScale = Math.min((float) smallestSide / (mAppIconSize + 2 * minOffset), 1f);
             if (cellHSpan != 1 || cellVSpan != 1) {
                 renderDrawableToBitmap(mDefaultWidgetBackground, preview, 0, 0, bitmapWidth,
                         bitmapHeight);
@@ -1018,7 +1016,8 @@
                 Drawable icon = null;
                 int hoffset = (int) (bitmapWidth / 2 - mAppIconSize * iconScale / 2);
                 int yoffset = (int) (bitmapHeight / 2 - mAppIconSize * iconScale / 2);
-                if (info.icon > 0) icon = mIconCache.getFullResIcon(packageName, info.icon);
+                if (iconId > 0) icon = mIconCache.getFullResIcon(packageName, iconId);
+                Resources resources = mLauncher.getResources();
                 if (icon == null) icon = resources.getDrawable(R.drawable.ic_launcher_application);
 
                 renderDrawableToBitmap(icon, preview, hoffset, yoffset,
@@ -1029,16 +1028,16 @@
         return preview;
     }
 
-    public void syncWidgetPageItems(int page, boolean immediate) {
+    public void syncWidgetPageItems(final int page, final boolean immediate) {
         int numItemsPerPage = mWidgetCountX * mWidgetCountY;
-        int contentWidth = mWidgetSpacingLayout.getContentWidth();
-        int contentHeight = mWidgetSpacingLayout.getContentHeight();
 
         // Calculate the dimensions of each cell we are giving to each widget
-        ArrayList<Object> items = new ArrayList<Object>();
-        int cellWidth = ((contentWidth - mPageLayoutPaddingLeft - mPageLayoutPaddingRight
+        final ArrayList<Object> items = new ArrayList<Object>();
+        int contentWidth = mWidgetSpacingLayout.getContentWidth();
+        final int cellWidth = ((contentWidth - mPageLayoutPaddingLeft - mPageLayoutPaddingRight
                 - ((mWidgetCountX - 1) * mWidgetWidthGap)) / mWidgetCountX);
-        int cellHeight = ((contentHeight - mPageLayoutPaddingTop - mPageLayoutPaddingBottom
+        int contentHeight = mWidgetSpacingLayout.getContentHeight();
+        final int cellHeight = ((contentHeight - mPageLayoutPaddingTop - mPageLayoutPaddingBottom
                 - ((mWidgetCountY - 1) * mWidgetHeightGap)) / mWidgetCountY);
 
         // Prepare the set of widgets to load previews for in the background
@@ -1048,7 +1047,7 @@
         }
 
         // Prepopulate the pages with the other widget info, and fill in the previews later
-        PagedViewGridLayout layout = (PagedViewGridLayout) getPageAt(page + mNumAppsPages);
+        final PagedViewGridLayout layout = (PagedViewGridLayout) getPageAt(page + mNumAppsPages);
         layout.setColumnCount(layout.getCellCountX());
         for (int i = 0; i < items.size(); ++i) {
             Object rawInfo = items.get(i);
@@ -1091,15 +1090,31 @@
             layout.addView(widget, lp);
         }
 
-        // Load the widget previews
-        if (immediate) {
-            AsyncTaskPageData data = new AsyncTaskPageData(page, items, cellWidth, cellHeight,
-                    mWidgetCountX, null, null);
-            loadWidgetPreviewsInBackground(null, data);
-            onSyncWidgetPageItems(data);
-        } else {
-            prepareLoadWidgetPreviewsTask(page, items, cellWidth, cellHeight, mWidgetCountX);
-        }
+        // wait until a call on onLayout to start loading, because
+        // PagedViewWidget.getPreviewSize() will return 0 if it hasn't been laid out
+        // TODO: can we do a measure/layout immediately?
+        layout.setOnLayoutListener(new Runnable() {
+            public void run() {
+                // Load the widget previews
+                int maxPreviewWidth = cellWidth;
+                int maxPreviewHeight = cellHeight;
+                if (layout.getChildCount() > 0) {
+                    PagedViewWidget w = (PagedViewWidget) layout.getChildAt(0);
+                    int[] maxSize = w.getPreviewSize();
+                    maxPreviewWidth = maxSize[0];
+                    maxPreviewHeight = maxSize[1];
+                }
+                if (immediate) {
+                    AsyncTaskPageData data = new AsyncTaskPageData(page, items,
+                            maxPreviewWidth, maxPreviewHeight, null, null);
+                    loadWidgetPreviewsInBackground(null, data);
+                    onSyncWidgetPageItems(data);
+                } else {
+                    prepareLoadWidgetPreviewsTask(page, items,
+                            maxPreviewWidth, maxPreviewHeight, mWidgetCountX);
+                }
+            }
+        });
     }
     private void loadWidgetPreviewsInBackground(AppsCustomizeAsyncTask task,
             AsyncTaskPageData data) {
@@ -1112,8 +1127,6 @@
         ArrayList<Object> items = data.items;
         ArrayList<Bitmap> images = data.generatedImages;
         int count = items.size();
-        int cellWidth = data.cellWidth;
-        int cellHeight = data.cellHeight;
         for (int i = 0; i < count; ++i) {
             if (task != null) {
                 // Ensure we haven't been cancelled yet
@@ -1127,12 +1140,13 @@
             if (rawInfo instanceof AppWidgetProviderInfo) {
                 AppWidgetProviderInfo info = (AppWidgetProviderInfo) rawInfo;
                 int[] cellSpans = mLauncher.getSpanForWidget(info, null);
-                images.add(getWidgetPreview(info, cellSpans[0],cellSpans[1],
-                        cellWidth, cellHeight));
+                Bitmap b = getWidgetPreview(info.provider, info.previewImage, info.icon,
+                        cellSpans[0], cellSpans[1], data.maxImageWidth, data.maxImageHeight);
+                images.add(b);
             } else if (rawInfo instanceof ResolveInfo) {
                 // Fill in the shortcuts information
                 ResolveInfo info = (ResolveInfo) rawInfo;
-                images.add(getShortcutPreview(info, cellWidth, cellHeight));
+                images.add(getShortcutPreview(info));
             }
         }
     }
@@ -1146,11 +1160,7 @@
             PagedViewWidget widget = (PagedViewWidget) layout.getChildAt(i);
             if (widget != null) {
                 Bitmap preview = data.generatedImages.get(i);
-                boolean scale =
-                    (preview.getWidth() >= data.cellWidth ||
-                     preview.getHeight() >= data.cellHeight);
-
-                widget.applyPreview(new FastBitmapDrawable(preview), i, scale);
+                widget.applyPreview(new FastBitmapDrawable(preview), i);
             }
         }
         layout.createHardwareLayer();
@@ -1265,7 +1275,7 @@
                         scale = 1.0f;
                         alpha = 1.0f;
                         // On the first page, we don't want the page to have any lateral motion
-                        translationX = getScrollX();
+                        translationX = 0;
                     } else if (i == getChildCount() - 1 && scrollProgress > 0) {
                         // Overscroll to the right
                         v.setPivotX((1 - TRANSITION_PIVOT) * pageWidth);
@@ -1273,7 +1283,7 @@
                         scale = 1.0f;
                         alpha = 1.0f;
                         // On the last page, we don't want the page to have any lateral motion.
-                        translationX =  getScrollX() - mMaxScrollX;
+                        translationX = 0;
                     } else {
                         v.setPivotY(pageHeight / 2.0f);
                         v.setPivotX(pageWidth / 2.0f);
@@ -1285,6 +1295,14 @@
                 v.setScaleX(scale);
                 v.setScaleY(scale);
                 v.setAlpha(alpha);
+
+                // If the view has 0 alpha, we set it to be invisible so as to prevent
+                // it from accepting touches
+                if (alpha < ViewConfiguration.ALPHA_THRESHOLD) {
+                    v.setVisibility(INVISIBLE);
+                } else if (v.getVisibility() != VISIBLE) {
+                    v.setVisibility(VISIBLE);
+                }
             }
         }
     }
@@ -1421,6 +1439,7 @@
         ApplicationInfo.dumpApplicationInfoList(LOG_TAG, "mApps", mApps);
         dumpAppWidgetProviderInfoList(LOG_TAG, "mWidgets", mWidgets);
     }
+
     private void dumpAppWidgetProviderInfoList(String tag, String label,
             ArrayList<Object> list) {
         Log.d(tag, label + " size=" + list.size());
@@ -1438,6 +1457,7 @@
             }
         }
     }
+
     @Override
     public void surrender() {
         // TODO: If we are in the middle of any process (ie. for holographic outlines, etc) we
diff --git a/src/com/android/launcher2/AppsCustomizeTabHost.java b/src/com/android/launcher2/AppsCustomizeTabHost.java
index 688ea15..41f8d7e 100644
--- a/src/com/android/launcher2/AppsCustomizeTabHost.java
+++ b/src/com/android/launcher2/AppsCustomizeTabHost.java
@@ -22,21 +22,20 @@
 import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.animation.DecelerateInterpolator;
-import android.widget.ImageView;
+import android.widget.FrameLayout;
 import android.widget.TabHost;
 import android.widget.TabWidget;
 import android.widget.TextView;
 
 import com.android.launcher.R;
 
+import java.util.ArrayList;
+
 public class AppsCustomizeTabHost extends TabHost implements LauncherTransitionable,
         TabHost.OnTabChangeListener  {
     static final String LOG_TAG = "AppsCustomizeTabHost";
@@ -49,7 +48,7 @@
     private ViewGroup mTabsContainer;
     private AppsCustomizePagedView mAppsCustomizePane;
     private boolean mSuppressContentCallback = false;
-    private ImageView mAnimationBuffer;
+    private FrameLayout mAnimationBuffer;
 
     private boolean mInTransition;
     private boolean mResetAfterTransition;
@@ -93,7 +92,7 @@
         mTabs = tabs;
         mTabsContainer = tabsContainer;
         mAppsCustomizePane = appsCustomizePane;
-        mAnimationBuffer = (ImageView) findViewById(R.id.animation_buffer);
+        mAnimationBuffer = (FrameLayout) findViewById(R.id.animation_buffer);
         if (tabs == null || mAppsCustomizePane == null) throw new Resources.NotFoundException();
 
         // Configure the tabs content factory to return the same paged view (that we change the
@@ -138,9 +137,8 @@
         // Set the width of the tab list to the content width
         if (remeasureTabWidth) {
             int contentWidth = mAppsCustomizePane.getPageContentWidth();
-            if (contentWidth > 0) {
-                // Set the width and show the tab bar (if we have a loading graphic, we can switch
-                // it off here)
+            if (contentWidth > 0 && mTabs.getLayoutParams().width != contentWidth) {
+                // Set the width and show the tab bar
                 mTabs.getLayoutParams().width = contentWidth;
                 post(new Runnable() {
                     public void run() {
@@ -202,17 +200,35 @@
                     return;
                 }
 
-                // Setup the animation buffer
-                Bitmap b = Bitmap.createBitmap(mAppsCustomizePane.getMeasuredWidth(),
-                        mAppsCustomizePane.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
-                Canvas c = new Canvas(b);
-                mAppsCustomizePane.draw(c);
-                mAppsCustomizePane.setAlpha(0f);
-                mAnimationBuffer.setImageBitmap(b);
-                mAnimationBuffer.setAlpha(1f);
-                mAnimationBuffer.setVisibility(View.VISIBLE);
-                c.setBitmap(null);
-                b = null;
+                // Take the visible pages and re-parent them temporarily to mAnimatorBuffer
+                // and then cross fade to the new pages
+
+                // We want the pages to be rendered in exactly the same way as they were when
+                // their parent was mAppsCustomizePane -- so set the scroll on mAnimationBuffer
+                // to be exactly the same as mAppsCustomizePane, and below, set the left/top
+                // parameters to be correct for each of the pages
+                mAnimationBuffer.scrollTo(mAppsCustomizePane.getScrollX(), 0);
+
+                int[] visiblePageRange = new int[2];
+                mAppsCustomizePane.getVisiblePages(visiblePageRange);
+                ArrayList<View> visiblePages = new ArrayList<View>();
+                for (int i = visiblePageRange[0]; i <= visiblePageRange[1]; i++) {
+                    visiblePages.add(mAppsCustomizePane.getPageAt(i));
+                }
+                // mAppsCustomizePane renders its children in reverse order, so
+                // add the pages to mAnimationBuffer in reverse order to match that behavior
+                for (int i = visiblePages.size() - 1; i >= 0; i--) {
+                    View child = visiblePages.get(i);
+                    PagedViewWidget.setDeletePreviewsWhenDetachedFromWindow(false);
+                    mAppsCustomizePane.removeView(child);
+                    PagedViewWidget.setDeletePreviewsWhenDetachedFromWindow(true);
+                    mAnimationBuffer.setAlpha(1f);
+                    mAnimationBuffer.setVisibility(View.VISIBLE);
+                    LayoutParams p = new FrameLayout.LayoutParams(child.getWidth(),
+                            child.getHeight());
+                    p.setMargins((int) child.getLeft(), (int) child.getTop(), 0, 0);
+                    mAnimationBuffer.addView(child, p);
+                }
 
                 // Toggle the new content
                 onTabChangedStart();
@@ -224,7 +240,12 @@
                     @Override
                     public void onAnimationEnd(Animator animation) {
                         mAnimationBuffer.setVisibility(View.GONE);
-                        mAnimationBuffer.setImageBitmap(null);
+                        mAnimationBuffer.removeAllViews();
+                    }
+                    @Override
+                    public void onAnimationCancel(Animator animation) {
+                        mAnimationBuffer.setVisibility(View.GONE);
+                        mAnimationBuffer.removeAllViews();
                     }
                 });
                 ObjectAnimator inAnim = ObjectAnimator.ofFloat(mAppsCustomizePane, "alpha", 1f);
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index 9ffc1d0..6e60280 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -36,7 +36,6 @@
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
 import android.graphics.RectF;
-import android.graphics.Region;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.NinePatchDrawable;
 import android.util.AttributeSet;
@@ -72,6 +71,7 @@
     private int mWidthGap;
     private int mHeightGap;
     private int mMaxGap;
+    private boolean mScrollingTransformsDirty = false;
 
     private final Rect mRect = new Rect();
     private final CellInfo mCellInfo = new CellInfo();
@@ -102,9 +102,6 @@
     private Drawable mOverScrollRight;
     private Rect mBackgroundRect;
     private Rect mForegroundRect;
-    private Rect mGlowBackgroundRect;
-    private float mGlowBackgroundScale;
-    private float mGlowBackgroundAlpha;
     private int mForegroundPadding;
 
     // If we're actively dragging something over this screen, mIsDragOverlapping is true
@@ -258,9 +255,6 @@
 
         mBackgroundRect = new Rect();
         mForegroundRect = new Rect();
-        mGlowBackgroundRect = new Rect();
-        setHoverScale(1.0f);
-        setHoverAlpha(1.0f);
 
         mChildren = new CellLayoutChildren(context);
         mChildren.setCellDimensions(mCellWidth, mCellHeight, mWidthGap, mHeightGap);
@@ -351,68 +345,23 @@
         return mIsDragOverlapping;
     }
 
-    private void updateGlowRect() {
-        float marginFraction = (mGlowBackgroundScale - 1.0f) / 2.0f;
-        int marginX = (int) (marginFraction * (mBackgroundRect.right - mBackgroundRect.left));
-        int marginY = (int) (marginFraction * (mBackgroundRect.bottom - mBackgroundRect.top));
-        mGlowBackgroundRect.set(mBackgroundRect.left - marginX, mBackgroundRect.top - marginY,
-                mBackgroundRect.right + marginX, mBackgroundRect.bottom + marginY);
-        invalidate();
+    protected void setOverscrollTransformsDirty(boolean dirty) {
+        mScrollingTransformsDirty = dirty;
     }
 
-    public void setHoverScale(float scaleFactor) {
-        if (scaleFactor != mGlowBackgroundScale) {
-            mGlowBackgroundScale = scaleFactor;
-            updateGlowRect();
-            if (getParent() != null) {
-                ((View) getParent()).invalidate();
-            }
+    protected void resetOverscrollTransforms() {
+        if (mScrollingTransformsDirty) {
+            setOverscrollTransformsDirty(false);
+            setTranslationX(0);
+            setRotationY(0);
+            // It doesn't matter if we pass true or false here, the important thing is that we
+            // pass 0, which results in the overscroll drawable not being drawn any more.
+            setOverScrollAmount(0, false);
+            setPivotX(getMeasuredWidth() / 2);
+            setPivotY(getMeasuredHeight() / 2);
         }
     }
 
-    public float getHoverScale() {
-        return mGlowBackgroundScale;
-    }
-
-    public float getHoverAlpha() {
-        return mGlowBackgroundAlpha;
-    }
-
-    public void setHoverAlpha(float alpha) {
-        mGlowBackgroundAlpha = alpha;
-        invalidate();
-    }
-
-    void animateDrop() {
-        Resources res = getResources();
-        float onDropScale = res.getInteger(R.integer.config_screenOnDropScalePercent) / 100.0f;
-        ObjectAnimator scaleUp = ObjectAnimator.ofFloat(this, "hoverScale", onDropScale);
-        scaleUp.setDuration(res.getInteger(R.integer.config_screenOnDropScaleUpDuration));
-        ObjectAnimator scaleDown = ObjectAnimator.ofFloat(this, "hoverScale", 1.0f);
-        scaleDown.setDuration(res.getInteger(R.integer.config_screenOnDropScaleDownDuration));
-        ObjectAnimator alphaFadeOut = ObjectAnimator.ofFloat(this, "hoverAlpha", 0.0f);
-
-        alphaFadeOut.setStartDelay(res.getInteger(R.integer.config_screenOnDropAlphaFadeDelay));
-        alphaFadeOut.setDuration(res.getInteger(R.integer.config_screenOnDropAlphaFadeDuration));
-
-        AnimatorSet bouncer = new AnimatorSet();
-        bouncer.play(scaleUp).before(scaleDown);
-        bouncer.play(scaleUp).with(alphaFadeOut);
-        bouncer.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationStart(Animator animation) {
-                setIsDragOverlapping(true);
-            }
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                setIsDragOverlapping(false);
-                setHoverScale(1.0f);
-                setHoverAlpha(1.0f);
-            }
-        });
-        bouncer.start();
-    }
-
     @Override
     protected void onDraw(Canvas canvas) {
         // When we're large, we are either drawn in a "hover" state (ie when dragging an item to
@@ -939,7 +888,6 @@
         mBackgroundRect.set(0, 0, w, h);
         mForegroundRect.set(mForegroundPadding, mForegroundPadding,
                 w - 2 * mForegroundPadding, h - 2 * mForegroundPadding);
-        updateGlowRect();
     }
 
     @Override
diff --git a/src/com/android/launcher2/DeleteDropTarget.java b/src/com/android/launcher2/DeleteDropTarget.java
index 1553d3c..4e93b22 100644
--- a/src/com/android/launcher2/DeleteDropTarget.java
+++ b/src/com/android/launcher2/DeleteDropTarget.java
@@ -23,6 +23,7 @@
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.graphics.drawable.TransitionDrawable;
 import android.util.AttributeSet;
 import android.view.View;
@@ -35,8 +36,10 @@
 
     private static int DELETE_ANIMATION_DURATION = 250;
     private ColorStateList mOriginalTextColor;
-    private TransitionDrawable mDrawable;
     private int mHoverColor = 0xFFFF0000;
+    private TransitionDrawable mUninstallDrawable;
+    private TransitionDrawable mRemoveDrawable;
+    private TransitionDrawable mCurrentDrawable;
 
     public DeleteDropTarget(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
@@ -58,8 +61,16 @@
         mHoverColor = r.getColor(R.color.delete_target_hover_tint);
         mHoverPaint.setColorFilter(new PorterDuffColorFilter(
                 mHoverColor, PorterDuff.Mode.SRC_ATOP));
-        mDrawable = (TransitionDrawable) getCompoundDrawables()[0];
-        mDrawable.setCrossFadeEnabled(true);
+        mUninstallDrawable = (TransitionDrawable) 
+                r.getDrawable(R.drawable.uninstall_target_selector);
+        mRemoveDrawable = (TransitionDrawable) r.getDrawable(R.drawable.remove_target_selector);
+
+        mRemoveDrawable.setCrossFadeEnabled(true);
+        mUninstallDrawable.setCrossFadeEnabled(true);
+
+        // The current drawable is set to either the remove drawable or the uninstall drawable 
+        // and is initially set to the remove drawable, as set in the layout xml.
+        mCurrentDrawable = (TransitionDrawable) getCompoundDrawables()[0];
 
         // Remove the text in the Phone UI in landscape
         int orientation = getResources().getConfiguration().orientation;
@@ -116,8 +127,15 @@
             }
         }
 
+        if (isUninstall) {
+            setCompoundDrawablesWithIntrinsicBounds(mUninstallDrawable, null, null, null);
+        } else {
+            setCompoundDrawablesWithIntrinsicBounds(mRemoveDrawable, null, null, null);
+        }
+        mCurrentDrawable = (TransitionDrawable) getCompoundDrawables()[0];
+
         mActive = isVisible;
-        mDrawable.resetTransition();
+        mCurrentDrawable.resetTransition();
         setTextColor(mOriginalTextColor);
         ((ViewGroup) getParent()).setVisibility(isVisible ? View.VISIBLE : View.GONE);
         if (getText().length() > 0) {
@@ -135,7 +153,7 @@
     public void onDragEnter(DragObject d) {
         super.onDragEnter(d);
 
-        mDrawable.startTransition(mTransitionDuration);
+        mCurrentDrawable.startTransition(mTransitionDuration);
         setTextColor(mHoverColor);
     }
 
@@ -143,7 +161,7 @@
         super.onDragExit(d);
 
         if (!d.dragComplete) {
-            mDrawable.resetTransition();
+            mCurrentDrawable.resetTransition();
             setTextColor(mOriginalTextColor);
         }
     }
@@ -155,8 +173,8 @@
         dragLayer.getViewRectRelativeToSelf(d.dragView, from);
         dragLayer.getViewRectRelativeToSelf(this, to);
 
-        int width = mDrawable.getIntrinsicWidth();
-        int height = mDrawable.getIntrinsicHeight();
+        int width = mCurrentDrawable.getIntrinsicWidth();
+        int height = mCurrentDrawable.getIntrinsicHeight();
         to.set(to.left + getPaddingLeft(), to.top + getPaddingTop(),
                 to.left + getPaddingLeft() + width, to.bottom);
 
diff --git a/src/com/android/launcher2/DragLayer.java b/src/com/android/launcher2/DragLayer.java
index 433db50..3c626d4 100644
--- a/src/com/android/launcher2/DragLayer.java
+++ b/src/com/android/launcher2/DragLayer.java
@@ -70,7 +70,7 @@
     private boolean mHoverPointClosesFolder = false;
     private Rect mHitRect = new Rect();
     private int mWorkspaceIndex = -1;
-    private int mHotseatIndex = -1;
+    private int mQsbIndex = -1;
 
     /**
      * Used to create a new DragLayer from XML.
@@ -627,13 +627,13 @@
     private void updateChildIndices() {
         if (mLauncher != null) {
             mWorkspaceIndex = indexOfChild(mLauncher.getWorkspace());
-            mHotseatIndex = indexOfChild(mLauncher.getHotseat());
+            mQsbIndex = indexOfChild(mLauncher.getSearchBar());
         }
     }
 
     @Override
     protected int getChildDrawingOrder(int childCount, int i) {
-        if (mWorkspaceIndex == -1 || mHotseatIndex == -1 || 
+        if (mWorkspaceIndex == -1 || mQsbIndex == -1 || 
                 mLauncher.getWorkspace().isDrawingBackgroundGradient()) {
             return i;
         }
@@ -641,10 +641,10 @@
         // This ensures that the workspace is drawn above the hotseat and qsb,
         // except when the workspace is drawing a background gradient, in which
         // case we want the workspace to stay behind these elements.
-        if (i == mHotseatIndex) {
+        if (i == mQsbIndex) {
             return mWorkspaceIndex;
         } else if (i == mWorkspaceIndex) {
-            return mHotseatIndex;
+            return mQsbIndex;
         } else {
             return i;
         }
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index a62dfa6..f91a471 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -1956,6 +1956,9 @@
     Hotseat getHotseat() {
         return mHotseat;
     }
+    SearchDropTargetBar getSearchBar() {
+        return mSearchDropTargetBar;
+    }
 
     /**
      * Returns the CellLayout of the specified container at the specified screen.
@@ -2503,8 +2506,6 @@
     void addExternalItemToScreen(ItemInfo itemInfo, final CellLayout layout) {
         if (!mWorkspace.addExternalItemToScreen(itemInfo, layout)) {
             showOutOfSpaceMessage();
-        } else {
-            layout.animateDrop();
         }
     }
 
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index 2de7d4a..14ef53f 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -127,6 +127,12 @@
     protected boolean mCenterPagesVertically;
     protected boolean mAllowOverScroll = true;
     protected int mUnboundedScrollX;
+    protected int[] mTempVisiblePagesRange = new int[2];
+
+    // mOverScrollX is equal to mScrollX when we're within the normal scroll range. Otherwise
+    // it is equal to the scaled overscroll position. We use a separate value so as to prevent
+    // the screens from continuing to translate beyond the normal bounds.
+    protected int mOverScrollX;
 
     // parameter that adjusts the layout to be optimized for pages with that scale factor
     protected float mLayoutScale = 1.0f;
@@ -376,6 +382,7 @@
                 overScroll(x - mMaxScrollX);
             }
         } else {
+            mOverScrollX = x;
             super.scrollTo(x, y);
         }
 
@@ -701,20 +708,7 @@
         return (int) (maxWidth * mLayoutScale + 0.5f);
     }
 
-    @Override
-    protected void dispatchDraw(Canvas canvas) {
-        int halfScreenSize = getMeasuredWidth() / 2;
-        int screenCenter = mScrollX + halfScreenSize;
-
-        if (screenCenter != mLastScreenCenter || mForceScreenScrolled) {
-            screenScrolled(screenCenter);
-            mLastScreenCenter = screenCenter;
-            mForceScreenScrolled = false;
-        }
-
-        // Find out which screens are visible; as an optimization we only call draw on them
-        // As an optimization, this code assumes that all pages have the same width as the 0th
-        // page.
+    protected void getVisiblePages(int[] range) {
         final int pageCount = getChildCount();
         if (pageCount > 0) {
             final int pageWidth = getScaledMeasuredWidth(getPageAt(0));
@@ -731,6 +725,33 @@
                 rightScreen++;
                 x += getScaledMeasuredWidth(getPageAt(rightScreen)) + mPageSpacing;
             }
+            range[0] = leftScreen;
+            range[1] = rightScreen;
+        } else {
+            range[0] = -1;
+            range[1] = -1;
+        }
+    }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        int halfScreenSize = getMeasuredWidth() / 2;
+        // mOverScrollX is equal to mScrollX when we're within the normal scroll range. Otherwise
+        // it is equal to the scaled overscroll position.
+        int screenCenter = mOverScrollX + halfScreenSize;
+
+        if (screenCenter != mLastScreenCenter || mForceScreenScrolled) {
+            screenScrolled(screenCenter);
+            mLastScreenCenter = screenCenter;
+            mForceScreenScrolled = false;
+        }
+
+        // Find out which screens are visible; as an optimization we only call draw on them
+        final int pageCount = getChildCount();
+        if (pageCount > 0) {
+            getVisiblePages(mTempVisiblePagesRange);
+            final int leftScreen = mTempVisiblePagesRange[0];
+            final int rightScreen = mTempVisiblePagesRange[1];
 
             final long drawingTime = getDrawingTime();
             // Clip to the bounds
@@ -1064,9 +1085,11 @@
 
         int overScrollAmount = (int) Math.round(f * screenSize);
         if (amount < 0) {
-            mScrollX = overScrollAmount;
+            mOverScrollX = overScrollAmount;
+            mScrollX = 0;
         } else {
-            mScrollX = mMaxScrollX + overScrollAmount;
+            mOverScrollX = mMaxScrollX + overScrollAmount;
+            mScrollX = mMaxScrollX;
         }
         invalidate();
     }
@@ -1086,9 +1109,11 @@
 
         int overScrollAmount = (int) Math.round(OVERSCROLL_DAMP_FACTOR * f * screenSize);
         if (amount < 0) {
-            mScrollX = overScrollAmount;
+            mOverScrollX = overScrollAmount;
+            mScrollX = 0;
         } else {
-            mScrollX = mMaxScrollX + overScrollAmount;
+            mOverScrollX = mMaxScrollX + overScrollAmount;
+            mScrollX = mMaxScrollX;
         }
         invalidate();
     }
@@ -1777,7 +1802,7 @@
             updateScrollingIndicatorPosition();
             cancelScrollingIndicatorAnimations();
             if (immediately) {
-                mScrollIndicator.setVisibility(View.GONE);
+                mScrollIndicator.setVisibility(View.INVISIBLE);
                 mScrollIndicator.setAlpha(0f);
             } else {
                 mScrollIndicatorAnimator = ObjectAnimator.ofFloat(mScrollIndicator, "alpha", 0f);
@@ -1791,7 +1816,7 @@
                     @Override
                     public void onAnimationEnd(Animator animation) {
                         if (!cancelled) {
-                            mScrollIndicator.setVisibility(View.GONE);
+                            mScrollIndicator.setVisibility(View.INVISIBLE);
                         }
                     }
                 });
diff --git a/src/com/android/launcher2/PagedViewGridLayout.java b/src/com/android/launcher2/PagedViewGridLayout.java
index 93626f0..01d7593 100644
--- a/src/com/android/launcher2/PagedViewGridLayout.java
+++ b/src/com/android/launcher2/PagedViewGridLayout.java
@@ -30,6 +30,7 @@
 
     private int mCellCountX;
     private int mCellCountY;
+    private Runnable mOnLayoutListener;
 
     public PagedViewGridLayout(Context context, int cellCountX, int cellCountY) {
         super(context, null, 0);
@@ -57,6 +58,17 @@
                 heightMeasureSpec);
     }
 
+    public void setOnLayoutListener(Runnable r) {
+        mOnLayoutListener = r;
+    }
+
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        if (mOnLayoutListener != null) {
+            mOnLayoutListener.run();
+        }
+    }
+
     @Override
     public boolean onTouchEvent(MotionEvent event) {
         boolean result = super.onTouchEvent(event);
diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java
index 12c98b2..d3541ff 100644
--- a/src/com/android/launcher2/PagedViewWidget.java
+++ b/src/com/android/launcher2/PagedViewWidget.java
@@ -44,6 +44,7 @@
 
     private static final int sPreviewFadeInDuration = 80;
     private static final int sPreviewFadeInStaggerDuration = 20;
+    private static boolean sDeletePreviewsWhenDetachedFromWindow = true;
 
     private final Paint mPaint = new Paint();
     private Bitmap mHolographicOutline;
@@ -89,17 +90,23 @@
         setClipToPadding(false);
     }
 
+    public static void setDeletePreviewsWhenDetachedFromWindow(boolean value) {
+        sDeletePreviewsWhenDetachedFromWindow = value;
+    }
+
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
 
-        final ImageView image = (ImageView) findViewById(R.id.widget_preview);
-        if (image != null) {
-            FastBitmapDrawable preview = (FastBitmapDrawable) image.getDrawable();
-            if (preview != null && preview.getBitmap() != null) {
-                preview.getBitmap().recycle();
-            }
-            image.setImageDrawable(null);
+        if (sDeletePreviewsWhenDetachedFromWindow) {
+            final ImageView image = (ImageView) findViewById(R.id.widget_preview);
+            if (image != null) {
+                FastBitmapDrawable preview = (FastBitmapDrawable) image.getDrawable();
+                if (preview != null && preview.getBitmap() != null) {
+                    preview.getBitmap().recycle();
+                }
+                image.setImageDrawable(null);
+                }
         }
     }
 
@@ -135,11 +142,21 @@
         }
     }
 
-    void applyPreview(FastBitmapDrawable preview, int index, boolean scale) {
-        final ImageView image = (ImageView) findViewById(R.id.widget_preview);
+    public int[] getPreviewSize() {
+        final ImageView i = (ImageView) findViewById(R.id.widget_preview);
+        int[] maxSize = new int[2];
+        maxSize[0] = i.getWidth() - i.getPaddingLeft() - i.getPaddingRight();
+        maxSize[1] = i.getHeight() - i.getPaddingBottom() - i.getPaddingTop();
+        return maxSize;
+    }
+
+    void applyPreview(FastBitmapDrawable preview, int index) {
+        final PagedViewWidgetImageView image =
+                (PagedViewWidgetImageView) findViewById(R.id.widget_preview);
         if (preview != null) {
+            image.mAllowRequestLayout = false;
             image.setImageDrawable(preview);
-            image.setScaleType(scale ? ImageView.ScaleType.FIT_START : ImageView.ScaleType.MATRIX);
+            image.mAllowRequestLayout = true;
             image.setAlpha(0f);
             image.animate()
                  .alpha(1f)
diff --git a/src/com/android/launcher2/PagedViewWidgetImageView.java b/src/com/android/launcher2/PagedViewWidgetImageView.java
new file mode 100644
index 0000000..844b337
--- /dev/null
+++ b/src/com/android/launcher2/PagedViewWidgetImageView.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher2;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+
+
+
+class PagedViewWidgetImageView extends ImageView {
+    public boolean mAllowRequestLayout = true;
+
+    public PagedViewWidgetImageView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public void requestLayout() {
+        if (mAllowRequestLayout) {
+            super.requestLayout();
+        }
+    }
+}
diff --git a/src/com/android/launcher2/PendingAddItemInfo.java b/src/com/android/launcher2/PendingAddItemInfo.java
index e243cc0..9c52ecf 100644
--- a/src/com/android/launcher2/PendingAddItemInfo.java
+++ b/src/com/android/launcher2/PendingAddItemInfo.java
@@ -33,7 +33,8 @@
 class PendingAddWidgetInfo extends PendingAddItemInfo {
     int minWidth;
     int minHeight;
-    boolean hasDefaultPreview;
+    int previewImage;
+    int icon;
 
     // Any configuration data that we want to pass to a configuration activity when
     // starting up a widget
@@ -45,7 +46,8 @@
         componentName = i.provider;
         minWidth = i.minWidth;
         minHeight = i.minHeight;
-        hasDefaultPreview = i.previewImage <= 0;
+        previewImage = i.previewImage;
+        icon = i.icon;
         if (dataMimeType != null && data != null) {
             mimeType = dataMimeType;
             configurationData = data;
diff --git a/src/com/android/launcher2/SearchDropTargetBar.java b/src/com/android/launcher2/SearchDropTargetBar.java
index e90406e..3a7f24b 100644
--- a/src/com/android/launcher2/SearchDropTargetBar.java
+++ b/src/com/android/launcher2/SearchDropTargetBar.java
@@ -119,7 +119,7 @@
         mDropTargetBarFadeOutAnim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
-                mDropTargetBar.setVisibility(View.GONE);
+                mDropTargetBar.setVisibility(View.INVISIBLE);
                 mDropTargetBar.setLayerType(View.LAYER_TYPE_NONE, null);
             }
         });
@@ -136,7 +136,7 @@
         mQSBSearchBarFadeOutAnim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
-                mQSBSearchBar.setVisibility(View.GONE);
+                mQSBSearchBar.setVisibility(View.INVISIBLE);
             }
         });
     }
@@ -166,7 +166,7 @@
         if (animated) {
             mQSBSearchBarFadeOutAnim.start();
         } else {
-            mQSBSearchBar.setVisibility(View.GONE);
+            mQSBSearchBar.setVisibility(View.INVISIBLE);
             mQSBSearchBar.setAlpha(0f);
         }
         mIsSearchBarHidden = true;
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index d3a31c4..8ac5248 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -26,6 +26,7 @@
 import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.app.AlertDialog;
 import android.app.WallpaperManager;
+import android.appwidget.AppWidgetHostView;
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ClipData;
@@ -314,6 +315,43 @@
         setMotionEventSplittingEnabled(true);
     }
 
+    // estimate the size of a widget with spans hSpan, vSpan. return MAX_VALUE for each
+    // dimension if unsuccessful
+    public int[] estimateItemSize(int hSpan, int vSpan,
+            PendingAddItemInfo pendingItemInfo, boolean springLoaded) {
+        int[] size = new int[2];
+        if (getChildCount() > 0) {
+            CellLayout cl = (CellLayout) mLauncher.getWorkspace().getChildAt(0);
+            RectF r = estimateItemPosition(cl, pendingItemInfo, 0, 0, hSpan, vSpan);
+            size[0] = (int) r.width();
+            size[1] = (int) r.height();
+            if (springLoaded) {
+                size[0] *= mSpringLoadedShrinkFactor;
+                size[1] *= mSpringLoadedShrinkFactor;
+            }
+            return size;
+        } else {
+            size[0] = Integer.MAX_VALUE;
+            size[1] = Integer.MAX_VALUE;
+            return size;
+        }
+    }
+    public RectF estimateItemPosition(CellLayout cl, ItemInfo pendingInfo,
+            int hCell, int vCell, int hSpan, int vSpan) {
+        RectF r = new RectF();
+        cl.cellToRect(hCell, vCell, hSpan, vSpan, r);
+        if (pendingInfo instanceof PendingAddWidgetInfo) {
+            PendingAddWidgetInfo widgetInfo = (PendingAddWidgetInfo) pendingInfo;
+            Rect p = AppWidgetHostView.getDefaultPaddingForWidget(mContext,
+                    widgetInfo.componentName, null);
+            r.top += p.top;
+            r.left += p.left;
+            r.right -= p.right;
+            r.bottom -= p.bottom;
+        }
+        return r;
+    }
+
     public void buildPageHardwareLayers() {
         if (getWindowToken() != null) {
             final int childCount = getChildCount();
@@ -1101,6 +1139,7 @@
     }
 
     private void screenScrolledLargeUI(int screenCenter) {
+        boolean isInOverscroll = false;
         for (int i = 0; i < getChildCount(); i++) {
             CellLayout cl = (CellLayout) getChildAt(i);
             if (cl != null) {
@@ -1111,11 +1150,17 @@
                 // If the current page (i) is being over scrolled, we use a different
                 // set of rules for setting the background alpha multiplier.
                 if (!isSmall()) {
-                    if ((mScrollX < 0 && i == 0) || (mScrollX > mMaxScrollX &&
-                            i == getChildCount() -1 )) {
+                    if ((mOverScrollX < 0 && i == 0) || (mOverScrollX > mMaxScrollX &&
+                            i == getChildCount() -1)) {
+                        isInOverscroll = true;
+                        rotation *= -1;
                         cl.setBackgroundAlphaMultiplier(
                                 overScrollBackgroundAlphaInterpolator(Math.abs(scrollProgress)));
                         mOverScrollPageIndex = i;
+                        cl.setOverScrollAmount(Math.abs(scrollProgress), i == 0);
+                        cl.setPivotX(cl.getMeasuredWidth() * (i == 0 ? 0.75f : 0.25f));
+                        cl.setPivotY(cl.getMeasuredHeight() * 0.5f);
+                        cl.setOverscrollTransformsDirty(true);
                     } else if (mOverScrollPageIndex != i) {
                         cl.setBackgroundAlphaMultiplier(
                                 backgroundAlphaInterpolator(Math.abs(scrollProgress)));
@@ -1130,29 +1175,25 @@
                 cl.fastInvalidate();
             }
         }
+        if (!isSwitchingState() && !isInOverscroll) {
+            ((CellLayout) getChildAt(0)).resetOverscrollTransforms();
+            ((CellLayout) getChildAt(getChildCount() - 1)).resetOverscrollTransforms();
+        }
         invalidate();
     }
 
-    private void resetCellLayoutTransforms(CellLayout cl, boolean left) {
-        cl.setTranslationX(0);
-        cl.setRotationY(0);
-        cl.setOverScrollAmount(0, left);
-        cl.setPivotX(cl.getMeasuredWidth() / 2);
-        cl.setPivotY(cl.getMeasuredHeight() / 2);
-    }
-
     private void screenScrolledStandardUI(int screenCenter) {
-        if (mScrollX < 0 || mScrollX > mMaxScrollX) {
-            int index = mScrollX < 0 ? 0 : getChildCount() - 1;
+        if (mOverScrollX < 0 || mOverScrollX > mMaxScrollX) {
+            int index = mOverScrollX < 0 ? 0 : getChildCount() - 1;
             CellLayout cl = (CellLayout) getChildAt(index);
             float scrollProgress = getScrollProgress(screenCenter, cl, index);
             cl.setOverScrollAmount(Math.abs(scrollProgress), index == 0);
-            float translationX = index == 0 ? mScrollX : - (mMaxScrollX - mScrollX);
             float rotation = - WORKSPACE_OVERSCROLL_ROTATION * scrollProgress;
             cl.setCameraDistance(mDensity * CAMERA_DISTANCE);
             cl.setPivotX(cl.getMeasuredWidth() * (index == 0 ? 0.75f : 0.25f));
-            cl.setTranslationX(translationX);
+            cl.setPivotY(cl.getMeasuredHeight() * 0.5f);
             cl.setRotationY(rotation);
+            cl.setOverscrollTransformsDirty(true);
             setFadeForOverScroll(Math.abs(scrollProgress));
         } else {
             if (mOverscrollFade != 0) {
@@ -1160,8 +1201,8 @@
             }
             // We don't want to mess with the translations during transitions
             if (!isSwitchingState()) {
-                resetCellLayoutTransforms((CellLayout) getChildAt(0), true);
-                resetCellLayoutTransforms((CellLayout) getChildAt(getChildCount() - 1), false);
+                ((CellLayout) getChildAt(0)).resetOverscrollTransforms();
+                ((CellLayout) getChildAt(getChildCount() - 1)).resetOverscrollTransforms();
             }
         }
     }
@@ -1241,6 +1282,19 @@
 
     @Override
     protected void dispatchDraw(Canvas canvas) {
+        if (mChildrenLayersEnabled) {
+            getVisiblePages(mTempVisiblePagesRange);
+            final int leftScreen = mTempVisiblePagesRange[0];
+            final int rightScreen = mTempVisiblePagesRange[1];
+            if (leftScreen != -1 && rightScreen != -1) {
+                // calling setChildrenLayersEnabled on a view that's not visible/rendered
+                // causes slowdowns on some graphics cards, so we set it here to be sure
+                // it's only called when it's safe (ie when the view will be rendered)
+                for (int i = leftScreen; i <= rightScreen; i++) {
+                    ((ViewGroup)getPageAt(i)).setChildrenLayersEnabled(true);
+                }
+            }
+        }
         super.dispatchDraw(canvas);
 
         if (mInScrollArea && !LauncherApplication.isScreenLarge()) {
@@ -1345,8 +1399,13 @@
 
         if (enableChildrenLayers != mChildrenLayersEnabled) {
             mChildrenLayersEnabled = enableChildrenLayers;
-            for (int i = 0; i < getPageCount(); i++) {
-                ((ViewGroup)getChildAt(i)).setChildrenLayersEnabled(enableChildrenLayers);
+            // calling setChildrenLayersEnabled on a view that's not visible/rendered
+            // causes slowdowns on some graphics cards, so we only disable it here and leave
+            // the enabling to dispatchDraw
+            if (!enableChildrenLayers) {
+                for (int i = 0; i < getPageCount(); i++) {
+                    ((ViewGroup)getChildAt(i)).setChildrenLayersEnabled(false);
+                }
             }
         }
     }
@@ -1442,11 +1501,7 @@
         mDragOutline = createDragOutline(v, canvas, bitmapPadding);
     }
 
-    public void onDragStartedWithItemSpans(int spanX, int spanY, Bitmap b) {
-        onDragStartedWithItemSpans(spanX, spanY, b, null);
-    }
-
-    public void onDragStartedWithItemSpans(int spanX, int spanY, Bitmap b, Paint alphaClipPaint) {
+    public void onDragStartedWithItem(PendingAddItemInfo info, Bitmap b, Paint alphaClipPaint) {
         final Canvas canvas = new Canvas();
 
         // We need to add extra padding to the bitmap to make room for the glow effect
@@ -1454,7 +1509,7 @@
 
         CellLayout cl = (CellLayout) getChildAt(0);
 
-        int[] size = cl.cellSpansToSize(spanX, spanY);
+        int[] size = estimateItemSize(info.spanX, info.spanY, info, false);
 
         // The outline is used to visualize where the item will land if dropped
         mDragOutline = createDragOutline(b, canvas, bitmapPadding, size[0], size[1], alphaClipPaint);
@@ -2895,11 +2950,11 @@
 
             // Now we animate the dragView, (ie. the widget or shortcut preview) into its final
             // location and size on the home screen.
+            RectF r = estimateItemPosition(cellLayout, pendingInfo,
+                    mTargetCell[0], mTargetCell[1], spanX, spanY);
             int loc[] = new int[2];
-            cellLayout.cellToPoint(mTargetCell[0], mTargetCell[1], loc);
-
-            RectF r = new RectF();
-            cellLayout.cellToRect(mTargetCell[0], mTargetCell[1], spanX, spanY, r);
+            loc[0] = (int) r.left;
+            loc[1] = (int) r.top;
             setFinalTransitionTransform(cellLayout);
             float cellLayoutScale =
                     mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(cellLayout, loc);
@@ -2960,7 +3015,6 @@
             addInScreen(view, container, screen, mTargetCell[0], mTargetCell[1], info.spanX,
                     info.spanY, insertAtFirst);
             cellLayout.onDropChild(view);
-            cellLayout.animateDrop();
             CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams();
             cellLayout.getChildrenLayout().measureChild(view);