From e627558feffa4ffe6435d7d13eda3d89f7c08095 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Mon, 29 Feb 2016 15:45:45 -0800 Subject: Fix pinned stack frame computation. We want to compute the frames for pinned like we do for freeform as we are not constraining layout to the suggested display area by the PhoneWindowManager. Also update applyGravityAndUpdateFrame to not clip frames to the display for child windows. In the case of computeFrameLw this would not be a problem as we would then go on to overwrite mFrame anyway, but in the case of repositionChild it could create issues (where we have applyGravityAndUpdateframe without compute frame). Bug: 26454664 Change-Id: I6fd4c9f37060d51003d041566368edd2b9eb7afd --- core/java/android/app/ActivityManager.java | 10 +++++++++ services/core/java/com/android/server/wm/Task.java | 5 +++++ .../java/com/android/server/wm/WindowState.java | 25 ++++++++++++---------- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 4aab163597d6..cb72a6a35f93 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -576,6 +576,16 @@ public class ActivityManager { || targetStackId == FREEFORM_WORKSPACE_STACK_ID; } + /** + * Return whether a stackId is a stack containing floating windows. Floating windows + * are laid out differently as they are allowed to extend past the display bounds + * without overscan insets. + */ + public static boolean tasksAreFloating(int stackId) { + return stackId == FREEFORM_WORKSPACE_STACK_ID + || stackId == PINNED_STACK_ID; + } + /** * Returns true if animation specs should be constructed for app transition that moves * the task to the specified stack. diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index c7b559904209..f097eb242bfa 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -19,6 +19,7 @@ package com.android.server.wm; import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; +import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.app.ActivityManager.StackId.HOME_STACK_ID; import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; @@ -685,6 +686,10 @@ class Task implements DimLayer.DimLayerUser { && mStack != null && StackId.isTaskResizeableByDockedStack(mStack.mStackId); } + boolean isFloating() { + return StackId.tasksAreFloating(mStack.mStackId); + } + /** * Whether the task should be treated as if it's docked. Returns true if the task * is currently in docked workspace, or it's side-by-side to a docked task. diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 40b6b50da6dd..818a3f541a62 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -635,7 +635,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { final Task task = getTask(); final boolean fullscreenTask = task == null || task.isFullscreen(); - final boolean freeformWorkspace = task != null && task.inFreeformWorkspace(); + final boolean windowsAreFloating = task != null && task.isFloating(); if (fullscreenTask || (isChildWindow() && (mAttrs.privateFlags & PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME) != 0)) { @@ -661,10 +661,10 @@ final class WindowState implements WindowManagerPolicy.WindowState { mContainingFrame.top -= mContainingFrame.bottom - cf.bottom; } - 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. + if (windowsAreFloating) { + // In floating modes (e.g. freeform, pinned) 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. if (mContainingFrame.isEmpty()) { mContainingFrame.set(cf); } @@ -720,7 +720,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { // Make sure the content and visible frames are inside of the // final window frame. - if (freeformWorkspace && !mFrame.isEmpty()) { + if (windowsAreFloating && !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.. @@ -772,9 +772,9 @@ final class WindowState implements WindowManagerPolicy.WindowState { Math.min(mStableFrame.bottom, frame.bottom)); } - if (!inFreeformWorkspace()) { - // Freeform windows can be positioned outside of the display frame, but that is not a - // reason to provide them with overscan insets. + if (!windowsAreFloating) { + // Windows from floating tasks (e.g. freeform, pinned) may be positioned outside + // of the display frame, but that is not a reason to provide them with overscan insets. mOverscanInsets.set(Math.max(mOverscanFrame.left - frame.left, 0), Math.max(mOverscanFrame.top - frame.top, 0), Math.max(frame.right - mOverscanFrame.right, 0), @@ -2479,7 +2479,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { final int ph = mContainingFrame.height(); final Task task = getTask(); final boolean nonFullscreenTask = task != null && !task.isFullscreen(); - + final boolean fitToDisplay = task != null && + !task.isFloating(); float x, y; int w,h; @@ -2536,7 +2537,9 @@ final class WindowState implements WindowManagerPolicy.WindowState { (int) (y + mAttrs.verticalMargin * ph), mFrame); // Now make sure the window fits in the overall display frame. - Gravity.applyDisplay(mAttrs.gravity, mDisplayFrame, mFrame); + if (fitToDisplay) { + Gravity.applyDisplay(mAttrs.gravity, mDisplayFrame, mFrame); + } } boolean isChildWindow() { -- cgit v1.2.3-59-g8ed1b