From f80e893163bc0c786b06282a12ed41b75e34f8d4 Mon Sep 17 00:00:00 2001 From: Tony Date: Fri, 21 Dec 2018 11:58:04 -0800 Subject: [PATCH] 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 --- src/com/android/launcher3/DeleteDropTarget.java | 3 ++- src/com/android/launcher3/Launcher.java | 5 +++-- src/com/android/launcher3/LauncherModel.java | 14 +++++++++++--- .../android/launcher3/model/BaseLoaderResults.java | 2 +- src/com/android/launcher3/model/ModelWriter.java | 4 ++-- 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java index c80f96bb80..d60dc87e4a 100644 --- a/src/com/android/launcher3/DeleteDropTarget.java +++ b/src/com/android/launcher3/DeleteDropTarget.java @@ -113,10 +113,11 @@ public class DeleteDropTarget extends ButtonDropTarget { 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 9125a98433..f09b6e852d 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -2112,7 +2112,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, * * 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 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, 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 9b4c5fd095..ebca2eaf45 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -142,7 +142,7 @@ public class LauncherModel extends BroadcastReceiver public void bindItems(List 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 apps); public void bindAppsAddedOrUpdated(ArrayList apps); public void preAddApps(); @@ -372,11 +372,16 @@ public class LauncherModel extends BroadcastReceiver } } + 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 @@ public class LauncherModel extends BroadcastReceiver // 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 d3dc91f3be..d9d0a4fd03 100644 --- a/src/com/android/launcher3/model/BaseLoaderResults.java +++ b/src/com/android/launcher3/model/BaseLoaderResults.java @@ -177,7 +177,7 @@ public abstract class BaseLoaderResults { 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 ca5428d94d..d8d99308e2 100644 --- a/src/com/android/launcher3/model/ModelWriter.java +++ b/src/com/android/launcher3/model/ModelWriter.java @@ -349,12 +349,12 @@ public class ModelWriter { 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 {