~aleteoryx/muditaos

992b0ea2c3c64f6b1a15b891513e67ff2a294b5a — Wojtek Rzepecki 4 years ago bf85137
[EGD-3171] Fix key shortRelease on app switch

Fix of shortRelease on app switch while long
press applied on previous window
M module-apps/apps-common/Application.cpp => module-apps/apps-common/Application.cpp +6 -9
@@ 115,7 115,7 @@ namespace app

        longPressTimer = sys::TimerFactory::createPeriodicTimer(this,
                                                                "LongPress",
                                                                std::chrono::milliseconds{key_timer_ms},
                                                                std::chrono::milliseconds{keyTimerMs},
                                                                [this](sys::Timer &) { longPressTimerCallback(); });

        connect(typeid(AppRefreshMessage),


@@ 174,21 174,18 @@ namespace app

    void Application::longPressTimerCallback()
    {
        // TODO if(check widget type long press trigger)
        uint32_t time = xTaskGetTickCount();
        if (keyTranslator->timeout(time)) {
            // previous key press was over standard keypress timeout - send long press
            gui::InputEvent iev = keyTranslator->translate(time);
        const auto actualTimeStamp = xTaskGetTickCount();
        if (keyTranslator->isKeyPressTimedOut(actualTimeStamp)) {
            gui::InputEvent iev = keyTranslator->translate(actualTimeStamp);
            messageInputEventApplication(this, this->GetName(), iev);
            // clean previous key
            keyTranslator->prev_key_press = {};
            keyTranslator->resetPreviousKeyPress();
            longPressTimer.stop();
        }
    }

    void Application::clearLongPressTimeout()
    {
        keyTranslator->prev_key_timedout = false;
        keyTranslator->setPreviousKeyTimedOut(false);
    }

    void Application::render(gui::RefreshModes mode)

M module-apps/apps-common/messages/AppMessage.hpp => module-apps/apps-common/messages/AppMessage.hpp +2 -2
@@ 210,8 210,8 @@ namespace app
            std::stringstream ss;
            ss << "{ ";
            ss << "state:   " << c_str(event.getState()) << ", ";
            ss << "RawKey:  " << c_str(rawKey.key_code) << "}";
            ss << "t0: " << rawKey.time_press << ", t1: " << rawKey.time_release;
            ss << "RawKey:  " << c_str(rawKey.keyCode) << "}";
            ss << "t0: " << rawKey.timePress << ", t1: " << rawKey.timeRelease;
            ss << " }";
            return ss.str().c_str();
        }

M module-gui/gui/input/InputEvent.hpp => module-gui/gui/input/InputEvent.hpp +7 -4
@@ 84,10 84,11 @@ namespace gui
      public:
        enum class State
        {
            Undefined        = 0x00,
            keyPressed       = 0x01,
            keyReleasedShort = 0x02,
            keyReleasedLong  = 0x04,
            Undefined        = 0x00, /// No action defined or translation error
            keyPressed       = 0x01, /// Key pressed event
            keyReleasedShort = 0x02, /// Key released before timeout
            keyReleasedLong  = 0x04, /// Key released after timeout
            keyMoved         = 0x05, /// Monostable key event
        };

        InputEvent(RawKey key, State state = State::Undefined, KeyCode keyCode = KeyCode::KEY_UNDEFINED);


@@ 192,6 193,8 @@ namespace gui
        return "keyReleasedShort";
    case gui::InputEvent::State::keyReleasedLong:
        return "keyReleasedLong ";
    case gui::InputEvent::State::keyMoved:
        return "keyMoved";
    }
    return "";
}

