Merge branch 'master' into honeycomb-release
diff --git a/res/drawable-xlarge-hdpi/home_press.9.png b/res/drawable-xlarge-hdpi/home_press.9.png
new file mode 100644
index 0000000..4beec62
--- /dev/null
+++ b/res/drawable-xlarge-hdpi/home_press.9.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/ic_voice_search.png b/res/drawable-xlarge-hdpi/ic_voice_search.png
new file mode 100644
index 0000000..66d14ae
--- /dev/null
+++ b/res/drawable-xlarge-hdpi/ic_voice_search.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/rotate_button_normal.png b/res/drawable-xlarge-hdpi/rotate_button_normal.png
deleted file mode 100644
index 3772018..0000000
--- a/res/drawable-xlarge-hdpi/rotate_button_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/rotate_button_pressed.png b/res/drawable-xlarge-hdpi/rotate_button_pressed.png
deleted file mode 100644
index 7ceb996..0000000
--- a/res/drawable-xlarge-hdpi/rotate_button_pressed.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/textfield_end.9.png b/res/drawable-xlarge-hdpi/textfield_end.9.png
new file mode 100644
index 0000000..be1b2b6
--- /dev/null
+++ b/res/drawable-xlarge-hdpi/textfield_end.9.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/textfield_start.9.png b/res/drawable-xlarge-hdpi/textfield_start.9.png
new file mode 100644
index 0000000..6b5ebe2
--- /dev/null
+++ b/res/drawable-xlarge-hdpi/textfield_start.9.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/app_market_generic.png b/res/drawable-xlarge-mdpi/app_market_generic.png
index 0ceaeef..c093e24 100644
--- a/res/drawable-xlarge-mdpi/app_market_generic.png
+++ b/res/drawable-xlarge-mdpi/app_market_generic.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/home_press.9.png b/res/drawable-xlarge-mdpi/home_press.9.png
new file mode 100644
index 0000000..ff841c3
--- /dev/null
+++ b/res/drawable-xlarge-mdpi/home_press.9.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/ic_voice_search.png b/res/drawable-xlarge-mdpi/ic_voice_search.png
new file mode 100644
index 0000000..a2fe874
--- /dev/null
+++ b/res/drawable-xlarge-mdpi/ic_voice_search.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/textfield_end.9.png b/res/drawable-xlarge-mdpi/textfield_end.9.png
new file mode 100644
index 0000000..94706b4
--- /dev/null
+++ b/res/drawable-xlarge-mdpi/textfield_end.9.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/textfield_start.9.png b/res/drawable-xlarge-mdpi/textfield_start.9.png
new file mode 100644
index 0000000..8cddc34
--- /dev/null
+++ b/res/drawable-xlarge-mdpi/textfield_start.9.png
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/glow_wallpaper_small.png b/res/drawable-xlarge-nodpi/glow_wallpaper_small.png
new file mode 100644
index 0000000..f83fc60
--- /dev/null
+++ b/res/drawable-xlarge-nodpi/glow_wallpaper_small.png
Binary files differ
diff --git a/res/drawable-xlarge/rotate_button.xml b/res/drawable-xlarge/button_bg.xml
similarity index 89%
rename from res/drawable-xlarge/rotate_button.xml
rename to res/drawable-xlarge/button_bg.xml
index c29efa4..9e6e1ff 100644
--- a/res/drawable-xlarge/rotate_button.xml
+++ b/res/drawable-xlarge/button_bg.xml
@@ -15,6 +15,6 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true" android:drawable="@drawable/rotate_button_pressed" />
-    <item android:drawable="@drawable/rotate_button_normal" />
+    <item android:state_pressed="true" android:drawable="@drawable/home_press" />
+    <item android:drawable="@android:color/transparent" />
 </selector>
diff --git a/res/layout-xlarge-land/all_apps_tabbed.xml b/res/layout-xlarge-land/all_apps_tabbed.xml
index 89a3104..8a0e8b8 100644
--- a/res/layout-xlarge-land/all_apps_tabbed.xml
+++ b/res/layout-xlarge-land/all_apps_tabbed.xml
@@ -20,13 +20,24 @@
         android:orientation="vertical"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
-        <TabWidget
-            android:id="@android:id/tabs"
+        <RelativeLayout
             android:layout_width="952dp"
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"
-            android:background="@drawable/tab_unselected_holo"
-            android:tabStripEnabled="false" />
+            android:background="@drawable/tab_unselected_holo">
+            <TabWidget
+                android:id="@android:id/tabs"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentLeft="true"
+                android:tabStripEnabled="false" />
+            <ImageView
+                android:id="@+id/market_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentRight="true"
+                android:onClick="onClickAppMarketButton" />
+        </RelativeLayout>
         <FrameLayout
             android:id="@android:id/tabcontent"
             android:layout_width="match_parent"
@@ -34,7 +45,7 @@
             <com.android.launcher2.AllAppsPagedView
                 android:id="@+id/all_apps_paged_view"
                 android:layout_width="match_parent"
-                android:layout_height="match_parent"
+                android:layout_height="wrap_content"
                 launcher:cellCountX="7"
                 launcher:cellCountY="5"
                 launcher:pageLayoutWidthGap="36dp"
diff --git a/res/layout-xlarge-land/launcher.xml b/res/layout-xlarge-land/launcher.xml
index e5ba393..7516796 100644
--- a/res/layout-xlarge-land/launcher.xml
+++ b/res/layout-xlarge-land/launcher.xml
@@ -22,23 +22,17 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <include
-        layout="@layout/all_apps_tabbed"
-        android:id="@+id/all_apps_view"
-        android:layout_width="match_parent"
-        android:layout_height="600dp"
-        android:layout_gravity="top"/>
-
     <!-- The workspace contains 5 screens of cells -->
     <com.android.launcher2.Workspace
         android:id="@+id/workspace"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:paddingTop="?android:attr/actionBarSize"
+        android:paddingBottom="10dp"
         launcher:defaultScreen="2"
         launcher:cellCountX="8"
         launcher:cellCountY="7"
-        launcher:pageSpacing="32dp">
+        launcher:pageSpacing="50dp">
 
         <include android:id="@+id/cell1" layout="@layout/workspace_screen" />
         <include android:id="@+id/cell2" layout="@layout/workspace_screen" />
@@ -47,22 +41,67 @@
         <include android:id="@+id/cell5" layout="@layout/workspace_screen" />
     </com.android.launcher2.Workspace>
 
+    <include
+        layout="@layout/all_apps_tabbed"
+        android:id="@+id/all_apps_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="top" />
+
     <RelativeLayout
         android:id="@+id/all_apps_button_cluster"
         android:layout_width="fill_parent"
         android:layout_height="?android:attr/actionBarSize"
         android:layout_gravity="top">
 
-        <ImageView
-            android:id="@+id/search_button"
+        <LinearLayout android:id="@+id/search_button_cluster"
             android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_gravity="left"
