Merge "Fixing problems in spring loaded mode and adding shortcut to hotseat. (5144911, 5144663)"
diff --git a/res/layout-large/market_button.xml b/res/layout-large/market_button.xml
new file mode 100644
index 0000000..ad5f6da
--- /dev/null
+++ b/res/layout-large/market_button.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<TextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
+    style="@style/MarketButton"
+    android:onClick="onClickAppMarketButton"
+    android:gravity="center"
+    android:paddingLeft="@dimen/toolbar_button_horizontal_padding"
+    android:paddingRight="@dimen/toolbar_button_horizontal_padding"
+    android:drawablePadding="10dp"
+    android:text="@string/market"
+    android:contentDescription="@string/market"
+    android:textColor="@color/workspace_all_apps_and_delete_zone_text_color"
+    android:textSize="18sp"
+    android:shadowColor="@color/workspace_all_apps_and_delete_zone_text_shadow_color"
+    android:shadowDx="0.0"
+    android:shadowDy="0.0"
+    android:shadowRadius="2.0"
+    android:background="@drawable/tab_widget_indicator_selector"
+    android:focusable="true"
+    android:clickable="true" />
diff --git a/res/layout/apps_customize_pane.xml b/res/layout/apps_customize_pane.xml
index 788d4c3..05e7fc1 100644
--- a/res/layout/apps_customize_pane.xml
+++ b/res/layout/apps_customize_pane.xml
@@ -35,27 +35,12 @@
                 android:layout_gravity="left"
                 android:background="@drawable/tab_unselected_holo"
                 android:tabStripEnabled="false" />
-            <TextView
-                style="@style/MarketButton"
+            <include
                 android:id="@+id/market_button"
-                android:onClick="onClickAppMarketButton"
+                layout="@layout/market_button"
                 android:layout_width="wrap_content"
                 android:layout_height="match_parent"
-                android:layout_gravity="right"
-                android:gravity="center"
-                android:paddingLeft="@dimen/toolbar_button_horizontal_padding"
-                android:paddingRight="@dimen/toolbar_button_horizontal_padding"
-                android:text="@string/market"
-                android:contentDescription="@string/market"
-                android:textColor="@color/workspace_all_apps_and_delete_zone_text_color"
-                android:textSize="18sp"
-                android:shadowColor="@color/workspace_all_apps_and_delete_zone_text_shadow_color"
-                android:shadowDx="0.0"
-                android:shadowDy="0.0"
-                android:shadowRadius="2.0"
-                android:background="@drawable/tab_widget_indicator_selector"
-                android:focusable="true"
-                android:clickable="true" />
+                android:layout_gravity="right" />
         </FrameLayout>
         <FrameLayout
             android:id="@android:id/tabcontent"
diff --git a/res/layout/apps_customize_progressbar.xml b/res/layout/apps_customize_progressbar.xml
new file mode 100644
index 0000000..d790f21
--- /dev/null
+++ b/res/layout/apps_customize_progressbar.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<ProgressBar
+   xmlns:android="http://schemas.android.com/apk/res/android"
+   xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
+   style="?android:attr/progressBarStyleLarge"
+   android:id="@+id/apps_customize_progress_bar"
+   android:layout_width="wrap_content"
+   android:layout_height="wrap_content"
+   android:layout_gravity="center"
+   android:layout_marginRight="5dp" />
diff --git a/res/layout/market_button.xml b/res/layout/market_button.xml
new file mode 100644
index 0000000..2d840d7
--- /dev/null
+++ b/res/layout/market_button.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<TextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
+    style="@style/MarketButton"
+    android:onClick="onClickAppMarketButton"
+    android:gravity="center"
+    android:paddingLeft="@dimen/toolbar_button_horizontal_padding"
+    android:paddingRight="@dimen/toolbar_button_horizontal_padding"
+    android:contentDescription="@string/market"
+    android:shadowColor="@color/workspace_all_apps_and_delete_zone_text_shadow_color"
+    android:shadowDx="0.0"
+    android:shadowDy="0.0"
+    android:shadowRadius="2.0"
+    android:background="@drawable/tab_widget_indicator_selector"
+    android:focusable="true"
+    android:clickable="true" />
diff --git a/res/values-large-port/dimens.xml b/res/values-large-port/dimens.xml
index e0651b2..4e1cf8f 100644
--- a/res/values-large-port/dimens.xml
+++ b/res/values-large-port/dimens.xml
@@ -18,10 +18,6 @@
 <!-- AppsCustomize -->
     <dimen name="apps_customize_cell_width">96dp</dimen>
     <dimen name="apps_customize_cell_height">96dp</dimen>
