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

Commit 9c19638c authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Support mouse right click on HomeScreen to show the customization menu" into tm-qpr-dev

parents f7590ed7 a6a67e34
Loading
Loading
Loading
Loading
+3 −12
Original line number Diff line number Diff line
@@ -17,11 +17,12 @@
package com.android.launcher3;

import android.os.Handler;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

import com.android.launcher3.util.TouchUtil;

/**
 * Utility class to handle tripper long press or right click on a view with custom timeout and
 * stylus event
@@ -64,7 +65,7 @@ public class CheckLongPressHelper {
                cancelLongPress();

                // Mouse right click should immediately trigger a long press
                if (isMouseRightClickDownOrMove(ev)) {
                if (TouchUtil.isMouseRightClickDownOrMove(ev)) {
                    mIsInMouseRightClick = true;
                    triggerLongPress();
                    final Handler handler = mView.getHandler();
@@ -176,14 +177,4 @@ public class CheckLongPressHelper {
        return event.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS
                && event.isButtonPressed(MotionEvent.BUTTON_SECONDARY);
    }

    /**
     * Detect ACTION_DOWN or ACTION_MOVE from mouse right button. Note that we cannot detect
     * ACTION_UP from mouse's right button because, in that case,
     * {@link MotionEvent#getButtonState()} returns 0 for any mouse button (right, middle, right).
     */
    private static boolean isMouseRightClickDownOrMove(MotionEvent event) {
        return event.isFromSource(InputDevice.SOURCE_MOUSE)
                && ((event.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0);
    }
}
+10 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.TouchUtil;

/**
 * Helper class to handle touch on empty space in workspace and show options popup on long press
@@ -105,6 +106,11 @@ public class WorkspaceTouchListener extends GestureDetector.SimpleOnGestureListe
            if (handleLongPress) {
                mLongPressState = STATE_REQUESTED;
                mTouchDownPoint.set(ev.getX(), ev.getY());
                // Mouse right button's ACTION_DOWN should immediately show menu
                if (TouchUtil.isMouseRightClickDownOrMove(ev)) {
                    maybeShowMenu();
                    return true;
                }
            }

            mWorkspace.onTouchEvent(ev);
@@ -185,6 +191,10 @@ public class WorkspaceTouchListener extends GestureDetector.SimpleOnGestureListe

    @Override
    public void onLongPress(MotionEvent event) {
        maybeShowMenu();
    }

    private void maybeShowMenu() {
        if (mLongPressState == STATE_REQUESTED) {
            TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "Workspace.longPress");
            if (canHandleLongPress()) {
+37 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.launcher3.util;

import android.view.InputDevice;
import android.view.MotionEvent;

import androidx.annotation.NonNull;

/** Util class for touch event. */
public final class TouchUtil {

    private TouchUtil() {}

    /**
     * Detect ACTION_DOWN or ACTION_MOVE from mouse right button. Note that we cannot detect
     * ACTION_UP from mouse's right button because, in that case,
     * {@link MotionEvent#getButtonState()} returns 0 for any mouse button (right, middle, right).
     */
    public static boolean isMouseRightClickDownOrMove(@NonNull MotionEvent event) {
        return event.isFromSource(InputDevice.SOURCE_MOUSE)
                && ((event.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0);
    }
}
+67 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.launcher3.util

import android.view.InputDevice
import android.view.MotionEvent
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith

/** Unit tests for [TouchUtil] */
@SmallTest
@RunWith(AndroidJUnit4::class)
class TouchUtilTest {

    @Test
    fun isMouseRightClickDownOrMove_onMouseRightButton_returnsTrue() {
        val ev = MotionEvent.obtain(200, 300, MotionEvent.ACTION_MOVE, 1.0f, 0.0f, 0)
        ev.source = InputDevice.SOURCE_MOUSE
        ev.buttonState = MotionEvent.BUTTON_SECONDARY

        assertThat(TouchUtil.isMouseRightClickDownOrMove(ev)).isTrue()
    }

    @Test
    fun isMouseRightClickDownOrMove_onMouseLeftButton_returnsFalse() {
        val ev = MotionEvent.obtain(200, 300, MotionEvent.ACTION_MOVE, 1.0f, 0.0f, 0)
        ev.source = InputDevice.SOURCE_MOUSE
        ev.buttonState = MotionEvent.BUTTON_PRIMARY

        assertThat(TouchUtil.isMouseRightClickDownOrMove(ev)).isFalse()
    }

    @Test
    fun isMouseRightClickDownOrMove_onMouseTertiaryButton_returnsFalse() {
        val ev = MotionEvent.obtain(200, 300, MotionEvent.ACTION_MOVE, 1.0f, 0.0f, 0)
        ev.source = InputDevice.SOURCE_MOUSE
        ev.buttonState = MotionEvent.BUTTON_TERTIARY

        assertThat(TouchUtil.isMouseRightClickDownOrMove(ev)).isFalse()
    }

    @Test
    fun isMouseRightClickDownOrMove_onDpadRightButton_returnsFalse() {
        val ev = MotionEvent.obtain(200, 300, MotionEvent.ACTION_MOVE, 1.0f, 0.0f, 0)
        ev.source = InputDevice.SOURCE_DPAD
        ev.buttonState = MotionEvent.BUTTON_SECONDARY

        assertThat(TouchUtil.isMouseRightClickDownOrMove(ev)).isFalse()
    }
}