-            android:layout_marginLeft="@dimen/toolbar_button_spacing"
+            android:layout_height="48dp"
+            android:gravity="bottom"
+            >
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:layout_marginLeft="16dp"
+                android:background="@drawable/textfield_start"
+                android:orientation="horizontal">
+                <!-- Global search icon -->
+                <ImageView
+                    android:id="@+id/search_button"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="bottom"
+                    android:paddingLeft="8dp"
+                    android:paddingRight="8dp"
+                    android:paddingTop="12dp"
+                    android:src="@drawable/search_button_generic"
+                    android:background="@drawable/button_bg"
+                    android:onClick="onClickSearchButton"
+                    android:focusable="true"
+                    android:clickable="true"/>
+            </LinearLayout>
 
-            android:onClick="onClickSearchButton"
-            android:focusable="true"
-            android:clickable="true"/>
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:background="@drawable/textfield_end"
+                android:orientation="horizontal">
+                <!-- Voice search icon -->
+                <ImageView
+                    android:id="@+id/voice_button"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="bottom"
+                    android:paddingLeft="8dp"
+                    android:paddingRight="8dp"
+                    android:paddingTop="12dp"
+                    android:src="@drawable/ic_voice_search"
+                    android:background="@drawable/button_bg"
+                    android:onClick="onClickVoiceButton"
+                    android:focusable="true"
+                    android:clickable="true"/>
+            </LinearLayout>
+        </LinearLayout>
 
         <ImageView
             android:id="@+id/configure_button"
@@ -92,25 +131,12 @@
             android:focusable="true"
             android:clickable="true" />
 
-        <!-- The button to bring up the installed app market.
-             The icon for this button will be dynamically set. -->
-        <ImageView
-            android:id="@+id/market_button"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_alignLeft="@id/all_apps_button"
-
-            android:onClick="onClickAppMarketButton"
-            android:focusable="false"
-            android:clickable="false"
-            android:visibility="gone"/>
-
         <com.android.launcher2.DeleteZone
             android:id="@+id/delete_zone"
             android:src="@drawable/delete_zone_selector"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
-            android:layout_alignLeft="@id/all_apps_button"
+            android:layout_alignRight="@id/all_apps_button"
 
             android:visibility="gone"
             launcher:direction="horizontal" />
diff --git a/res/layout-xlarge-land/workspace_screen.xml b/res/layout-xlarge-land/workspace_screen.xml
index 64de05e..e983b79 100644
--- a/res/layout-xlarge-land/workspace_screen.xml
+++ b/res/layout-xlarge-land/workspace_screen.xml
@@ -26,7 +26,7 @@
     launcher:cellHeight="@dimen/workspace_cell_height"
     launcher:widthGap="@dimen/workspace_width_gap"
     launcher:heightGap="@dimen/workspace_height_gap"
-    launcher:yAxisStartPadding="25dip"
-    launcher:yAxisEndPadding="25dip"
-    launcher:xAxisStartPadding="40dip"
-    launcher:xAxisEndPadding="40dip" />
+    launcher:yAxisStartPadding="15dip"
+    launcher:yAxisEndPadding="15dip"
+    launcher:xAxisStartPadding="25dip"
+    launcher:xAxisEndPadding="25dip" />
diff --git a/res/layout-xlarge-port/all_apps_tabbed.xml b/res/layout-xlarge-port/all_apps_tabbed.xml
index 65e3729..038a9a0 100644
--- a/res/layout-xlarge-port/all_apps_tabbed.xml
+++ b/res/layout-xlarge-port/all_apps_tabbed.xml
@@ -20,13 +20,24 @@
         android:orientation="vertical"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
-        <TabWidget
-            android:id="@android:id/tabs"
+        <RelativeLayout
             android:layout_width="700dp"
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"
-            android:background="@drawable/tab_unselected_holo"
-            android:tabStripEnabled="false" />
+            android:background="@drawable/tab_unselected_holo">
+            <TabWidget
+                android:id="@android:id/tabs"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentLeft="true"
+                android:tabStripEnabled="false" />
+            <ImageView
+                android:id="@+id/market_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentRight="true"
+                android:onClick="onClickAppMarketButton" />
+        </RelativeLayout>
         <FrameLayout
             android:id="@android:id/tabcontent"
             android:layout_width="match_parent"
@@ -34,7 +45,7 @@
             <com.android.launcher2.AllAppsPagedView
                 android:id="@+id/all_apps_paged_view"
                 android:layout_width="match_parent"
-                android:layout_height="match_parent"
+                android:layout_height="wrap_content"
                 launcher:cellCountX="5"
                 launcher:cellCountY="7"
                 launcher:pageLayoutWidthGap="36dp"
diff --git a/res/layout-xlarge-port/launcher.xml b/res/layout-xlarge-port/launcher.xml
index 13b69fe..c2ca467 100644
--- a/res/layout-xlarge-port/launcher.xml
+++ b/res/layout-xlarge-port/launcher.xml
@@ -22,19 +22,13 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <include
-        layout="@layout/all_apps_tabbed"
-        android:id="@+id/all_apps_view"
-        android:layout_width="match_parent"
-        android:layout_height="1040dp"
-        android:layout_gravity="top"/>
-
     <!-- The workspace contains 5 screens of cells -->
     <com.android.launcher2.Workspace
         android:id="@+id/workspace"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:paddingTop="?android:attr/actionBarSize"
+        android:paddingBottom="10dp"
         launcher:defaultScreen="2"
         launcher:cellCountX="8"
         launcher:cellCountY="7"
@@ -47,22 +41,67 @@
         <include android:id="@+id/cell5" layout="@layout/workspace_screen" />
     </com.android.launcher2.Workspace>
 
+    <include
+        layout="@layout/all_apps_tabbed"
+        android:id="@+id/all_apps_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="top"/>
+
     <RelativeLayout
         android:id="@+id/all_apps_button_cluster"
         android:layout_width="fill_parent"
         android:layout_height="?android:attr/actionBarSize"
         android:layout_gravity="top">
 
-        <ImageView
-            android:id="@+id/search_button"
+        <LinearLayout android:id="@+id/search_button_cluster"
             android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_gravity="left"
-            android:layout_marginLeft="@dimen/toolbar_button_spacing"
+            android:layout_height="48dp"
+            android:gravity="bottom"
+            >
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:layout_marginLeft="16dp"
+                android:background="@drawable/textfield_start"
+                android:orientation="horizontal">
+                <!-- Global search icon -->
+                <ImageView
+                    android:id="@+id/search_button"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="bottom"
+                    android:paddingLeft="8dp"
+                    android:paddingRight="8dp"
+                    android:paddingTop="12dp"
+                    android:src="@drawable/search_button_generic"
+                    android:background="@drawable/button_bg"
+                    android:onClick="onClickSearchButton"
+                    android:focusable="true"
+                    android:clickable="true"/>
+            </LinearLayout>
 