-    <!-- The amount of space to account for the next/prev pages when
-         calculating the number of columns to fit a page.
-         In portrait/large we use apps_customize_cell_width / 8. -->
-    <dimen name="apps_customize_peek_width">12dp</dimen>
     <dimen name="workspace_page_spacing">64dp</dimen>
 
 <!-- Workspace -->
@@ -40,6 +36,6 @@
     <dimen name="apps_customize_pageLayoutHeightGap">36dp</dimen>
     <dimen name="apps_customize_pageLayoutPaddingTop">25dp</dimen>
     <dimen name="apps_customize_pageLayoutPaddingBottom">10dp</dimen>
-    <dimen name="apps_customize_pageLayoutPaddingLeft">20dp</dimen>
-    <dimen name="apps_customize_pageLayoutPaddingRight">20dp</dimen>
+    <dimen name="apps_customize_pageLayoutPaddingLeft">10dp</dimen>
+    <dimen name="apps_customize_pageLayoutPaddingRight">10dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/res/values-large/dimens.xml b/res/values-large/dimens.xml
index 234fcdb..3fe53b5 100644
--- a/res/values-large/dimens.xml
+++ b/res/values-large/dimens.xml
@@ -33,10 +33,6 @@
     <dimen name="apps_customize_tab_bar_height">56dp</dimen>
     <dimen name="apps_customize_cell_width">96dp</dimen>
     <dimen name="apps_customize_cell_height">96dp</dimen>
-    <!-- The amount of space to account for the next/prev pages when
-         calculating the number of columns to fit a page.
-         In landscape/large we use apps_customize_cell_width / 4. -->
-    <dimen name="apps_customize_peek_width">48dp</dimen>
     <dimen name="apps_customize_widget_cell_width_gap">36dp</dimen>
     <dimen name="apps_customize_widget_cell_height_gap">36dp</dimen>
 
diff --git a/res/values-large/styles.xml b/res/values-large/styles.xml
index 41bd9cd..265eff8 100644
--- a/res/values-large/styles.xml
+++ b/res/values-large/styles.xml
@@ -20,7 +20,7 @@
 <resources>
 <!-- Workspace -->
     <style name="WorkspaceIcon.Portrait">
-        <item name="android:drawablePadding">4dp</item>
+        <item name="android:drawablePadding">0dp</item>
         <item name="android:paddingLeft">4dp</item>
         <item name="android:paddingRight">4dp</item>
         <item name="android:paddingTop">4dp</item>
@@ -35,7 +35,7 @@
         <item name="android:textSize">13dip</item>
     </style>
     <style name="WorkspaceIcon.Landscape">
-        <item name="android:drawablePadding">4dp</item>
+        <item name="android:drawablePadding">0dp</item>
         <item name="android:paddingLeft">4dp</item>
         <item name="android:paddingRight">4dp</item>
         <item name="android:paddingTop">4dp</item>
@@ -49,10 +49,6 @@
         <item name="android:paddingBottom">0dp</item>
         <item name="android:textSize">13dip</item>
     </style>
-    <style name="WorkspaceIcon.AppsCustomize">
-        <item name="android:drawablePadding">2dp</item>
-        <item name="android:textSize">13dip</item>
-    </style>
 
     <style name="Theme" parent="android:Theme.Holo.Wallpaper.NoTitleBar">
         <item name="android:windowActionModeOverlay">true</item>
@@ -62,6 +58,24 @@
         <item name="android:screenOrientation">unspecified</item>
     </style>
 
+    <style name="WorkspaceIcon.Portrait.AppsCustomize">
+        <item name="android:background">@null</item>
+        <item name="android:paddingTop">4dp</item>
+        <item name="android:paddingBottom">0dp</item>
+        <item name="android:paddingLeft">0dp</item>
+        <item name="android:paddingRight">0dp</item>
+        <item name="android:drawablePadding">4dp</item>
+        <item name="android:includeFontPadding">false</item>
+        <item name="android:textSize">13dip</item>
+    </style>
+    <style name="WorkspaceIcon.Landscape.AppsCustomize">
+        <item name="android:background">@null</item>
+        <item name="android:paddingTop">4dp</item>
+        <item name="android:paddingBottom">0dp</item>
+        <item name="android:drawablePadding">4dp</item>
+        <item name="android:includeFontPadding">false</item>
+        <item name="android:textSize">13dip</item>
+    </style>
     <style name="TabIndicator.AppsCustomize">
         <item name="android:paddingLeft">40dp</item>
         <item name="android:paddingRight">40dp</item>
