From da4c2d609bfd9cca1614750e5f9ad06641a85323 Mon Sep 17 00:00:00 2001 From: arthurhung Date: Tue, 21 Apr 2020 14:38:54 +0800 Subject: [PATCH] Fix freeform window can't resize The WindowState touch region would be cropped by task bounds, but in free form window mode, we could has some extra space outside the window content in order to resize window, we should include the resize border in the touch region. - Touch region should include the resize border and prevent it to be cropped by task bounds if window is freeform. - Apply show or hide transaction for InputSurface immediately. Bug: 152248369 Test: Enable freeform and resize. Change-Id: I738da8f8c5cc08483c71edfc29eb7110c6111154 --- .../com/android/server/wm/InputMonitor.java | 14 --------- .../com/android/server/wm/TaskPositioner.java | 6 ++-- .../server/wm/TaskPositioningController.java | 19 +++++++----- .../com/android/server/wm/WindowState.java | 29 +++++++++++++------ 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index 656dca531a226..1b1898b76506f 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -27,7 +27,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.graphics.Rect; @@ -38,7 +37,6 @@ import android.os.Process; import android.os.Trace; import android.os.UserHandle; import android.util.ArrayMap; -import android.util.Log; import android.util.Slog; import android.view.InputApplicationHandle; import android.view.InputChannel; @@ -138,18 +136,6 @@ final class InputMonitor { // If there's a drag in flight, provide a pseudo-window to catch drag input final boolean inDrag = mService.mDragDropController.dragDropActiveLocked(); - final boolean inPositioning = - mService.mTaskPositioningController.isPositioningLocked(); - if (inPositioning) { - if (DEBUG_TASK_POSITIONING) { - Log.d(TAG_WM, "Inserting window handle for repositioning"); - } - mService.mTaskPositioningController.showInputSurface(mInputTransaction, - mDisplayId); - } else { - mService.mTaskPositioningController.hideInputSurface(mInputTransaction, - mDisplayId); - } // Add all windows on the default display. mUpdateInputForAllWindowsConsumer.updateInputWindows(inDrag); diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java index be0d6f8a0b9f0..c68b660bb76fd 100644 --- a/services/core/java/com/android/server/wm/TaskPositioner.java +++ b/services/core/java/com/android/server/wm/TaskPositioner.java @@ -53,7 +53,6 @@ import android.view.InputDevice; import android.view.InputEvent; import android.view.InputWindowHandle; import android.view.MotionEvent; -import android.view.SurfaceControl; import android.view.WindowManager; import com.android.internal.annotations.VisibleForTesting; @@ -268,9 +267,7 @@ class TaskPositioner implements IBinder.DeathRecipient { mDisplayContent.getDisplayRotation().pause(); // Notify InputMonitor to take mDragWindowHandle. - final SurfaceControl.Transaction t = mService.mTransactionFactory.get(); - mDisplayContent.getInputMonitor().updateInputWindowsImmediately(t); - t.syncInputWindows().apply(); + mService.mTaskPositioningController.showInputSurface(win.getDisplayId()); final DisplayMetrics displayMetrics = displayContent.getDisplayMetrics(); mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, displayMetrics); @@ -301,6 +298,7 @@ class TaskPositioner implements IBinder.DeathRecipient { return; } + mService.mTaskPositioningController.hideInputSurface(mDisplayContent.getDisplayId()); mService.mInputManager.unregisterInputChannel(mServerChannel); mInputEventReceiver.dispose(); diff --git a/services/core/java/com/android/server/wm/TaskPositioningController.java b/services/core/java/com/android/server/wm/TaskPositioningController.java index 2d303faa79216..d343daf46f139 100644 --- a/services/core/java/com/android/server/wm/TaskPositioningController.java +++ b/services/core/java/com/android/server/wm/TaskPositioningController.java @@ -55,6 +55,8 @@ class TaskPositioningController { return mTaskPositioner != null; } + final SurfaceControl.Transaction mTransaction; + InputWindowHandle getDragWindowHandleLocked() { return mTaskPositioner != null ? mTaskPositioner.mDragWindowHandle : null; } @@ -65,16 +67,18 @@ class TaskPositioningController { mInputManager = inputManager; mActivityManager = activityManager; mHandler = new Handler(looper); + mTransaction = service.mTransactionFactory.get(); } - void hideInputSurface(SurfaceControl.Transaction t, int displayId) { + void hideInputSurface(int displayId) { if (mPositioningDisplay != null && mPositioningDisplay.getDisplayId() == displayId && mInputSurface != null) { - t.hide(mInputSurface); + mTransaction.hide(mInputSurface); + mTransaction.syncInputWindows().apply(); } } - void showInputSurface(SurfaceControl.Transaction t, int displayId) { + void showInputSurface(int displayId) { if (mPositioningDisplay == null || mPositioningDisplay.getDisplayId() != displayId) { return; } @@ -92,16 +96,17 @@ class TaskPositioningController { return; } - t.show(mInputSurface); - t.setInputWindowInfo(mInputSurface, h); - t.setLayer(mInputSurface, Integer.MAX_VALUE); + mTransaction.show(mInputSurface); + mTransaction.setInputWindowInfo(mInputSurface, h); + mTransaction.setLayer(mInputSurface, Integer.MAX_VALUE); final Display display = dc.getDisplay(); final Point p = new Point(); display.getRealSize(p); mTmpClipRect.set(0, 0, p.x, p.y); - t.setWindowCrop(mInputSurface, mTmpClipRect); + mTransaction.setWindowCrop(mInputSurface, mTmpClipRect); + mTransaction.syncInputWindows().apply(); } boolean startMovingTask(IWindow window, float startX, float startY) { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index bbe5d942874dc..2dc95ab8a7d2c 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2489,6 +2489,23 @@ class WindowState extends WindowContainer implements WindowManagerP return flags; } + /** + * Expands the given rectangle by the region of window resize handle for freeform window. + * @param inOutRect The rectangle to update. + */ + private void adjustRegionInFreefromWindowMode(Rect inOutRect) { + if (!inFreeformWindowingMode()) { + return; + } + + // For freeform windows, we need the touch region to include the whole + // surface for the shadows. + final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics(); + final int delta = WindowManagerService.dipToPixel( + RESIZE_HANDLE_WIDTH_IN_DP, displayMetrics); + inOutRect.inset(-delta, -delta); + } + /** * Updates the region for a window in an Activity that was a touch modal. This will limit * the outer touch to the activity stack region. @@ -2512,14 +2529,7 @@ class WindowState extends WindowContainer implements WindowManagerP getRootTask().getDimBounds(mTmpRect); } } - if (inFreeformWindowingMode()) { - // For freeform windows, we need the touch region to include the whole - // surface for the shadows. - final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics(); - final int delta = WindowManagerService.dipToPixel( - RESIZE_HANDLE_WIDTH_IN_DP, displayMetrics); - mTmpRect.inset(-delta, -delta); - } + adjustRegionInFreefromWindowMode(mTmpRect); outRegion.set(mTmpRect); cropRegionToStackBoundsIfNeeded(outRegion); } @@ -3334,7 +3344,7 @@ class WindowState extends WindowContainer implements WindowManagerP } final ActivityStack stack = task.getStack(); - if (stack == null) { + if (stack == null || inFreeformWindowingMode()) { return; } @@ -3353,6 +3363,7 @@ class WindowState extends WindowContainer implements WindowManagerP } stack.getDimBounds(mTmpRect); + adjustRegionInFreefromWindowMode(mTmpRect); region.op(mTmpRect, Region.Op.INTERSECT); }