-            android:onClick="onClickSearchButton"
-            android:focusable="true"
-            android:clickable="true"/>
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:background="@drawable/textfield_end"
+                android:orientation="horizontal">
+                <!-- Voice search icon -->
+                <ImageView
+                    android:id="@+id/voice_button"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="bottom"
+                    android:paddingLeft="8dp"
+                    android:paddingRight="8dp"
+                    android:paddingTop="12dp"
+                    android:src="@drawable/ic_voice_search"
+                    android:background="@drawable/button_bg"
+                    android:onClick="onClickVoiceButton"
+                    android:focusable="true"
+                    android:clickable="true"/>
+            </LinearLayout>
+        </LinearLayout>
 
         <ImageView
             android:id="@+id/configure_button"
@@ -110,7 +149,7 @@
             android:src="@drawable/delete_zone_selector"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
-            android:layout_alignLeft="@id/all_apps_button"
+            android:layout_alignRight="@id/all_apps_button"
 
             android:visibility="gone"
             launcher:direction="horizontal" />
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 22d1b63..3a47dea 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Stažené"</string>
     <string name="all_apps_no_games" msgid="5293893733372793696">"Nenalezeny žádné hry."</string>
     <string name="all_apps_no_downloads" msgid="6145042636084482299">"Žádné stažené aplikace."</string>
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 6806993..c898d67 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Downloadet"</string>
     <string name="all_apps_no_games" msgid="5293893733372793696">"Ingen spil."</string>
     <string name="all_apps_no_downloads" msgid="6145042636084482299">"Ingen hentede programmer."</string>
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index e60eb34..8ae0101 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Heruntergeladen"</string>
     <string name="all_apps_no_games" msgid="5293893733372793696">"Keine Spiele gefunden."</string>
     <string name="all_apps_no_downloads" msgid="6145042636084482299">"Keine heruntergeladenen Apps"</string>
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 0298d91..442a5d5 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Η λήψη ολοκληρώθηκε"</string>
     <string name="all_apps_no_games" msgid="5293893733372793696">"Δεν βρέθηκαν παιχνίδια."</string>
     <string name="all_apps_no_downloads" msgid="6145042636084482299">"Δεν βρέθηκαν ληφθ. εφαρμ."</string>
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 9158dbc..ed7a0f2 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Descargado"</string>
     <string name="all_apps_no_games" msgid="5293893733372793696">"No se encontraron juegos."</string>
     <string name="all_apps_no_downloads" msgid="6145042636084482299">"No se encontraron apps."</string>
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index f9d8b15..b173de0 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Descargadas"</string>
     <string name="all_apps_no_games" msgid="5293893733372793696">"No hay juegos."</string>
     <string name="all_apps_no_downloads" msgid="6145042636084482299">"Sin aplicaciones descarg."</string>
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 5827611..0b9e816 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Téléchargées"</string>
     <string name="all_apps_no_games" msgid="5293893733372793696">"Aucun jeu n\'a été trouvé."</string>
     <string name="all_apps_no_downloads" msgid="6145042636084482299">"Pas d\'application téléchargée"</string>
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 5b40b98..1763f55 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Scaricate"</string>
     <string name="all_apps_no_games" msgid="5293893733372793696">"Nessun gioco trovato."</string>
     <string name="all_apps_no_downloads" msgid="6145042636084482299">"Nessuna appl. scaricata"</string>
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 5932429..776e8ad 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"ダウンロード済み"</string>
     <string name="all_apps_no_games" msgid="5293893733372793696">"ゲームなし"</string>
     <string name="all_apps_no_downloads" msgid="6145042636084482299">"ダウンロードアプリなし"</string>
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 6dc4a60..d1bab2a 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"다운로드앱"</string>
     <string name="all_apps_no_games" msgid="5293893733372793696">"게임이 없습니다."</string>
     <string name="all_apps_no_downloads" msgid="6145042636084482299">"다운로드한 애플리케이션이 없습니다."</string>
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 40cbbba..e83ce45 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Nedlastet"</string>
     <string name="all_apps_no_games" msgid="5293893733372793696">"Finner ingen spill."</string>
     <string name="all_apps_no_downloads" msgid="6145042636084482299">"Finner ingen nedl.prog."</string>
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index fa19eea..541dbc8 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Gedownload"</string>
     <string name="all_apps_no_games" msgid="5293893733372793696">"Geen games gevonden."</string>
     <string name="all_apps_no_downloads" msgid="6145042636084482299">"Geen gedownl. apps gevond."</string>
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index cdfb0a9..d5c8fef 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Pobrane"</string>
     <string name="all_apps_no_games" msgid="5293893733372793696">"Nie znaleziono gier."</string>
     <string name="all_apps_no_downloads" msgid="6145042636084482299">"Brak pobranych aplikacji."</string>
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 59effc7..12b65c9 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Transferidas"</string>
     <string name="all_apps_no_games" msgid="5293893733372793696">"Sem jogos."</string>
     <string name="all_apps_no_downloads" msgid="6145042636084482299">"Sem aplic. transferidas."</string>
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 7f947a6..fd2f12a 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Download concluído"</string>
     <string name="all_apps_no_games" msgid="5293893733372793696">"Nenhum jogo encontrado."</string>
     <string name="all_apps_no_downloads" msgid="6145042636084482299">"Nenhum aplic. encontrado."</string>
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index 5e7b1e7..fdbce15 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -51,7 +51,7 @@
     <skip />
     <!-- no translation found for all_apps_no_downloads (6145042636084482299) -->
     <skip />
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index acfa352..9abc657 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Загруженные"</string>
     <string name="all_apps_no_games" msgid="5293893733372793696">"Игр не найдено."</string>
     <string name="all_apps_no_downloads" msgid="6145042636084482299">"Нет загруженных приложений."</string>
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 7248635..8a00147 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"Hämtade"</string>
     <string name="all_apps_no_games" msgid="5293893733372793696">"Inga spel hittades."</string>
     <string name="all_apps_no_downloads" msgid="6145042636084482299">"Inga hämtade appar."</string>
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 9716ea7..2da3997 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"İndirilenler"</string>
     <string name="all_apps_no_games" msgid="5293893733372793696">"Oyun bulunamadı."</string>
     <string name="all_apps_no_downloads" msgid="6145042636084482299">"İndirilmş uyg bulunamadı."</string>
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/res/values-xlarge-land/dimens.xml b/res/values-xlarge-land/dimens.xml
index db31cf1..51037f5 100644
--- a/res/values-xlarge-land/dimens.xml
+++ b/res/values-xlarge-land/dimens.xml
@@ -17,9 +17,9 @@
 <resources>
     <!-- the area at the edge of the screen that makes the workspace go left
          or right while you're dragging. -->
-    <dimen name="scroll_zone">160dip</dimen>
+    <dimen name="scroll_zone">100dip</dimen>
 
     <!-- Width/height gap overrides for the workspace -->
