When undoing a removal, always return to the page it came from
We were already returning to the current page, but this wasn't
always right, e.g. when removing the last item on the last page.
So now we mark the page the item was removed from, and bind that
page first when undo is clicked.
This also addresses an issue where we incorrectly returned to the
first page if currentPage = INVALID_RESTORE_PAGE, which happens if
there are no items on the first page.
Bug: 118846684
Change-Id: I4ec1f64b24ba1cc308ce08bfb3111b5981fae99b
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index c80f96b..d60dc87 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -113,10 +113,11 @@
public void completeDrop(DragObject d) {
ItemInfo item = d.dragInfo;
if (canRemove(item)) {
+ int itemPage = mLauncher.getWorkspace().getCurrentPage();
onAccessibilityDrop(null, item);
ModelWriter modelWriter = mLauncher.getModelWriter();
Snackbar.show(mLauncher, R.string.item_removed, R.string.undo,
- modelWriter::commitDelete, modelWriter::abortDelete);
+ modelWriter::commitDelete, () -> modelWriter.abortDelete(itemPage));
}
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 9125a98..f09b6e8 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -2112,7 +2112,7 @@
*
* Implementation of the method from LauncherModel.Callbacks.
*/
- public void finishBindingItems(int currentScreen) {
+ public void finishBindingItems(int pageBoundFirst) {
TraceHelper.beginSection("finishBindingItems");
mWorkspace.restoreInstanceStateForRemainingPages();
@@ -2127,7 +2127,8 @@
InstallShortcutReceiver.disableAndFlushInstallQueue(
InstallShortcutReceiver.FLAG_LOADER_RUNNING, this);
- mWorkspace.setCurrentPage(currentScreen);
+ // When undoing the removal of the last item on a page, return to that page.
+ mWorkspace.setCurrentPage(pageBoundFirst);
TraceHelper.endSection("finishBindingItems");
}
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 9b4c5fd..ebca2ea 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -142,7 +142,7 @@
public void bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons);
public void bindScreens(IntArray orderedScreenIds);
public void finishFirstPageBind(ViewOnDrawExecutor executor);
- public void finishBindingItems(int currentScreen);
+ public void finishBindingItems(int pageBoundFirst);
public void bindAllApplications(ArrayList<AppInfo> apps);
public void bindAppsAddedOrUpdated(ArrayList<AppInfo> apps);
public void preAddApps();
@@ -372,11 +372,16 @@
}
}
+ public void forceReload() {
+ forceReload(-1);
+ }
+
/**
* Reloads the workspace items from the DB and re-binds the workspace. This should generally
* not be called as DB updates are automatically followed by UI update
+ * @param synchronousBindPage The page to bind first. Can pass -1 to use the current page.
*/
- public void forceReload() {
+ public void forceReload(int synchronousBindPage) {
synchronized (mLock) {
// Stop any existing loaders first, so they don't set mModelLoaded to true later
stopLoader();
@@ -387,7 +392,10 @@
// the next time launcher starts
Callbacks callbacks = getCallback();
if (callbacks != null) {
- startLoader(callbacks.getCurrentWorkspaceScreen());
+ if (synchronousBindPage < 0) {
+ synchronousBindPage = callbacks.getCurrentWorkspaceScreen();
+ }
+ startLoader(synchronousBindPage);
}
}
diff --git a/src/com/android/launcher3/model/BaseLoaderResults.java b/src/com/android/launcher3/model/BaseLoaderResults.java
index d3dc91f..d9d0a4f 100644
--- a/src/com/android/launcher3/model/BaseLoaderResults.java
+++ b/src/com/android/launcher3/model/BaseLoaderResults.java
@@ -177,7 +177,7 @@
public void run() {
Callbacks callbacks = mCallbacks.get();
if (callbacks != null) {
- callbacks.finishBindingItems(currentScreen);
+ callbacks.finishBindingItems(mPageToBindFirst);
}
}
};
diff --git a/src/com/android/launcher3/model/ModelWriter.java b/src/com/android/launcher3/model/ModelWriter.java
index ca5428d..d8d9930 100644
--- a/src/com/android/launcher3/model/ModelWriter.java
+++ b/src/com/android/launcher3/model/ModelWriter.java
@@ -349,12 +349,12 @@
mDeleteRunnables.clear();
}
- public void abortDelete() {
+ public void abortDelete(int pageToBindFirst) {
mPreparingToUndo = false;
mDeleteRunnables.clear();
// We do a full reload here instead of just a rebind because Folders change their internal
// state when dragging an item out, which clobbers the rebind unless we load from the DB.
- mModel.forceReload();
+ mModel.forceReload(pageToBindFirst);
}
private class UpdateItemRunnable extends UpdateItemBaseRunnable {