Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d6d5f8f0 authored by Filip Gruszczynski's avatar Filip Gruszczynski Committed by Android (Google) Code Review
Browse files

Merge "Fix freeform to recents animating window being cuttoff."

parents c373adb8 f34a04cc
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -559,6 +559,14 @@ public class ActivityManager {
        public static boolean isAlwaysOnTop(int stackId) {
            return stackId == PINNED_STACK_ID;
        }

        /**
         * Returns true if the application windows in this stack should be displayed above all
         * other application windows, including during the animation.
         */
        public static boolean shouldIncreaseApplicationWindowLayer(int stackId) {
            return stackId == PINNED_STACK_ID || stackId == DOCKED_STACK_ID;
        }
    }

    /**
+2 −3
Original line number Diff line number Diff line
@@ -8693,9 +8693,8 @@ public class WindowManagerService extends IWindowManager.Stub
        }
        if (!force) {
            final TaskStack stack = w.getStack();
            if (stack != null && (StackId.isAlwaysOnTop(stack.mStackId)
                    || stack.mStackId == DOCKED_STACK_ID)) {
                // If the window's stack is always on top, we want to make it above other windows
            if (stack != null && (StackId.shouldIncreaseApplicationWindowLayer(stack.mStackId))) {
                // For pinned and docked stack window, we want to make them above other windows
                // also when these windows are animating.
                force = true;
            }
+0 −14
Original line number Diff line number Diff line
@@ -259,13 +259,6 @@ final class WindowState implements WindowManagerPolicy.WindowState {
     */
    int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;

    /**
     * This is rectangle of the window's surface that is not covered by
     * system decorations.
     */
    final Rect mSystemDecorRect = new Rect();
    final Rect mLastSystemDecorRect = new Rect();

    // Current transformation being applied.
    float mGlobalScale=1;
    float mInvGlobalScale=1;