-    <dimen name="workspace_width_gap">16dp</dimen>
-    <dimen name="workspace_height_gap">5dp</dimen>
+    <dimen name="workspace_width_gap">32dp</dimen>
+    <dimen name="workspace_height_gap">2dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/res/values-xlarge/dimens.xml b/res/values-xlarge/dimens.xml
index 667f0e3..d98674f 100644
--- a/res/values-xlarge/dimens.xml
+++ b/res/values-xlarge/dimens.xml
@@ -45,4 +45,9 @@
     <dimen name="toolbar_padding">10dip</dimen>
 
     <dimen name="toolbar_button_spacing">20dip</dimen>
+
+    <!-- height & width of the drop rectangle for the trash icon -->
+    <dimen name="delete_zone_size">50dip</dimen>
+    <dimen name="delete_zone_min_padding">10dip</dimen>
+    <dimen name="delete_zone_max_padding">20dip</dimen>
 </resources>
diff --git a/res/values-xlarge/styles.xml b/res/values-xlarge/styles.xml
index 83cdbcc..fcbd969 100644
--- a/res/values-xlarge/styles.xml
+++ b/res/values-xlarge/styles.xml
@@ -35,5 +35,6 @@
     <style name="WorkspaceIcon.Landscape">
         <item name="android:drawablePadding">0dip</item>
         <item name="android:paddingTop">0dip</item>
+        <item name="android:includeFontPadding">false</item>
     </style>
 </resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 22bba84..6f1ace7 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"已下载"</string>
     <string name="all_apps_no_games" msgid="5293893733372793696">"未找到游戏。"</string>
     <string name="all_apps_no_downloads" msgid="6145042636084482299">"未找到已下载的应用程序。"</string>
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 6cc7c32..4308584 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_apps_tab_downloaded" msgid="2300935549064726963">"下載內容"</string>
     <string name="all_apps_no_games" msgid="5293893733372793696">"找不到遊戲。"</string>
     <string name="all_apps_no_downloads" msgid="6145042636084482299">"找不到已下載的應用程式。"</string>
-    <!-- no translation found for external_drop_widget_error (7794528430439958736) -->
+    <!-- no translation found for external_drop_widget_error (4976816434597126575) -->
     <skip />
     <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) -->
     <skip />
diff --git a/src/com/android/launcher2/AllAppsPagedView.java b/src/com/android/launcher2/AllAppsPagedView.java
index 351384f..1f3df5f 100644
--- a/src/com/android/launcher2/AllAppsPagedView.java
+++ b/src/com/android/launcher2/AllAppsPagedView.java
@@ -498,8 +498,10 @@
             }
         });
 
-        menu.add(0, MENU_APP_INFO, 0, R.string.cab_menu_app_info).setActionView(infoButton);
         menu.add(0, MENU_DELETE_APP, 0, R.string.cab_menu_delete_app).setActionView(deleteZone);
+        menu.add(0, MENU_APP_INFO, 0, R.string.cab_menu_app_info).setActionView(infoButton);
+
+        mLauncher.getWorkspace().shrinkToBottomVisible();
 
         return true;
     }
diff --git a/src/com/android/launcher2/AllAppsTabbed.java b/src/com/android/launcher2/AllAppsTabbed.java
index a6e21b9..0e32461 100644
--- a/src/com/android/launcher2/AllAppsTabbed.java
+++ b/src/com/android/launcher2/AllAppsTabbed.java
@@ -25,6 +25,7 @@
 import android.content.res.Resources;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.MotionEvent;
 import android.view.View;
 import android.widget.TabHost;
 
@@ -169,4 +170,12 @@
     public void surrender() {
         mAllApps.surrender();
     }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        if (ev.getY() > mAllApps.getBottom()) {
+            return false;
+        }
+        return true;
+    }
 }
diff --git a/src/com/android/launcher2/ApplicationInfoDropTarget.java b/src/com/android/launcher2/ApplicationInfoDropTarget.java
index 3e5ebd5..c2922ab 100644
--- a/src/com/android/launcher2/ApplicationInfoDropTarget.java
+++ b/src/com/android/launcher2/ApplicationInfoDropTarget.java
@@ -16,6 +16,8 @@
 
 package com.android.launcher2;
 
+import com.android.launcher.R;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.graphics.Paint;
@@ -133,11 +135,16 @@
             // In that case, this icon is more tightly spaced next to the delete icon so we want
             // it to have a smaller drag region. When the new drag&drop system comes in, we'll
             // dispatch the drag/drop by calculating what target you're overlapping
-            final int dragPadding = mManageVisibility ? 50 : 10;
-            outRect.top -= dragPadding;
-            outRect.left -= dragPadding;
-            outRect.bottom += dragPadding;
-            outRect.right += dragPadding;
+            final int minPadding = R.dimen.delete_zone_min_padding;
+            final int maxPadding = R.dimen.delete_zone_max_padding;
+            final int outerDragPadding =
+                    getResources().getDimensionPixelSize(R.dimen.delete_zone_size);
+            final int innerDragPadding = getResources().getDimensionPixelSize(
+                    mManageVisibility ? maxPadding : minPadding);
+            outRect.top -= outerDragPadding;
+            outRect.left -= innerDragPadding;
+            outRect.bottom += outerDragPadding;
+            outRect.right += outerDragPadding;
         }
     }
 
diff --git a/src/com/android/launcher2/DeleteZone.java b/src/com/android/launcher2/DeleteZone.java
index 4acde1c..be651b2 100644
--- a/src/com/android/launcher2/DeleteZone.java
+++ b/src/com/android/launcher2/DeleteZone.java
@@ -210,56 +210,72 @@
             // In that case, this icon is more tightly spaced next to the delete icon so we want
             // it to have a smaller drag region. When the new drag&drop system comes in, we'll
             // dispatch the drag/drop by calculating what target you're overlapping