diff --git a/res/values-xlarge-port/dimens.xml b/res/values-xlarge-port/dimens.xml
index 4f53280..0850e8c 100644
--- a/res/values-xlarge-port/dimens.xml
+++ b/res/values-xlarge-port/dimens.xml
@@ -15,11 +15,6 @@
 -->
 
 <resources>
-    <!-- The amount of space to account for the next/prev pages when
-         calculating the number of columns to fit a page.
-         In portrait/xlarge we use apps_customize_cell_width / 4. -->
-    <dimen name="apps_customize_peek_width">48dp</dimen>
-
     <!-- We can also afford to have a slightly wider portrait layout in
          xlarge -->
     <dimen name="apps_customize_pageLayoutWidthGap">36dp</dimen>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 1efeb9e..ece0fd8 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -23,6 +23,9 @@
     <color name="delete_target_hover_tint">#DAFF0000</color>
     <color name="info_target_hover_tint">#DA0099CC</color>
 
+    <!-- The alpha/color to apply to the drag image -->
+    <color name="drag_view_multiply_color">#CCFFFFFF</color>
+
     <color name="bubble_dark_background">#20000000</color>
 
     <color name="appwidget_error_color">#FCCC</color>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 641f8ea..3934237 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -41,7 +41,6 @@
     <!-- The width can be 72dp because we don't have L/R padding -->
     <dimen name="apps_customize_cell_width">72dp</dimen>
     <dimen name="apps_customize_cell_height">80dp</dimen>
-    <dimen name="apps_customize_peek_width">0dp</dimen>
     <dimen name="apps_customize_max_gap">18dp</dimen>
     <dimen name="apps_customize_widget_cell_width_gap">10dp</dimen>
     <dimen name="apps_customize_widget_cell_height_gap">10dp</dimen>
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index 53d154f..16dad1b 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -33,6 +33,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.Config;
 import android.graphics.Canvas;
+import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
@@ -172,6 +173,7 @@
     private Canvas mCanvas;
     private Drawable mDefaultWidgetBackground;
     private IconCache mIconCache;
+    private int mDragViewMultiplyColor;
 
     // Dimens
     private int mContentWidth;
@@ -202,7 +204,8 @@
         // Save the default widget preview background
         Resources resources = context.getResources();
         mDefaultWidgetBackground = resources.getDrawable(R.drawable.default_widget_preview_holo);
-        mAppIconSize = getResources().getDimensionPixelSize(R.dimen.app_icon_size);
+        mAppIconSize = resources.getDimensionPixelSize(R.dimen.app_icon_size);
+        mDragViewMultiplyColor = resources.getColor(R.color.drag_view_multiply_color);
 
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PagedView, 0, 0);
         // TODO-APPS_CUSTOMIZE: remove these unnecessary attrs after
@@ -242,9 +245,8 @@
     }
 
     @Override
-    protected void onWallpaperTap(MotionEvent ev) {
-        int action = ev.getAction();
-        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
+    protected void onUnhandledTap(MotionEvent ev) {
+        if (LauncherApplication.isScreenLarge()) {
             // Dismiss AppsCustomize if we tap
             mLauncher.showWorkspace(true);
         }
@@ -409,7 +411,7 @@
             createItemInfo.spanY = spanXY[1];
 
             b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
-            renderDrawableToBitmap(preview, b, 0, 0, w, h, 1, 1);
+            renderDrawableToBitmap(preview, b, 0, 0, w, h, 1, 1, mDragViewMultiplyColor);
         } 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
@@ -420,6 +422,7 @@
             mCanvas.save();
             preview.draw(mCanvas);
             mCanvas.restore();
+            mCanvas.drawColor(mDragViewMultiplyColor, PorterDuff.Mode.MULTIPLY);
             mCanvas.setBitmap(null);
             createItemInfo.spanX = createItemInfo.spanY = 1;
         }
