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

Commit 3005e755 authored by Chong Zhang's avatar Chong Zhang
Browse files

Misc fixes for window moving and resizing

- Do not skip resizeTask if we're starting or ending drag. We need
  the relayout because surface mode is changing.

- When we're changing the surface mode, need to wait for the first
  draw to finish before we can modify shown frame. Otherwise there
  could be 1 old frame displayed with new position, which makes the
  window position look a bit off.

- Clean up dragResizing/dragResizeChanged flags.

Change-Id: Ia396d6b88fd616ad57aa8cd24ca7e1161add7205
parent 153a2930
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -3061,7 +3061,12 @@ public final class ActivityStackSupervisor implements DisplayListener {
            return;
        }

        if (task.mBounds != null && task.mBounds.equals(bounds)) {
        // TODO: change resizedByUser to an enum (or bitmask?) to indicate the origin of
        //       this resize (eg. systemResize, userResize, forcedResized).
        // If the resize is a drag-resize by user, let it go through even if the bounds
        // is not changing, as we might need a relayout due to surface size change
        // (to/from fullscreen).
        if (task.mBounds != null && task.mBounds.equals(bounds) && !resizedByUser) {
            // Nothing to do here...
            return;
        }
+30 −0
Original line number Diff line number Diff line
@@ -72,6 +72,12 @@ class Task implements DimLayer.DimLayerUser {
    // For handling display rotations.
    private Rect mTmpRect2 = new Rect();

    // Whether the task is currently being drag-resized
    private boolean mDragResizing;

    // Whether the task is starting or ending to be drag-resized
    private boolean mDragResizeChanging;

    // The particular window with FLAG_DIM_BEHIND set. If null, hide mDimLayer.
    WindowStateAnimator mDimWinAnimator;
    // Used to support {@link android.view.WindowManager.LayoutParams#FLAG_DIM_BEHIND}
@@ -227,10 +233,34 @@ class Task implements DimLayer.DimLayerUser {
        return boundsChange;
    }

    boolean resizeLocked(Rect bounds, Configuration configuration) {
        int boundsChanged = setBounds(bounds, configuration);
        if (mDragResizeChanging) {
            boundsChanged |= BOUNDS_CHANGE_SIZE;
            mDragResizeChanging = false;
        }
        if (boundsChanged == BOUNDS_CHANGE_NONE) {
            return false;
        }
        if ((boundsChanged & BOUNDS_CHANGE_SIZE) == BOUNDS_CHANGE_SIZE) {
            resizeWindows();
        }
        return true;
    }

    void getBounds(Rect out) {
        out.set(mBounds);
    }

    void setDragResizing(boolean dragResizing) {
        mDragResizeChanging = mDragResizing != dragResizing;
        mDragResizing = dragResizing;
    }

    boolean isDragResizing() {
        return mDragResizing;
    }

    void updateDisplayInfo(final DisplayContent displayContent) {
        if (displayContent == null) {
            return;
+34 −27
Original line number Diff line number Diff line
@@ -86,8 +86,7 @@ class TaskPositioner implements DimLayer.DimLayerUser {
    private int mMinVisibleWidth;
    private int mMinVisibleHeight;

    private int mTaskId;
    private TaskStack mStack;
    private Task mTask;
    private boolean mResizing;
    private final Rect mWindowOriginalBounds = new Rect();
    private final Rect mWindowDragBounds = new Rect();
@@ -136,7 +135,7 @@ class TaskPositioner implements DimLayer.DimLayerUser {
                        }
                        try {
                            mService.mActivityManager.resizeTask(
                                    mTaskId, mWindowDragBounds, true /* resizedByUser */);
                                    mTask.mTaskId, mWindowDragBounds, true /* resizedByUser */);
                        } catch(RemoteException e) {}
                    } break;

@@ -156,21 +155,29 @@ class TaskPositioner implements DimLayer.DimLayerUser {
                }

                if (endDrag) {
                    mResizing = false;
                    synchronized (mService.mWindowMap) {
                        endDragLocked();
                    }
                    try {
                        if (mResizing) {
                            // We were using fullscreen surface during resizing. Request
                            // resizeTask() one last time to restore surface to window size.
                            mService.mActivityManager.resizeTask(
                                mTaskId, mWindowDragBounds, true /* resizedByUser */);
                    } catch(RemoteException e) {}
                    // Post back to WM to handle clean-ups. We still need the input
                    // event handler for the last finishInputEvent()!
                    mService.mH.sendEmptyMessage(H.FINISH_TASK_POSITIONING);
                                    mTask.mTaskId, mWindowDragBounds, true /* resizedByUser */);
                        }

                        if (mCurrentDimSide != CTRL_NONE) {
                            final int createMode = mCurrentDimSide == CTRL_LEFT
                                    ? DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT
                                    : DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
                            mService.mActivityManager.moveTaskToDockedStack(
                                mTaskId, createMode, true /*toTop*/);
                                    mTask.mTaskId, createMode, true /*toTop*/);
                        }
                    } catch(RemoteException e) {}

                    // Post back to WM to handle clean-ups. We still need the input
                    // event handler for the last finishInputEvent()!
                    mService.mH.sendEmptyMessage(H.FINISH_TASK_POSITIONING);
                }
                handled = true;
            } catch (Exception e) {
@@ -291,10 +298,6 @@ class TaskPositioner implements DimLayer.DimLayerUser {
        mService.resumeRotationLocked();
    }

    boolean isTaskResizing(final Task task) {
        return mResizing && task != null && mTaskId == task.mTaskId;
    }

    void startDragLocked(WindowState win, boolean resize, float startX, float startY) {
        if (DEBUG_TASK_POSITIONING) {
            Slog.d(TAG, "startDragLocked: win=" + win + ", resize=" + resize
@@ -318,13 +321,16 @@ class TaskPositioner implements DimLayer.DimLayerUser {
            mResizing = true;
        }

        final Task task = win.getTask();
        mTaskId = task.mTaskId;
        mStack = task.mStack;
        mTask = win.getTask();
        mStartDragX = startX;
        mStartDragY = startY;

        mService.getTaskBounds(mTaskId, mWindowOriginalBounds);
        mService.getTaskBounds(mTask.mTaskId, mWindowOriginalBounds);
    }

    private void endDragLocked() {
        mResizing = false;
        mTask.setDragResizing(false);
    }

    /** Returns true if the move operation should be ended. */
@@ -354,11 +360,12 @@ class TaskPositioner implements DimLayer.DimLayerUser {
                bottom = Math.max(top + mMinVisibleHeight, bottom + deltaY);
            }
            mWindowDragBounds.set(left, top, right, bottom);
            mTask.setDragResizing(true);
            return false;
        }

        // This is a moving operation.
        mStack.getBounds(mTmpRect);
        mTask.mStack.getBounds(mTmpRect);
        mTmpRect.inset(mMinVisibleWidth, mMinVisibleHeight);
        if (!mTmpRect.contains((int) x, (int) y)) {
            // We end the moving operation if position is outside the stack bounds.
@@ -397,13 +404,13 @@ class TaskPositioner implements DimLayer.DimLayerUser {
     * shouldn't be shown.
     */
    private int getDimSide(int x) {
        if (mStack.mStackId != FREEFORM_WORKSPACE_STACK_ID
                || !mStack.isFullscreen()
        if (mTask.mStack.mStackId != FREEFORM_WORKSPACE_STACK_ID
                || !mTask.mStack.isFullscreen()
                || mService.mCurConfiguration.orientation != ORIENTATION_LANDSCAPE) {
            return CTRL_NONE;
        }

        mStack.getBounds(mTmpRect);
        mTask.mStack.getBounds(mTmpRect);
        if (x - mSideMargin <= mTmpRect.left) {
            return CTRL_LEFT;
        }
@@ -415,7 +422,7 @@ class TaskPositioner implements DimLayer.DimLayerUser {
    }

    private void showDimLayer() {
        mStack.getBounds(mTmpRect);
        mTask.mStack.getBounds(mTmpRect);
        if (mCurrentDimSide == CTRL_LEFT) {
            mTmpRect.right = mTmpRect.centerX();
        } else if (mCurrentDimSide == CTRL_RIGHT) {
@@ -433,7 +440,7 @@ class TaskPositioner implements DimLayer.DimLayerUser {

    @Override /** {@link DimLayer.DimLayerUser} */
    public DisplayInfo getDisplayInfo() {
        return mStack.getDisplayInfo();
        return mTask.mStack.getDisplayInfo();
    }

    private int getDragLayerLocked() {
+12 −13
Original line number Diff line number Diff line
@@ -2589,9 +2589,13 @@ public class WindowManagerService extends IWindowManager.Stub
                    }
                }

                dragResizing = win.isDragResizing();
                if (win.mDragResizing != dragResizing) {
                    win.mDragResizing = dragResizing;
                // If we're starting a drag-resize, we'll be changing the surface size as well as
                // notifying the client to render to with an offset from the surface's top-left.
                // Do a screen freeze, and keep the old surface until the the first frame drawn to
                // the new surface comes back, so that we avoid a flash due to mismatching surface
                // setups on window manager side and client side.
                if (win.isDragResizeChanged()) {
                    win.setDragResizing();
                    if (win.mHasSurface) {
                        winAnimator.mDestroyPendingSurfaceUponRedraw = true;
                        winAnimator.mSurfaceDestroyDeferred = true;
@@ -2600,6 +2604,7 @@ public class WindowManagerService extends IWindowManager.Stub
                        toBeDisplayed = true;
                    }
                }
                dragResizing = win.isDragResizing();
                try {
                    if (!win.mHasSurface) {
                        surfaceChanged = true;
@@ -4688,19 +4693,13 @@ public class WindowManagerService extends IWindowManager.Stub
                throw new IllegalArgumentException("resizeTask: taskId " + taskId
                        + " not found.");
            }
            final int boundsChanged = task.setBounds(bounds, configuration);
            if (boundsChanged != Task.BOUNDS_CHANGE_NONE) {
                if ((boundsChanged & Task.BOUNDS_CHANGE_SIZE) == Task.BOUNDS_CHANGE_SIZE) {
                    task.resizeWindows();
                }

                if (relayout) {
            if (task.resizeLocked(bounds, configuration) && relayout) {
                task.getDisplayContent().layoutNeeded = true;
                mWindowPlacerLocked.performSurfacePlacement();
            }
        }
    }
    }

    public void getTaskBounds(int taskId, Rect bounds) {
        synchronized (mWindowMap) {
@@ -8480,7 +8479,7 @@ public class WindowManagerService extends IWindowManager.Stub
                Slog.v(TAG, "Win " + w + " config changed: "
                        + mCurConfiguration);
            }
            final boolean dragResizingChanged = w.mDragResizing != w.isDragResizing();
            final boolean dragResizingChanged = w.isDragResizeChanged();
            if (localLOGV) Slog.v(TAG, "Resizing " + w
                    + ": configChanged=" + configChanged
                    + " dragResizingChanged=" + dragResizingChanged
+12 −2
Original line number Diff line number Diff line
@@ -129,6 +129,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
    boolean mAttachedHidden;    // is our parent window hidden?
    boolean mWallpaperVisible;  // for wallpaper, what was last vis report?
    boolean mDragResizing;
    boolean mDragResizeChanging;

    RemoteCallbackList<IWindowFocusObserver> mFocusCallbacks;

@@ -1691,9 +1692,18 @@ final class WindowState implements WindowManagerPolicy.WindowState {
        return task != null && task.inFreeformWorkspace();
    }

    boolean isDragResizing() {
    boolean isDragResizeChanged() {
        final Task task = getTask();
        return task != null && mDragResizing != task.isDragResizing();
    }

    void setDragResizing() {
        final Task task = getTask();
        return mService.mTaskPositioner != null && mService.mTaskPositioner.isTaskResizing(task);
        mDragResizing = task != null && task.isDragResizing();
    }

    boolean isDragResizing() {
        return mDragResizing;
    }

    void dump(PrintWriter pw, String prefix, boolean dumpAll) {
Loading