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

Commit 2a0210e8 authored by Harry Cutts's avatar Harry Cutts
Browse files

GestureConverter: add option to make 3-finger tap a shortcut

By default, it will remain as middle-click, but if the user chooses to
customize it we'll handle it like a special keyboard shortcut by sending
a JNI call up to InputManagerService.

Test: 3-finger tap with flag enabled, check log line appears
Test: 3-finger tap with flag disabled, check button events appear at
    https://w3c.github.io/uievents/tools/mouse-event-viewer.html
Test: atest inputflinger_test:GestureConverterTest
Test: m checkinput
Flag: com.android.hardware.input.touchpad_three_finger_tap_shortcut
Bug: 365063048
Change-Id: I771d46e1aafe9164dd32771cfdb55a3b259b5a0d
parent 114851e8
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -242,6 +242,9 @@ struct InputReaderConfiguration {
    // context (a.k.a. "right") clicks.
    // context (a.k.a. "right") clicks.
    bool touchpadRightClickZoneEnabled;
    bool touchpadRightClickZoneEnabled;


    // True to use three-finger tap as a customizable shortcut; false to use it as a middle-click.
    bool touchpadThreeFingerTapShortcutEnabled;

    // The set of currently disabled input devices.
    // The set of currently disabled input devices.
    std::set<int32_t> disabledDevices;
    std::set<int32_t> disabledDevices;


@@ -293,6 +296,7 @@ struct InputReaderConfiguration {
            touchpadTapDraggingEnabled(false),
            touchpadTapDraggingEnabled(false),
            shouldNotifyTouchpadHardwareState(false),
            shouldNotifyTouchpadHardwareState(false),
            touchpadRightClickZoneEnabled(false),
            touchpadRightClickZoneEnabled(false),
            touchpadThreeFingerTapShortcutEnabled(false),
            stylusButtonMotionEventsEnabled(true),
            stylusButtonMotionEventsEnabled(true),
            stylusPointerIconEnabled(false),
            stylusPointerIconEnabled(false),
            mouseReverseVerticalScrollingEnabled(false),
            mouseReverseVerticalScrollingEnabled(false),
@@ -496,6 +500,9 @@ public:
    /* Sends the Info of gestures that happen on the touchpad. */
    /* Sends the Info of gestures that happen on the touchpad. */
    virtual void notifyTouchpadGestureInfo(GestureType type, int32_t deviceId) = 0;
    virtual void notifyTouchpadGestureInfo(GestureType type, int32_t deviceId) = 0;


    /* Notifies the policy that the user has performed a three-finger touchpad tap. */
    virtual void notifyTouchpadThreeFingerTap() = 0;

    /* Gets the keyboard layout for a particular input device. */
    /* Gets the keyboard layout for a particular input device. */
    virtual std::shared_ptr<KeyCharacterMap> getKeyboardLayoutOverlay(
    virtual std::shared_ptr<KeyCharacterMap> getKeyboardLayoutOverlay(
            const InputDeviceIdentifier& identifier,
            const InputDeviceIdentifier& identifier,
+3 −0
Original line number Original line Diff line number Diff line
@@ -375,6 +375,9 @@ std::list<NotifyArgs> TouchpadInputMapper::reconfigure(nsecs_t when,
        mPropertyProvider.getProperty("Button Right Click Zone Enable")
        mPropertyProvider.getProperty("Button Right Click Zone Enable")
                .setBoolValues({config.touchpadRightClickZoneEnabled});
                .setBoolValues({config.touchpadRightClickZoneEnabled});
        mTouchpadHardwareStateNotificationsEnabled = config.shouldNotifyTouchpadHardwareState;
        mTouchpadHardwareStateNotificationsEnabled = config.shouldNotifyTouchpadHardwareState;

        mGestureConverter.setThreeFingerTapShortcutEnabled(
                config.touchpadThreeFingerTapShortcutEnabled);
    }
    }
    std::list<NotifyArgs> out;
    std::list<NotifyArgs> out;
    if ((!changes.any() && config.pointerCaptureRequest.isEnable()) ||
    if ((!changes.any() && config.pointerCaptureRequest.isEnable()) ||
+8 −1
Original line number Original line Diff line number Diff line
@@ -261,6 +261,14 @@ std::list<NotifyArgs> GestureConverter::handleButtonsChange(nsecs_t when, nsecs_
    }
    }


    const uint32_t buttonsPressed = gesture.details.buttons.down;
    const uint32_t buttonsPressed = gesture.details.buttons.down;
    const uint32_t buttonsReleased = gesture.details.buttons.up;

    if (mThreeFingerTapShortcutEnabled && gesture.details.buttons.is_tap &&
        buttonsPressed == GESTURES_BUTTON_MIDDLE && buttonsReleased == GESTURES_BUTTON_MIDDLE) {
        mReaderContext.getPolicy()->notifyTouchpadThreeFingerTap();
        return out;
    }

    bool pointerDown = isPointerDown(mButtonState) ||
    bool pointerDown = isPointerDown(mButtonState) ||
            buttonsPressed &
            buttonsPressed &
                    (GESTURES_BUTTON_LEFT | GESTURES_BUTTON_MIDDLE | GESTURES_BUTTON_RIGHT);
                    (GESTURES_BUTTON_LEFT | GESTURES_BUTTON_MIDDLE | GESTURES_BUTTON_RIGHT);
@@ -291,7 +299,6 @@ std::list<NotifyArgs> GestureConverter::handleButtonsChange(nsecs_t when, nsecs_
    // changes: a set of buttons going down, followed by a set of buttons going up.
    // changes: a set of buttons going down, followed by a set of buttons going up.
    mButtonState = newButtonState;
    mButtonState = newButtonState;


    const uint32_t buttonsReleased = gesture.details.buttons.up;
    for (uint32_t button = 1; button <= GESTURES_BUTTON_FORWARD; button <<= 1) {
    for (uint32_t button = 1; button <= GESTURES_BUTTON_FORWARD; button <<= 1) {
        if (buttonsReleased & button) {
        if (buttonsReleased & button) {
            uint32_t actionButton = gesturesButtonToMotionEventButton(button);
            uint32_t actionButton = gesturesButtonToMotionEventButton(button);
+6 −0
Original line number Original line Diff line number Diff line
@@ -55,6 +55,10 @@ public:


    void setBoundsInLogicalDisplay(FloatRect bounds) { mBoundsInLogicalDisplay = bounds; }
    void setBoundsInLogicalDisplay(FloatRect bounds) { mBoundsInLogicalDisplay = bounds; }


    void setThreeFingerTapShortcutEnabled(bool enabled) {
        mThreeFingerTapShortcutEnabled = enabled;
    }

    void populateMotionRanges(InputDeviceInfo& info) const;
    void populateMotionRanges(InputDeviceInfo& info) const;


    [[nodiscard]] std::list<NotifyArgs> handleGesture(nsecs_t when, nsecs_t readTime,
    [[nodiscard]] std::list<NotifyArgs> handleGesture(nsecs_t when, nsecs_t readTime,
@@ -101,6 +105,8 @@ private:
    const bool mEnableFlingStop;
    const bool mEnableFlingStop;
    const bool mEnableNoFocusChange;
    const bool mEnableNoFocusChange;


    bool mThreeFingerTapShortcutEnabled;

    std::optional<ui::LogicalDisplayId> mDisplayId;
    std::optional<ui::LogicalDisplayId> mDisplayId;
    FloatRect mBoundsInLogicalDisplay{};
    FloatRect mBoundsInLogicalDisplay{};
    ui::Rotation mOrientation = ui::ROTATION_0;
    ui::Rotation mOrientation = ui::ROTATION_0;
+17 −0
Original line number Original line Diff line number Diff line
@@ -80,6 +80,17 @@ void FakeInputReaderPolicy::assertTouchpadHardwareStateNotified() {
    ASSERT_TRUE(success) << "Timed out waiting for hardware state to be notified";
    ASSERT_TRUE(success) << "Timed out waiting for hardware state to be notified";
}
}


void FakeInputReaderPolicy::assertTouchpadThreeFingerTapNotified() {
    std::unique_lock lock(mLock);
    base::ScopedLockAssertion assumeLocked(mLock);

    const bool success =
            mTouchpadThreeFingerTapNotified.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
                return mTouchpadThreeFingerTapHasBeenReported;
            });
    ASSERT_TRUE(success) << "Timed out waiting for three-finger tap to be notified";
}

void FakeInputReaderPolicy::clearViewports() {
void FakeInputReaderPolicy::clearViewports() {
    mViewports.clear();
    mViewports.clear();
    mConfig.setDisplayViewports(mViewports);
    mConfig.setDisplayViewports(mViewports);
@@ -259,6 +270,12 @@ void FakeInputReaderPolicy::notifyTouchpadGestureInfo(GestureType type, int32_t
    std::scoped_lock lock(mLock);
    std::scoped_lock lock(mLock);
}
}


void FakeInputReaderPolicy::notifyTouchpadThreeFingerTap() {
    std::scoped_lock lock(mLock);
    mTouchpadThreeFingerTapHasBeenReported = true;
    mTouchpadThreeFingerTapNotified.notify_all();
}

std::shared_ptr<KeyCharacterMap> FakeInputReaderPolicy::getKeyboardLayoutOverlay(
std::shared_ptr<KeyCharacterMap> FakeInputReaderPolicy::getKeyboardLayoutOverlay(
        const InputDeviceIdentifier&, const std::optional<KeyboardLayoutInfo>) {
        const InputDeviceIdentifier&, const std::optional<KeyboardLayoutInfo>) {
    return nullptr;
    return nullptr;
Loading