From 9184ec686072e9343c9dd73cf45324e5e89e042f Mon Sep 17 00:00:00 2001 From: Chong Zhang Date: Thu, 24 Sep 2015 12:32:21 -0700 Subject: [PATCH] Use visible frame instead of task bounds for detecting resize start Initial task bounds might be adjusted (for status bar, etc.). Touch should be set up using visible frames instead of task bounds. bug: 24336351 Change-Id: I944e3185a06c39b451432bdda5ad87880a0482f3 --- .../java/com/android/server/wm/DisplayContent.java | 38 ++++++++++++++-------- services/core/java/com/android/server/wm/Task.java | 5 +++ .../android/server/wm/WindowManagerService.java | 22 ++++--------- .../java/com/android/server/wm/WindowState.java | 13 +++----- 4 files changed, 40 insertions(+), 38 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 4392ab43579c..ede377de0b14 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -22,6 +22,7 @@ import static android.app.ActivityManager.HOME_STACK_ID; import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY; import static com.android.server.wm.WindowManagerService.TAG; import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP; +import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH; import android.graphics.Rect; import android.graphics.Region; @@ -255,10 +256,10 @@ class DisplayContent { } /** - * Find the id of the task whose outside touch area (for resizing) (x, y) - * falls within. Returns -1 if the touch doesn't fall into a resizing area. + * Find the window whose outside touch area (for resizing) (x, y) falls within. + * Returns null if the touch doesn't fall into a resizing area. */ - int taskIdForControlPoint(int x, int y) { + WindowState findWindowForControlPoint(int x, int y) { final int delta = mService.dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics); for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { TaskStack stack = mStacks.get(stackNdx); @@ -269,22 +270,31 @@ class DisplayContent { for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { final Task task = tasks.get(taskNdx); if (task.isFullscreen()) { - return -1; + return null; } - task.getBounds(mTmpRect); - mTmpRect.inset(-delta, -delta); - if (mTmpRect.contains(x, y)) { - mTmpRect.inset(delta, delta); - if (!mTmpRect.contains(x, y)) { - return task.mTaskId; + + // We need to use the visible frame on the window for any touch-related + // tests. Can't use the task's bounds because the original task bounds + // might be adjusted to fit the content frame. (One example is when the + // task is put to top-left quadrant, the actual visible frame would not + // start at (0,0) after it's adjusted for the status bar.) + WindowState win = task.getTopAppMainWindow(); + if (win != null) { + win.getVisibleBounds(mTmpRect, !BOUNDS_FOR_TOUCH); + mTmpRect.inset(-delta, -delta); + if (mTmpRect.contains(x, y)) { + mTmpRect.inset(delta, delta); + if (!mTmpRect.contains(x, y)) { + return win; + } + // User touched inside the task. No need to look further, + // focus transfer will be handled in ACTION_UP. + return null; } - // User touched inside the task. No need to look further, - // focus transfer will be handled in ACTION_UP. - return -1; } } } - return -1; + return null; } void setTouchExcludeRegion(Task focusedTask) { diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 6ebff4212b16..d1111f70346a 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -437,6 +437,11 @@ class Task implements DimLayer.DimLayerUser { return mStack != null && mStack.mStackId == DOCKED_STACK_ID; } + WindowState getTopAppMainWindow() { + final int tokensCount = mAppTokens.size(); + return tokensCount > 0 ? mAppTokens.get(tokensCount - 1).findMainWindow() : null; + } + @Override public boolean isFullscreen() { return mFullscreen; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index d510c4a4f7f0..22f9f50fe6dd 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -6885,37 +6885,29 @@ public class WindowManagerService extends IWindowManager.Stub } boolean startMovingTask(IWindow window, float startX, float startY) { - WindowState callingWin = null; + WindowState win = null; synchronized (mWindowMap) { - callingWin = windowForClientLocked(null, window, false); - if (!startPositioningLocked(callingWin, false /*resize*/, startX, startY)) { + win = windowForClientLocked(null, window, false); + if (!startPositioningLocked(win, false /*resize*/, startX, startY)) { return false; } } try { - mActivityManager.setFocusedTask(callingWin.getTask().mTaskId); + mActivityManager.setFocusedTask(win.getTask().mTaskId); } catch(RemoteException e) {} return true; } private void startResizingTask(DisplayContent displayContent, int startX, int startY) { - int taskId = -1; - AppWindowToken atoken = null; + WindowState win = null; synchronized (mWindowMap) { - taskId = displayContent.taskIdForControlPoint(startX, startY); - Task task = mTaskIdToTask.get(taskId); - if (task == null || task.mAppTokens == null) { - return; - } - AppTokenList tokens = task.mAppTokens; - atoken = tokens.get(tokens.size() - 1); - WindowState win = atoken.findMainWindow(); + win = displayContent.findWindowForControlPoint(startX, startY); if (!startPositioningLocked(win, true /*resize*/, startX, startY)) { return; } } try { - mActivityManager.setFocusedTask(taskId); + mActivityManager.setFocusedTask(win.getTask().mTaskId); } catch(RemoteException e) {} } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 64440d389910..c73dbaf607eb 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -943,7 +943,6 @@ final class WindowState implements WindowManagerPolicy.WindowState { */ void getVisibleBounds(Rect bounds, boolean forTouch) { boolean intersectWithStackBounds = mAppToken != null && mAppToken.mCropWindowsToStack; - boolean isFreeform = false; bounds.setEmpty(); mTmpRect.setEmpty(); if (intersectWithStackBounds) { @@ -955,13 +954,9 @@ final class WindowState implements WindowManagerPolicy.WindowState { } } - final Task task = getTask(); - if (task != null) { - task.getBounds(bounds); - isFreeform = task.inFreeformWorkspace(); - if (intersectWithStackBounds) { - bounds.intersect(mTmpRect); - } + bounds.set(mVisibleFrame); + if (intersectWithStackBounds) { + bounds.intersect(mTmpRect); } if (bounds.isEmpty()) { @@ -971,7 +966,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { } return; } - if (forTouch && isFreeform) { + if (forTouch && inFreeformWorkspace()) { final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics(); final int delta = mService.dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, displayMetrics); bounds.inset(-delta, -delta); -- 2.11.0