@@ -745,6 +748,10 @@
     }
     private void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int x, int y, int w, int h,
             float scaleX, float scaleY) {
+        renderDrawableToBitmap(d, bitmap, x, y, w, h, scaleX, scaleY, 0xFFFFFFFF);
+    }
+    private void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int x, int y, int w, int h,
+            float scaleX, float scaleY, int multiplyColor) {
         if (bitmap != null) {
             Canvas c = new Canvas(bitmap);
             c.scale(scaleX, scaleY);
@@ -752,6 +759,9 @@
             d.setBounds(x, y, x + w, y + h);
             d.draw(c);
             d.setBounds(oldBounds); // Restore the bounds
+            if (multiplyColor != 0xFFFFFFFF) {
+                c.drawColor(mDragViewMultiplyColor, PorterDuff.Mode.MULTIPLY);
+            }
             c.setBitmap(null);
         }
     }
@@ -828,7 +838,7 @@
 
             preview = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Config.ARGB_8888);
             renderDrawableToBitmap(mDefaultWidgetBackground, preview, 0, 0, expectedWidth,
-                    expectedHeight, 1f,1f);
+                    expectedHeight, 1f, 1f);
 
             // Draw the icon in the top left corner
             try {
diff --git a/src/com/android/launcher2/AppsCustomizeTabHost.java b/src/com/android/launcher2/AppsCustomizeTabHost.java
index 25001b1..dcf4441 100644
--- a/src/com/android/launcher2/AppsCustomizeTabHost.java
+++ b/src/com/android/launcher2/AppsCustomizeTabHost.java
@@ -45,6 +45,9 @@
     private ViewGroup mTabsContainer;
     private AppsCustomizePagedView mAppsCustomizePane;
 
+    private boolean mInTransition;
+    private boolean mResetAfterTransition;
+
     public AppsCustomizeTabHost(Context context, AttributeSet attrs) {
         super(context, attrs);
         mLayoutInflater = LayoutInflater.from(context);
@@ -130,6 +133,11 @@
                 // it off here)
                 mTabs.getLayoutParams().width = contentWidth;
                 mTabsContainer.setAlpha(1f);
+                post(new Runnable() {
+                    public void run() {
+                        mTabs.requestLayout();
+                    }
+                });
             }
         }
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -223,9 +231,20 @@
         return super.getDescendantFocusability();
     }
 
+    void reset() {
+        if (mInTransition) {
+            // Defer to after the transition to reset
+            mResetAfterTransition = true;
+        } else {
+            // Reset immediately
+            mAppsCustomizePane.reset();
+        }
+    }
+
     /* LauncherTransitionable overrides */
     @Override
     public void onLauncherTransitionStart(Animator animation, boolean toWorkspace) {
+        mInTransition = true;
         // isHardwareAccelerated() checks if we're attached to a window and if that
         // window is HW accelerated-- we were sometimes not attached to a window
         // and buildLayer was throwing an IllegalStateException
@@ -240,10 +259,15 @@
         if (!toWorkspace && !LauncherApplication.isScreenLarge()) {
             mAppsCustomizePane.showScrollingIndicator(false);
         }
+        if (mResetAfterTransition) {
+            mAppsCustomizePane.reset();
+            mResetAfterTransition = false;
+        }
     }
 
     @Override
     public void onLauncherTransitionEnd(Animator animation, boolean toWorkspace) {
+        mInTransition = false;
         if (animation != null) {
             setLayerType(LAYER_TYPE_NONE, null);
         }
diff --git a/src/com/android/launcher2/BubbleTextView.java b/src/com/android/launcher2/BubbleTextView.java
index 08f337e..45f58a4 100644
--- a/src/com/android/launcher2/BubbleTextView.java
+++ b/src/com/android/launcher2/BubbleTextView.java
@@ -29,7 +29,6 @@
 import android.graphics.Region.Op;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
-import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
 import android.widget.TextView;
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index d9d0487..a17e2d6 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -81,6 +81,7 @@
     int[] mTempLocation = new int[2];
 
     boolean[][] mOccupied;
+    private boolean mLastDownOnOccupiedCell = false;
 
     private OnTouchListener mInterceptTouchListener;
 
@@ -752,6 +753,8 @@
             }
         }
 
+        mLastDownOnOccupiedCell = found;
+
         if (!found) {
             final int cellXY[] = mTmpXY;
             pointToCellExact(x, y, cellXY);
@@ -1877,4 +1880,8 @@
                     + ", x=" + cellX + ", y=" + cellY + "]";
         }
     }
