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

Commit 634adaca authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Mouse: Add support to swap mouse primary button" into main

parents fbf5a5bd d77178e4
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -96,7 +96,8 @@ struct InputReaderConfiguration {
        // The key remapping has changed.
        KEY_REMAPPING = 1u << 14,

        // The mouse settings changed, this includes mouse reverse vertical scrolling.
        // The mouse settings changed, this includes mouse reverse vertical scrolling and swap
        // primary button.
        MOUSE_SETTINGS = 1u << 15,

        // All devices must be reopened.
@@ -259,6 +260,11 @@ struct InputReaderConfiguration {
    // wheel downwards scrolls the content upwards.
    bool mouseReverseVerticalScrollingEnabled;

    // True if the connected mouse should have its primary button (default: left click) swapped,
    // so that the right click will be the primary action button and the left click will be the
    // secondary action.
    bool mouseSwapPrimaryButtonEnabled;

    InputReaderConfiguration()
          : virtualKeyQuietTime(0),
            defaultPointerDisplayId(ui::LogicalDisplayId::DEFAULT),
@@ -290,7 +296,8 @@ struct InputReaderConfiguration {
            touchpadRightClickZoneEnabled(false),
            stylusButtonMotionEventsEnabled(true),
            stylusPointerIconEnabled(false),
            mouseReverseVerticalScrollingEnabled(false) {}
            mouseReverseVerticalScrollingEnabled(false),
            mouseSwapPrimaryButtonEnabled(false) {}

    std::optional<DisplayViewport> getDisplayViewportByType(ViewportType type) const;
    std::optional<DisplayViewport> getDisplayViewportByUniqueId(const std::string& uniqueDisplayId)
+1 −0
Original line number Diff line number Diff line
@@ -548,6 +548,7 @@ void CursorInputMapper::configureOnChangeDisplayInfo(const InputReaderConfigurat

void CursorInputMapper::configureOnChangeMouseSettings(const InputReaderConfiguration& config) {
    mMouseReverseVerticalScrolling = config.mouseReverseVerticalScrollingEnabled;
    mCursorButtonAccumulator.setSwapLeftRightButtons(config.mouseSwapPrimaryButtonEnabled);
}

} // namespace android
+8 −2
Original line number Diff line number Diff line
@@ -47,6 +47,10 @@ void CursorButtonAccumulator::clearButtons() {
    mBtnTask = 0;
}

void CursorButtonAccumulator::setSwapLeftRightButtons(bool shouldSwap) {
    mSwapLeftRightButtons = shouldSwap;
}

void CursorButtonAccumulator::process(const RawEvent& rawEvent) {
    if (rawEvent.type == EV_KEY) {
        switch (rawEvent.code) {
@@ -81,10 +85,12 @@ void CursorButtonAccumulator::process(const RawEvent& rawEvent) {
uint32_t CursorButtonAccumulator::getButtonState() const {
    uint32_t result = 0;
    if (mBtnLeft) {
        result |= AMOTION_EVENT_BUTTON_PRIMARY;
        result |= mSwapLeftRightButtons ? AMOTION_EVENT_BUTTON_SECONDARY
                                        : AMOTION_EVENT_BUTTON_PRIMARY;
    }
    if (mBtnRight) {
        result |= AMOTION_EVENT_BUTTON_SECONDARY;
        result |= mSwapLeftRightButtons ? AMOTION_EVENT_BUTTON_PRIMARY
                                        : AMOTION_EVENT_BUTTON_SECONDARY;
    }
    if (mBtnMiddle) {
        result |= AMOTION_EVENT_BUTTON_TERTIARY;
+4 −0
Original line number Diff line number Diff line
@@ -41,6 +41,8 @@ public:
    inline bool isExtraPressed() const { return mBtnExtra; }
    inline bool isTaskPressed() const { return mBtnTask; }

    void setSwapLeftRightButtons(bool shouldSwap);

private:
    bool mBtnLeft;
    bool mBtnRight;
@@ -51,6 +53,8 @@ private:
    bool mBtnExtra;
    bool mBtnTask;

    bool mSwapLeftRightButtons = false;

    void clearButtons();
};

+73 −1
Original line number Diff line number Diff line
@@ -205,9 +205,14 @@ TEST_F(CursorInputMapperUnitTest, HoverAndLeftButtonPress) {
    args.clear();
    args += process(EV_KEY, BTN_LEFT, 1);
    args += process(EV_SYN, SYN_REPORT, 0);

    ASSERT_THAT(args,
                ElementsAre(VariantWith<NotifyMotionArgs>(WithMotionAction(ACTION_DOWN)),
                            VariantWith<NotifyMotionArgs>(WithMotionAction(BUTTON_PRESS))));
                            VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(BUTTON_PRESS),
                                          WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY)))));
    ASSERT_THAT(args,
                Each(VariantWith<NotifyMotionArgs>(WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY))));

    // Move some more.
    args.clear();
@@ -220,10 +225,77 @@ TEST_F(CursorInputMapperUnitTest, HoverAndLeftButtonPress) {
    args.clear();
    args += process(EV_KEY, BTN_LEFT, 0);
    args += process(EV_SYN, SYN_REPORT, 0);
    ASSERT_THAT(args,
                ElementsAre(VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(BUTTON_RELEASE),
                                          WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY))),
                            VariantWith<NotifyMotionArgs>(WithMotionAction(ACTION_UP)),
                            VariantWith<NotifyMotionArgs>(WithMotionAction(HOVER_MOVE))));
}

