~ruther/qmk_firmware

7d692d64f3997b816607c282b09fecae14212fe6 — Pascal Getreuer 2 years ago 9908ed7
Fix Layer Mod handling of with right-handed mods. (#19845)


2 files changed, 64 insertions(+), 1 deletions(-)

M quantum/keymap_common.c
M tests/basic/test_action_layer.cpp
M quantum/keymap_common.c => quantum/keymap_common.c +1 -1
@@ 128,7 128,7 @@ action_t action_for_keycode(uint16_t keycode) {
        case QK_LAYER_MOD ... QK_LAYER_MOD_MAX:
            mod          = mod_config(QK_LAYER_MOD_GET_MODS(keycode));
            action_layer = QK_LAYER_MOD_GET_LAYER(keycode);
            action.code  = ACTION_LAYER_MODS(action_layer, mod);
            action.code  = ACTION_LAYER_MODS(action_layer, (mod & 0x10) ? mod << 4 : mod);
            break;
#endif
#ifndef NO_ACTION_TAPPING

M tests/basic/test_action_layer.cpp => tests/basic/test_action_layer.cpp +63 -0
@@ 19,6 19,7 @@
#include "test_common.hpp"

using testing::_;
using testing::AnyNumber;
using testing::InSequence;

class ActionLayer : public TestFixture {};


@@ 399,3 400,65 @@ TEST_F(ActionLayer, LayerTapReleasedBeforeKeypressReleaseWithModifiers) {
    EXPECT_TRUE(layer_state_is(0));
    VERIFY_AND_CLEAR(driver);
}

TEST_F(ActionLayer, LayerModWithKeypress) {
    TestDriver driver;
    KeymapKey  layer_key   = KeymapKey{0, 0, 0, LM(1, MOD_RALT)};
    KeymapKey  regular_key = KeymapKey{0, 1, 0, KC_A};
    set_keymap({layer_key, regular_key, KeymapKey{1, 1, 0, KC_B}});

    // Allow any number of reports with no keys or only KC_RALT.
    // clang-format off
    EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
                KeyboardReport(),
                KeyboardReport(KC_RALT))))
        .Times(AnyNumber());
    // clang-format on
    EXPECT_REPORT(driver, (KC_RALT, KC_B)).Times(1);

    layer_key.press();
    run_one_scan_loop();
    EXPECT_TRUE(layer_state_is(1));
    EXPECT_EQ(get_mods(), MOD_BIT(KC_RALT));

    tap_key(regular_key);

    layer_key.release();
    run_one_scan_loop();
    EXPECT_TRUE(layer_state_is(0));
    EXPECT_EQ(get_mods(), 0);

    VERIFY_AND_CLEAR(driver);
}

TEST_F(ActionLayer, LayerModHonorsModConfig) {
    TestDriver driver;
    KeymapKey  layer_key   = KeymapKey{0, 0, 0, LM(1, MOD_RALT)};
    KeymapKey  regular_key = KeymapKey{0, 1, 0, KC_A};
    set_keymap({layer_key, regular_key, KeymapKey{1, 1, 0, KC_B}});

    // Allow any number of reports with no keys or only KC_RALT.
    // clang-format off
    EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
                KeyboardReport(),
                KeyboardReport(KC_RGUI))))
        .Times(AnyNumber());
    // clang-format on
    EXPECT_REPORT(driver, (KC_RGUI, KC_B)).Times(1);

    keymap_config.swap_ralt_rgui = true;

    layer_key.press();
    run_one_scan_loop();
    EXPECT_TRUE(layer_state_is(1));
    EXPECT_EQ(get_mods(), MOD_BIT(KC_RGUI));

    tap_key(regular_key);

    layer_key.release();
    run_one_scan_loop();
    EXPECT_TRUE(layer_state_is(0));
    EXPECT_EQ(get_mods(), 0);

    VERIFY_AND_CLEAR(driver);
}