From 0eca43d4eadfcd28d147b2817c6fef2a495c3743 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Tue, 6 Jul 2021 18:54:59 +0200 Subject: [PATCH] feat(common/core): Implement capsAlwaysOff system store This change implements the core part in a way that makes the tests pass. This still needs corresponding changes in the engine. --- common/core/desktop/.gitignore | 2 + .../include/keyman/keyboardprocessor.h.in | 5 +- .../desktop/src/km_kbp_processevent_api.cpp | 12 +- common/core/desktop/src/kmx/kmx_capslock.cpp | 105 +++--- .../core/desktop/src/kmx/kmx_environment.cpp | 8 - common/core/desktop/src/kmx/kmx_environment.h | 2 - .../core/desktop/src/kmx/kmx_processevent.cpp | 48 ++- .../core/desktop/src/kmx/kmx_processevent.h | 14 +- common/core/desktop/src/kmx/kmx_processor.cpp | 343 +++++++++--------- common/core/desktop/src/kmx/kmx_processor.hpp | 29 +- .../core/desktop/src/mock/mock_processor.cpp | 25 +- .../core/desktop/src/mock/mock_processor.hpp | 26 +- common/core/desktop/src/processor.hpp | 27 +- .../rust/keyman_keyboard_processor/src/lib.rs | 4 +- .../core/desktop/src/rust/native/src/lib.rs | 4 +- .../desktop/src/rust/rust_mock_processor.cpp | 12 +- .../desktop/src/rust/rust_mock_processor.hpp | 27 +- common/core/desktop/src/rust/wasm/src/lib.rs | 4 +- common/core/desktop/src/state.cpp | 10 +- common/core/desktop/src/state.hpp | 2 +- .../desktop/tests/unit/kmnkbd/debug_api.cpp | 20 +- .../desktop/tests/unit/kmnkbd/state_api.cpp | 12 +- .../tests/unit/kmx/031 - caps lock.kmn | 4 +- .../tests/unit/kmx/032 - caps control.kmn | 4 +- .../tests/unit/kmx/033 - caps always off.kmn | 4 +- .../tests/unit/kmx/033 - caps always off.kmx | Bin 0 -> 516 bytes .../047 - caps always off initially on.kmn | 23 ++ .../047 - caps always off initially on.kmx | Bin 0 -> 516 bytes common/core/desktop/tests/unit/kmx/README.md | 13 +- common/core/desktop/tests/unit/kmx/kmx.cpp | 113 +++--- .../core/desktop/tests/unit/kmx/meson.build | 5 +- .../tests/unit/rust_mock/state_api.cpp | 4 +- linux/.editorconfig | 5 - linux/ibus-keyman/src/engine.c | 69 ++-- 34 files changed, 566 insertions(+), 419 deletions(-) create mode 100644 common/core/desktop/tests/unit/kmx/033 - caps always off.kmx create mode 100644 common/core/desktop/tests/unit/kmx/047 - caps always off initially on.kmn create mode 100644 common/core/desktop/tests/unit/kmx/047 - caps always off initially on.kmx delete mode 100644 linux/.editorconfig diff --git a/common/core/desktop/.gitignore b/common/core/desktop/.gitignore index 40a3439fe8..90ca8c2bb1 100644 --- a/common/core/desktop/.gitignore +++ b/common/core/desktop/.gitignore @@ -9,3 +9,5 @@ wasm.build TIER.md VERSION.md shellHelperFunctions.sh + +src/rust/keyman_keyboard_processor/target/ diff --git a/common/core/desktop/include/keyman/keyboardprocessor.h.in b/common/core/desktop/include/keyman/keyboardprocessor.h.in index 430dc0b455..6bb681f672 100644 --- a/common/core/desktop/include/keyman/keyboardprocessor.h.in +++ b/common/core/desktop/include/keyman/keyboardprocessor.h.in @@ -478,6 +478,7 @@ typedef struct { uintptr_t marker; // MARKER type km_kbp_option_item const * option; // OPT types km_kbp_usv character; // CHAR type + uint8_t capsLock; // CAPSLOCK type, 1 to turn on, 0 to turn off }; } km_kbp_action_item; @@ -494,6 +495,7 @@ enum km_kbp_action_type { // for applications where context is cached, this clears the context; // for applications where context is read from the focused text store, // the context is just re-read and markers flushed. + KM_KBP_IT_CAPSLOCK = 8, // Enable or disable capsLock KM_KBP_IT_MAX_TYPE_ID }; @@ -940,7 +942,8 @@ KMN_API km_kbp_status km_kbp_process_event(km_kbp_state *state, km_kbp_virtual_key vk, - uint16_t modifier_state); + uint16_t modifier_state, + uint8_t is_key_down); #if defined(__cplusplus) } // extern "C" diff --git a/common/core/desktop/src/km_kbp_processevent_api.cpp b/common/core/desktop/src/km_kbp_processevent_api.cpp index 698ae7b2f2..747ee2858c 100644 --- a/common/core/desktop/src/km_kbp_processevent_api.cpp +++ b/common/core/desktop/src/km_kbp_processevent_api.cpp @@ -12,15 +12,15 @@ #include "processor.hpp" #include "state.hpp" -km_kbp_status +km_kbp_status km_kbp_process_event(km_kbp_state *state, - km_kbp_virtual_key vk, uint16_t modifier_state) -{ - return state->processor().process_event(state, vk, modifier_state); + km_kbp_virtual_key vk, + uint16_t modifier_state, + uint8_t is_key_down) { + return state->processor().process_event(state, vk, modifier_state, is_key_down); } - -km_kbp_attr const * +km_kbp_attr const * km_kbp_get_engine_attrs(km_kbp_state const *state) { return &state->processor().attributes(); diff --git a/common/core/desktop/src/kmx/kmx_capslock.cpp b/common/core/desktop/src/kmx/kmx_capslock.cpp index cd11290af7..9db0fab0a0 100644 --- a/common/core/desktop/src/kmx/kmx_capslock.cpp +++ b/common/core/desktop/src/kmx/kmx_capslock.cpp @@ -2,57 +2,80 @@ Copyright: Copyright (C) 2003-2018 SIL International. Authors: mcdurdin */ +#include #include using namespace km::kbp; using namespace kmx; -void KMX_ProcessEvent::ResetCapsLock(void) -{ - DebugLog("ResetCapsLock: enter"); +/** + * Set caps lock state. + * Called by ProcessEvent. + * May update `modifiers` to add or remove `CAPITALFLAG` according to capsLockOn + * parameter. May queue actions to set caps lock state. + * + * @param[in,out] modifiers The modifier key bitmap + * @param capsLockOn The desired caps lock state + */ +void KMX_ProcessEvent::SetCapsLock(KMX_DWORD &modifiers, KMX_BOOL capsLockOn) { + KMX_BOOL capsLockCurrentlyOn = IsCapsLockOn(modifiers); + if (capsLockCurrentlyOn == capsLockOn) { + return; + } - if (m_keyboard.Keyboard->dwFlags & KF_CAPSALWAYSOFF) - { + DebugLog("Caps lock is %s, switching %s", capsLockCurrentlyOn ? "on" : "off", capsLockOn ? "on" : "off"); + + m_actions.QueueAction(QIT_CAPSLOCK, capsLockOn); + if (capsLockOn) { + modifiers |= CAPITALFLAG; + } else { + modifiers &= ~CAPITALFLAG; + } +} + +/** + * Deal with CapsAlwaysOff store option and turns caps lock off if necessary. + * Called by ProcessEvent. + * May update `modifiers` to add or remove `CAPITALFLAG` according to keyboard + * requirements. May queue actions to set caps lock state. + * + * @param[in,out] modifiers The modifier key bitmap + */ +void KMX_ProcessEvent::ResetCapsLock(KMX_DWORD &modifiers) { + if (m_keyboard.Keyboard->dwFlags & KF_CAPSALWAYSOFF) { DebugLog("ResetCapsLock: caps lock should be always off"); - if (m_environment.capsLock()) - { - DebugLog("ResetCapsLock: caps lock is on, switching off caps lock"); - m_actions.QueueAction(QIT_CAPSLOCK, 0); - } - } - DebugLog("ResetCapsLock: exit"); -} - - -void KMX_ProcessEvent::KeyCapsLockPress(KMX_BOOL FIsUp) -{ - if (m_keyboard.Keyboard->dwFlags & KF_CAPSONONLY) - { - if(FIsUp && !m_environment.capsLock()) - { - m_actions.QueueAction(QIT_CAPSLOCK, 1); - } - } - else if (m_keyboard.Keyboard->dwFlags & KF_CAPSALWAYSOFF) - { - if(!FIsUp && m_environment.capsLock()) - { - m_actions.QueueAction(QIT_CAPSLOCK, 0); - } + SetCapsLock(modifiers, FALSE); } } - -void KMX_ProcessEvent::KeyShiftPress(KMX_BOOL FIsUp) -{ - if(!m_environment.capsLock()) return; - - if (m_keyboard.Keyboard->dwFlags & KF_SHIFTFREESCAPS) - { - if(!FIsUp) - { - m_actions.QueueAction(QIT_CAPSLOCK, 0); - } +/** + * Deal with CapsLock store options on CapsLock key press. Called by ProcessEvent. + * May update `modifiers` to add or remove `CAPITALFLAG` according to keyboard + * requirements. May queue actions to set caps lock state. + * + * @param[in,out] modifiers The modifier key bitmap + * @param isKeyDown TRUE if this is called on KeyDown event, FALSE if + * called on KeyUp event + */ +void KMX_ProcessEvent::KeyCapsLockPress(KMX_DWORD &modifiers, KMX_BOOL isKeyDown) { + if (m_keyboard.Keyboard->dwFlags & KF_CAPSONONLY && !isKeyDown) { + SetCapsLock(modifiers, TRUE); + } else if (m_keyboard.Keyboard->dwFlags & KF_CAPSALWAYSOFF && isKeyDown) { + SetCapsLock(modifiers, FALSE); } } +/** + * Deal with CapsLock store options on Shift key press. Called by ProcessEvent. + * May update `modifiers` to remove `CAPITALFLAG` according to keyboard + * requirements. May queue actions to reset caps lock state. + * + * @param[in,out] modifiers The modifier key bitmap + * @param isKeyDown TRUE if this is called on KeyDown event, FALSE if + * called on KeyUp event + */ +void KMX_ProcessEvent::KeyShiftPress(KMX_DWORD &modifiers, KMX_BOOL isKeyDown) { + if (m_keyboard.Keyboard->dwFlags & KF_SHIFTFREESCAPS && isKeyDown) { + SetCapsLock(modifiers, FALSE); + } +} diff --git a/common/core/desktop/src/kmx/kmx_environment.cpp b/common/core/desktop/src/kmx/kmx_environment.cpp index 1e166225c1..4d3d3c5490 100644 --- a/common/core/desktop/src/kmx/kmx_environment.cpp +++ b/common/core/desktop/src/kmx/kmx_environment.cpp @@ -16,7 +16,6 @@ namespace { *DEFAULT_BASELAYOUT = u"kbdus.dll", *DEFAULT_BASELAYOUTALT = u"en-US", *DEFAULT_SIMULATEALTGR = u"0", - *DEFAULT_CAPSLOCK = u"0", *DEFAULT_BASELAYOUTGIVESCTRLRALTFORRALT = u"0"; } @@ -25,7 +24,6 @@ KMX_Environment::KMX_Environment() { Set(KM_KBP_KMX_ENV_BASELAYOUT, DEFAULT_BASELAYOUT); Set(KM_KBP_KMX_ENV_BASELAYOUTALT, DEFAULT_BASELAYOUTALT); Set(KM_KBP_KMX_ENV_SIMULATEALTGR, DEFAULT_SIMULATEALTGR); - Set(KM_KBP_KMX_ENV_CAPSLOCK, DEFAULT_CAPSLOCK); Set(KM_KBP_KMX_ENV_BASELAYOUTGIVESCTRLRALTFORRALT, DEFAULT_BASELAYOUTGIVESCTRLRALTFORRALT); } @@ -46,9 +44,6 @@ char16_t const * KMX_Environment::LookUp(std::u16string const & key) const { else if (!u16icmp(key.c_str(), KM_KBP_KMX_ENV_SIMULATEALTGR)) { return _simulateAltGr ? u"1" : u"0"; } - else if (!u16icmp(key.c_str(), KM_KBP_KMX_ENV_CAPSLOCK)) { - return _capsLock ? u"1" : u"0"; - } else if (!u16icmp(key.c_str(), KM_KBP_KMX_ENV_BASELAYOUTGIVESCTRLRALTFORRALT)) { return _baseLayoutGivesCtrlRAltForRAlt ? u"1" : u"0"; } @@ -74,9 +69,6 @@ void KMX_Environment::Set(std::u16string const & key, std::u16string const & val else if (!u16icmp(key.c_str(), KM_KBP_KMX_ENV_SIMULATEALTGR)) { _simulateAltGr = value == u"1"; } - else if (!u16icmp(key.c_str(), KM_KBP_KMX_ENV_CAPSLOCK)) { - _capsLock = value == u"1"; - } else if (!u16icmp(key.c_str(), KM_KBP_KMX_ENV_BASELAYOUTGIVESCTRLRALTFORRALT)) { _baseLayoutGivesCtrlRAltForRAlt = value == u"1"; } diff --git a/common/core/desktop/src/kmx/kmx_environment.h b/common/core/desktop/src/kmx/kmx_environment.h index f1ee70faf6..4d934e0d10 100644 --- a/common/core/desktop/src/kmx/kmx_environment.h +++ b/common/core/desktop/src/kmx/kmx_environment.h @@ -12,7 +12,6 @@ class KMX_Environment { private: KMX_BOOL _simulateAltGr, _baseLayoutGivesCtrlRAltForRAlt; std::u16string _baseLayout, _baseLayoutAlt; - KMX_BOOL _capsLock; std::u16string _platform; void InitOption( std::vector