/**
 * Test that enabling mouse swap primary button will have the left click result in a
 * `SECONDARY_BUTTON` event and a right click will result in a `PRIMARY_BUTTON` event.
 */
TEST_F(CursorInputMapperUnitTest, SwappedPrimaryButtonPress) {
    mReaderConfiguration.mouseSwapPrimaryButtonEnabled = true;
    createMapper();
    std::list<NotifyArgs> args;

    // Now click the left mouse button , expect a `SECONDARY_BUTTON` button state.
    args.clear();
    args += process(EV_KEY, BTN_LEFT, 1);
    args += process(EV_SYN, SYN_REPORT, 0);

    ASSERT_THAT(args,
                ElementsAre(VariantWith<NotifyMotionArgs>(WithMotionAction(ACTION_DOWN)),
                            VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(BUTTON_PRESS),
                                          WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY)))));
    ASSERT_THAT(args,
                Each(VariantWith<NotifyMotionArgs>(
                        WithButtonState(AMOTION_EVENT_BUTTON_SECONDARY))));

    // Release the left button.
    args.clear();
    args += process(EV_KEY, BTN_LEFT, 0);
    args += process(EV_SYN, SYN_REPORT, 0);

    ASSERT_THAT(args,
                ElementsAre(VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(BUTTON_RELEASE),
                                          WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY))),
                            VariantWith<NotifyMotionArgs>(WithMotionAction(ACTION_UP)),
                            VariantWith<NotifyMotionArgs>(WithMotionAction(HOVER_MOVE))));

    // Now click the right mouse button , expect a `PRIMARY_BUTTON` button state.
    args.clear();
    args += process(EV_KEY, BTN_RIGHT, 1);
    args += process(EV_SYN, SYN_REPORT, 0);

    ASSERT_THAT(args,
                ElementsAre(VariantWith<NotifyMotionArgs>(WithMotionAction(ACTION_DOWN)),
                            VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(BUTTON_PRESS),
                                          WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY)))));
    ASSERT_THAT(args,
                Each(VariantWith<NotifyMotionArgs>(WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY))));

    // Release the right button.
    args.clear();
    args += process(EV_KEY, BTN_RIGHT, 0);
    args += process(EV_SYN, SYN_REPORT, 0);
    ASSERT_THAT(args,
                ElementsAre(VariantWith<NotifyMotionArgs>(WithMotionAction(BUTTON_RELEASE)),
                            VariantWith<NotifyMotionArgs>(WithMotionAction(ACTION_UP)),
                            VariantWith<NotifyMotionArgs>(WithMotionAction(HOVER_MOVE))));

    ASSERT_THAT(args,
                ElementsAre(VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(BUTTON_RELEASE),
                                          WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY))),
                            VariantWith<NotifyMotionArgs>(WithMotionAction(ACTION_UP)),
                            VariantWith<NotifyMotionArgs>(WithMotionAction(HOVER_MOVE))));
}

/**