-            final int dragPadding = mManageVisibility ? 50 : 10;
-            outRect.top -= dragPadding;
-            outRect.left -= dragPadding;
-            outRect.bottom += dragPadding;
-            outRect.right += dragPadding;
+            final int minPadding = R.dimen.delete_zone_min_padding;
+            final int maxPadding = R.dimen.delete_zone_max_padding;
+            final int outerDragPadding =
+                    getResources().getDimensionPixelSize(R.dimen.delete_zone_size);
+            final int innerDragPadding = getResources().getDimensionPixelSize(
+                    mManageVisibility ? maxPadding : minPadding);
+            outRect.top -= outerDragPadding;
+            outRect.left -= innerDragPadding;
+            outRect.bottom += outerDragPadding;
+            outRect.right += innerDragPadding;
         }
     }
 
     private void createAnimations() {
-        if (mInAnimation == null) {
-            mInAnimation = new FastAnimationSet();
-            final AnimationSet animationSet = mInAnimation;
-            animationSet.setInterpolator(new AccelerateInterpolator());
-            animationSet.addAnimation(new AlphaAnimation(0.0f, 1.0f));
-            if (mOrientation == ORIENTATION_HORIZONTAL) {
-                animationSet.addAnimation(new TranslateAnimation(Animation.ABSOLUTE, 0.0f,
-                        Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f,
-                        Animation.RELATIVE_TO_SELF, 0.0f));
-            } else {
-                animationSet.addAnimation(new TranslateAnimation(Animation.RELATIVE_TO_SELF,
-                        1.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.ABSOLUTE, 0.0f,
-                        Animation.ABSOLUTE, 0.0f));
-            }
-            animationSet.setDuration(ANIMATION_DURATION);
-        }
         if (mHandleInAnimation == null) {
             mHandleInAnimation = new AlphaAnimation(0.0f, 1.0f);
             mHandleInAnimation.setDuration(ANIMATION_DURATION);
         }
-        if (mOutAnimation == null) {
-            mOutAnimation = new FastAnimationSet();
-            final AnimationSet animationSet = mOutAnimation;
-            animationSet.setInterpolator(new AccelerateInterpolator());
-            animationSet.addAnimation(new AlphaAnimation(1.0f, 0.0f));
-            if (mOrientation == ORIENTATION_HORIZONTAL) {
-                animationSet.addAnimation(new FastTranslateAnimation(Animation.ABSOLUTE, 0.0f,
-                        Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
-                        Animation.RELATIVE_TO_SELF, 1.0f));
+
+        if (mInAnimation == null) {
+            mInAnimation = new FastAnimationSet();
+            if (!LauncherApplication.isScreenXLarge()) {
+                final AnimationSet animationSet = mInAnimation;
+                animationSet.setInterpolator(new AccelerateInterpolator());
+                animationSet.addAnimation(new AlphaAnimation(0.0f, 1.0f));
+                if (mOrientation == ORIENTATION_HORIZONTAL) {
+                    animationSet.addAnimation(new TranslateAnimation(Animation.ABSOLUTE, 0.0f,
+                            Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f,
+                            Animation.RELATIVE_TO_SELF, 0.0f));
+                } else {
+                    animationSet.addAnimation(new TranslateAnimation(Animation.RELATIVE_TO_SELF,
+                            1.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.ABSOLUTE, 0.0f,
+                            Animation.ABSOLUTE, 0.0f));
+                }
+                animationSet.setDuration(ANIMATION_DURATION);
             } else {
-                animationSet.addAnimation(new FastTranslateAnimation(Animation.RELATIVE_TO_SELF,
-                        0.0f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.ABSOLUTE, 0.0f,
-                        Animation.ABSOLUTE, 0.0f));
+                mInAnimation.addAnimation(mHandleInAnimation);
             }
-            animationSet.setDuration(ANIMATION_DURATION);
         }
+
         if (mHandleOutAnimation == null) {
             mHandleOutAnimation = new AlphaAnimation(1.0f, 0.0f);
             mHandleOutAnimation.setFillAfter(true);
             mHandleOutAnimation.setDuration(ANIMATION_DURATION);
         }
+
+        if (mOutAnimation == null) {
+            mOutAnimation = new FastAnimationSet();
+            if (!LauncherApplication.isScreenXLarge()) {
+                final AnimationSet animationSet = mOutAnimation;
+                animationSet.setInterpolator(new AccelerateInterpolator());
+                animationSet.addAnimation(new AlphaAnimation(1.0f, 0.0f));
+                if (mOrientation == ORIENTATION_HORIZONTAL) {
+                    animationSet.addAnimation(new FastTranslateAnimation(Animation.ABSOLUTE, 0.0f,
+                            Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
+                            Animation.RELATIVE_TO_SELF, 1.0f));
+                } else {
+                    animationSet.addAnimation(new FastTranslateAnimation(Animation.RELATIVE_TO_SELF,
+                            0.0f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.ABSOLUTE, 0.0f,
+                            Animation.ABSOLUTE, 0.0f));
+                }
+                animationSet.setDuration(ANIMATION_DURATION);
+            } else {
+                mOutAnimation.addAnimation(mHandleOutAnimation);
+            }
+        }
     }
 
     void setLauncher(Launcher launcher) {
diff --git a/src/com/android/launcher2/DragController.java b/src/com/android/launcher2/DragController.java
index d796fbe..2b566b7 100644
--- a/src/com/android/launcher2/DragController.java
+++ b/src/com/android/launcher2/DragController.java
@@ -20,7 +20,6 @@
 
 import android.content.Context;
 import android.graphics.Bitmap;
-import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.os.Handler;
@@ -58,6 +57,7 @@
     private static final int SCROLL_OUTSIDE_ZONE = 0;
     private static final int SCROLL_WAITING_IN_ZONE = 1;
 
+    static final int SCROLL_NONE = -1;
     static final int SCROLL_LEFT = 0;
     static final int SCROLL_RIGHT = 1;
 
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 464ea64..55a6176 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -73,6 +73,7 @@
 import android.os.SystemProperties;
 import android.provider.LiveFolders;
 import android.provider.Settings;
+import android.speech.RecognizerIntent;
 import android.text.Selection;
 import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
@@ -312,7 +313,6 @@
             String shortcutsLabel = getString(R.string.shortcuts_tab_label);
             mHomeCustomizationDrawer.addTab(mHomeCustomizationDrawer.newTabSpec(SHORTCUTS_TAG)
                     .setIndicator(shortcutsLabel).setContent(contentFactory));
-
             mHomeCustomizationDrawer.setOnTabChangedListener(new OnTabChangeListener() {
                 public void onTabChanged(String tabId) {
                     // animate the changing of the tab content by fading pages in and out
@@ -876,6 +876,7 @@
         }
 
         mWorkspace = (Workspace) dragLayer.findViewById(R.id.workspace);
+
         final Workspace workspace = mWorkspace;
         workspace.setHapticFeedbackEnabled(false);
 
@@ -1925,6 +1926,21 @@
     }
 
     /**
+     * Event handler for the voice button
+     *
+     * @param v The view that was clicked.
+     */
+    public void onClickVoiceButton(View v) {
+        startVoiceSearch();
+    }
+
+    private void startVoiceSearch() {
+        Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        startActivity(intent);
+    }
+
+    /**
      * Event handler for the "gear" button that appears on the home screen, which
      * enters home screen customization mode.
      *
@@ -2477,9 +2493,8 @@
      * @param hideSeq AnimatorSet in which to put "hide" animations, or null.
      */
     private void hideAndShowToolbarButtons(State newState, AnimatorSet showSeq, AnimatorSet hideSeq) {
-        final View searchButton = findViewById(R.id.search_button);
+        final View searchButton = findViewById(R.id.search_button_cluster);
         final View allAppsButton = findViewById(R.id.all_apps_button);
-        final View marketButton = findViewById(R.id.market_button);
         final View configureButton = findViewById(R.id.configure_button);
 
         switch (newState) {
@@ -2487,20 +2502,16 @@
             hideOrShowToolbarButton(true, searchButton, showSeq);
             hideOrShowToolbarButton(true, allAppsButton, showSeq);
             hideOrShowToolbarButton(true, configureButton, showSeq);
-            hideOrShowToolbarButton(false, marketButton, hideSeq);
             mDeleteZone.setHandle(allAppsButton);
             break;
         case ALL_APPS:
-            hideOrShowToolbarButton(true, configureButton, showSeq);
-            hideOrShowToolbarButton(true, marketButton, showSeq);
+            hideOrShowToolbarButton(false, configureButton, hideSeq);
             hideOrShowToolbarButton(false, searchButton, hideSeq);
             hideOrShowToolbarButton(false, allAppsButton, hideSeq);
-            mDeleteZone.setHandle(marketButton);
             break;
         case CUSTOMIZE:
-            hideOrShowToolbarButton(true, allAppsButton, showSeq);
+            hideOrShowToolbarButton(false, allAppsButton, hideSeq);
             hideOrShowToolbarButton(false, searchButton, hideSeq);
-            hideOrShowToolbarButton(false, marketButton, hideSeq);
             hideOrShowToolbarButton(false, configureButton, hideSeq);
             mDeleteZone.setHandle(allAppsButton);
             break;
@@ -2544,7 +2555,7 @@
         setPivotsForZoom(toView, toState, scale);
 
         if (toAllApps) {
-            mWorkspace.shrinkToBottom(animated);
+            mWorkspace.shrinkToBottomHidden(animated);
         } else {
             mWorkspace.shrinkToTop(animated);
         }
@@ -2683,7 +2694,7 @@
         mAllAppsPagedView.endChoiceMode();
 
         if (toState == State.ALL_APPS) {
-            mWorkspace.shrinkToBottom(animated);
+            mWorkspace.shrinkToBottomHidden(animated);
         } else {
             mWorkspace.shrinkToTop(animated);
         }
@@ -2754,6 +2765,7 @@
 
         // TODO: fade these two too
         mDeleteZone.setVisibility(View.GONE);
+
         // Change the state *after* we've called all the transition code
         mState = State.ALL_APPS;
     }
@@ -2774,6 +2786,7 @@
         } else if (mState == State.CUSTOMIZE) {
             hideCustomizationDrawer(animated);
         }
+
         // Change the state *after* we've called all the transition code
         mState = State.WORKSPACE;
     }
@@ -2901,6 +2914,21 @@
             if (activityName != null) {
                 updateButtonWithIconFromExternalActivity(
                         R.id.search_button, activityName, R.drawable.search_button_generic);
+            } else {
+                findViewById(R.id.search_button).setVisibility(View.GONE);
+            }
+        }
+    }
+
+    private void updateVoiceSearchIcon() {
+        if (LauncherApplication.isScreenXLarge()) {
+            Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
+            ComponentName activityName = intent.resolveActivity(getPackageManager());
+            if (activityName != null) {
+                updateButtonWithIconFromExternalActivity(
+                        R.id.voice_button, activityName, R.drawable.ic_voice_search);
+            } else {
+                findViewById(R.id.voice_button).setVisibility(View.GONE);
             }
         }
     }
@@ -3252,6 +3280,16 @@
     }
 
     /**
+     * Updates the icons on the launcher that are affected by changes to the package list
+     * on the device.
+     */
+    private void updateIconsAffectedByPackageManagerChanges() {
+        updateAppMarketIcon();
+        updateGlobalSearchIcon();
+        updateVoiceSearchIcon();
+    }
+
+    /**
      * Add the icons for all apps.
      *
      * Implementation of the method from LauncherModel.Callbacks.
@@ -3261,8 +3299,7 @@
         if (mCustomizePagedView != null) {
             mCustomizePagedView.setApps(apps);
         }
-        updateAppMarketIcon();
-        updateGlobalSearchIcon();
+        updateIconsAffectedByPackageManagerChanges();
     }
 
     /**
@@ -3277,8 +3314,7 @@
         if (mCustomizePagedView != null) {
             mCustomizePagedView.addApps(apps);
         }
-        updateAppMarketIcon();
-        updateGlobalSearchIcon();
+        updateIconsAffectedByPackageManagerChanges();
     }
 
     /**
@@ -3294,8 +3330,7 @@
         if (mCustomizePagedView != null) {
             mCustomizePagedView.updateApps(apps);
         }
-        updateAppMarketIcon();
-        updateGlobalSearchIcon();
+        updateIconsAffectedByPackageManagerChanges();
     }
 
     /**
@@ -3312,8 +3347,7 @@
         if (mCustomizePagedView != null) {
             mCustomizePagedView.removeApps(apps);
         }
-        updateAppMarketIcon();
-        updateGlobalSearchIcon();
+        updateIconsAffectedByPackageManagerChanges();
     }
 
     /**
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index d4dffe6..fb8b7d6 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -349,11 +349,16 @@
             throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");
         }
 
+        /* Allow the height to be set as WRAP_CONTENT. This allows the particular case
+         * of the All apps view on XLarge displays to not take up more space then it needs. Width
+         * is still not allowed to be set as WRAP_CONTENT since many parts of the code expect
+         * each page to have the same width.
+         */
         final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
