Skip to content

The latency of the LT implement #2

@Hzqi

Description

@Hzqi

I have found the th40 LT implement will wired, like LT need to hold for a long can switch layer, reduce the TAPPING_TEMP will not work.
Actually LT rule may follow belows:

LT down → Other key press → LT hold                       : Switch to Layer & keep it active
LT down → Other key press → LT up                         : Switch to Layer & send that key from the Layer
LT down → Released within 200ms (tapping term)           : Send assigned key (KC_SPC)

for faster i may add these two rules:

LT down → Released within 200ms → Another key within 50ms  : Switch to Layer, send key, then revert layer
LT down → Released within 200ms → Another key after 50ms  : Stay in current layer & send that key

So I implement this function ,

// Define Layer Tap keys manually
#define LT1_SPACE LT(_LAYER1, KC_SPC)
#define LT2_SPACE LT(_LAYER2, KC_SPC)

// Define layers
enum layers {
    _BASE,
    _LAYER1,
    _LAYER2,
    _LAYER3
};

// Timers and state tracking
static uint16_t lt1_press_timer = 0;
static uint16_t lt1_release_timer = 0;
static bool lt1_pressed = false;
static bool lt1_released = false;
static bool lt1_other_key_pressed = false;
static bool lt1_should_revert_layer = false;

static uint16_t lt2_press_timer = 0;
static uint16_t lt2_release_timer = 0;
static bool lt2_pressed = false;
static bool lt2_released = false;
static bool lt2_other_key_pressed = false;
static bool lt2_should_revert_layer = false;

bool custom_process_record_user(uint16_t keycode, keyrecord_t *record) {
    switch (keycode) {
        case LT1_SPACE:
        case LT2_SPACE:
            if (record->event.pressed) {  // LT Key Down
                if (keycode == LT1_SPACE) {
                    lt1_pressed = true;
                    lt1_released = false;
                    lt1_other_key_pressed = false;
                    lt1_should_revert_layer = false;
                    lt1_press_timer = timer_read();
                } else if (keycode == LT2_SPACE) {
                    lt2_pressed = true;
                    lt2_released = false;
                    lt2_other_key_pressed = false;
                    lt2_should_revert_layer = false;
                    lt2_press_timer = timer_read();
                }
            } else {  // LT Key Up
                if (keycode == LT1_SPACE) {
                    lt1_pressed = false;
                    lt1_released = true;
                    lt1_release_timer = timer_read();

                    uint16_t press_duration = timer_elapsed(lt1_press_timer);
                    if (!lt1_other_key_pressed && press_duration < 200) {
                        tap_code(KC_SPC);
                        return false;
                    }
                } else if (keycode == LT2_SPACE) {
                    lt2_pressed = false;
                    lt2_released = true;
                    lt2_release_timer = timer_read();

                    uint16_t press_duration = timer_elapsed(lt2_press_timer);
                    if (!lt2_other_key_pressed && press_duration < 200) {
                        tap_code(KC_SPC);
                        return false;
                    }
                }
            }
            return false;  // Prevent default behavior

        default:
            if (lt1_pressed) {  // If another key is pressed while LT1 is held
                if (timer_elapsed(lt1_press_timer) < 200) {
                    layer_on(_LAYER1);
                    lt1_other_key_pressed = true;
                }
            } else if (lt1_released) {
                uint16_t release_elapsed = timer_elapsed(lt1_release_timer);

                if (release_elapsed < 50) {  // If another key is pressed within 50ms of LT release
                    layer_on(_LAYER1);
                    lt1_should_revert_layer = true;
                } else {  // If another key is pressed after 50ms
                    layer_off(_LAYER1);
                }
                lt1_released = false;
            }

            if (lt2_pressed) {  // If another key is pressed while LT2 is held
                if (timer_elapsed(lt2_press_timer) < 200) {
                    layer_on(_LAYER2);
                    lt2_other_key_pressed = true;
                }
            } else if (lt2_released) {
                uint16_t release_elapsed = timer_elapsed(lt2_release_timer);

                if (release_elapsed < 50) {  // If another key is pressed within 50ms of LT release
                    layer_on(_LAYER2);
                    lt2_should_revert_layer = true;
                } else {  // If another key is pressed after 50ms
                    layer_off(_LAYER2);
                }
                lt2_released = false;
            }
            break;
    }

    // If a key was pressed within 50ms of LT release, revert the layer
    if (lt1_should_revert_layer) {
        layer_off(_LAYER1);
        lt1_should_revert_layer = false;
    }
    if (lt2_should_revert_layer) {
        layer_off(_LAYER2);
        lt2_should_revert_layer = false;
    }

    return true;  // Process other keys normally
}

But this may have some bug that i havent found.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions