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

Commit a34a264a authored by Shamali P's avatar Shamali P
Browse files

Focus on the right pane when choosing an app on left

As before, user can also do 4-finger swipe down to move to right pane.

Bug: 345396938
Flag: EXEMPT bugfix
Test: Manual - see video in comments
Change-Id: If72862af2b05ae54c47e8d446a168252d3fc8194
parent 8e537d1e
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.launcher3.widget.picker;

import static android.animation.ValueAnimator.areAnimatorsEnabled;

import static com.android.launcher3.widget.picker.WidgetsListAdapter.VIEW_TYPE_WIDGETS_LIST;

import androidx.recyclerview.widget.DefaultItemAnimator;
@@ -26,6 +28,14 @@ public class WidgetsListItemAnimator extends DefaultItemAnimator {
    public static final int MOVE_DURATION_MS = 90;
    public static final int ADD_DURATION_MS = 120;

    // DefaultItemAnimator runs change and move animations before running add animations (i.e.
    // before expanded list item's content start animating to become visible on screen).
    public static final int WIDGET_LIST_ITEM_APPEARANCE_START_DELAY =
            areAnimatorsEnabled() ? (CHANGE_DURATION_MS + MOVE_DURATION_MS) : 0;
    // Delay after which all item animations are ran and list item's content is visible.
    public static final int WIDGET_LIST_ITEM_APPEARANCE_DELAY =
            WIDGET_LIST_ITEM_APPEARANCE_START_DELAY + ADD_DURATION_MS;

    public WidgetsListItemAnimator() {
        super();

+2 −6
Original line number Diff line number Diff line
@@ -15,10 +15,7 @@
 */
package com.android.launcher3.widget.picker;

import static com.android.launcher3.widget.picker.WidgetsListItemAnimator.CHANGE_DURATION_MS;
import static com.android.launcher3.widget.picker.WidgetsListItemAnimator.MOVE_DURATION_MS;

import static android.animation.ValueAnimator.areAnimatorsEnabled;
import static com.android.launcher3.widget.picker.WidgetsListItemAnimator.WIDGET_LIST_ITEM_APPEARANCE_START_DELAY;

import android.content.Context;
import android.graphics.Bitmap;
@@ -157,8 +154,7 @@ public final class WidgetsListTableViewHolderBinder
            // Pass resize delay to let the "move" and "change" animations run before resizing the
            // row.
            tableRow.setupRow(widgetItems.size(),
                    /*resizeDelayMs=*/
                    areAnimatorsEnabled() ? (CHANGE_DURATION_MS + MOVE_DURATION_MS) : 0);
                    /*resizeDelayMs=*/ WIDGET_LIST_ITEM_APPEARANCE_START_DELAY);
            if (tableRow.getChildCount() > widgetItems.size()) {
                for (int j = widgetItems.size(); j < tableRow.getChildCount(); j++) {
                    tableRow.getChildAt(j).setVisibility(View.GONE);
+43 −12
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static com.android.launcher3.UtilitiesKt.CLIP_CHILDREN_FALSE_MODIFIER;
import static com.android.launcher3.UtilitiesKt.CLIP_TO_PADDING_FALSE_MODIFIER;
import static com.android.launcher3.UtilitiesKt.modifyAttributesOnViewTree;
import static com.android.launcher3.UtilitiesKt.restoreAttributesOnViewTree;
import static com.android.launcher3.widget.picker.WidgetsListItemAnimator.WIDGET_LIST_ITEM_APPEARANCE_DELAY;

import android.content.Context;
import android.graphics.Rect;
@@ -31,6 +32,7 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ScrollView;
@@ -281,10 +283,19 @@ public class WidgetsTwoPaneSheet extends WidgetsFullSheet {
            mRightPane.removeAllViews();
            mRightPane.addView(mWidgetRecommendationsContainer);
            mRightPaneScrollView.setScrollY(0);
            mRightPane.setAccessibilityPaneTitle(suggestionsRightPaneTitle);
            mSuggestedWidgetsPackageUserKey = PackageUserKey.fromPackageItemInfo(packageItemInfo);
            final boolean isChangingHeaders = mSelectedHeader == null
                    || !mSelectedHeader.equals(mSuggestedWidgetsPackageUserKey);
            // If the initial focus view is still focused, it is likely a programmatic header
            // click.
            if (mSelectedHeader != null
                    && !getAccessibilityInitialFocusView().isAccessibilityFocused()) {
                post(() -> {
                    mRightPaneScrollView.setAccessibilityPaneTitle(suggestionsRightPaneTitle);
                    mRightPaneScrollView.performAccessibilityAction(
                            AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
                });
            }
            if (isChangingHeaders)  {
                // If switching from another header, unselect any WidgetCells. This is necessary
                // because we do not clear/recycle the WidgetCells in the recommendations container
@@ -296,7 +307,6 @@ public class WidgetsTwoPaneSheet extends WidgetsFullSheet {
            mSelectedHeader = mSuggestedWidgetsPackageUserKey;
        });
        mSuggestedWidgetsContainer.addView(mSuggestedWidgetsHeader);
        mRightPane.setAccessibilityPaneTitle(suggestionsRightPaneTitle);
    }

    @Override
@@ -323,12 +333,14 @@ public class WidgetsTwoPaneSheet extends WidgetsFullSheet {

        mActivePage = currentActivePage;

        if (mSuggestedWidgetsHeader == null) {
        // When using talkback, swiping left while on right pane, should navigate to the widgets
        // list on left.
        mAdapters.get(mActivePage).mWidgetsRecyclerView.setAccessibilityTraversalBefore(
                mRightPaneScrollView.getId());

        // On page change, select the first item in the list to show in the right pane.
        mAdapters.get(currentActivePage).mWidgetsListAdapter.selectFirstHeaderEntry();
        mAdapters.get(currentActivePage).mWidgetsRecyclerView.scrollToTop();
        } else if (currentActivePage == PERSONAL_TAB || currentActivePage == WORK_TAB) {
            mSuggestedWidgetsHeader.callOnClick();
        }
    }

    @Override
@@ -383,6 +395,10 @@ public class WidgetsTwoPaneSheet extends WidgetsFullSheet {
            public void onHeaderChanged(@NonNull PackageUserKey selectedHeader) {
                final boolean isSameHeader = mSelectedHeader != null
                        && mSelectedHeader.equals(selectedHeader);
                // If the initial focus view is still focused, it is likely a programmatic header
                // click.
                final boolean isUserClick = mSelectedHeader != null
                        && !getAccessibilityInitialFocusView().isAccessibilityFocused();
                mSelectedHeader = selectedHeader;
                WidgetsListContentEntry contentEntry = mActivityContext.getPopupDataProvider()
                        .getSelectedAppWidgets(selectedHeader);
@@ -427,11 +443,14 @@ public class WidgetsTwoPaneSheet extends WidgetsFullSheet {
                };
                mRightPane.removeAllViews();
                mRightPane.addView(widgetsRowViewHolder.itemView);
                mRightPaneScrollView.setScrollY(0);
                mRightPane.setAccessibilityPaneTitle(
                        getContext().getString(
                if (isUserClick) {
                    mRightPaneScrollView.setAccessibilityPaneTitle(getContext().getString(
                            R.string.widget_picker_right_pane_accessibility_title,
                            contentEntry.mPkgItem.title));
                    postDelayed(() -> focusOnFirstWidgetCell(widgetsRowViewHolder.tableContainer),
                            WIDGET_LIST_ITEM_APPEARANCE_DELAY);
                }
                mRightPaneScrollView.setScrollY(0);
            }
        };
    }
@@ -445,6 +464,18 @@ public class WidgetsTwoPaneSheet extends WidgetsFullSheet {
        }
    }

    /**
     * Requests focus on the first widget cell in the given widget section.
     */
    private static void focusOnFirstWidgetCell(ViewGroup parent) {
        if (parent == null) return;
        WidgetCell cell = Utilities.findViewByPredicate(parent, v -> v instanceof WidgetCell);
        if (cell != null) {
            cell.performAccessibilityAction(
                    AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
        }
    }

    private static void unselectWidgetCell(ViewGroup parent, WidgetItem item) {
        if (parent == null || item == null) return;
        WidgetCell cell = Utilities.findViewByPredicate(parent, v -> v instanceof WidgetCell wc