+
+    public boolean lastDownOnOccupiedCell() {
+        return mLastDownOnOccupiedCell;
+    }
 }
diff --git a/src/com/android/launcher2/DragController.java b/src/com/android/launcher2/DragController.java
index 647a425..afbf80d 100644
--- a/src/com/android/launcher2/DragController.java
+++ b/src/com/android/launcher2/DragController.java
@@ -31,7 +31,6 @@
 import android.view.inputmethod.InputMethodManager;
 
 import com.android.launcher.R;
-import com.android.launcher2.DropTarget.DragObject;
 
 import java.util.ArrayList;
 
diff --git a/src/com/android/launcher2/FolderIcon.java b/src/com/android/launcher2/FolderIcon.java
index b6b027a..6cd7847 100644
--- a/src/com/android/launcher2/FolderIcon.java
+++ b/src/com/android/launcher2/FolderIcon.java
@@ -24,7 +24,6 @@
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.Paint;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
diff --git a/src/com/android/launcher2/IconCache.java b/src/com/android/launcher2/IconCache.java
index 1fdafc8..b2ebe2a 100644
--- a/src/com/android/launcher2/IconCache.java
+++ b/src/com/android/launcher2/IconCache.java
@@ -44,7 +44,6 @@
     private final Bitmap mDefaultIcon;
     private final LauncherApplication mContext;
     private final PackageManager mPackageManager;
-    private final Utilities.BubbleText mBubble;
     private final HashMap<ComponentName, CacheEntry> mCache =
             new HashMap<ComponentName, CacheEntry>(INITIAL_ICON_CACHE_CAPACITY);
     private int mIconDpi;
@@ -52,7 +51,6 @@
     public IconCache(LauncherApplication context) {
         mContext = context;
         mPackageManager = context.getPackageManager();
-        mBubble = new Utilities.BubbleText(context);
         int density = context.getResources().getDisplayMetrics().densityDpi;
         if (LauncherApplication.isScreenLarge()) {
             if (density == DisplayMetrics.DENSITY_LOW) {
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index b260ae3..0f074ac 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -291,6 +291,11 @@
             mModel.startLoader(this, true);
         }
 
+        if (!mModel.isAllAppsLoaded()) {
+            ViewGroup appsCustomizeContentParent = (ViewGroup) mAppsCustomizeContent.getParent();
+            mInflater.inflate(R.layout.apps_customize_progressbar, appsCustomizeContentParent);
+        }
+
         // For handling default keys
         mDefaultKeySsb = new SpannableStringBuilder();
         Selection.setSelection(mDefaultKeySsb, 0);
@@ -914,10 +919,11 @@
                 mDragLayer.clearAllResizeFrames();
                 updateRunning();
 
-                // Reset AllApps to it's initial state only if we are not in the middle of
+                // Reset AllApps to its initial state only if we are not in the middle of
                 // processing a multi-step drop
-                if (mAppsCustomizeContent != null && mPendingAddInfo.container == ItemInfo.NO_ID) {
-                    mAppsCustomizeContent.reset();
+                if (mAppsCustomizeTabHost != null && mPendingAddInfo.container == ItemInfo.NO_ID) {
+                    mAppsCustomizeTabHost.reset();
+                    showWorkspace(false);
                 }
             } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
                 mUserPresent = true;
@@ -1090,8 +1096,8 @@
             }
 
             // Reset AllApps to its initial state
-            if (mAppsCustomizeContent != null) {
-                mAppsCustomizeContent.reset();
+            if (mAppsCustomizeTabHost != null) {
+                mAppsCustomizeTabHost.reset();
             }
         }
     }
@@ -1212,6 +1218,8 @@
     @Override
     public boolean onSearchRequested() {
         startSearch(null, false, null, true);
+        // Use a custom animation for launching search
+        overridePendingTransition(R.anim.fade_in_fast, R.anim.fade_out_fast);
         return true;
     }
 
