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

Commit 5f147467 authored by Tiger's avatar Tiger Committed by Tiger Huang
Browse files

Let view focus move across adjacent task fragments by tab keys

Before this CL, the focus could only be moved to the focusable views in
a window by tab keys if there are multiple focusable views in the
window.

This CL gives the tab key a chance to move the focus to the adjacent
task fragments while the next focus will be looped.

Fix: 283618824
Test: atest ActivityEmbeddingFocusTests
Test: Run commands: `adb shell input keyevent KEYCODE_TAB` while running
      2-pane Settings. See if the focus will go to the adjacent window.
Change-Id: I16c68a514cd7bf9238e2a9fcbc130b025a3ae872
parent e53175bc
Loading
Loading
Loading
Loading
+16 −5
Original line number Diff line number Diff line
@@ -314,13 +314,20 @@ public class FocusFinder {
        if (count < 2) {
            return null;
        }
        View next = null;
        final boolean[] looped = new boolean[1];
        switch (direction) {
            case View.FOCUS_FORWARD:
                return getNextFocusable(focused, focusables, count);
                next = getNextFocusable(focused, focusables, count, looped);
                break;
            case View.FOCUS_BACKWARD:
                return getPreviousFocusable(focused, focusables, count);
                next = getPreviousFocusable(focused, focusables, count, looped);
                break;
        }
        return focusables.get(count - 1);
        if (root != null && root.mAttachInfo != null && root == root.getRootView()) {
            root.mAttachInfo.mNextFocusLooped = looped[0];
        }
        return next != null ? next : focusables.get(count - 1);
    }

    private void setFocusBottomRight(ViewGroup root, Rect focusedRect) {
@@ -375,7 +382,8 @@ public class FocusFinder {
        return closest;
    }

    private static View getNextFocusable(View focused, ArrayList<View> focusables, int count) {
    private static View getNextFocusable(View focused, ArrayList<View> focusables, int count,
            boolean[] outLooped) {
        if (count < 2) {
            return null;
        }
@@ -385,10 +393,12 @@ public class FocusFinder {
                return focusables.get(position + 1);
            }
        }
        outLooped[0] = true;
        return focusables.get(0);
    }

    private static View getPreviousFocusable(View focused, ArrayList<View> focusables, int count) {
    private static View getPreviousFocusable(View focused, ArrayList<View> focusables, int count,
            boolean[] outLooped) {
        if (count < 2) {
            return null;
        }
@@ -398,6 +408,7 @@ public class FocusFinder {
                return focusables.get(position - 1);
            }
        }
        outLooped[0] = true;
        return focusables.get(count - 1);
    }

+7 −0
Original line number Diff line number Diff line
@@ -31333,6 +31333,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
         */
        final ArrayList<View> mTempArrayList = new ArrayList<View>(24);
        /**
         * Indicates if the next focus will be looped back to the first focusable view of the entire
         * hierarchy when finding in the direction of {@link #FOCUS_FORWARD} or to the last
         * focusable view when finding in the direction of {@link #FOCUS_BACKWARD}.
         */
        boolean mNextFocusLooped = false;
        /**
         * The id of the window for accessibility purposes.
         */
+10 −0
Original line number Diff line number Diff line
@@ -7270,8 +7270,18 @@ public final class ViewRootImpl implements ViewParent,
            if (direction != 0) {
                View focused = mView.findFocus();
                if (focused != null) {
                    mAttachInfo.mNextFocusLooped = false;
                    View v = focused.focusSearch(direction);
                    if (v != null && v != focused) {
                        if (mAttachInfo.mNextFocusLooped) {
                            // The next focus is looped. Let's try to move the focus to the adjacent
                            // window. Note: we still need to move the focus in this window
                            // regardless of what moveFocusToAdjacentWindow returns, so the focus
                            // can be looped back from the focus in the adjacent window to next
                            // focus of this window.
                            moveFocusToAdjacentWindow(direction);
                        }
                        // do the math the get the interesting rect
                        // of previous focused into the coord system of
                        // newly focused view