-        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
-        if (heightMode != MeasureSpec.EXACTLY) {
-            throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");
-        }
+        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+        int maxChildHeight = 0;
+
+        final int verticalPadding = mPaddingTop + mPaddingBottom;
 
         // The children are given the same width and height as the workspace
         // unless they were set to WRAP_CONTENT
@@ -380,9 +385,14 @@
             final int childWidthMeasureSpec =
                 MeasureSpec.makeMeasureSpec(widthSize, childWidthMode);
             final int childHeightMeasureSpec =
-                MeasureSpec.makeMeasureSpec(heightSize, childHeightMode);
+                MeasureSpec.makeMeasureSpec(heightSize - verticalPadding, childHeightMode);
 
             child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+            maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight());
+        }
+
+        if (heightMode == MeasureSpec.AT_MOST) {
+            heightSize = maxChildHeight + verticalPadding;
         }
 
         setMeasuredDimension(widthSize, heightSize);
@@ -399,6 +409,7 @@
             mFirstLayout = false;
         }
 
+        final int verticalPadding = mPaddingTop + mPaddingBottom;
         final int childCount = getChildCount();
         int childLeft = 0;
         if (childCount > 0) {
@@ -409,10 +420,13 @@
             final View child = getChildAt(i);
             if (child.getVisibility() != View.GONE) {
                 final int childWidth = child.getMeasuredWidth();
-                final int childHeight = (mCenterPagesVertically ?
-                        (getMeasuredHeight() - child.getMeasuredHeight()) / 2 : 0);
-                child.layout(childLeft, childHeight,
-                        childLeft + childWidth, childHeight + child.getMeasuredHeight());
+                final int childHeight = child.getMeasuredHeight();
+                int childTop = mPaddingTop;
+                if (mCenterPagesVertically) {
+                    childTop += ((getMeasuredHeight() - verticalPadding) - childHeight) / 2;
+                }
+                child.layout(childLeft, childTop,
+                        childLeft + childWidth, childTop + childHeight);
                 childLeft += childWidth + mPageSpacing;
             }
         }