@@ -1537,9 +1545,7 @@
      * @param v The view that was clicked.
      */
     public void onClickSearchButton(View v) {
-        startSearch(null, false, null, true);
-        // Use a custom animation for launching search
-        overridePendingTransition(R.anim.fade_in_fast, R.anim.fade_out_fast);
+        onSearchRequested();
     }
 
     /**
@@ -2464,11 +2470,6 @@
             sAppMarketIcon = updateTextButtonWithIconFromExternalActivity(
                     R.id.market_button, activityName, R.drawable.ic_launcher_market_holo);
             marketButton.setVisibility(View.VISIBLE);
-            
-            // Remove the shop icon text in the Phone UI
-            if (!LauncherApplication.isScreenLarge()) {
-                ((TextView) marketButton).setText("");
-            }
         } else {
             // We should hide and disable the view so that we don't try and restore the visibility
             // of it when we swap between drag & normal states from IconDropTarget subclasses.
@@ -2774,10 +2775,25 @@
      *
      * Implementation of the method from LauncherModel.Callbacks.
      */
-    public void bindAllApplications(ArrayList<ApplicationInfo> apps) {
-        if (mAppsCustomizeContent != null) {
-            mAppsCustomizeContent.setApps(apps);
+    public void bindAllApplications(final ArrayList<ApplicationInfo> apps) {
+        // Remove the progress bar entirely; we could also make it GONE
+        // but better to remove it since we know it's not going to be used
+        View progressBar = mAppsCustomizeTabHost.
+            findViewById(R.id.apps_customize_progress_bar);
+        if (progressBar != null) {
+            ((ViewGroup)progressBar.getParent()).removeView(progressBar);
         }
+        // We just post the call to setApps so the user sees the progress bar
+        // disappear-- otherwise, it just looks like the progress bar froze
+        // which doesn't look great
+        mAppsCustomizeTabHost.post(new Runnable() {
+            public void run() {
+                if (mAppsCustomizeContent != null) {
+                    mAppsCustomizeContent.setApps(apps);
+                }
+            }
+        });
+
         updateIconsAffectedByPackageManagerChanges();
         updateGlobalSearchIcon();
     }
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index 206de14..c46e175 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -644,6 +644,10 @@
         }
     }
 
