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

Commit d0469087 authored by Chong Zhang's avatar Chong Zhang Committed by Android (Google) Code Review
Browse files

Merge "Fixes for touch exclusion region"

parents 9fded232 d8ceb855
Loading
Loading
Loading
Loading
+55 −48
Original line number Diff line number Diff line
@@ -291,27 +291,29 @@ class DisplayContent {
            final ArrayList<Task> tasks = mStacks.get(stackNdx).getTasks();
            for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
                final Task task = tasks.get(taskNdx);
                // 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. For example, the presence of the IME adjusting the
                final WindowState win = task.getTopVisibleAppMainWindow();
                if (win == null) {
                    continue;
                }
                // We need to use the task's dim bounds (which is derived from the visible
                // bounds of its apps windows) for any touch-related tests. Can't use
                // the task's original bounds because it might be adjusted to fit the
                // content frame. For example, the presence of the IME adjusting the
                // windows frames when the app window is the IME target.
                final WindowState win = task.getTopAppMainWindow();
                if (win != null) {
                    win.getVisibleBounds(mTmpRect);
                task.getDimBounds(mTmpRect);
                if (mTmpRect.contains(x, y)) {
                    return task.mTaskId;
                }
            }
        }
        }
        return -1;
    }

    /**
     * Find the window whose outside touch area (for resizing) (x, y) falls within.
     * Find the task whose outside touch area (for resizing) (x, y) falls within.
     * Returns null if the touch doesn't fall into a resizing area.
     */
    WindowState findWindowForControlPoint(int x, int y) {
    Task findTaskForControlPoint(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);
@@ -325,19 +327,18 @@ class DisplayContent {
                    return null;
                }

                // 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.)
                final WindowState win = task.getTopAppMainWindow();
                if (win != null) {
                    win.getVisibleBounds(mTmpRect);
                // We need to use the task's dim bounds (which is derived from the visible
                // bounds of its apps windows) for any touch-related tests. Can't use
                // the task's original bounds because it might be adjusted to fit the
                // content frame. One example is when the task is put to top-left quadrant,
                // the actual visible area would not start at (0,0) after it's adjusted
                // for the status bar.
                task.getDimBounds(mTmpRect);
                mTmpRect.inset(-delta, -delta);
                if (mTmpRect.contains(x, y)) {
                    mTmpRect.inset(delta, delta);
                    if (!mTmpRect.contains(x, y)) {
                            return win;
                        return task;
                    }
                    // User touched inside the task. No need to look further,
                    // focus transfer will be handled in ACTION_UP.
@@ -345,18 +346,23 @@ class DisplayContent {
                }
            }
        }
        }
        return null;
    }

    void setTouchExcludeRegion(Task focusedTask) {
        mTouchExcludeRegion.set(mBaseDisplayRect);
        WindowList windows = getWindowList();
        final int delta = mService.dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
        for (int i = windows.size() - 1; i >= 0; --i) {
            final WindowState win = windows.get(i);
            final Task task = win.getTask();
            if (win.isVisibleLw() && task != null) {
        boolean addBackFocusedTask = false;
        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
            TaskStack stack = mStacks.get(stackNdx);
            final ArrayList<Task> tasks = stack.getTasks();
            for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
                final Task task = tasks.get(taskNdx);
                final WindowState win = task.getTopVisibleAppMainWindow();
                if (win == null) {
                    continue;
                }

                /**
                 * Exclusion region is the region that TapDetector doesn't care about.
                 * Here we want to remove all non-focused tasks from the exclusion region.
@@ -368,13 +374,17 @@ class DisplayContent {
                 */
                final boolean isFreeformed = task.inFreeformWorkspace();
                if (task != focusedTask || isFreeformed) {
                    mTmpRect.set(win.mVisibleFrame);
                    mTmpRect.intersect(win.mVisibleInsets);
                    /**
                     * If the task is freeformed, enlarge the area to account for outside
                     * touch area for resize.
                     */
                    task.getDimBounds(mTmpRect);
                    if (isFreeformed) {
                        // If we're removing a freeform, focused app from the exclusion region,
                        // we need to add back its touchable frame later. Remember the touchable
                        // frame now.
                        if (task == focusedTask) {
                            addBackFocusedTask = true;
                            mTmpRect2.set(mTmpRect);
                        }
                        // If the task is freeformed, enlarge the area to account for outside
                        // touch area for resize.
                        mTmpRect.inset(-delta, -delta);
                        // Intersect with display content rect. If we have system decor (status bar/
                        // navigation bar), we want to exclude that from the tap detection.
@@ -385,16 +395,13 @@ class DisplayContent {
                    }
                    mTouchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE);
                }
                /**
                 * If we removed the focused task above, add it back and only leave its
                 * outside touch area in the exclusion. TapDectector is not interested in
                 * any touch inside the focused task itself.
                 */
                if (task == focusedTask && isFreeformed) {
                    mTmpRect.inset(delta, delta);
                    mTouchExcludeRegion.op(mTmpRect, Region.Op.UNION);
            }
        }
        // If we removed the focused task above, add it back and only leave its
        // outside touch area in the exclusion. TapDectector is not interested in
        // any touch inside the focused task itself.
        if (addBackFocusedTask) {
            mTouchExcludeRegion.op(mTmpRect2, Region.Op.UNION);
        }
        if (mTapDetector != null) {
            mTapDetector.setTouchExcludeRegion(mTouchExcludeRegion);
+18 −7
Original line number Diff line number Diff line
@@ -284,7 +284,12 @@ class Task implements DimLayer.DimLayerUser {
    boolean getMaxVisibleBounds(Rect out) {
        boolean foundTop = false;
        for (int i = mAppTokens.size() - 1; i >= 0; i--) {
            final WindowState win = mAppTokens.get(i).findMainWindow();
            final AppWindowToken token = mAppTokens.get(i);
            // skip hidden (or about to hide) apps
            if (token.mIsExiting || token.clientHidden || token.hiddenRequested) {
                continue;
            }
            final WindowState win = token.findMainWindow();
            if (win == null) {
                continue;
            }
@@ -413,14 +418,20 @@ 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;
    WindowState getTopVisibleAppMainWindow() {
        final AppWindowToken token = getTopVisibleAppToken();
        return token != null ? token.findMainWindow() : null;
    }

    AppWindowToken getTopAppWindowToken() {
        final int tokensCount = mAppTokens.size();
        return tokensCount > 0 ? mAppTokens.get(tokensCount - 1) : null;
    AppWindowToken getTopVisibleAppToken() {
        for (int i = mAppTokens.size() - 1; i >= 0; i--) {
            final AppWindowToken token = mAppTokens.get(i);
            // skip hidden (or about to hide) apps
            if (!token.mIsExiting && !token.clientHidden && !token.hiddenRequested) {
                return token;
            }
        }
        return null;
    }

    @Override
+16 −12
Original line number Diff line number Diff line
@@ -332,30 +332,34 @@ class TaskPositioner implements DimLayer.DimLayerUser {
                + ", {" + startX + ", " + startY + "}");
        }
        mCtrlType = CTRL_NONE;
        mTask = win.getTask();
        mStartDragX = startX;
        mStartDragY = startY;

        // Use the dim bounds, not the original task bounds. The cursor
        // movement should be calculated relative to the visible bounds.
        // Also, use the dim bounds of the task which accounts for
        // multiple app windows. Don't use any bounds from win itself as it
        // may not be the same size as the task.
        mTask.getDimBounds(mTmpRect);

        if (resize) {
            final Rect visibleFrame = win.mVisibleFrame;
            if (startX < visibleFrame.left) {
            if (startX < mTmpRect.left) {
                mCtrlType |= CTRL_LEFT;
            }
            if (startX > visibleFrame.right) {
            if (startX > mTmpRect.right) {
                mCtrlType |= CTRL_RIGHT;
            }
            if (startY < visibleFrame.top) {
            if (startY < mTmpRect.top) {
                mCtrlType |= CTRL_TOP;
            }
            if (startY > visibleFrame.bottom) {
            if (startY > mTmpRect.bottom) {
                mCtrlType |= CTRL_BOTTOM;
            }
            mResizing = true;
        }

        mTask = win.getTask();
        mStartDragX = startX;
        mStartDragY = startY;

        // Use the visible bounds, not the original task bounds. The cursor
        // movement should be calculated relative to the visible bounds.
        mWindowOriginalBounds.set(win.mVisibleFrame);
        mWindowOriginalBounds.set(mTmpRect);
    }

    private void endDragLocked() {
+3 −3
Original line number Diff line number Diff line
@@ -90,11 +90,11 @@ public class TaskTapPointerEventListener implements PointerEventListener {
            case MotionEvent.ACTION_HOVER_MOVE: {
                final int x = (int) motionEvent.getX();
                final int y = (int) motionEvent.getY();
                final WindowState window = mDisplayContent.findWindowForControlPoint(x, y);
                if (window == null) {
                final Task task = mDisplayContent.findTaskForControlPoint(x, y);
                if (task == null) {
                    break;
                }
                window.getVisibleBounds(mTmpRect);
                task.getDimBounds(mTmpRect);
                if (!mTmpRect.isEmpty() && !mTmpRect.contains(x, y)) {
                    int iconShape = STYLE_DEFAULT;
                    if (x < mTmpRect.left) {
+5 −4
Original line number Diff line number Diff line
@@ -7069,15 +7069,16 @@ public class WindowManagerService extends IWindowManager.Stub
    }

    private void startResizingTask(DisplayContent displayContent, int startX, int startY) {
        WindowState win = null;
        Task task = null;
        synchronized (mWindowMap) {
            win = displayContent.findWindowForControlPoint(startX, startY);
            if (win == null || !startPositioningLocked(win, true /*resize*/, startX, startY)) {
            task = displayContent.findTaskForControlPoint(startX, startY);
            if (task == null || !startPositioningLocked(
                    task.getTopVisibleAppMainWindow(), true /*resize*/, startX, startY)) {
                return;
            }
        }
        try {
            mActivityManager.setFocusedTask(win.getTask().mTaskId);
            mActivityManager.setFocusedTask(task.mTaskId);
        } catch(RemoteException e) {}
    }

Loading