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

Commit 618a5044 authored by Tony Wickham's avatar Tony Wickham
Browse files

Allow quick scrub/switch from minus one

Launcher's window doesn't have focus when on minus one. In this case, we
tell the minus one overlay to hide and add a window focused callback to
start quick scrub/switch after launcher regains focus. Since the
transition from minus one takes longer than for launcher to get window
focus, we also defer until the overlay is completely hidden before
starting the quick scrub transition.

Bug: 70180755
Change-Id: Ifcf85aaf1942b51394e68e209b89807fa4007afe
parent aefd0621
Loading
Loading
Loading
Loading
+12 −5
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_POINTER_DOWN;
import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.ACTION_UP;

import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SCRUB;
import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SWITCH;

@@ -41,13 +40,15 @@ import android.view.Choreographer;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewTreeObserver;

import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherState;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.model.ModelPreload;
import com.android.launcher3.R;
import com.android.launcher3.Workspace;
import com.android.launcher3.model.ModelPreload;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.ISystemUiProxy;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -216,9 +217,6 @@ public class TouchInteractionService extends Service {
        }

        View target = launcher.getDragLayer();
        if (!target.getWindowId().isFocused()) {
            return mNoOpTouchConsumer;
        }
        return new LauncherTouchConsumer(launcher, target);
    }

@@ -244,6 +242,9 @@ public class TouchInteractionService extends Service {

        @Override
        public void accept(MotionEvent ev) {
            if (!mTarget.getWindowId().isFocused()) {
                return;
            }
            int action = ev.getActionMasked();
            if (action == ACTION_DOWN) {
                mTrackingStarted = false;
@@ -294,6 +295,12 @@ public class TouchInteractionService extends Service {
        public void updateTouchTracking(int interactionType) {
            mMainThreadExecutor.execute(() -> {
                if (TouchConsumer.isInteractionQuick(interactionType)) {
                    if (mLauncher.getWorkspace().runOnOverlayHidden(
                            () -> updateTouchTracking(interactionType))) {
                        // Hide the minus one overlay so launcher can get window focus.
                        mLauncher.onQuickstepGestureStarted(true);
                        return;
                    }
                    Runnable onComplete = null;
                    if (interactionType == INTERACTION_QUICK_SCRUB) {
                        mQuickScrubController.onQuickScrubStart(true);
+59 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.Toast;

import com.android.launcher3.Launcher.LauncherOverlay;
@@ -235,6 +236,7 @@ public class Workspace extends PagedView
    boolean mStartedSendingScrollEvents;
    float mLastOverlayScroll = 0;
    boolean mOverlayShown = false;
    private Runnable mOnOverlayHiddenCallback;

    private boolean mForceDrawAdjacentPages = false;
    private boolean mPageRearrangeEnabled = false;
@@ -1163,6 +1165,10 @@ public class Workspace extends PagedView
            if (mOverlayShown) {
                mLauncher.getUserEventDispatcher().logActionOnContainer(Action.Touch.SWIPE,
                        Action.Direction.RIGHT, ContainerType.WORKSPACE, -1);
                if (mOnOverlayHiddenCallback != null) {
                    mOnOverlayHiddenCallback.run();
                    mOnOverlayHiddenCallback = null;
                }
            }
            mOverlayShown = false;
        }
@@ -1188,6 +1194,59 @@ public class Workspace extends PagedView
        mLauncher.getDragLayer().setAlpha(alpha);
    }

    /**
     * Runs the given callback when the minus one overlay is hidden. Specifically, it is run
     * when launcher's window has focus and the overlay is no longer being shown. If a callback
     * is already present, the new callback will chain off it so both are run.
     *
     * @return Whether the callback was deferred.
     */
    public boolean runOnOverlayHidden(Runnable callback) {
        View rootView = getRootView();
        if (rootView.hasWindowFocus()) {
            if (mOverlayShown) {
                chainOverlayHiddenCallback(callback);
                return true;
            } else {
                callback.run();
                return false;
            }
        }
        ViewTreeObserver observer = rootView.getViewTreeObserver();
        if (observer != null && observer.isAlive()) {
            observer.addOnWindowFocusChangeListener(
                    new ViewTreeObserver.OnWindowFocusChangeListener() {
                        @Override
                        public void onWindowFocusChanged(boolean hasFocus) {
                            if (hasFocus) {
                                // Defer further if the minus one overlay is still showing.
                                if (mOverlayShown) {
                                    chainOverlayHiddenCallback(callback);
                                } else {
                                    callback.run();
                                }
                                observer.removeOnWindowFocusChangeListener(this);
                            }
                        }
                    });
            return true;
        }
        return false;
    }

    private void chainOverlayHiddenCallback(Runnable callback) {
        if (mOnOverlayHiddenCallback == null) {
            mOnOverlayHiddenCallback = callback;
        } else {
            // Chain the new callback onto the previous callback(s).
            Runnable oldCallback = mOnOverlayHiddenCallback;
            mOnOverlayHiddenCallback = () -> {
                oldCallback.run();
                callback.run();
            };
        }
    }

    @Override
    protected void notifyPageSwitchListener(int prevPage) {
        super.notifyPageSwitchListener(prevPage);