M module-gui/gui/input/Translator.cpp => module-gui/gui/input/Translator.cpp +53 -34
@@ 16,49 16,68 @@ namespace gui
        constexpr auto special = "special";
    } // namespace filetype

    void recon_long_press(InputEvent &evt, const RawKey &key, const RawKey &prev_key_press, uint32_t time)
    {
        if (key.state == RawKey::State::Released && prev_key_press.key_code == key.key_code) {
            // determine long press
            if (key.time_release - prev_key_press.time_press >= key_time_longpress_ms) {
                evt.setState(InputEvent::State::keyReleasedLong);
            }
        }
    }

    InputEvent KeyBaseTranslation::set(RawKey key)
    {
        gui::InputEvent evt(key);
        if (key.state == RawKey::State::Pressed) {
        switch (key.state) {
        case RawKey::State::Pressed:
            evt.setState(InputEvent::State::keyPressed);
            break;
        case RawKey::State::Released:
            translateRelease(evt, key);
            break;
        case RawKey::State::Moved:
            evt.setState(InputEvent::State::keyMoved);
            break;
        case RawKey::State::Undefined:
            evt.setState(InputEvent::State::Undefined);
            break;
        }
        else if (key.state == RawKey::State::Released) {
            evt.setState(InputEvent::State::keyReleasedShort);
        }
        recon_long_press(evt, key, prev_key_press, key_time_longpress_ms);
        // store last key press/release
        if (key.state == RawKey::State::Pressed) {
            prev_key_press = key;
            previousKeyPress = key;
        }
        if (key.state != RawKey::State::Released) {
            prev_key_released = false;
        isPreviousKeyPressed = (key.state == RawKey::State::Pressed);

        return evt;
    }

    void KeyBaseTranslation::translateRelease(InputEvent &evt, const RawKey &key)
    {
        if (!isPreviousKeyPressed) {
            // Release can only happen after Press
            evt.setState(InputEvent::State::Undefined);
            return;
        }
        if ((previousKeyPress.keyCode == key.keyCode) &&
            (key.timeRelease - previousKeyPress.timePress >= keyTimeLongpressMs)) {
            evt.setState(InputEvent::State::keyReleasedLong);
        }
        else {
            prev_key_released = true;
            evt.setState(InputEvent::State::keyReleasedShort);
        }
        return evt;
    }

    bool KeyBaseTranslation::timeout(uint32_t time)
    bool KeyBaseTranslation::isKeyPressTimedOut(uint32_t actualTimeStamp)
    {
        if (!prev_key_released && (prev_key_press.time_press != 0) &&
            (time - prev_key_press.time_press >= key_time_longpress_ms)) {
            prev_key_timedout = true;
        if (isPreviousKeyPressed && (previousKeyPress.timePress != 0) &&
            (actualTimeStamp - previousKeyPress.timePress >= keyTimeLongpressMs)) {
            isPreviousKeyTimedOut = true;
            return true;
        }
        return false;
    }

    void KeyBaseTranslation::resetPreviousKeyPress()
    {
        previousKeyPress = {};
    }

    void KeyBaseTranslation::setPreviousKeyTimedOut(bool status)
    {
        isPreviousKeyTimedOut = status;
    }

    gui::KeyCode getKeyCode(bsp::KeyCodes code)
    {
        switch (code) {


@@ 141,6 160,7 @@ namespace gui
            return gui::KeyCode::HEADSET_OK;

        case bsp::KeyCodes::HeadsetVolUp:
            void resetPreviousKeyPress();
            return gui::KeyCode::HEADSET_VOLUP;

        case bsp::KeyCodes::HeadsetVolDown:


@@ 156,29 176,28 @@ namespace gui
    {
        auto evt = KeyBaseTranslation::set(key);
        // when last action timed out we don't want to handle key release
        if (prev_key_timedout && key.state == RawKey::State::Released) {
        if (isPreviousKeyTimedOut && key.state == RawKey::State::Released) {
            evt.setState(InputEvent::State::Undefined);
            prev_key_timedout = false;
            isPreviousKeyTimedOut = false;
        }
        evt.setKeyCode(getKeyCode(key.key_code));
        evt.setKeyCode(getKeyCode(key.keyCode));
        return evt;
    }

    InputEvent KeyInputSimpleTranslation::translate(uint32_t timeout)
    {
        RawKey key{RawKey::State::Released, prev_key_press.key_code, 0, timeout};
        return InputEvent{key, InputEvent::State::keyReleasedLong, getKeyCode(key.key_code)};
        RawKey key{RawKey::State::Released, previousKeyPress.keyCode, 0, timeout};
        return InputEvent{key, InputEvent::State::keyReleasedLong, getKeyCode(key.keyCode)};
    }

    uint32_t KeyInputMappedTranslation::handle(RawKey key, const std::string &keymap)
    {
        // get shortpress
        if (prev_key_press.key_code != key.key_code) {
        if (previousKeyPress.keyCode != key.keyCode) {
            times = 0;
        }
        else if (key.state == RawKey::State::Released) {
            /// TODO use key_time_cycle_ms from keymap (if exists in keymap...)
            if (key.time_release - prev_key_press.time_release < key_time_cycle_ms) {
            if (key.timeRelease - previousKeyPress.timeRelease < keyTimeCycleMs) {
                ++times;
            }
            else {


@@ 186,9 205,9 @@ namespace gui
            }
        }
        if (key.state == RawKey::State::Released) {
            prev_key_press = key;
            previousKeyPress = key;
        }
        return profiles.get(keymap).getCharKey(key.key_code, times);
        return profiles.get(keymap).getCharKey(key.keyCode, times);
    }

    uint32_t KeyInputMappedTranslation::getTimes() const noexcept

M module-gui/gui/input/Translator.hpp => module-gui/gui/input/Translator.hpp +18 -23
@@ 1,46 1,41 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "InputEvent.hpp"
#include "Profile.hpp"
#include "bsp/keyboard/key_codes.hpp"
#include <bsp/keyboard/key_codes.hpp>
#include <common_data/RawKey.hpp>
#include <cstdint>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include <common_data/RawKey.hpp>

namespace gui
{

    // TODO if neccessary `custom` keymap can be added her
    enum class Keymaps
    {
        ABC,
        abc,
        digit,
    };

    class KeyBaseTranslation
    {
      public:
        // previous pressed key (only for pressed keys), used for shortpress and longpress
        RawKey prev_key_press = {};
        // was previous key released? used for longpress only
        bool prev_key_released = true;
        // did previous key already timed out (and send longpress as a result)
        bool prev_key_timedout = false;
        /// RawKey to Input Event translation
        InputEvent set(RawKey key);
        /// timeout keypress (only press) - returns true on timeout'ed keypress
        bool timeout(uint32_t time);
        /// Check if keyPress is timed out for particular timestamp
        bool isKeyPressTimedOut(uint32_t actualTimeStamp);
        /// Reset previous key press status
        void resetPreviousKeyPress();
        /// Set previous key press timeout status
        void setPreviousKeyTimedOut(bool status);

      protected:
        RawKey previousKeyPress    = {};
        bool isPreviousKeyPressed  = false;
        bool isPreviousKeyTimedOut = false;

      private:
        void translateRelease(InputEvent &evt, const RawKey &key);
    };

    /// KeyPress translator
    /// simplest 1:1 keys handling, used when application needs simplest key parsing possible
    /// no keys behaviour analysis done here - just mapping
    class KeyInputSimpleTranslation : public KeyBaseTranslation
    {
      public:

M module-gui/test/test-catch-text/test-gui-Text.cpp => module-gui/test/test-catch-text/test-gui-Text.cpp +2 -2
@@ 204,10 204,10 @@ TEST_CASE("handle input mode ABC/abc/1234")
        auto time_long_enough_to_not_be_multipress = 1000;
        text.onInput(next_mode);
        auto rawKey_2 = key_2.getRawKey();
        rawKey_2.time_release += time_long_enough_to_not_be_multipress;
        rawKey_2.timeRelease += time_long_enough_to_not_be_multipress;
        REQUIRE(text.getInputMode()->is(InputMode::abc));
        text.onInput(gui::InputEvent{rawKey_2, key_2.getState()});
        rawKey_2.time_release += time_long_enough_to_not_be_multipress;
        rawKey_2.timeRelease += time_long_enough_to_not_be_multipress;
        str += "a";
        REQUIRE(str == text.getText());


M module-gui/test/test-catch/CMakeLists.txt => module-gui/test/test-catch/CMakeLists.txt +1 -0
@@ 11,6 11,7 @@ add_catch2_executable(
                ../mock/TestWindow.cpp
                ../mock/InitializedFontManager.cpp
        test-language-input-parser.cpp
        test-key-translator.cpp
        INCLUDE
                ..
        LIBS

A module-gui/test/test-catch/test-key-translator.cpp => module-gui/test/test-catch/test-key-translator.cpp +80 -0
@@ 0,0 1,80 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <catch2/catch.hpp>
#include <Translator.hpp>

TEST_CASE("Regular key press and release")
{
    gui::KeyBaseTranslation translator;
    RawKey key;

    key.state  = RawKey::State::Pressed;
    auto event = translator.set(key);
    REQUIRE(event.getState() == gui::InputEvent::State::keyPressed);

    key.state = RawKey::State::Released;
    event     = translator.set(key);
    REQUIRE(event.getState() == gui::InputEvent::State::keyReleasedShort);
}

TEST_CASE("Key release before first key press")
{
    gui::KeyBaseTranslation translator;
    RawKey key;

    key.state  = RawKey::State::Released;
    auto event = translator.set(key);
    REQUIRE(event.getState() == gui::InputEvent::State::Undefined);
}

TEST_CASE("Key long release")
{
    gui::KeyBaseTranslation translator;
    RawKey key;
    constexpr auto timeToLongRelease = 1001;

    key.state     = RawKey::State::Pressed;
    key.timePress = 0;
    auto event    = translator.set(key);
    REQUIRE(event.getState() == gui::InputEvent::State::keyPressed);

    key.state       = RawKey::State::Released;
    key.timeRelease = timeToLongRelease;
    event           = translator.set(key);
    REQUIRE(event.getState() == gui::InputEvent::State::keyReleasedLong);
}

TEST_CASE("Key Moved")
{
    gui::KeyBaseTranslation translator;
    RawKey key;

    key.state  = RawKey::State::Moved;
    auto event = translator.set(key);
    REQUIRE(event.getState() == gui::InputEvent::State::keyMoved);
}

TEST_CASE("Key Undefined")
{
    gui::KeyBaseTranslation translator;
    RawKey key;

    auto event = translator.set(key);
    REQUIRE(event.getState() == gui::InputEvent::State::Undefined);
}

TEST_CASE("External long press timeout check")
{
    gui::KeyBaseTranslation translator;
    RawKey key;
    constexpr auto timeBeforeLongRelease = 500;
    constexpr auto timeToLongRelease     = 1001;

    key.state     = RawKey::State::Pressed;
    key.timePress = 1;
    translator.set(key);

    REQUIRE(!translator.isKeyPressTimedOut(timeBeforeLongRelease));
    REQUIRE(translator.isKeyPressTimedOut(timeToLongRelease));
}

M module-gui/test/test-catch/test-language-input-parser.cpp => module-gui/test/test-catch/test-language-input-parser.cpp +31 -33
@@ 12,49 12,49 @@ TEST_CASE("Parsing English input language")

    SECTION("Getting charKey from lower letters")
    {
        key.key_code = bsp::KeyCodes::NumericKey1;
        key.keyCode = bsp::KeyCodes::NumericKey1;
        REQUIRE(translator.handle(key, "English_lower") == 46);
        key.key_code = bsp::KeyCodes::NumericKey2;
        key.keyCode = bsp::KeyCodes::NumericKey2;
        REQUIRE(translator.handle(key, "English_lower") == 97);
        key.key_code = bsp::KeyCodes::NumericKey3;
        key.keyCode = bsp::KeyCodes::NumericKey3;
        REQUIRE(translator.handle(key, "English_lower") == 100);
        key.key_code = bsp::KeyCodes::NumericKey4;
        key.keyCode = bsp::KeyCodes::NumericKey4;
        REQUIRE(translator.handle(key, "English_lower") == 103);
        key.key_code = bsp::KeyCodes::NumericKey5;
        key.keyCode = bsp::KeyCodes::NumericKey5;
        REQUIRE(translator.handle(key, "English_lower") == 106);
        key.key_code = bsp::KeyCodes::NumericKey6;
        key.keyCode = bsp::KeyCodes::NumericKey6;
        REQUIRE(translator.handle(key, "English_lower") == 109);
        key.key_code = bsp::KeyCodes::NumericKey7;
        key.keyCode = bsp::KeyCodes::NumericKey7;
        REQUIRE(translator.handle(key, "English_lower") == 112);
        key.key_code = bsp::KeyCodes::NumericKey8;
        key.keyCode = bsp::KeyCodes::NumericKey8;
        REQUIRE(translator.handle(key, "English_lower") == 116);
        key.key_code = bsp::KeyCodes::NumericKey9;
        key.keyCode = bsp::KeyCodes::NumericKey9;
        REQUIRE(translator.handle(key, "English_lower") == 119);
        key.key_code = bsp::KeyCodes::NumericKey0;
        key.keyCode = bsp::KeyCodes::NumericKey0;
        REQUIRE(translator.handle(key, "English_lower") == 32);
    }

    SECTION("Getting charKey from upper letters")
    {
        key.key_code = bsp::KeyCodes::NumericKey1;
        key.keyCode = bsp::KeyCodes::NumericKey1;
        REQUIRE(translator.handle(key, "English_upper") == 46);
        key.key_code = bsp::KeyCodes::NumericKey2;
        key.keyCode = bsp::KeyCodes::NumericKey2;
        REQUIRE(translator.handle(key, "English_upper") == 65);
        key.key_code = bsp::KeyCodes::NumericKey3;
        key.keyCode = bsp::KeyCodes::NumericKey3;
        REQUIRE(translator.handle(key, "English_upper") == 68);
        key.key_code = bsp::KeyCodes::NumericKey4;
        key.keyCode = bsp::KeyCodes::NumericKey4;
        REQUIRE(translator.handle(key, "English_upper") == 71);
        key.key_code = bsp::KeyCodes::NumericKey5;
        key.keyCode = bsp::KeyCodes::NumericKey5;
        REQUIRE(translator.handle(key, "English_upper") == 74);
        key.key_code = bsp::KeyCodes::NumericKey6;
        key.keyCode = bsp::KeyCodes::NumericKey6;
        REQUIRE(translator.handle(key, "English_upper") == 77);
        key.key_code = bsp::KeyCodes::NumericKey7;
        key.keyCode = bsp::KeyCodes::NumericKey7;
        REQUIRE(translator.handle(key, "English_upper") == 80);
        key.key_code = bsp::KeyCodes::NumericKey8;
        key.keyCode = bsp::KeyCodes::NumericKey8;
        REQUIRE(translator.handle(key, "English_upper") == 84);
        key.key_code = bsp::KeyCodes::NumericKey9;
        key.keyCode = bsp::KeyCodes::NumericKey9;
        REQUIRE(translator.handle(key, "English_upper") == 87);
        key.key_code = bsp::KeyCodes::NumericKey0;
        key.keyCode = bsp::KeyCodes::NumericKey0;
        REQUIRE(translator.handle(key, "English_upper") == 32);
    }
}


@@ 64,37 64,35 @@ TEST_CASE("Parsing numeric keyboard")
    gui::KeyInputMappedTranslation translator;
    RawKey key;

    key.key_code = bsp::KeyCodes::NumericKey1;
    key.keyCode = bsp::KeyCodes::NumericKey1;
    REQUIRE(translator.handle(key, "numeric") == 49);
    key.key_code = bsp::KeyCodes::NumericKey2;
    key.keyCode = bsp::KeyCodes::NumericKey2;
    REQUIRE(translator.handle(key, "numeric") == 50);
    key.key_code = bsp::KeyCodes::NumericKey3;
    key.keyCode = bsp::KeyCodes::NumericKey3;
    REQUIRE(translator.handle(key, "numeric") == 51);
    key.key_code = bsp::KeyCodes::NumericKey4;
    key.keyCode = bsp::KeyCodes::NumericKey4;
    REQUIRE(translator.handle(key, "numeric") == 52);
    key.key_code = bsp::KeyCodes::NumericKey5;
    key.keyCode = bsp::KeyCodes::NumericKey5;
    REQUIRE(translator.handle(key, "numeric") == 53);
    key.key_code = bsp::KeyCodes::NumericKey6;
    key.keyCode = bsp::KeyCodes::NumericKey6;
    REQUIRE(translator.handle(key, "numeric") == 54);
    key.key_code = bsp::KeyCodes::NumericKey7;
    key.keyCode = bsp::KeyCodes::NumericKey7;
    REQUIRE(translator.handle(key, "numeric") == 55);
    key.key_code = bsp::KeyCodes::NumericKey8;
    key.keyCode = bsp::KeyCodes::NumericKey8;
    REQUIRE(translator.handle(key, "numeric") == 56);
    key.key_code = bsp::KeyCodes::NumericKey9;
    key.keyCode = bsp::KeyCodes::NumericKey9;
    REQUIRE(translator.handle(key, "numeric") == 57);
    key.key_code = bsp::KeyCodes::NumericKey0;
    key.keyCode = bsp::KeyCodes::NumericKey0;
    REQUIRE(translator.handle(key, "numeric") == 48);
}

TEST_CASE("Getting charKey after clicking button twice")
{
    gui::KeyInputMappedTranslation translator;
    gui::KeyBaseTranslation baseTranslation;
    RawKey key;

    key.key_code                   = bsp::KeyCodes::NumericKey2;
    key.keyCode                    = bsp::KeyCodes::NumericKey2;
    key.state                      = RawKey::State::Released;
    baseTranslation.prev_key_press = key;
    translator.handle(key, "English_lower");
    REQUIRE(translator.handle(key, "English_lower") == 98);
}

M module-services/service-desktop/endpoints/developerMode/DeveloperModeHelper.cpp => module-services/service-desktop/endpoints/developerMode/DeveloperModeHelper.cpp +1 -1
@@ 249,7 249,7 @@ auto DeveloperModeHelper::getKeyCode(int val) noexcept -> bsp::KeyCodes

bool DeveloperModeHelper::sendKeypress(bsp::KeyCodes keyCode, gui::InputEvent::State state)
{
    RawKey key{.state = RawKey::State::Released, .key_code = keyCode};
    RawKey key{.state = RawKey::State::Released, .keyCode = keyCode};

    gui::InputEvent event(key, state, static_cast<gui::KeyCode>(keyCode));
    auto message = std::make_shared<app::AppInputEventMessage>(event);

M module-services/service-evtmgr/EventManager.cpp => module-services/service-evtmgr/EventManager.cpp +3 -3
@@ 348,7 348,7 @@ void EventManager::handleKeyEvent(sys::Message *msg)
    message->key    = kbdMessage->key;

    if (message->key.state == RawKey::State::Pressed) {
        const auto code = message->key.key_code;
        const auto code = message->key.keyCode;
        if (code == bsp::KeyCodes::FnRight) {
            bus.sendUnicast(message, service::name::system_manager);
        }


@@ 369,8 369,8 @@ void EventManager::handleKeyEvent(sys::Message *msg)

void EventManager::handleKeyMoveEvent(RawKey key)
{
    if (isSliderKeyCode(key.key_code)) {
        LOG_INFO("Slider position: %s", magic_enum::enum_name(key.key_code).data());
    if (isSliderKeyCode(key.keyCode)) {
        LOG_INFO("Slider position: %s", magic_enum::enum_name(key.keyCode).data());
        const auto mode = sys::SystemManager::translateSliderState(key);
        bus.sendUnicast(std::make_shared<sys::PhoneModeRequest>(mode), service::name::system_manager);
    }

M module-services/service-evtmgr/WorkerEvent.cpp => module-services/service-evtmgr/WorkerEvent.cpp +3 -3
@@ 262,7 262,7 @@ void WorkerEvent::processKeyEvent(bsp::KeyEvents event, bsp::KeyCodes code)
{
    auto message = std::make_shared<sevm::KbdMessage>();

    message->key.key_code = code;
    message->key.keyCode = code;

    switch (event) {
    case bsp::KeyEvents::Pressed:


@@ 270,7 270,7 @@ void WorkerEvent::processKeyEvent(bsp::KeyEvents event, bsp::KeyCodes code)
            return;
        }
        message->key.state      = RawKey::State::Pressed;
        message->key.time_press = xTaskGetTickCount();
        message->key.timePress  = xTaskGetTickCount();
        lastPressed             = code;
        lastState               = event;
        break;


@@ 284,7 284,7 @@ void WorkerEvent::processKeyEvent(bsp::KeyEvents event, bsp::KeyCodes code)
        lastState = bsp::KeyEvents::Released;
        {
            message->key.state        = RawKey::State::Released;
            message->key.time_release = xTaskGetTickCount();
            message->key.timeRelease  = xTaskGetTickCount();
        }
        break;
    case bsp::KeyEvents::Moved:

M module-sys/SystemManager/SystemManager.cpp => module-sys/SystemManager/SystemManager.cpp +1 -1
@@ 748,7 748,7 @@ namespace sys

    phone_modes::PhoneMode SystemManager::translateSliderState(const RawKey &key)
    {
        const auto code = key.key_code;
        const auto code = key.keyCode;
        if (code != bsp::KeyCodes::SSwitchUp && code != bsp::KeyCodes::SSwitchMid &&
            code != bsp::KeyCodes::SSwitchDown) {
            throw std::invalid_argument{"Invalid key code passed."};

M module-utils/common_data/RawKey.hpp => module-utils/common_data/RawKey.hpp +16 -16
@@ 7,31 7,31 @@
#include <bsp/keyboard/key_codes.hpp>

/// default application timer trigger
const inline uint32_t key_timer_ms = 200;
const inline uint32_t keyTimerMs = 200;
/// default time key press will be counted as press again
const inline uint32_t key_time_cycle_ms = 500;
const inline uint32_t keyTimeCycleMs = 500;
/// default long press time
const inline uint32_t key_time_longpress_ms = 1000;
const inline uint32_t keyTimeLongpressMs = 1000;

struct RawKey
{
    enum class State
    {
        Undefined,
        Pressed,
        Released,
        Moved,
    } state                   = State::Undefined;
    bsp::KeyCodes key_code = bsp::KeyCodes::Undefined;
    unsigned int time_press   = 0;
    unsigned int time_release = 0;
        Undefined, /// Undefined key state
        Pressed,   /// Bistable key pressed
        Released,  /// Bistable key released
        Moved,     /// Monostable key moved
    } state                  = State::Undefined;
    bsp::KeyCodes keyCode    = bsp::KeyCodes::Undefined;
    unsigned int timePress   = 0;
    unsigned int timeRelease = 0;

    /// set all values to zero, set new key_code and state
    void reset(bsp::KeyCodes key_code = bsp::KeyCodes::Undefined, State state = State::Undefined)
    /// set all values to zero, set new keyCode and state
    void reset(bsp::KeyCodes keyCode = bsp::KeyCodes::Undefined, State state = State::Undefined)
    {
        this->key_code = key_code;
        this->keyCode  = keyCode;
        this->state    = state;
        time_press     = 0;
        time_release   = 0;
        timePress      = 0;
        timeRelease    = 0;
    }
};