+    public boolean isAllAppsLoaded() {
+        return mAllAppsLoaded;
+    }
+
     /**
      * Runnable for the thread that loads the contents of the launcher:
      *   - workspace icons
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index 0321e3f..d2d734c 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -131,7 +131,7 @@
     private PageSwitchListener mPageSwitchListener;
 
     private ArrayList<Boolean> mDirtyPageContent;
-    private boolean mDirtyPageAlpha;
+    private boolean mDirtyPageAlpha = true;
 
     // choice modes
     protected static final int CHOICE_MODE_NONE = 0;
@@ -1138,7 +1138,7 @@
                     snapToDestination();
                 }
             } else {
-                onWallpaperTap(ev);
+                onUnhandledTap(ev);
             }
             mTouchState = TOUCH_STATE_REST;
             mActivePointerId = INVALID_POINTER;
@@ -1222,12 +1222,9 @@
                 mVelocityTracker.clear();
             }
         }
-        if (mTouchState == TOUCH_STATE_REST) {
-            onWallpaperTap(ev);
-        }
     }
 
-    protected void onWallpaperTap(MotionEvent ev) {}
+    protected void onUnhandledTap(MotionEvent ev) {}
 
     @Override
     public void requestChildFocus(View child, View focused) {
diff --git a/src/com/android/launcher2/PagedViewCellLayout.java b/src/com/android/launcher2/PagedViewCellLayout.java
index bec00ec..63cf9e8 100644
--- a/src/com/android/launcher2/PagedViewCellLayout.java
+++ b/src/com/android/launcher2/PagedViewCellLayout.java
@@ -46,7 +46,6 @@
     private int mWidthGap;
     private int mHeightGap;
     private int mMaxGap;
-    private float mPeekWidth;
     protected PagedViewCellLayoutChildren mChildren;
     private PagedViewCellLayoutChildren mHolographicChildren;
     private boolean mAllowHardwareLayerCreation = false;
@@ -71,7 +70,6 @@
             resources.getDimensionPixelSize(R.dimen.apps_customize_cell_width);
         mOriginalCellHeight = mCellHeight =
             resources.getDimensionPixelSize(R.dimen.apps_customize_cell_height);
-        mPeekWidth = resources.getDimensionPixelSize(R.dimen.apps_customize_peek_width);
         mCellCountX = LauncherModel.getCellCountX();
         mCellCountY = LauncherModel.getCellCountY();
         mOriginalHeightGap = mOriginalHeightGap = mWidthGap = mHeightGap = -1;
@@ -366,7 +364,7 @@
         // The space for a page assuming that we want to show half of a column of the previous and
         // next pages is the width - left padding (current & next page) - right padding (previous &
         // current page) - half cell width (for previous and next pages)
-        int availWidth = (int) (width - (2 * mPaddingLeft + 2 * mPaddingRight) - (2 * mPeekWidth));
+        int availWidth = (int) (width - (2 * mPaddingLeft + 2 * mPaddingRight));
 
         // We know that we have to fit N cells with N-1 width gaps, so we just juggle to solve for N
         int n = Math.max(1, (availWidth + mWidthGap) / (mCellWidth + mWidthGap));
diff --git a/src/com/android/launcher2/Utilities.java b/src/com/android/launcher2/Utilities.java
index b537f7a..f7f97c5 100644
--- a/src/com/android/launcher2/Utilities.java
+++ b/src/com/android/launcher2/Utilities.java
@@ -29,17 +29,11 @@
 import android.graphics.PaintFlagsDrawFilter;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
-import android.graphics.RectF;
 import android.graphics.TableMaskFilter;
-import android.graphics.Typeface;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.PaintDrawable;
-import android.text.StaticLayout;
-import android.text.TextPaint;
-import android.text.Layout.Alignment;
 import android.util.DisplayMetrics;
-import android.util.Log;
 
 import com.android.launcher.R;
 
@@ -265,120 +259,6 @@
         sDisabledPaint.setAlpha(0x88);
     }
 
-    static class BubbleText {
-        private static final int MAX_LINES = 2;
-
-        private final TextPaint mTextPaint;
-
-        private final RectF mBubbleRect = new RectF();
-
-        private final float mTextWidth;
-        private final int mLeading;
-        private final int mFirstLineY;
-        private final int mLineHeight;
-
-        private final int mBitmapWidth;
-        private final int mBitmapHeight;
-        private final int mDensity;
-
-        BubbleText(Context context) {
-            final Resources resources = context.getResources();
-
-            final DisplayMetrics metrics = resources.getDisplayMetrics();
-            final float scale = metrics.density;
-            mDensity = metrics.densityDpi;
-
-            final float paddingLeft = 2.0f * scale;
-            final float paddingRight = 2.0f * scale;
-            final float cellWidth = resources.getDimension(R.dimen.title_texture_width);
-
-            RectF bubbleRect = mBubbleRect;
-            bubbleRect.left = 0;
-            bubbleRect.top = 0;
-            bubbleRect.right = (int) cellWidth;
-
-            mTextWidth = cellWidth - paddingLeft - paddingRight;
-
-            TextPaint textPaint = mTextPaint = new TextPaint();
-            textPaint.setTypeface(Typeface.DEFAULT);
-            textPaint.setTextSize(13*scale);
-            textPaint.setColor(0xffffffff);
-            textPaint.setAntiAlias(true);
-            if (TEXT_BURN) {
-                textPaint.setShadowLayer(8, 0, 0, 0xff000000);
-            }
-
-            float ascent = -textPaint.ascent();
-            float descent = textPaint.descent();
-            float leading = 0.0f;//(ascent+descent) * 0.1f;
-            mLeading = (int)(leading + 0.5f);
-            mFirstLineY = (int)(leading + ascent + 0.5f);
-            mLineHeight = (int)(leading + ascent + descent + 0.5f);
-
-            mBitmapWidth = (int)(mBubbleRect.width() + 0.5f);
-            mBitmapHeight = roundToPow2((int)((MAX_LINES * mLineHeight) + leading + 0.5f));
-
-            mBubbleRect.offsetTo((mBitmapWidth-mBubbleRect.width())/2, 0);
-
-            if (false) {
-                Log.d(TAG, "mBitmapWidth=" + mBitmapWidth + " mBitmapHeight="
-                        + mBitmapHeight + " w=" + ((int)(mBubbleRect.width() + 0.5f))
-                        + " h=" + ((int)((MAX_LINES * mLineHeight) + leading + 0.5f)));
-            }
-        }
-
-        /** You own the bitmap after this and you must call recycle on it. */
-        Bitmap createTextBitmap(String text) {
-            Bitmap b = Bitmap.createBitmap(mBitmapWidth, mBitmapHeight, Bitmap.Config.ALPHA_8);
-            b.setDensity(mDensity);
-            Canvas c = new Canvas(b);
-
-            StaticLayout layout = new StaticLayout(text, mTextPaint, (int)mTextWidth,
-                    Alignment.ALIGN_CENTER, 1, 0, true);
-            int lineCount = layout.getLineCount();
-            if (lineCount > MAX_LINES) {
-                lineCount = MAX_LINES;
-            }
-            //if (!TEXT_BURN && lineCount > 0) {
-                //RectF bubbleRect = mBubbleRect;
-                //bubbleRect.bottom = height(lineCount);
-                //c.drawRoundRect(bubbleRect, mCornerRadius, mCornerRadius, mRectPaint);
-            //}
-            for (int i=0; i<lineCount; i++) {
-                //int x = (int)((mBubbleRect.width() - layout.getLineMax(i)) / 2.0f);
-                //int y = mFirstLineY + (i * mLineHeight);
-                final String lineText = text.substring(layout.getLineStart(i), layout.getLineEnd(i));
-                int x = (int)(mBubbleRect.left
-                        + ((mBubbleRect.width() - mTextPaint.measureText(lineText)) * 0.5f));
-                int y = mFirstLineY + (i * mLineHeight);
-                c.drawText(lineText, x, y, mTextPaint);
-            }
-
-            c.setBitmap(null);
-            return b;
-        }
-
-        private int height(int lineCount) {
-            return (int)((lineCount * mLineHeight) + mLeading + mLeading + 0.0f);
-        }
-
-        int getBubbleWidth() {
-            return (int)(mBubbleRect.width() + 0.5f);
-        }
-
-        int getMaxBubbleHeight() {
-            return height(MAX_LINES);
-        }
-
-        int getBitmapWidth() {
-            return mBitmapWidth;
-        }
-
-        int getBitmapHeight() {
-            return mBitmapHeight;
-        }
-    }
-
     /** Only works for positive numbers. */
     static int roundToPow2(int n) {
         int orig = n;
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index ede08cc..e2fcfec 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -17,12 +17,12 @@
 package com.android.launcher2;
 
 import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
-import android.animation.Animator.AnimatorListener;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.app.AlertDialog;
 import android.app.WallpaperManager;
@@ -33,15 +33,14 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.Camera;
 import android.graphics.Canvas;
-import android.graphics.Color;
 import android.graphics.Matrix;
 import android.graphics.Paint;
+import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Region.Op;
@@ -183,6 +182,7 @@
     private Bitmap mDragOutline = null;
     private final Rect mTempRect = new Rect();
     private final int[] mTempXY = new int[2];
+    private int mDragViewMultiplyColor;
 
     // Paint used to draw external drop outline
     private final Paint mExternalDragOutlinePaint = new Paint();
@@ -306,6 +306,7 @@
 
         mSpringLoadedShrinkFactor =
             res.getInteger(R.integer.config_workspaceSpringLoadShrinkPercentage) / 100.0f;
+        mDragViewMultiplyColor = res.getColor(R.color.drag_view_multiply_color);
 
         // if the value is manually specified, use that instead
         cellCountX = a.getInt(R.styleable.Workspace_cellCountX, cellCountX);
@@ -597,11 +598,20 @@
 
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
-        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+        switch (ev.getAction() & MotionEvent.ACTION_MASK) {
+        case MotionEvent.ACTION_DOWN:
             mXDown = ev.getX();
             mYDown = ev.getY();
+            break;
+        case MotionEvent.ACTION_POINTER_UP:
+        case MotionEvent.ACTION_UP:
+            if (mTouchState == TOUCH_STATE_REST) {
+                final CellLayout currentPage = (CellLayout) getChildAt(mCurrentPage);
+                if (!currentPage.lastDownOnOccupiedCell()) {
+                    onWallpaperTap(ev);
+                }
+            }
         }
-
         return super.onInterceptTouchEvent(ev);
     }
 
@@ -1290,7 +1300,6 @@
         }
     }
 
-    @Override
     protected void onWallpaperTap(MotionEvent ev) {
         final int[] position = mTempCell;
         getLocationOnScreen(position);
@@ -1964,6 +1973,7 @@
         canvas.setBitmap(b);
         drawDragView(v, canvas, padding, true);
         mOutlineHelper.applyOuterBlur(b, canvas, outlineColor);
+        canvas.drawColor(mDragViewMultiplyColor, PorterDuff.Mode.MULTIPLY);
         canvas.setBitmap(null);
 
         return b;