diff --git a/src/com/android/launcher2/SmoothPagedView.java b/src/com/android/launcher2/SmoothPagedView.java
index 56037ff..8e729e4 100644
--- a/src/com/android/launcher2/SmoothPagedView.java
+++ b/src/com/android/launcher2/SmoothPagedView.java
@@ -131,7 +131,7 @@
         snapToPageWithVelocity(whichPage, 0, true);
     }
 
-    void snapToPageWithVelocity(int whichPage, int velocity, boolean settle) {
+    private void snapToPageWithVelocity(int whichPage, int velocity, boolean settle) {
             // if (!mScroller.isFinished()) return;
 
         whichPage = Math.max(0, Math.min(whichPage, getChildCount() - 1));
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 7e33a2c..169f53f 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -43,6 +43,7 @@
 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.Matrix;
 import android.graphics.Paint;
@@ -83,6 +84,7 @@
 
     // Y rotation to apply to the workspace screens
     private static final float WORKSPACE_ROTATION = 12.5f;
+    private static final float WORKSPACE_TRANSLATION = 50.0f;
 
     // These are extra scale factors to apply to the mini home screens
     // so as to achieve the desired transform
@@ -153,7 +155,12 @@
     private ShrinkPosition mWaitingToShrinkPosition;
     private AnimatorSet mAnimator;
 
+    /** Is the user is dragging an item near the edge of a page? */
     private boolean mInScrollArea = false;
+
+    /** If mInScrollArea is true, the direction of the scroll. */
+    private int mPendingScrollDirection = DragController.SCROLL_NONE;
+
     private boolean mInDragMode = false;
 
     private final HolographicOutlineHelper mOutlineHelper = new HolographicOutlineHelper();
@@ -172,6 +179,11 @@
     /** Used to trigger an animation as soon as the workspace stops scrolling. */
     private Animator mAnimOnPageEndMoving = null;
 
+    // Camera and Matrix used to determine the final position of a neighboring CellLayout
+    private final Matrix mMatrix = new Matrix();
+    private final Camera mCamera = new Camera();
+    private final float mTempFloat2[] = new float[2];
+
     /**
      * Used to inflate the Workspace from XML.
      *
@@ -414,7 +426,10 @@
     public boolean onTouch(View v, MotionEvent event) {
         // this is an intercepted event being forwarded from a cell layout
         if (mIsSmall || mIsInUnshrinkAnimation) {
-            mLauncher.onWorkspaceClick((CellLayout) v);
+            // Only allow clicks on a CellLayout if it is visible
+            if (mShrunkenState != ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN) {
+                mLauncher.onWorkspaceClick((CellLayout) v);
+            }
             return true;
         } else if (!mPageMoving) {
             if (v == getChildAt(mCurrentPage - 1)) {
@@ -444,7 +459,12 @@
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         if (mIsSmall || mIsInUnshrinkAnimation) {
-            // when the home screens are shrunken, shouldn't allow side-scrolling
+            if (mLauncher.isAllAppsVisible() &&
+                    mShrunkenState == ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN) {
+                // Intercept this event so we can show the workspace in full view
+                // when it is clicked on and it is small
+                return true;
+            }
             return false;
         }
         return super.onInterceptTouchEvent(ev);
@@ -550,6 +570,31 @@
         return mBackgroundAlpha;
     }
 
+    /**
+     * Due to 3D transformations, if two CellLayouts are theoretically touching each other,
+     * on the xy plane, when one is rotated along the y-axis, the gap between them is perceived
+     * as being larger. This method computes what offset the rotated view should be translated
+     * in order to minimize this perceived gap.
+     * @param degrees Angle of the view
+     * @param width Width of the view
+     * @param height Height of the view
+     * @return Offset to be used in a View.setTranslationX() call
+     */
+    private float getOffsetXForRotation(float degrees, int width, int height) {
+        mMatrix.reset();
+        mCamera.save();
+        mCamera.rotateY(Math.abs(degrees));
+        mCamera.getMatrix(mMatrix);
+        mCamera.restore();
+
+        mMatrix.preTranslate(-width * 0.5f, -height * 0.5f);
+        mMatrix.postTranslate(width * 0.5f, height * 0.5f);
+        mTempFloat2[0] = width;
+        mTempFloat2[1] = height;
+        mMatrix.mapPoints(mTempFloat2);
+        return (width - mTempFloat2[0]) * (degrees > 0.0f ? 1.0f : -1.0f);
+    }
+
     @Override
     protected void screenScrolled(int screenCenter) {
         final int halfScreenSize = getMeasuredWidth() / 2;
@@ -567,6 +612,8 @@
                 cl.setBackgroundAlphaMultiplier(Math.abs(scrollProgress));
 
                 float rotation = WORKSPACE_ROTATION * scrollProgress;
+                float translationX = getOffsetXForRotation(rotation, cl.getWidth(), cl.getHeight());
+                cl.setTranslationX(translationX);
                 cl.setRotationY(rotation);
             }
         }
@@ -681,6 +728,7 @@
                 return false;
             }
         }
+
         return super.dispatchTouchEvent(ev);
     }
 
@@ -719,7 +767,14 @@
                 mScroller.abortAnimation();
             }
             setCurrentPage(mCurrentPage);
-            return false; // We don't want the events.  Let them fall through to the all apps view.
+
+            if (mShrunkenState == ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN) {
+                mLauncher.showWorkspace(true);
+                // Let the events fall through to the CellLayouts because if they are not
+                // hit, then we get a crash due to a missing ACTION_DOWN touch event
+            }
+
+            return false; // We don't want the events
         }
 
         return super.onTouchEvent(ev);
@@ -737,14 +792,22 @@
         shrink(ShrinkPosition.SHRINK_TO_MIDDLE, true);
     }
 
