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

Commit 8afe7c7d authored by chaviw's avatar chaviw
Browse files

Only switch task focus to window's task that was tapped outside current focus

The previous logic would check what Task was at the coordinates that the event
receiver got. This was an issue if a window that was tapped didn't have a Task,
for example, system windows. The Task focus would get switched to the Task that
was behind the tapped window.

This change leverages the new API onPointerDownOutsideFocusLocked. When a down
outside focus occurs, WindowManager will check if the window has a Task + the
check that existed previously, before determining whether the new Task should
get focus.

Fixes: 129571534
Test: Steps from bug
Test: Resize in freeform continues to work.
Change-Id: I73286e03f505cdf37f30fa5914cf24f843a6bc7c
parent dd07ae57
Loading
Loading
Loading
Loading
+0 −27
Original line number Diff line number Diff line
@@ -2361,33 +2361,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        layoutAndAssignWindowLayersIfNeeded();
    }

    /**
     * Used to obtain task ID when user taps on coordinate (x, y) in this display, and outside
     * current task in focus.
     *
     * This returns the task ID of the foremost task at (x, y) if the task is not home. Otherwise it
     * returns -1.
     *
     * @param x horizontal coordinate of the tap position
     * @param y vertical coordinate of the tap position
     * @return the task ID if a non-home task is found; -1 if not
     */
    int taskForTapOutside(int x, int y) {
        for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
            final TaskStack stack = mTaskStackContainers.getChildAt(stackNdx);
            if (stack.isActivityTypeHome() && !stack.inMultiWindowMode()) {
                // We skip not only home stack, but also everything behind home because user can't
                // see them when home stack is isn't in multi-window mode.
                break;
            }
            final int taskId = stack.taskIdFromPoint(x, y);
            if (taskId != -1) {
                return taskId;
            }
        }
        return -1;
    }

    /**
     * Returns true if the input point is within an app window.
     */
+4 −10
Original line number Diff line number Diff line
@@ -127,7 +127,6 @@ class TaskPositioningController {

    void handleTapOutsideTask(DisplayContent displayContent, int x, int y) {
        mHandler.post(() -> {
            int taskId = -1;
            synchronized (mService.mGlobalLock) {
                final Task task = displayContent.findTaskForResizePoint(x, y);
                if (task != null) {
@@ -135,17 +134,12 @@ class TaskPositioningController {
                            task.preserveOrientationOnResize(), x, y)) {
                        return;
                    }
                    taskId = task.mTaskId;
                } else {
                    taskId = displayContent.taskForTapOutside(x, y);
                }
            }
            if (taskId >= 0) {
                    try {
                    mActivityManager.setFocusedTask(taskId);
                        mActivityManager.setFocusedTask(task.mTaskId);
                    } catch (RemoteException e) {
                    }
                }
            }
        });
    }

+0 −25
Original line number Diff line number Diff line
@@ -1458,31 +1458,6 @@ public class TaskStack extends WindowContainer<Task> implements
        return false;
    }

    int taskIdFromPoint(int x, int y) {
        getBounds(mTmpRect);
        if (!mTmpRect.contains(x, y) || isAdjustedForMinimizedDockedStack()) {
            return -1;
        }

        for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; --taskNdx) {
            final Task task = mChildren.get(taskNdx);
            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.
            task.getDimBounds(mTmpRect);
            if (mTmpRect.contains(x, y)) {
                return task.mTaskId;
            }
        }

        return -1;
    }

    void findTaskForResizePoint(int x, int y, int delta,
            DisplayContent.TaskForResizePointSearchResult results) {
        if (!getWindowConfiguration().canResizeTask()) {
+26 −2
Original line number Diff line number Diff line
@@ -7587,12 +7587,36 @@ public class WindowManagerService extends IWindowManager.Stub
            return;
        }

        final DisplayContent displayContent = touchedWindow.getDisplayContent();
        handleTaskFocusChange(touchedWindow.getTask());
        handleDisplayFocusChange(touchedWindow);
    }

    private void handleTaskFocusChange(Task task) {
        if (task == null) {
            return;
        }

        final TaskStack stack = task.mStack;
        // We ignore home stack since we don't want home stack to move to front when touched.
        // Specifically, in freeform we don't want tapping on home to cause the freeform apps to go
        // behind home. See b/117376413
        if (stack.isActivityTypeHome()) {
            return;
        }

        try {
            mActivityTaskManager.setFocusedTask(task.mTaskId);
        } catch (RemoteException e) {
        }
    }

    private void handleDisplayFocusChange(WindowState window) {
        final DisplayContent displayContent = window.getDisplayContent();
        if (displayContent == null) {
            return;
        }

        if (!touchedWindow.canReceiveKeys()) {
        if (!window.canReceiveKeys()) {
            // If the window that received the input event cannot receive keys, don't move the
            // display it's on to the top since that window won't be able to get focus anyway.
            return;