@@ -2085,13 +2078,6 @@ final class WindowState implements WindowManagerPolicy.WindowState {
            pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
                    pw.print(" last="); mLastFrame.printShortString(pw);
                    pw.println();
            pw.print(prefix); pw.print("mSystemDecorRect="); mSystemDecorRect.printShortString(pw);
                    pw.print(" last="); mLastSystemDecorRect.printShortString(pw);
                    if (mWinAnimator.mHasClipRect) {
                        pw.print(" mLastClipRect=");
                        mWinAnimator.mLastClipRect.printShortString(pw);
                    }
                    pw.println();
        }
        if (mEnforceSizeCompat) {
            pw.print(prefix); pw.print("mCompatFrame="); mCompatFrame.printShortString(pw);
+51 −22
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WIND
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_CROP;
import static com.android.server.wm.WindowManagerDebugConfig.HIDE_STACK_CRAWLS;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
@@ -128,6 +129,13 @@ class WindowStateAnimator {
    Rect mLastClipRect = new Rect();
    Rect mTmpStackBounds = new Rect();

    /**
     * This is rectangle of the window's surface that is not covered by
     * system decorations.
     */
    private final Rect mSystemDecorRect = new Rect();
    private final Rect mLastSystemDecorRect = new Rect();

    // Used to save animation distances between the time they are calculated and when they are used.
    private int mAnimDx;
    private int mAnimDy;
@@ -599,7 +607,7 @@ class WindowStateAnimator {
            }

            // We may abort, so initialize to defaults.
            w.mLastSystemDecorRect.set(0, 0, 0, 0);
            mLastSystemDecorRect.set(0, 0, 0, 0);
            mHasClipRect = false;
            mClipRect.set(0, 0, 0, 0);
            mLastClipRect.set(0, 0, 0, 0);
@@ -1048,8 +1056,9 @@ class WindowStateAnimator {
        }
    }

    private void applyDecorRect(final Rect decorRect) {
    private void calculateSystemDecorRect() {
        final WindowState w = mWin;
        final Rect decorRect = w.mDecorFrame;
        final int width = w.mFrame.width();
        final int height = w.mFrame.height();

@@ -1058,11 +1067,17 @@ class WindowStateAnimator {
        final int top = w.mYOffset + w.mFrame.top;

        // Initialize the decor rect to the entire frame.
        w.mSystemDecorRect.set(0, 0, width, height);
        mSystemDecorRect.set(0, 0, width, height);

        // If a freeform window is animating from a position where it would be cutoff, it would be
        // cutoff during the animation. We don't want that, so for the duration of the animation
        // we ignore the decor cropping and depend on layering to position windows correctly.
        final boolean cropToDecor = !(w.inFreeformWorkspace() && w.isAnimatingLw());
        if (cropToDecor) {
            // Intersect with the decor rect, offsetted by window position.
        w.mSystemDecorRect.intersect(decorRect.left - left, decorRect.top - top,
            mSystemDecorRect.intersect(decorRect.left - left, decorRect.top - top,
                    decorRect.right - left, decorRect.bottom - top);
        }

        // If size compatibility is being applied to the window, the
        // surface is scaled relative to the screen.  Also apply this
@@ -1072,10 +1087,10 @@ class WindowStateAnimator {
        // much and hide part of the window that should be seen.
        if (w.mEnforceSizeCompat && w.mInvGlobalScale != 1.0f) {
            final float scale = w.mInvGlobalScale;
            w.mSystemDecorRect.left = (int) (w.mSystemDecorRect.left * scale - 0.5f);
            w.mSystemDecorRect.top = (int) (w.mSystemDecorRect.top * scale - 0.5f);
            w.mSystemDecorRect.right = (int) ((w.mSystemDecorRect.right+1) * scale - 0.5f);
            w.mSystemDecorRect.bottom = (int) ((w.mSystemDecorRect.bottom+1) * scale - 0.5f);
            mSystemDecorRect.left = (int) (mSystemDecorRect.left * scale - 0.5f);
            mSystemDecorRect.top = (int) (mSystemDecorRect.top * scale - 0.5f);
            mSystemDecorRect.right = (int) ((mSystemDecorRect.right+1) * scale - 0.5f);
            mSystemDecorRect.bottom = (int) ((mSystemDecorRect.bottom+1) * scale - 0.5f);
        }
    }

@@ -1086,30 +1101,34 @@ class WindowStateAnimator {
            return;
        }
        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
        if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Updating crop for window: " + w + ", " + "mLastCrop=" +
                mLastClipRect);

        // Need to recompute a new system decor rect each time.
        if (!w.isDefaultDisplay()) {
            // On a different display there is no system decor.  Crop the window
            // by the screen boundaries.
            w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
            w.mSystemDecorRect.intersect(-w.mCompatFrame.left, -w.mCompatFrame.top,
            mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
            mSystemDecorRect.intersect(-w.mCompatFrame.left, -w.mCompatFrame.top,
                    displayInfo.logicalWidth - w.mCompatFrame.left,
                    displayInfo.logicalHeight - w.mCompatFrame.top);
        } else if (w.mLayer >= mService.mSystemDecorLayer) {
            // Above the decor layer is easy, just use the entire window.
            w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
            mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
        } else if (w.mDecorFrame.isEmpty()) {
            // Windows without policy decor aren't cropped.
            w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
            mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
        } else if (w.mAttrs.type == LayoutParams.TYPE_WALLPAPER && mAnimator.isAnimating()) {
            // If we're animating, the wallpaper crop should only be updated at the end of the
            // animation.
            mTmpClipRect.set(w.mSystemDecorRect);
            applyDecorRect(w.mDecorFrame);
            w.mSystemDecorRect.union(mTmpClipRect);
            mTmpClipRect.set(mSystemDecorRect);
            calculateSystemDecorRect();
            mSystemDecorRect.union(mTmpClipRect);
        } else {
            // Crop to the system decor specified by policy.
            applyDecorRect(w.mDecorFrame);
            calculateSystemDecorRect();
            if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Applying decor to crop for " + w + ", mDecorFrame="
                    + w.mDecorFrame + ", mSystemDecorRect=" + mSystemDecorRect);
        }

        final boolean fullscreen = w.isFrameFullscreen(displayInfo);
@@ -1123,7 +1142,9 @@ class WindowStateAnimator {
        } else {
            // We use the clip rect as provided by the tranformation for non-fullscreen windows to
            // avoid premature clipping with the system decor rect.
            clipRect.set((mHasClipRect && !fullscreen) ? mClipRect : w.mSystemDecorRect);
            clipRect.set((mHasClipRect && !fullscreen) ? mClipRect : mSystemDecorRect);
            if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Initial clip rect: " + clipRect + ", mHasClipRect="
                    + mHasClipRect + ", fullscreen=" + fullscreen);
        }
        // Expand the clip rect for surface insets.
        final WindowManager.LayoutParams attrs = w.mAttrs;
@@ -1143,6 +1164,7 @@ class WindowStateAnimator {
        clipRect.offset(attrs.surfaceInsets.left, attrs.surfaceInsets.top);

        adjustCropToStackBounds(w, clipRect, isFreeformResizing);
        if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Clip rect after stack adjustment=" + mClipRect);

        w.transformFromScreenToSurfaceSpace(clipRect);

@@ -1160,13 +1182,14 @@ class WindowStateAnimator {
        }

        // We don't apply the stack bounds crop if:
        // 1. The window is currently animating docked mode, otherwise the animating window will be
        // suddenly cut off.
        // 1. The window is currently animating docked mode or in freeform mode, otherwise the
        // animating window will be suddenly (docked) or for whole animation (freeform) cut off.
        // 2. The window that is being replaced during animation, because it was living in a
        // different stack. If we suddenly crop it to the new stack bounds, it might get cut off.
        // We don't want it to happen, so we let it ignore the stack bounds until it gets removed.
        // The window that will replace it will abide them.
        if (isAnimating() && (appToken.mWillReplaceWindow || w.inDockedWorkspace())) {
        if (isAnimating() && (appToken.mWillReplaceWindow || w.inDockedWorkspace()
                || w.inFreeformWorkspace())) {
            return;
        }

@@ -1646,6 +1669,12 @@ class WindowStateAnimator {
        if (dumpAll) {
            pw.print(prefix); pw.print("mDrawState="); pw.print(drawStateToString());
            pw.print(prefix); pw.print(" mLastHidden="); pw.println(mLastHidden);
            pw.print(prefix); pw.print("mSystemDecorRect="); mSystemDecorRect.printShortString(pw);
            pw.print(" last="); mLastSystemDecorRect.printShortString(pw);
            if (mHasClipRect) {
                pw.print(" mLastClipRect="); mLastClipRect.printShortString(pw);
            }
            pw.println();
        }

        if (mPendingDestroySurface != null) {