Folder support in Taskbar
- Add TaskbarActivityContext which allows shared Launcher elements to
"just work" using existing generic ActivityContext.
- TaskbarContainerView extends BaseDragLayer<TaskbarActivityContext>.
- Inflate FolderIcon and Folder using TaskbarActivityContext to be
shown in TaskbarContainerView.
- Use TaskbarActivityContext's DeviceProfile to determine icon size
instead of overriding in styles. This also ensures that normal
BubbleTextView icons have the same size as FolderIcons.
Test: Place a folder in home screen hotseat, ensure it shows up in
taskbar and can be opened, and that apps inside it can be launched
or dragged.
Bug: 171917176
Change-Id: Ic25d2f84bcd7e3399c88989305ea565497c030d9
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 68c3851..a0e87cf 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -130,4 +130,5 @@
<dimen name="taskbar_icon_spacing">14dp</dimen>
<dimen name="taskbar_divider_thickness">1dp</dimen>
<dimen name="taskbar_divider_height">24dp</dimen>
+ <dimen name="taskbar_folder_margin">16dp</dimen>
</resources>
diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml
index 5a353f0..df089f6 100644
--- a/quickstep/res/values/styles.xml
+++ b/quickstep/res/values/styles.xml
@@ -89,6 +89,5 @@
<!-- Icon displayed on the taskbar -->
<style name="BaseIcon.Workspace.Taskbar" >
<item name="iconDisplay">taskbar</item>
- <item name="iconSizeOverride">@dimen/taskbar_icon_size</item>
</style>
</resources>
\ No newline at end of file
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index edcd0a2..d1fa2fd 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -30,7 +30,6 @@
import android.content.IntentSender;
import android.os.Bundle;
import android.os.CancellationSignal;
-import android.view.LayoutInflater;
import android.view.View;
import androidx.annotation.Nullable;
@@ -43,7 +42,7 @@
import com.android.launcher3.statehandlers.BackButtonAlphaHandler;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.StateManager.StateHandler;
-import com.android.launcher3.taskbar.TaskbarContainerView;
+import com.android.launcher3.taskbar.TaskbarActivityContext;
import com.android.launcher3.taskbar.TaskbarController;
import com.android.launcher3.taskbar.TaskbarStateHandler;
import com.android.launcher3.uioverrides.RecentsViewStateController;
@@ -207,6 +206,7 @@
mActionsView.updateVerticalMargin(SysUINavigationMode.getMode(this));
addTaskbarIfNecessary();
+ addOnDeviceProfileChangeListener(newDp -> addTaskbarIfNecessary());
}
@Override
@@ -223,9 +223,9 @@
mTaskbarController = null;
}
if (FeatureFlags.ENABLE_TASKBAR.get() && mDeviceProfile.isTablet) {
- TaskbarContainerView taskbarContainer = (TaskbarContainerView) LayoutInflater.from(this)
- .inflate(R.layout.taskbar, null, false);
- mTaskbarController = new TaskbarController(this, taskbarContainer);
+ TaskbarActivityContext taskbarActivityContext = new TaskbarActivityContext(this);
+ mTaskbarController = new TaskbarController(this,
+ taskbarActivityContext.getTaskbarContainerView());
mTaskbarController.init();
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
new file mode 100644
index 0000000..06372fe
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.taskbar;
+
+import android.content.ContextWrapper;
+import android.graphics.Rect;
+import android.view.LayoutInflater;
+
+import com.android.launcher3.BaseQuickstepLauncher;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.R;
+import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.views.BaseDragLayer;
+
+/**
+ * The {@link ActivityContext} with which we inflate Taskbar-related Views. This allows UI elements
+ * that are used by both Launcher and Taskbar (such as Folder) to reference a generic
+ * ActivityContext and BaseDragLayer instead of the Launcher activity and its DragLayer.
+ */
+public class TaskbarActivityContext extends ContextWrapper implements ActivityContext {
+
+ private final DeviceProfile mDeviceProfile;
+ private final LayoutInflater mLayoutInflater;
+ private final TaskbarContainerView mTaskbarContainerView;
+
+ public TaskbarActivityContext(BaseQuickstepLauncher launcher) {
+ super(launcher);
+ mDeviceProfile = launcher.getDeviceProfile().copy(this);
+ float taskbarIconSize = getResources().getDimension(R.dimen.taskbar_icon_size);
+ float iconScale = taskbarIconSize / mDeviceProfile.iconSizePx;
+ mDeviceProfile.updateIconSize(iconScale, getResources());
+
+ mLayoutInflater = LayoutInflater.from(this).cloneInContext(this);
+
+ mTaskbarContainerView = (TaskbarContainerView) mLayoutInflater
+ .inflate(R.layout.taskbar, null, false);
+ }
+
+ public TaskbarContainerView getTaskbarContainerView() {
+ return mTaskbarContainerView;
+ }
+
+ /**
+ * @return A LayoutInflater to use in this Context. Views inflated with this LayoutInflater will
+ * be able to access this TaskbarActivityContext via ActivityContext.lookupContext().
+ */
+ public LayoutInflater getLayoutInflater() {
+ return mLayoutInflater;
+ }
+
+ @Override
+ public BaseDragLayer<TaskbarActivityContext> getDragLayer() {
+ return mTaskbarContainerView;
+ }
+
+ @Override
+ public DeviceProfile getDeviceProfile() {
+ return mDeviceProfile;
+ }
+
+ @Override
+ public Rect getFolderBoundingBox() {
+ return mTaskbarContainerView.getFolderBoundingBox();
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarContainerView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarContainerView.java
index 3b361c4..ddd0d15 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarContainerView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarContainerView.java
@@ -19,19 +19,29 @@
import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_REGION;
import android.content.Context;
+import android.graphics.Rect;
import android.util.AttributeSet;
-import android.widget.FrameLayout;
+import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.launcher3.R;
import com.android.launcher3.anim.AlphaUpdateListener;
+import com.android.launcher3.util.TouchController;
+import com.android.launcher3.views.BaseDragLayer;
import com.android.systemui.shared.system.ViewTreeObserverWrapper;
/**
* Top-level ViewGroup that hosts the TaskbarView as well as Views created by it such as Folder.
*/
-public class TaskbarContainerView extends FrameLayout {
+public class TaskbarContainerView extends BaseDragLayer<TaskbarActivityContext> {
+
+ private final int[] mTempLoc = new int[2];
+ private final int mFolderMargin;
+
+ // Initialized in TaskbarController constructor.
+ private TaskbarController.TaskbarContainerViewCallbacks mControllerCallbacks;
// Initialized in init.
private TaskbarView mTaskbarView;
@@ -52,12 +62,23 @@
public TaskbarContainerView(@NonNull Context context, @Nullable AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
+ super(context, attrs, 1 /* alphaChannelCount */);
+ mFolderMargin = getResources().getDimensionPixelSize(R.dimen.taskbar_folder_margin);
+ }
+
+ protected void construct(TaskbarController.TaskbarContainerViewCallbacks callbacks) {
+ mControllerCallbacks = callbacks;
}
protected void init(TaskbarView taskbarView) {
mTaskbarView = taskbarView;
mTaskbarInsetsComputer = createTaskbarInsetsComputer();
+ recreateControllers();
+ }
+
+ @Override
+ public void recreateControllers() {
+ mControllers = new TouchController[0];
}
private ViewTreeObserverWrapper.OnComputeInsetsListener createTaskbarInsetsComputer() {
@@ -70,6 +91,17 @@
// We're visible again, accept touches anywhere in our bounds.
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_FRAME);
}
+
+ // TaskbarContainerView provides insets to other apps based on contentInsets. These
+ // insets should stay consistent even if we expand TaskbarContainerView's bounds, e.g.
+ // to show a floating view like Folder. Thus, we set the contentInsets to be where
+ // mTaskbarView is, since its position never changes and insets rather than overlays.
+ int[] loc = mTempLoc;
+ mTaskbarView.getLocationInWindow(loc);
+ insetsInfo.contentInsets.left = loc[0];
+ insetsInfo.contentInsets.top = loc[1];
+ insetsInfo.contentInsets.right = getWidth() - (loc[0] + mTaskbarView.getWidth());
+ insetsInfo.contentInsets.bottom = getHeight() - (loc[1] + mTaskbarView.getHeight());
};
}
@@ -91,4 +123,30 @@
cleanup();
}
+
+ @Override
+ protected boolean canFindActiveController() {
+ // Unlike super class, we want to be able to find controllers when touches occur in the
+ // gesture area. For example, this allows Folder to close itself when touching the Taskbar.
+ return true;
+ }
+
+ @Override
+ public void onViewRemoved(View child) {
+ super.onViewRemoved(child);
+ mControllerCallbacks.onViewRemoved();
+ }
+
+ /**
+ * @return Bounds (in our coordinates) where an opened Folder can display.
+ */
+ protected Rect getFolderBoundingBox() {
+ Rect boundingBox = new Rect(0, 0, getWidth(), getHeight() - mTaskbarView.getHeight());
+ boundingBox.inset(mFolderMargin, mFolderMargin);
+ return boundingBox;
+ }
+
+ protected TaskbarActivityContext getTaskbarActivityContext() {
+ return mActivity;
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java
index 260428d..ab05fbf 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java
@@ -34,11 +34,15 @@
import androidx.annotation.Nullable;
+import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.QuickstepAppTransitionManagerImpl;
import com.android.launcher3.R;
import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.folder.Folder;
+import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.touch.ItemClickHandler;
@@ -81,8 +85,9 @@
TaskbarContainerView taskbarContainerView) {
mLauncher = launcher;
mTaskbarContainerView = taskbarContainerView;
+ mTaskbarContainerView.construct(createTaskbarContainerViewCallbacks());
mTaskbarView = mTaskbarContainerView.findViewById(R.id.taskbar_view);
- mTaskbarView.setCallbacks(createTaskbarViewCallbacks());
+ mTaskbarView.construct(createTaskbarViewCallbacks());
mWindowManager = mLauncher.getWindowManager();
mTaskbarSize = new Point(MATCH_PARENT,
mLauncher.getResources().getDimensionPixelSize(R.dimen.taskbar_size));
@@ -110,6 +115,18 @@
};
}
+ private TaskbarContainerViewCallbacks createTaskbarContainerViewCallbacks() {
+ return new TaskbarContainerViewCallbacks() {
+ @Override
+ public void onViewRemoved() {
+ if (mTaskbarContainerView.getChildCount() == 1) {
+ // Only TaskbarView remains.
+ setTaskbarWindowFullscreen(false);
+ }
+ }
+ };
+ }
+
private TaskbarViewCallbacks createTaskbarViewCallbacks() {
return new TaskbarViewCallbacks() {
@Override
@@ -120,9 +137,29 @@
Task task = (Task) tag;
ActivityManagerWrapper.getInstance().startActivityFromRecents(task.key,
ActivityOptions.makeBasic());
+ } else if (tag instanceof FolderInfo) {
+ FolderIcon folderIcon = (FolderIcon) view;
+ Folder folder = folderIcon.getFolder();
+
+ setTaskbarWindowFullscreen(true);
+
+ mTaskbarContainerView.post(() -> {
+ folder.animateOpen();
+
+ folder.iterateOverItems((itemInfo, itemView) -> {
+ itemView.setOnClickListener(getItemOnClickListener());
+ itemView.setOnLongClickListener(getItemOnLongClickListener());
+ // To play haptic when dragging, like other Taskbar items do.
+ itemView.setHapticFeedbackEnabled(true);
+ return false;
+ });
+ });
} else {
ItemClickHandler.INSTANCE.onClick(view);
}
+
+ AbstractFloatingView.closeAllOpenViews(
+ mTaskbarContainerView.getTaskbarActivityContext());
};
}
@@ -345,6 +382,20 @@
}
/**
+ * Updates the TaskbarContainer to MATCH_PARENT vs original Taskbar size.
+ */
+ private void setTaskbarWindowFullscreen(boolean fullscreen) {
+ if (fullscreen) {
+ mWindowLayoutParams.width = MATCH_PARENT;
+ mWindowLayoutParams.height = MATCH_PARENT;
+ } else {
+ mWindowLayoutParams.width = mTaskbarSize.x;
+ mWindowLayoutParams.height = mTaskbarSize.y;
+ }
+ mWindowManager.updateViewLayout(mTaskbarContainerView, mWindowLayoutParams);
+ }
+
+ /**
* Contains methods that TaskbarStateHandler can call to interface with TaskbarController.
*/
protected interface TaskbarStateHandlerCallbacks {
@@ -361,6 +412,13 @@
}
/**
+ * Contains methods that TaskbarContainerView can call to interface with TaskbarController.
+ */
+ protected interface TaskbarContainerViewCallbacks {
+ void onViewRemoved();
+ }
+
+ /**
* Contains methods that TaskbarView can call to interface with TaskbarController.
*/
protected interface TaskbarViewCallbacks {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index d8f3bb5..df77f87 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -22,7 +22,6 @@
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.DragEvent;
-import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
@@ -32,10 +31,14 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.R;
+import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.views.ActivityContext;
import com.android.systemui.shared.recents.model.Task;
/**
@@ -51,6 +54,9 @@
private final RectF mDelegateSlopBounds = new RectF();
private final int[] mTempOutLocation = new int[2];
+ // Initialized in TaskbarController constructor.
+ private TaskbarController.TaskbarViewCallbacks mControllerCallbacks;
+
// Initialized in init().
private int mHotseatStartIndex;
private int mHotseatEndIndex;
@@ -58,8 +64,6 @@
private int mRecentsStartIndex;
private int mRecentsEndIndex;
- private TaskbarController.TaskbarViewCallbacks mControllerCallbacks;
-
// Delegate touches to the closest view if within mIconTouchSize.
private boolean mDelegateTargeted;
private View mDelegateView;
@@ -90,7 +94,7 @@
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
- protected void setCallbacks(TaskbarController.TaskbarViewCallbacks taskbarViewCallbacks) {
+ protected void construct(TaskbarController.TaskbarViewCallbacks taskbarViewCallbacks) {
mControllerCallbacks = taskbarViewCallbacks;
}
@@ -130,17 +134,37 @@
// Replace any Hotseat views with the appropriate type if it's not already that type.
final int expectedLayoutResId;
+ boolean isFolder = false;
+ boolean needsReinflate = false;
if (hotseatItemInfo != null && hotseatItemInfo.isPredictedItem()) {
expectedLayoutResId = R.layout.taskbar_predicted_app_icon;
+ } else if (hotseatItemInfo instanceof FolderInfo) {
+ expectedLayoutResId = R.layout.folder_icon;
+ isFolder = true;
+ // Unlike for BubbleTextView, we can't reapply a new FolderInfo after inflation, so
+ // if the info changes we need to reinflate. This should only happen if a new folder
+ // is dragged to the position that another folder previously existed.
+ needsReinflate = hotseatView != null && hotseatView.getTag() != hotseatItemInfo;
} else {
expectedLayoutResId = R.layout.taskbar_app_icon;
}
- if (hotseatView == null || hotseatView.getSourceLayoutResId() != expectedLayoutResId) {
+ if (hotseatView == null || hotseatView.getSourceLayoutResId() != expectedLayoutResId
+ || needsReinflate) {
removeView(hotseatView);
- BubbleTextView btv = (BubbleTextView) inflate(expectedLayoutResId);
- LayoutParams lp = new LayoutParams(btv.getIconSize(), btv.getIconSize());
+ TaskbarActivityContext activityContext =
+ ActivityContext.lookupContext(getContext());
+ if (isFolder) {
+ FolderInfo folderInfo = (FolderInfo) hotseatItemInfo;
+ FolderIcon folderIcon = FolderIcon.inflateFolderAndIcon(expectedLayoutResId,
+ activityContext, this, folderInfo);
+ folderIcon.setTextVisible(false);
+ hotseatView = folderIcon;
+ } else {
+ hotseatView = inflate(expectedLayoutResId);
+ }
+ int iconSize = activityContext.getDeviceProfile().iconSizePx;
+ LayoutParams lp = new LayoutParams(iconSize, iconSize);
lp.setMargins(mItemMarginLeftRight, 0, mItemMarginLeftRight, 0);
- hotseatView = btv;
addView(hotseatView, hotseatIndex, lp);
}
@@ -153,6 +177,11 @@
hotseatView.setOnClickListener(mControllerCallbacks.getItemOnClickListener());
hotseatView.setOnLongClickListener(
mControllerCallbacks.getItemOnLongClickListener());
+ } else if (isFolder) {
+ hotseatView.setVisibility(VISIBLE);
+ hotseatView.setOnClickListener(mControllerCallbacks.getItemOnClickListener());
+ hotseatView.setOnLongClickListener(
+ mControllerCallbacks.getItemOnLongClickListener());
} else {
hotseatView.setVisibility(GONE);
hotseatView.setOnClickListener(null);
@@ -345,6 +374,7 @@
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
mIsDraggingItem = true;
+ AbstractFloatingView.closeAllOpenViews(ActivityContext.lookupContext(getContext()));
return true;
case DragEvent.ACTION_DRAG_ENDED:
mIsDraggingItem = false;
@@ -358,6 +388,7 @@
}
private View inflate(@LayoutRes int layoutResId) {
- return LayoutInflater.from(getContext()).inflate(layoutResId, this, false);
+ TaskbarActivityContext taskbarActivityContext = ActivityContext.lookupContext(getContext());
+ return taskbarActivityContext.getLayoutInflater().inflate(layoutResId, this, false);
}
}
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index edc7e9b..e5a4335 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -505,7 +505,7 @@
* @param canvas The canvas to draw to.
*/
protected void drawDotIfNecessary(Canvas canvas) {
- if (mDisplay == DISPLAY_TASKBAR) {
+ if (mActivity instanceof Launcher && ((Launcher) mActivity).isViewInTaskbar(this)) {
// TODO: support notification dots in Taskbar
return;
}
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 19915b7..83a7d77 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -375,7 +375,7 @@
* iconTextSizePx, iconDrawablePaddingPx, cellWidth/Height, allApps* variants,
* hotseat sizes, workspaceSpringLoadedShrinkFactor, folderIconSizePx, and folderIconOffsetYPx.
*/
- private void updateIconSize(float scale, Resources res) {
+ public void updateIconSize(float scale, Resources res) {
// Workspace
final boolean isVerticalLayout = isVerticalBarLayout();
float invIconSizeDp = isVerticalLayout ? inv.landscapeIconSize : inv.iconSize;
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 9efbc7d..504b29e 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -1616,6 +1616,11 @@
return false;
}
+ @Override
+ public boolean canInterceptEventsInSystemGestureRegion() {
+ return true;
+ }
+
/**
* Alternative to using {@link #getClipToOutline()} as it only works with derivatives of
* rounded rect.
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 65a4fba..75d8f22 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -754,6 +754,9 @@
}
public void clearLeaveBehindIfExists() {
+ if (!(getLayoutParams() instanceof CellLayout.LayoutParams)) {
+ return;
+ }
((CellLayout.LayoutParams) getLayoutParams()).canReorder = true;
if (isInHotseat()) {
CellLayout cl = (CellLayout) getParent().getParent();
@@ -762,6 +765,9 @@
}
public void drawLeaveBehindIfExists() {
+ if (!(getLayoutParams() instanceof CellLayout.LayoutParams)) {
+ return;
+ }
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
// While the folder is open, the position of the icon cannot change.
lp.canReorder = false;
diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java
index 15f7730..1939d15 100644
--- a/src/com/android/launcher3/views/BaseDragLayer.java
+++ b/src/com/android/launcher3/views/BaseDragLayer.java
@@ -206,15 +206,19 @@
protected boolean findActiveController(MotionEvent ev) {
mActiveController = null;
- if ((mTouchDispatchState & (TOUCH_DISPATCHING_FROM_VIEW_GESTURE_REGION
- | TOUCH_DISPATCHING_FROM_PROXY)) == 0) {
- // Only look for controllers if we are not dispatching from gesture area and proxy is
- // not active
+ if (canFindActiveController()) {
mActiveController = findControllerToHandleTouch(ev);
}
return mActiveController != null;
}
+ protected boolean canFindActiveController() {
+ // Only look for controllers if we are not dispatching from gesture area and proxy is
+ // not active
+ return (mTouchDispatchState & (TOUCH_DISPATCHING_FROM_VIEW_GESTURE_REGION
+ | TOUCH_DISPATCHING_FROM_PROXY)) == 0;
+ }
+
@Override
public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
// Shortcuts can appear above folder