Adding a touchable area around a task
To allow task/window resizing through decors drawn
outside the task bounds (e.g. shadows) on the free form
desktop.
Bug: 23324672
Change-Id: Iaf88ec658e235aa74317a0f33d25fee83f959ac3
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 222945c..e87dcde 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH;
import com.android.server.input.InputApplicationHandle;
import com.android.server.input.InputWindowHandle;
import com.android.server.wm.WindowManagerService.DragInputEventReceiver;
@@ -413,7 +414,7 @@
continue;
}
- child.getTaskBounds(mTmpRect);
+ child.getTaskBounds(mTmpRect, !BOUNDS_FOR_TOUCH);
if (!mTmpRect.contains(x, y)) {
// outside of this window's activity stack == don't tell about drags
continue;
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 65f26c1..b3244ff 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH;
import android.app.ActivityManagerNative;
import android.graphics.Rect;
import android.os.RemoteException;
@@ -177,7 +178,7 @@
if (modal && child.mAppToken != null) {
// Limit the outer touch to the activity stack region.
flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
- child.getTaskBounds(mTmpRect);
+ child.getTaskBounds(mTmpRect, BOUNDS_FOR_TOUCH);
inputWindowHandle.touchableRegion.set(mTmpRect);
} else {
// Not modal or full screen modal
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 7e7d009..aef7921 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -114,6 +114,7 @@
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
+import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH;
import com.android.internal.app.IAssistScreenshotReceiver;
import com.android.internal.app.IBatteryStats;
import com.android.internal.util.FastPrintWriter;
@@ -5633,7 +5634,7 @@
int right = wf.right - cr.right;
int bottom = wf.bottom - cr.bottom;
frame.union(left, top, right, bottom);
- ws.getTaskBounds(stackBounds);
+ ws.getTaskBounds(stackBounds, !BOUNDS_FOR_TOUCH);
if (!frame.intersect(stackBounds)) {
// Set frame empty if there's no intersection.
frame.setEmpty();
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index b56b1f9..092a6d1 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -80,8 +80,14 @@
static final String TAG = "WindowState";
// The minimal size of a window within the usable area of the freeform stack.
- static final int MINIMUM_VISIBLE_WIDTH_IN_DP = 48;
- static final int MINIMUM_VISIBLE_HEIGHT_IN_DP = 32;
+ private static final int MINIMUM_VISIBLE_WIDTH_IN_DP = 48;
+ private static final int MINIMUM_VISIBLE_HEIGHT_IN_DP = 32;
+
+ // The thickness of a window resize handle outside the window bounds on the free form workspace
+ // to capture touch events in that area.
+ private static final int RESIZE_HANDLE_WIDTH_IN_DP = 10;
+
+ static final boolean BOUNDS_FOR_TOUCH = true;
final WindowManagerService mService;
final WindowManagerPolicy mPolicy;
@@ -541,9 +547,8 @@
mHaveFrame = true;
final Task task = mAppToken != null ? getTask() : null;
- final boolean isFreeFormWorkspace = task != null && task.mStack != null &&
- task.mStack.mStackId == FREEFORM_WORKSPACE_STACK_ID;
final boolean nonFullscreenTask = task != null && !task.isFullscreen();
+ final boolean freeformWorkspace = inFreeformWorkspace();
if (nonFullscreenTask) {
task.getBounds(mContainingFrame);
final WindowState imeWin = mService.mInputMethodWindow;
@@ -553,7 +558,7 @@
mContainingFrame.top -= mContainingFrame.bottom - cf.bottom;
}
- if (isFreeFormWorkspace) {
+ if (freeformWorkspace) {
// In free form mode we have only to set the rectangle if it wasn't set already. No
// need to intersect it with the (visible) "content frame" since it is allowed to
// be outside the visible desktop.
@@ -669,7 +674,7 @@
// Make sure the content and visible frames are inside of the
// final window frame.
- if (isFreeFormWorkspace && !mFrame.isEmpty()) {
+ if (freeformWorkspace && !mFrame.isEmpty()) {
// Keep the frame out of the blocked system area, limit it in size to the content area
// and make sure that there is always a minimum visible so that the user can drag it
// into a usable area..
@@ -910,10 +915,22 @@
return mDisplayContent.getHomeStack();
}
- void getTaskBounds(Rect bounds) {
+ /**
+ * Retrieves the bounds for a task.
+ * @param bounds The rect which gets the bounds.
+ * @param forTouch Pass in BOUNDS_FOR_TOUCH to get touch related bounds, otherwise visible
+ * bounds will be returned.
+ */
+ void getTaskBounds(Rect bounds, boolean forTouch) {
final Task task = getTask();
if (task != null) {
task.getBounds(bounds);
+ if (forTouch == BOUNDS_FOR_TOUCH) {
+ if (inFreeformWorkspace()) {
+ final int delta = calculatePixelFromDp(RESIZE_HANDLE_WIDTH_IN_DP);
+ bounds.inset(-delta, -delta);
+ }
+ }
return;
}
bounds.set(mFrame);
@@ -1612,6 +1629,12 @@
}
}
+ private boolean inFreeformWorkspace() {
+ final Task task = getTask();
+ return task != null && task.mStack != null &&
+ task.mStack.mStackId == FREEFORM_WORKSPACE_STACK_ID;
+ }
+
private int calculatePixelFromDp(int dp) {
final Configuration serviceConfig = mService.mCurConfiguration;
// TODO(multidisplay): Update Dp to that of display stack is on.