-    void shrinkToBottom() {
-        shrinkToBottom(true);
+    void shrinkToBottomHidden() {
+        shrinkToBottomHidden(true);
     }
 
-    void shrinkToBottom(boolean animated) {
+    void shrinkToBottomVisible() {
+        shrinkToBottomVisible(true);
+    }
+
+    void shrinkToBottomHidden(boolean animated) {
         shrink(ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN, animated);
     }
 
+    void shrinkToBottomVisible(boolean animated) {
+        shrink(ShrinkPosition.SHRINK_TO_BOTTOM_VISIBLE, animated);
+    }
+
     private float getYScaleForScreen(int screen) {
         int x = Math.abs(screen - 2);
 
@@ -813,7 +876,7 @@
             // We shrink and disappear to nothing in the case of all apps
             // (which is when we shrink to the bottom)
             newY = screenHeight - newY - scaledPageHeight;
-            finalAlpha = 0.25f;
+            finalAlpha = 0.0f;
         } else if (shrinkPosition == ShrinkPosition.SHRINK_TO_MIDDLE) {
             newY = screenHeight / 2 - scaledPageHeight / 2;
             finalAlpha = 1.0f;
@@ -985,14 +1048,11 @@
      * start a drag in Launcher, regardless of whether the drag has ever entered the Workspace
      *
      * These methods mark the appropriate pages as accepting drops (which alters their visual
-     * appearance) and, if the pages are hidden, makes them visible.
+     * appearance).
      *
      */
     public void onDragStartedWithItemSpans(int spanX, int spanY) {
         updateWhichPagesAcceptDropsDuringDrag(mShrunkenState, spanX, spanY);
-        if (mShrunkenState == ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN) {
-            shrink(ShrinkPosition.SHRINK_TO_BOTTOM_VISIBLE, true);
-        }
     }
 
     public void onDragStartedWithItemMinSize(int minWidth, int minHeight) {
@@ -1004,9 +1064,6 @@
     // never dragged over
     public void onDragStopped() {
         updateWhichPagesAcceptDrops(mShrunkenState);
-        if (mShrunkenState == ShrinkPosition.SHRINK_TO_BOTTOM_VISIBLE) {
-            shrink(ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN, true);
-        }
     }
 
     // We call this when we trigger an unshrink by clicking on the CellLayout cl
@@ -1051,6 +1108,7 @@
             if (mAnimator != null) {
                 mAnimator.cancel();
             }
+
             mAnimator = new AnimatorSet();
             final int screenCount = getChildCount();
 
@@ -1066,10 +1124,11 @@
                     rotation = -WORKSPACE_ROTATION;
                 }
 
-                if (animated) {
+                float translation = getOffsetXForRotation(rotation, cl.getWidth(), cl.getHeight());
 
+                if (animated) {
                     ObjectAnimator animWithInterpolator = ObjectAnimator.ofPropertyValuesHolder(cl,
-                            PropertyValuesHolder.ofFloat("translationX", 0.0f),
+                            PropertyValuesHolder.ofFloat("translationX", translation),
                             PropertyValuesHolder.ofFloat("translationY", 0.0f),
                             PropertyValuesHolder.ofFloat("scaleX", 1.0f),
                             PropertyValuesHolder.ofFloat("scaleY", 1.0f),
@@ -1080,7 +1139,7 @@
                     animWithInterpolator.setInterpolator(mZoomInInterpolator);
                     mAnimator.playTogether(animWithInterpolator);
                 } else {
-                    cl.setTranslationX(0.0f);
+                    cl.setTranslationX(translation);
                     cl.setTranslationY(0.0f);
                     cl.setScaleX(1.0f);
                     cl.setScaleY(1.0f);
@@ -1089,6 +1148,7 @@
                     cl.setRotationY(rotation);
                 }
             }
+
             if (animated) {
                 // If we call this when we're not animated, onAnimationEnd is never called on
                 // the listener; make sure we only use the listener when we're actually animating
@@ -1369,16 +1429,32 @@
             onDropExternal(originX, originY, dragInfo, mDragTargetLayout);
         } else if (mDragInfo != null) {
             final View cell = mDragInfo.cell;
-            if (mDragTargetLayout != null) {
+            CellLayout dropTargetLayout = mDragTargetLayout;
+
+            // Handle the case where the user drops when in the scroll area.
+            // This is treated as a drop on the adjacent page.
+            if (dropTargetLayout == null && mInScrollArea) {
+                if (mPendingScrollDirection == DragController.SCROLL_LEFT) {
+                    dropTargetLayout = (CellLayout) getChildAt(mCurrentPage - 1);
+                } else if (mPendingScrollDirection == DragController.SCROLL_RIGHT) {
+                    dropTargetLayout = (CellLayout) getChildAt(mCurrentPage + 1);
+                }
+            }
+
+            if (dropTargetLayout != null) {
                 // Move internally
                 mTargetCell = findNearestVacantArea(originX, originY,
-                        mDragInfo.spanX, mDragInfo.spanY, cell, mDragTargetLayout,
+                        mDragInfo.spanX, mDragInfo.spanY, cell, dropTargetLayout,
                         mTargetCell);
 
-                if (mTargetCell == null) {
-                    snapToPage(mDragInfo.screen);
-                } else {
-                    int screen = indexOfChild(mDragTargetLayout);
+                final int screen = (mTargetCell == null) ?
+                        mDragInfo.screen : indexOfChild(dropTargetLayout);
+
+                if (screen != mCurrentPage) {
+                    snapToPage(screen);
+                }
+
+                if (mTargetCell != null) {
                     if (screen != mDragInfo.screen) {
                         // Reparent the view
                         ((CellLayout) getChildAt(mDragInfo.screen)).removeView(cell);
@@ -1389,7 +1465,7 @@
                     // update the item's position after drop
                     final ItemInfo info = (ItemInfo) cell.getTag();
                     CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams();
-                    mDragTargetLayout.onMove(cell, mTargetCell[0], mTargetCell[1]);
+                    dropTargetLayout.onMove(cell, mTargetCell[0], mTargetCell[1]);
                     lp.cellX = mTargetCell[0];
                     lp.cellY = mTargetCell[1];
                     cell.setId(LauncherModel.getCellLayoutChildId(-1, mDragInfo.screen,
@@ -1418,7 +1494,6 @@
             mDragTargetLayout = getCurrentDropLayout();
             mDragTargetLayout.onDragEnter();
             showOutlines();
-            mInDragMode = true;
         }
     }
 
@@ -1823,7 +1898,6 @@
         }
         if (!mIsPageMoving) {
             hideOutlines();
-            mInDragMode = false;
         }
         clearAllHovers();
     }
@@ -2027,9 +2101,13 @@
     public void onEnterScrollArea(int direction) {
         if (!mIsSmall && !mIsInUnshrinkAnimation) {
             mInScrollArea = true;
-            final int screen = getCurrentPage() + ((direction == DragController.SCROLL_LEFT) ? -1 : 1);
-            if (0 <= screen && screen < getChildCount()) {
-                ((CellLayout) getChildAt(screen)).setHover(true);
+            mPendingScrollDirection = direction;
+
+            final int page = mCurrentPage + (direction == DragController.SCROLL_LEFT ? -1 : 1);
+            final CellLayout layout = (CellLayout) getChildAt(page);
+
+            if (layout != null) {
+                layout.setHover(true);
 
                 if (mDragTargetLayout != null) {
                     mDragTargetLayout.onDragExit();
@@ -2050,6 +2128,7 @@
     public void onExitScrollArea() {
         if (mInScrollArea) {
             mInScrollArea = false;
+            mPendingScrollDirection = DragController.SCROLL_NONE;
             clearAllHovers();
         }
     }