From c86ab582a7694f19015d9a287e76b04e635fff8d Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Thu, 4 Apr 2024 12:14:54 -0500 Subject: [PATCH 01/60] chore(core): reinstate context reset test in ldml - reverts 04a6e164d7c65df1d9e1496646332e1d933c188d for k_102_keytest.xml --- core/tests/unit/ldml/keyboards/k_102_keytest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/tests/unit/ldml/keyboards/k_102_keytest.xml b/core/tests/unit/ldml/keyboards/k_102_keytest.xml index 5b47eb5f155..907295bac40 100644 --- a/core/tests/unit/ldml/keyboards/k_102_keytest.xml +++ b/core/tests/unit/ldml/keyboards/k_102_keytest.xml @@ -2,7 +2,7 @@ From c91095f0caeb688b99a0e14e850fde3ed8bdc4d5 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Thu, 4 Apr 2024 17:12:26 -0500 Subject: [PATCH 02/60] fix(core): core to automatically reset context if a frame key pressed - update ldml test with an exception for k_102_keytest --- core/src/km_core_processevent_api.cpp | 4 + core/src/km_core_state_api.cpp | 29 ++- core/src/km_vkey_to_contextreset.hpp | 278 ++++++++++++++++++++++++++ core/src/kmx/kmx_consts.cpp | 272 ------------------------- core/src/kmx/kmx_processevent.cpp | 2 - core/src/kmx/kmx_processevent.h | 3 - core/src/state.hpp | 13 ++ core/tests/unit/ldml/ldml.cpp | 21 +- 8 files changed, 336 insertions(+), 286 deletions(-) create mode 100644 core/src/km_vkey_to_contextreset.hpp diff --git a/core/src/km_core_processevent_api.cpp b/core/src/km_core_processevent_api.cpp index 7d48979cc4a..4b5b1fd715f 100644 --- a/core/src/km_core_processevent_api.cpp +++ b/core/src/km_core_processevent_api.cpp @@ -52,6 +52,10 @@ km_core_process_event(km_core_state *state, } km_core_status status = state->processor().process_event(state, vk, modifier_state, is_key_down, event_flags); + if (km_core_state_should_clear_context(state, vk, modifier_state, is_key_down, event_flags)) { + state->context().clear(); + } + state->apply_actions_and_merge_app_context(); return status; diff --git a/core/src/km_core_state_api.cpp b/core/src/km_core_state_api.cpp index 8b8807b1d24..7f12aa7a66a 100644 --- a/core/src/km_core_state_api.cpp +++ b/core/src/km_core_state_api.cpp @@ -24,6 +24,9 @@ using namespace km::core; +// pull in the reset table +#include "km_vkey_to_contextreset.hpp" + // Forward declarations class context; @@ -363,4 +366,28 @@ km_core_cp * km_core_state_context_debug( result[s.size()] = 0; return result; -} \ No newline at end of file +} + +bool +km_core_state_has_type(km_core_state *state, uint8_t type) { + return std::any_of( + state->actions().begin(), state->actions().end(), + [type](const km::core::action &a) { return a.type == type; }); +} + +bool +km_core_state_should_clear_context(km_core_state *state, + km_core_virtual_key vk, + uint16_t modifier_state, + uint8_t is_key_down, + uint16_t event_flags) { + // if emit_keystroke is present, check if a context reset is needed + if (km_core_state_has_type(state, KM_CORE_IT_EMIT_KEYSTROKE)) { + if (km::core::vkey_to_contextreset[vk]) { + return true; + } else if (vk == KM_CORE_VKEY_BKSP && km_core_state_has_type(state, KM_CORE_IT_BACK)) { + return true; + } + } + return false; +} diff --git a/core/src/km_vkey_to_contextreset.hpp b/core/src/km_vkey_to_contextreset.hpp new file mode 100644 index 00000000000..0f8ae7cf05c --- /dev/null +++ b/core/src/km_vkey_to_contextreset.hpp @@ -0,0 +1,278 @@ +#pragma once + +namespace km { +namespace core { + +static bool vkey_to_contextreset[256] = { + true, //L"K_?00", // &H0 + true, //L"K_LBUTTON", // &H1 + true, //L"K_RBUTTON", // &H2 + true, //L"K_CANCEL", // &H3 + true, //L"K_MBUTTON", // &H4 + true, //L"K_?05", // &H5 + true, //L"K_?06", // &H6 + true, //L"K_?07", // &H7 + true, //L"K_BKSP", // &H8 + true, //L"K_TAB", // &H9 + true, //L"K_?0A", // &HA + true, //L"K_?0B", // &HB + true, //L"K_KP5", // &HC + true, //L"K_ENTER", // &HD + true, //L"K_?0E", // &HE + true, //L"K_?0F", // &HF + false, //L"K_SHIFT", // &H10 + false, //L"K_CONTROL", // &H11 + false, //L"K_ALT", // &H12 + true, //L"K_PAUSE", // &H13 + false, //L"K_CAPS", // &H14 + true, //L"K_KANJI?15", // &H15 + true, //L"K_KANJI?16", // &H16 + true, //L"K_KANJI?17", // &H17 + true, //L"K_KANJI?18", // &H18 + true, //L"K_KANJI?19", // &H19 + true, //L"K_?1A", // &H1A + true, //L"K_ESC", // &H1B + true, //L"K_KANJI?1C", // &H1C + true, //L"K_KANJI?1D", // &H1D + true, //L"K_KANJI?1E", // &H1E + true, //L"K_KANJI?1F", // &H1F + false, //L"K_SPACE", // &H20 + true, //L"K_PGUP", // &H21 + true, //L"K_PGDN", // &H22 + true, //L"K_END", // &H23 + true, //L"K_HOME", // &H24 + true, //L"K_LEFT", // &H25 + true, //L"K_UP", // &H26 + true, //L"K_RIGHT", // &H27 + true, //L"K_DOWN", // &H28 + true, //L"K_SEL", // &H29 + true, //L"K_PRINT", // &H2A + true, //L"K_EXEC", // &H2B + true, //L"K_PRTSCN", // &H2C + false, //L"K_INS", // &H2D + true, //L"K_DEL", // &H2E + true, //L"K_HELP", // &H2F + false, //L"K_0", // &H30 + false, //L"K_1", // &H31 + false, //L"K_2", // &H32 + false, //L"K_3", // &H33 + false, //L"K_4", // &H34 + false, //L"K_5", // &H35 + false, //L"K_6", // &H36 + false, //L"K_7", // &H37 + false, //L"K_8", // &H38 + false, //L"K_9", // &H39 + false, //L"K_?3A", // &H3A + false, //L"K_?3B", // &H3B + false, //L"K_?3C", // &H3C + false, //L"K_?3D", // &H3D + false, //L"K_?3E", // &H3E + false, //L"K_?3F", // &H3F + false, //L"K_?40", // &H40 + + false, //L"K_A", // &H41 + false, //L"K_B", // &H42 + false, //L"K_C", // &H43 + false, //L"K_D", // &H44 + false, //L"K_E", // &H45 + false, //L"K_F", // &H46 + false, //L"K_G", // &H47 + false, //L"K_H", // &H48 + false, //L"K_I", // &H49 + false, //L"K_J", // &H4A + false, //L"K_K", // &H4B + false, //L"K_L", // &H4C + false, //L"K_M", // &H4D + false, //L"K_N", // &H4E + false, //L"K_O", // &H4F + false, //L"K_P", // &H50 + false, //L"K_Q", // &H51 + false, //L"K_R", // &H52 + false, //L"K_S", // &H53 + false, //L"K_T", // &H54 + false, //L"K_U", // &H55 + false, //L"K_V", // &H56 + false, //L"K_W", // &H57 + false, //L"K_X", // &H58 + false, //L"K_Y", // &H59 + false, //L"K_Z", // &H5A + false, //L"K_?5B", // &H5B + false, //L"K_?5C", // &H5C + false, //L"K_?5D", // &H5D + false, //L"K_?5E", // &H5E + false, //L"K_?5F", // &H5F + false, //L"K_NP0", // &H60 + false, //L"K_NP1", // &H61 + false, //L"K_NP2", // &H62 + false, //L"K_NP3", // &H63 + false, //L"K_NP4", // &H64 + false, //L"K_NP5", // &H65 + false, //L"K_NP6", // &H66 + false, //L"K_NP7", // &H67 + false, //L"K_NP8", // &H68 + false, //L"K_NP9", // &H69 + false, //L"K_NPSTAR", // &H6A + false, //L"K_NPPLUS", // &H6B + false, //L"K_SEPARATOR", // &H6C + false, //L"K_NPMINUS", // &H6D + false, //L"K_NPDOT", // &H6E + false, //L"K_NPSLASH", // &H6F + true, //L"K_F1", // &H70 + true, //L"K_F2", // &H71 + true, //L"K_F3", // &H72 + true, //L"K_F4", // &H73 + true, //L"K_F5", // &H74 + true, //L"K_F6", // &H75 + true, //L"K_F7", // &H76 + true, //L"K_F8", // &H77 + true, //L"K_F9", // &H78 + true, //L"K_F10", // &H79 + true, //L"K_F11", // &H7A + true, //L"K_F12", // &H7B + true, //L"K_F13", // &H7C + true, //L"K_F14", // &H7D + true, //L"K_F15", // &H7E + true, //L"K_F16", // &H7F + true, //L"K_F17", // &H80 + true, //L"K_F18", // &H81 + true, //L"K_F19", // &H82 + true, //L"K_F20", // &H83 + true, //L"K_F21", // &H84 + true, //L"K_F22", // &H85 + true, //L"K_F23", // &H86 + true, //L"K_F24", // &H87 + + false, //L"K_?88", // &H88 + false, //L"K_?89", // &H89 + false, //L"K_?8A", // &H8A + false, //L"K_?8B", // &H8B + false, //L"K_?8C", // &H8C + false, //L"K_?8D", // &H8D + false, //L"K_?8E", // &H8E + false, //L"K_?8F", // &H8F + + false, //L"K_NUMLOCK", // &H90 + false, //L"K_SCROLL", // &H91 + + false, //L"K_?92", // &H92 + false, //L"K_?93", // &H93 + false, //L"K_?94", // &H94 + false, //L"K_?95", // &H95 + false, //L"K_?96", // &H96 + false, //L"K_?97", // &H97 + false, //L"K_?98", // &H98 + false, //L"K_?99", // &H99 + false, //L"K_?9A", // &H9A + false, //L"K_?9B", // &H9B + false, //L"K_?9C", // &H9C + false, //L"K_?9D", // &H9D + false, //L"K_?9E", // &H9E + false, //L"K_?9F", // &H9F + false, //L"K_?A0", // &HA0 + false, //L"K_?A1", // &HA1 + false, //L"K_?A2", // &HA2 + false, //L"K_?A3", // &HA3 + false, //L"K_?A4", // &HA4 + false, //L"K_?A5", // &HA5 + false, //L"K_?A6", // &HA6 + false, //L"K_?A7", // &HA7 + false, //L"K_?A8", // &HA8 + false, //L"K_?A9", // &HA9 + false, //L"K_?AA", // &HAA + false, //L"K_?AB", // &HAB + false, //L"K_?AC", // &HAC + false, //L"K_?AD", // &HAD + false, //L"K_?AE", // &HAE + false, //L"K_?AF", // &HAF + false, //L"K_?B0", // &HB0 + false, //L"K_?B1", // &HB1 + false, //L"K_?B2", // &HB2 + false, //L"K_?B3", // &HB3 + false, //L"K_?B4", // &HB4 + false, //L"K_?B5", // &HB5 + false, //L"K_?B6", // &HB6 + false, //L"K_?B7", // &HB7 + false, //L"K_?B8", // &HB8 + false, //L"K_?B9", // &HB9 + + false, //L"K_COLON", // &HBA + false, //L"K_EQUAL", // &HBB + false, //L"K_COMMA", // &HBC + false, //L"K_HYPHEN", // &HBD + false, //L"K_PERIOD", // &HBE + false, //L"K_SLASH", // &HBF + false, //L"K_BKQUOTE", // &HC0 + + false, //L"K_?C1", // &HC1 + false, //L"K_?C2", // &HC2 + false, //L"K_?C3", // &HC3 + false, //L"K_?C4", // &HC4 + false, //L"K_?C5", // &HC5 + false, //L"K_?C6", // &HC6 + false, //L"K_?C7", // &HC7 + false, //L"K_?C8", // &HC8 + false, //L"K_?C9", // &HC9 + false, //L"K_?CA", // &HCA + false, //L"K_?CB", // &HCB + false, //L"K_?CC", // &HCC + false, //L"K_?CD", // &HCD + false, //L"K_?CE", // &HCE + false, //L"K_?CF", // &HCF + false, //L"K_?D0", // &HD0 + false, //L"K_?D1", // &HD1 + false, //L"K_?D2", // &HD2 + false, //L"K_?D3", // &HD3 + false, //L"K_?D4", // &HD4 + false, //L"K_?D5", // &HD5 + false, //L"K_?D6", // &HD6 + false, //L"K_?D7", // &HD7 + false, //L"K_?D8", // &HD8 + false, //L"K_?D9", // &HD9 + false, //L"K_?DA", // &HDA + + false, //L"K_LBRKT", // &HDB + false, //L"K_BKSLASH", // &HDC + false, //L"K_RBRKT", // &HDD + false, //L"K_QUOTE", // &HDE + false, //L"K_oDF", // &HDF + false, //L"K_oE0", // &HE0 + false, //L"K_oE1", // &HE1 + false, //L"K_oE2", // &HE2 + false, //L"K_oE3", // &HE3 + false, //L"K_oE4", // &HE4 + + false, //L"K_?E5", // &HE5 + + false, //L"K_oE6", // &HE6 + + false, //L"K_?E7", // &HE7 + false, //L"K_?E8", // &HE8 + + false, //L"K_oE9", // &HE9 + false, //L"K_oEA", // &HEA + false, //L"K_oEB", // &HEB + false, //L"K_oEC", // &HEC + false, //L"K_oED", // &HED + false, //L"K_oEE", // &HEE + false, //L"K_oEF", // &HEF + false, //L"K_oF0", // &HF0 + false, //L"K_oF1", // &HF1 + false, //L"K_oF2", // &HF2 + false, //L"K_oF3", // &HF3 + false, //L"K_oF4", // &HF4 + false, //L"K_oF5", // &HF5 + + false, //L"K_?F6", // &HF6 + false, //L"K_?F7", // &HF7 + false, //L"K_?F8", // &HF8 + false, //L"K_?F9", // &HF9 + false, //L"K_?FA", // &HFA + false, //L"K_?FB", // &HFB + false, //L"K_?FC", // &HFC + false, //L"K_?FD", // &HFD + false, //L"K_?FE", // &HFE + false, //L"K_?FF" // &HFF +}; + +} +} diff --git a/core/src/kmx/kmx_consts.cpp b/core/src/kmx/kmx_consts.cpp index ae9e7806896..009ef1a4433 100644 --- a/core/src/kmx/kmx_consts.cpp +++ b/core/src/kmx/kmx_consts.cpp @@ -104,278 +104,6 @@ const struct char_to_vkey s_char_to_vkey[] = { {0, 0, 0} }; -const bool vkey_to_contextreset[256] = { - true, //L"K_?00", // &H0 - true, //L"K_LBUTTON", // &H1 - true, //L"K_RBUTTON", // &H2 - true, //L"K_CANCEL", // &H3 - true, //L"K_MBUTTON", // &H4 - true, //L"K_?05", // &H5 - true, //L"K_?06", // &H6 - true, //L"K_?07", // &H7 - true, //L"K_BKSP", // &H8 - true, //L"K_TAB", // &H9 - true, //L"K_?0A", // &HA - true, //L"K_?0B", // &HB - true, //L"K_KP5", // &HC - true, //L"K_ENTER", // &HD - true, //L"K_?0E", // &HE - true, //L"K_?0F", // &HF - false, //L"K_SHIFT", // &H10 - false, //L"K_CONTROL", // &H11 - false, //L"K_ALT", // &H12 - true, //L"K_PAUSE", // &H13 - false, //L"K_CAPS", // &H14 - true, //L"K_KANJI?15", // &H15 - true, //L"K_KANJI?16", // &H16 - true, //L"K_KANJI?17", // &H17 - true, //L"K_KANJI?18", // &H18 - true, //L"K_KANJI?19", // &H19 - true, //L"K_?1A", // &H1A - true, //L"K_ESC", // &H1B - true, //L"K_KANJI?1C", // &H1C - true, //L"K_KANJI?1D", // &H1D - true, //L"K_KANJI?1E", // &H1E - true, //L"K_KANJI?1F", // &H1F - false, //L"K_SPACE", // &H20 - true, //L"K_PGUP", // &H21 - true, //L"K_PGDN", // &H22 - true, //L"K_END", // &H23 - true, //L"K_HOME", // &H24 - true, //L"K_LEFT", // &H25 - true, //L"K_UP", // &H26 - true, //L"K_RIGHT", // &H27 - true, //L"K_DOWN", // &H28 - true, //L"K_SEL", // &H29 - true, //L"K_PRINT", // &H2A - true, //L"K_EXEC", // &H2B - true, //L"K_PRTSCN", // &H2C - false, //L"K_INS", // &H2D - true, //L"K_DEL", // &H2E - true, //L"K_HELP", // &H2F - false, //L"K_0", // &H30 - false, //L"K_1", // &H31 - false, //L"K_2", // &H32 - false, //L"K_3", // &H33 - false, //L"K_4", // &H34 - false, //L"K_5", // &H35 - false, //L"K_6", // &H36 - false, //L"K_7", // &H37 - false, //L"K_8", // &H38 - false, //L"K_9", // &H39 - false, //L"K_?3A", // &H3A - false, //L"K_?3B", // &H3B - false, //L"K_?3C", // &H3C - false, //L"K_?3D", // &H3D - false, //L"K_?3E", // &H3E - false, //L"K_?3F", // &H3F - false, //L"K_?40", // &H40 - - false, //L"K_A", // &H41 - false, //L"K_B", // &H42 - false, //L"K_C", // &H43 - false, //L"K_D", // &H44 - false, //L"K_E", // &H45 - false, //L"K_F", // &H46 - false, //L"K_G", // &H47 - false, //L"K_H", // &H48 - false, //L"K_I", // &H49 - false, //L"K_J", // &H4A - false, //L"K_K", // &H4B - false, //L"K_L", // &H4C - false, //L"K_M", // &H4D - false, //L"K_N", // &H4E - false, //L"K_O", // &H4F - false, //L"K_P", // &H50 - false, //L"K_Q", // &H51 - false, //L"K_R", // &H52 - false, //L"K_S", // &H53 - false, //L"K_T", // &H54 - false, //L"K_U", // &H55 - false, //L"K_V", // &H56 - false, //L"K_W", // &H57 - false, //L"K_X", // &H58 - false, //L"K_Y", // &H59 - false, //L"K_Z", // &H5A - false, //L"K_?5B", // &H5B - false, //L"K_?5C", // &H5C - false, //L"K_?5D", // &H5D - false, //L"K_?5E", // &H5E - false, //L"K_?5F", // &H5F - false, //L"K_NP0", // &H60 - false, //L"K_NP1", // &H61 - false, //L"K_NP2", // &H62 - false, //L"K_NP3", // &H63 - false, //L"K_NP4", // &H64 - false, //L"K_NP5", // &H65 - false, //L"K_NP6", // &H66 - false, //L"K_NP7", // &H67 - false, //L"K_NP8", // &H68 - false, //L"K_NP9", // &H69 - false, //L"K_NPSTAR", // &H6A - false, //L"K_NPPLUS", // &H6B - false, //L"K_SEPARATOR", // &H6C - false, //L"K_NPMINUS", // &H6D - false, //L"K_NPDOT", // &H6E - false, //L"K_NPSLASH", // &H6F - true, //L"K_F1", // &H70 - true, //L"K_F2", // &H71 - true, //L"K_F3", // &H72 - true, //L"K_F4", // &H73 - true, //L"K_F5", // &H74 - true, //L"K_F6", // &H75 - true, //L"K_F7", // &H76 - true, //L"K_F8", // &H77 - true, //L"K_F9", // &H78 - true, //L"K_F10", // &H79 - true, //L"K_F11", // &H7A - true, //L"K_F12", // &H7B - true, //L"K_F13", // &H7C - true, //L"K_F14", // &H7D - true, //L"K_F15", // &H7E - true, //L"K_F16", // &H7F - true, //L"K_F17", // &H80 - true, //L"K_F18", // &H81 - true, //L"K_F19", // &H82 - true, //L"K_F20", // &H83 - true, //L"K_F21", // &H84 - true, //L"K_F22", // &H85 - true, //L"K_F23", // &H86 - true, //L"K_F24", // &H87 - - false, //L"K_?88", // &H88 - false, //L"K_?89", // &H89 - false, //L"K_?8A", // &H8A - false, //L"K_?8B", // &H8B - false, //L"K_?8C", // &H8C - false, //L"K_?8D", // &H8D - false, //L"K_?8E", // &H8E - false, //L"K_?8F", // &H8F - - false, //L"K_NUMLOCK", // &H90 - false, //L"K_SCROLL", // &H91 - - false, //L"K_?92", // &H92 - false, //L"K_?93", // &H93 - false, //L"K_?94", // &H94 - false, //L"K_?95", // &H95 - false, //L"K_?96", // &H96 - false, //L"K_?97", // &H97 - false, //L"K_?98", // &H98 - false, //L"K_?99", // &H99 - false, //L"K_?9A", // &H9A - false, //L"K_?9B", // &H9B - false, //L"K_?9C", // &H9C - false, //L"K_?9D", // &H9D - false, //L"K_?9E", // &H9E - false, //L"K_?9F", // &H9F - false, //L"K_?A0", // &HA0 - false, //L"K_?A1", // &HA1 - false, //L"K_?A2", // &HA2 - false, //L"K_?A3", // &HA3 - false, //L"K_?A4", // &HA4 - false, //L"K_?A5", // &HA5 - false, //L"K_?A6", // &HA6 - false, //L"K_?A7", // &HA7 - false, //L"K_?A8", // &HA8 - false, //L"K_?A9", // &HA9 - false, //L"K_?AA", // &HAA - false, //L"K_?AB", // &HAB - false, //L"K_?AC", // &HAC - false, //L"K_?AD", // &HAD - false, //L"K_?AE", // &HAE - false, //L"K_?AF", // &HAF - false, //L"K_?B0", // &HB0 - false, //L"K_?B1", // &HB1 - false, //L"K_?B2", // &HB2 - false, //L"K_?B3", // &HB3 - false, //L"K_?B4", // &HB4 - false, //L"K_?B5", // &HB5 - false, //L"K_?B6", // &HB6 - false, //L"K_?B7", // &HB7 - false, //L"K_?B8", // &HB8 - false, //L"K_?B9", // &HB9 - - false, //L"K_COLON", // &HBA - false, //L"K_EQUAL", // &HBB - false, //L"K_COMMA", // &HBC - false, //L"K_HYPHEN", // &HBD - false, //L"K_PERIOD", // &HBE - false, //L"K_SLASH", // &HBF - false, //L"K_BKQUOTE", // &HC0 - - false, //L"K_?C1", // &HC1 - false, //L"K_?C2", // &HC2 - false, //L"K_?C3", // &HC3 - false, //L"K_?C4", // &HC4 - false, //L"K_?C5", // &HC5 - false, //L"K_?C6", // &HC6 - false, //L"K_?C7", // &HC7 - false, //L"K_?C8", // &HC8 - false, //L"K_?C9", // &HC9 - false, //L"K_?CA", // &HCA - false, //L"K_?CB", // &HCB - false, //L"K_?CC", // &HCC - false, //L"K_?CD", // &HCD - false, //L"K_?CE", // &HCE - false, //L"K_?CF", // &HCF - false, //L"K_?D0", // &HD0 - false, //L"K_?D1", // &HD1 - false, //L"K_?D2", // &HD2 - false, //L"K_?D3", // &HD3 - false, //L"K_?D4", // &HD4 - false, //L"K_?D5", // &HD5 - false, //L"K_?D6", // &HD6 - false, //L"K_?D7", // &HD7 - false, //L"K_?D8", // &HD8 - false, //L"K_?D9", // &HD9 - false, //L"K_?DA", // &HDA - - false, //L"K_LBRKT", // &HDB - false, //L"K_BKSLASH", // &HDC - false, //L"K_RBRKT", // &HDD - false, //L"K_QUOTE", // &HDE - false, //L"K_oDF", // &HDF - false, //L"K_oE0", // &HE0 - false, //L"K_oE1", // &HE1 - false, //L"K_oE2", // &HE2 - false, //L"K_oE3", // &HE3 - false, //L"K_oE4", // &HE4 - - false, //L"K_?E5", // &HE5 - - false, //L"K_oE6", // &HE6 - - false, //L"K_?E7", // &HE7 - false, //L"K_?E8", // &HE8 - - false, //L"K_oE9", // &HE9 - false, //L"K_oEA", // &HEA - false, //L"K_oEB", // &HEB - false, //L"K_oEC", // &HEC - false, //L"K_oED", // &HED - false, //L"K_oEE", // &HEE - false, //L"K_oEF", // &HEF - false, //L"K_oF0", // &HF0 - false, //L"K_oF1", // &HF1 - false, //L"K_oF2", // &HF2 - false, //L"K_oF3", // &HF3 - false, //L"K_oF4", // &HF4 - false, //L"K_oF5", // &HF5 - - false, //L"K_?F6", // &HF6 - false, //L"K_?F7", // &HF7 - false, //L"K_?F8", // &HF8 - false, //L"K_?F9", // &HF9 - false, //L"K_?FA", // &HFA - false, //L"K_?FB", // &HFB - false, //L"K_?FC", // &HFC - false, //L"K_?FD", // &HFD - false, //L"K_?FE", // &HFE - false, //L"K_?FF" // &HFF -}; - - } // namespace kmx } // namespace core } // namespace km diff --git a/core/src/kmx/kmx_processevent.cpp b/core/src/kmx/kmx_processevent.cpp index 4b98312c369..604c6f6fe2e 100644 --- a/core/src/kmx/kmx_processevent.cpp +++ b/core/src/kmx/kmx_processevent.cpp @@ -276,7 +276,6 @@ KMX_BOOL KMX_ProcessEvent::ProcessGroup(LPGROUP gp, KMX_BOOL *pOutputKeystroke) // If there is now no character in the context, we want to // emit the backspace for application to use if(!pdeletecontext || *pdeletecontext == 0) { // I4933 - m_actions.QueueAction(QIT_INVALIDATECONTEXT, 0); if(m_debug_items) { m_debug_items->push_group_exit(m_actions.Length(), KM_CORE_DEBUG_FLAG_NOMATCH, gp); } @@ -301,7 +300,6 @@ KMX_BOOL KMX_ProcessEvent::ProcessGroup(LPGROUP gp, KMX_BOOL *pOutputKeystroke) return FALSE; } else { // I4024 // I4128 // I4287 // I4290 DebugLog(" ... IsLegacy = FALSE; IsTIP = TRUE"); // I4128 - m_actions.QueueAction(QIT_INVALIDATECONTEXT, 0); if(m_debug_items) { m_debug_items->push_group_exit(m_actions.Length(), KM_CORE_DEBUG_FLAG_NOMATCH, gp); } diff --git a/core/src/kmx/kmx_processevent.h b/core/src/kmx/kmx_processevent.h index 681c1782acc..50e84c996d8 100644 --- a/core/src/kmx/kmx_processevent.h +++ b/core/src/kmx/kmx_processevent.h @@ -126,9 +126,6 @@ struct char_to_vkey { extern const struct char_to_vkey s_char_to_vkey[]; -/** for vkeys 0..FF, 'true' if a context reset should be performed before emit */ -extern const bool vkey_to_contextreset[]; - } // namespace kmx } // namespace core } // namespace km diff --git a/core/src/state.hpp b/core/src/state.hpp index 5d1e5355254..6b0aa6ba8cf 100644 --- a/core/src/state.hpp +++ b/core/src/state.hpp @@ -184,3 +184,16 @@ struct km_core_state : public km::core::state km_core_state(Args&&... args) : km::core::state(std::forward(args)...) {} }; + + +/** @return true if this is a state which should clear the context */ +bool +km_core_state_should_clear_context(km_core_state *state, + km_core_virtual_key vk, + uint16_t modifier_state, + uint8_t is_key_down, + uint16_t event_flags); + +/** @return true if there are any actions of the type */ +bool +km_core_state_has_type(km_core_state *state, uint8_t type); diff --git a/core/tests/unit/ldml/ldml.cpp b/core/tests/unit/ldml/ldml.cpp index bef485a8783..92b50b2f116 100644 --- a/core/tests/unit/ldml/ldml.cpp +++ b/core/tests/unit/ldml/ldml.cpp @@ -239,7 +239,7 @@ verify_context(std::u16string& text_store, km_core_state* &test_state, std::vect // Verify that both our local test_context and the core's test_state.context have // not diverged auto ci = citems; - for (auto test_ci = test_context.begin(); ci->type != KM_CORE_CT_END || test_ci != test_context.end(); ci++, test_ci++) { + for (auto test_ci = test_context.begin(); ; ci++, test_ci++) { // skip over markers, they won't be in test_context while (ci->type == KM_CORE_CT_MARKER) { ci++; @@ -254,13 +254,13 @@ verify_context(std::u16string& text_store, km_core_state* &test_state, std::vect assert(test_ci->type == ci->type && test_ci->marker == ci->marker); } - km_core_context_items_dispose(citems); - if (text_store != buf) { - std::cerr << "text store has diverged from buf" << std::endl; - std::cerr << "text store: " << string_to_hex(text_store) << " [" << text_store << "]" << std::endl; - assert(false); - } - delete[] buf; + km_core_context_items_dispose(citems); + if (text_store != buf) { + std::cerr << "text store has diverged from buf" << std::endl; + std::cerr << "text store: " << string_to_hex(text_store) << " [" << text_store << "]" << std::endl; + assert(false); + } + delete[] buf; } int @@ -329,6 +329,11 @@ run_test(const km::core::path &source, const km::core::path &compiled, km::tests test_state, p.vk, p.modifier_state | test_source.caps_lock_state(), key_down, KM_CORE_EVENT_FLAG_DEFAULT)); // TODO-LDML: for now. Should send touch and hardware events. + if (km_core_state_should_clear_context(test_state, p.vk, p.modifier_state | test_source.caps_lock_state(), key_down, + KM_CORE_EVENT_FLAG_DEFAULT)) { + test_context.clear(); + text_store.clear(); + } for (auto act = km_core_state_action_items(test_state, nullptr); act->type != KM_CORE_IT_END; act++) { apply_action(test_state, *act, text_store, test_context, test_source, test_context); } From f1b0d8c83703aee4fd2a4f581e02dcc162b16a57 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Fri, 5 Apr 2024 11:58:47 -0500 Subject: [PATCH 03/60] fix(core): core to automatically reset context if a frame key pressed - move the reset table into its own cpp - update function signatures per review comments Fixes: #10955 --- core/src/km_core_processevent_api.cpp | 2 +- core/src/km_core_state_api.cpp | 17 +++++++---------- core/src/meson.build | 1 + core/src/state.hpp | 11 +++++------ ...ontextreset.hpp => vkey_to_contextreset.cpp} | 4 ++-- core/src/vkey_to_contextreset.hpp | 10 ++++++++++ core/tests/unit/ldml/ldml.cpp | 2 +- 7 files changed, 27 insertions(+), 20 deletions(-) rename core/src/{km_vkey_to_contextreset.hpp => vkey_to_contextreset.cpp} (99%) create mode 100644 core/src/vkey_to_contextreset.hpp diff --git a/core/src/km_core_processevent_api.cpp b/core/src/km_core_processevent_api.cpp index 4b5b1fd715f..8ccf0e4fa73 100644 --- a/core/src/km_core_processevent_api.cpp +++ b/core/src/km_core_processevent_api.cpp @@ -52,7 +52,7 @@ km_core_process_event(km_core_state *state, } km_core_status status = state->processor().process_event(state, vk, modifier_state, is_key_down, event_flags); - if (km_core_state_should_clear_context(state, vk, modifier_state, is_key_down, event_flags)) { + if (state_should_clear_context(state, vk, modifier_state, is_key_down, event_flags)) { state->context().clear(); } diff --git a/core/src/km_core_state_api.cpp b/core/src/km_core_state_api.cpp index 7f12aa7a66a..f9449fcb51f 100644 --- a/core/src/km_core_state_api.cpp +++ b/core/src/km_core_state_api.cpp @@ -20,13 +20,10 @@ #include "processor.hpp" #include "state.hpp" - +#include "vkey_to_contextreset.hpp" using namespace km::core; -// pull in the reset table -#include "km_vkey_to_contextreset.hpp" - // Forward declarations class context; @@ -368,24 +365,24 @@ km_core_cp * km_core_state_context_debug( return result; } -bool -km_core_state_has_type(km_core_state *state, uint8_t type) { +static bool +state_has_action_type(km_core_state *state, uint8_t type) { return std::any_of( state->actions().begin(), state->actions().end(), [type](const km::core::action &a) { return a.type == type; }); } bool -km_core_state_should_clear_context(km_core_state *state, +state_should_clear_context(km_core_state *state, km_core_virtual_key vk, uint16_t modifier_state, uint8_t is_key_down, uint16_t event_flags) { // if emit_keystroke is present, check if a context reset is needed - if (km_core_state_has_type(state, KM_CORE_IT_EMIT_KEYSTROKE)) { - if (km::core::vkey_to_contextreset[vk]) { + if (state_has_action_type(state, KM_CORE_IT_EMIT_KEYSTROKE)) { + if (vkey_to_contextreset[vk]) { return true; - } else if (vk == KM_CORE_VKEY_BKSP && km_core_state_has_type(state, KM_CORE_IT_BACK)) { + } else if (vk == KM_CORE_VKEY_BKSP && state_has_action_type(state, KM_CORE_IT_BACK)) { return true; } } diff --git a/core/src/meson.build b/core/src/meson.build index 9943c2fd070..7027136dd4c 100644 --- a/core/src/meson.build +++ b/core/src/meson.build @@ -49,6 +49,7 @@ kmx_files = files( 'keyboard.cpp', 'state.cpp', 'debuglog.cpp', + 'vkey_to_contextreset.cpp', 'km_core_action_api.cpp', 'km_core_context_api.cpp', 'km_core_keyboard_api.cpp', diff --git a/core/src/state.hpp b/core/src/state.hpp index 6b0aa6ba8cf..ffdbb2deb72 100644 --- a/core/src/state.hpp +++ b/core/src/state.hpp @@ -186,14 +186,13 @@ struct km_core_state : public km::core::state }; -/** @return true if this is a state which should clear the context */ +/** + * Evaluate the + * @return true if this is a state which should clear the context + */ bool -km_core_state_should_clear_context(km_core_state *state, +state_should_clear_context(km_core_state *state, km_core_virtual_key vk, uint16_t modifier_state, uint8_t is_key_down, uint16_t event_flags); - -/** @return true if there are any actions of the type */ -bool -km_core_state_has_type(km_core_state *state, uint8_t type); diff --git a/core/src/km_vkey_to_contextreset.hpp b/core/src/vkey_to_contextreset.cpp similarity index 99% rename from core/src/km_vkey_to_contextreset.hpp rename to core/src/vkey_to_contextreset.cpp index 0f8ae7cf05c..cbfd8497faf 100644 --- a/core/src/km_vkey_to_contextreset.hpp +++ b/core/src/vkey_to_contextreset.cpp @@ -1,9 +1,9 @@ -#pragma once +#include "vkey_to_contextreset.hpp" namespace km { namespace core { -static bool vkey_to_contextreset[256] = { +bool vkey_to_contextreset[256] = { true, //L"K_?00", // &H0 true, //L"K_LBUTTON", // &H1 true, //L"K_RBUTTON", // &H2 diff --git a/core/src/vkey_to_contextreset.hpp b/core/src/vkey_to_contextreset.hpp new file mode 100644 index 00000000000..fd183ad9330 --- /dev/null +++ b/core/src/vkey_to_contextreset.hpp @@ -0,0 +1,10 @@ +#pragma once + +namespace km { +namespace core { + +/** true for any vkeys which require a context reset (such as frame keys) */ +extern bool vkey_to_contextreset[256]; + +} +} diff --git a/core/tests/unit/ldml/ldml.cpp b/core/tests/unit/ldml/ldml.cpp index 92b50b2f116..fffdfbd08ae 100644 --- a/core/tests/unit/ldml/ldml.cpp +++ b/core/tests/unit/ldml/ldml.cpp @@ -329,7 +329,7 @@ run_test(const km::core::path &source, const km::core::path &compiled, km::tests test_state, p.vk, p.modifier_state | test_source.caps_lock_state(), key_down, KM_CORE_EVENT_FLAG_DEFAULT)); // TODO-LDML: for now. Should send touch and hardware events. - if (km_core_state_should_clear_context(test_state, p.vk, p.modifier_state | test_source.caps_lock_state(), key_down, + if (state_should_clear_context(test_state, p.vk, p.modifier_state | test_source.caps_lock_state(), key_down, KM_CORE_EVENT_FLAG_DEFAULT)) { test_context.clear(); text_store.clear(); From 628d13d7a6ef5dd0b726faa66f2caf31b1584516 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Fri, 5 Apr 2024 12:05:57 -0500 Subject: [PATCH 04/60] fix(core): core to automatically reset context if a frame key pressed - update comments per review Fixes: #10955 --- core/src/km_core_state_api.cpp | 4 ++-- core/src/state.hpp | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/core/src/km_core_state_api.cpp b/core/src/km_core_state_api.cpp index f9449fcb51f..a7773219393 100644 --- a/core/src/km_core_state_api.cpp +++ b/core/src/km_core_state_api.cpp @@ -380,9 +380,9 @@ state_should_clear_context(km_core_state *state, uint16_t event_flags) { // if emit_keystroke is present, check if a context reset is needed if (state_has_action_type(state, KM_CORE_IT_EMIT_KEYSTROKE)) { - if (vkey_to_contextreset[vk]) { + if (vk == KM_CORE_VKEY_BKSP && state_has_action_type(state, KM_CORE_IT_BACK)) { return true; - } else if (vk == KM_CORE_VKEY_BKSP && state_has_action_type(state, KM_CORE_IT_BACK)) { + } else if (vkey_to_contextreset[vk]) { return true; } } diff --git a/core/src/state.hpp b/core/src/state.hpp index ffdbb2deb72..d2840fe49c6 100644 --- a/core/src/state.hpp +++ b/core/src/state.hpp @@ -187,7 +187,14 @@ struct km_core_state : public km::core::state /** - * Evaluate the + * Evaluate the state and vkey used. + * Determine whether the context should be cleared. + * @param state A pointer to the opaque state object. + * @param vk A virtual key that was processed. + * @param modifier_state The combinations of modifier keys set at the time key `vk` was pressed, bitmask + from the km_core_modifier_state enum. + * @param is_key_down 1 if it was a key-down event + * @param event_flags Event level flags, see km_core_event_flags * @return true if this is a state which should clear the context */ bool From 784a994f12d62a0439e854d9674ab5d680cacfa1 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Fri, 5 Apr 2024 13:22:47 -0500 Subject: [PATCH 05/60] fix(core): update ldml test source to handle reset Fixes: #10955 --- .../unit/ldml/keyboards/k_102_keytest.xml | 33 ++++++++++++------- core/tests/unit/ldml/ldml_test_source.cpp | 30 +++++++++++------ core/tests/unit/ldml/ldml_test_source.hpp | 5 +-- 3 files changed, 44 insertions(+), 24 deletions(-) diff --git a/core/tests/unit/ldml/keyboards/k_102_keytest.xml b/core/tests/unit/ldml/keyboards/k_102_keytest.xml index 907295bac40..ad0f1131fa4 100644 --- a/core/tests/unit/ldml/keyboards/k_102_keytest.xml +++ b/core/tests/unit/ldml/keyboards/k_102_keytest.xml @@ -1,19 +1,28 @@ +Note that the 'expected' lines are cumulative unless there's a reset event. + +@@keys: [K_BKQUOTE][K_1][K_ENTER][K_Z] +@@expected: z +Comment: 1=gap, enter=not mapped/mappable - reset. (z used as a subtest separator) + +@@keys: [K_Q][K_BKQUOTE][K_Z] +@@expected: zAz +Comment: q\m{q}a => A due to transform + +@@keys: [K_Q][K_2][K_BKQUOTE][K_Z] +@@expected: zAzAz +Comment: 2=not mapped, but NO reset. + +@@keys: [K_Q][K_1][K_BKQUOTE][K_Z] +@@expected: zAzAzAz +Comment: 1 is a gap (no effect) so no ctx reset + +@@keys: [K_Q][K_ENTER][K_BKQUOTE][K_Z] +@@expected: az +Comment: enter=not mappable, causes ctx reset. - diff --git a/core/tests/unit/ldml/ldml_test_source.cpp b/core/tests/unit/ldml/ldml_test_source.cpp index 71c5a7ee4e0..f171116aace 100644 --- a/core/tests/unit/ldml/ldml_test_source.cpp +++ b/core/tests/unit/ldml/ldml_test_source.cpp @@ -280,13 +280,15 @@ LdmlEmbeddedTestSource::load_source( const km::core::path &path ) { if (!line.length()) continue; if (line.compare(0, s_keys.length(), s_keys) == 0) { - keys = line.substr(s_keys.length()); - trim(keys); + auto k = line.substr(s_keys.length()); + trim(k); + keys.emplace_back(k); } else if (is_token(s_expected, line)) { if (line == "\\b") { expected_beep = true; } else { - expected = parse_source_string(line); + // allow multiple expected lines + expected.emplace_back(parse_source_string(line)); } } else if (is_token(s_expecterror, line)) { expected_error = true; @@ -297,8 +299,12 @@ LdmlEmbeddedTestSource::load_source( const km::core::path &path ) { } } - if (keys == "") { + if (keys.empty()) { // We must at least have a key sequence to run the test + std::cerr << "Need at least one key sequence." << std::endl; + return __LINE__; + } else if(keys.size() != expected.size()) { + std::cerr << "Need the same number of " << s_keys << " and " << s_expected << " lines." << std::endl; return __LINE__; } @@ -387,15 +393,19 @@ LdmlEmbeddedTestSource::vkey_to_event(std::string const &vk_event) { void LdmlEmbeddedTestSource::next_action(ldml_action &fillin) { - if (is_done) { + if (is_done || keys.empty()) { // We were already done. return done. fillin.type = LDML_ACTION_DONE; return; - } else if(keys.empty()) { - // Got to the end of the keys. time to check + } else if(keys[0].empty()) { + // Got to the end of a key set. time to check fillin.type = LDML_ACTION_CHECK_EXPECTED; - fillin.string = expected; // copy expected - is_done = true; // so we get DONE next time + fillin.string = expected[0]; // copy expected + expected.pop_front(); + keys.pop_front(); + if (keys.empty()) { + is_done = true; // so we get DONE next time + } } else { fillin.type = LDML_ACTION_KEY_EVENT; fillin.k = next_key(); @@ -406,7 +416,7 @@ LdmlEmbeddedTestSource::next_action(ldml_action &fillin) { key_event LdmlEmbeddedTestSource::next_key() { // mutate this->keys - return next_key(keys); + return next_key(keys[0]); } key_event diff --git a/core/tests/unit/ldml/ldml_test_source.hpp b/core/tests/unit/ldml/ldml_test_source.hpp index a0eed2ec8e1..4637af9bd44 100644 --- a/core/tests/unit/ldml/ldml_test_source.hpp +++ b/core/tests/unit/ldml/ldml_test_source.hpp @@ -149,8 +149,9 @@ class LdmlEmbeddedTestSource : public LdmlTestSource { key_event next_key(std::string &keys); key_event next_key(); - std::string keys = ""; - std::u16string expected = u"", context = u""; + std::deque keys; + std::deque expected; + std::u16string context = u""; bool expected_beep = false; bool expected_error = false; bool is_done = false; From 55483e4ccc83c80985ee2a2884e7c908889b55bc Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Fri, 5 Apr 2024 14:42:52 -0500 Subject: [PATCH 06/60] fix(core): update ldml test source to handle reset - correct invalidate logic Fixes: #10955 --- core/src/km_core_processevent_api.cpp | 8 +++++++- core/src/km_core_state_api.cpp | 8 +++++--- core/src/state.hpp | 4 ++-- .../unit/ldml/invalid-keyboards/ik_000_null_invalid.xml | 2 +- core/tests/unit/ldml/ldml.cpp | 2 +- core/tests/unit/ldml/ldml_test_source.cpp | 2 +- 6 files changed, 17 insertions(+), 9 deletions(-) diff --git a/core/src/km_core_processevent_api.cpp b/core/src/km_core_processevent_api.cpp index 8ccf0e4fa73..93ba9afbe43 100644 --- a/core/src/km_core_processevent_api.cpp +++ b/core/src/km_core_processevent_api.cpp @@ -52,8 +52,14 @@ km_core_process_event(km_core_state *state, } km_core_status status = state->processor().process_event(state, vk, modifier_state, is_key_down, event_flags); - if (state_should_clear_context(state, vk, modifier_state, is_key_down, event_flags)) { + if (state_should_invalidate_context(state, vk, modifier_state, is_key_down, event_flags)) { state->context().clear(); + // we are already committed. So we need to un-commit (remove the end of the vector) + if (state->actions().back().type == KM_CORE_IT_END) { + state->actions().pop_back(); + } + state->actions().push_invalidate_context(); + state->actions().commit(); } state->apply_actions_and_merge_app_context(); diff --git a/core/src/km_core_state_api.cpp b/core/src/km_core_state_api.cpp index a7773219393..abc835fd524 100644 --- a/core/src/km_core_state_api.cpp +++ b/core/src/km_core_state_api.cpp @@ -373,15 +373,17 @@ state_has_action_type(km_core_state *state, uint8_t type) { } bool -state_should_clear_context(km_core_state *state, +state_should_invalidate_context(km_core_state *state, km_core_virtual_key vk, uint16_t modifier_state, uint8_t is_key_down, uint16_t event_flags) { // if emit_keystroke is present, check if a context reset is needed if (state_has_action_type(state, KM_CORE_IT_EMIT_KEYSTROKE)) { - if (vk == KM_CORE_VKEY_BKSP && state_has_action_type(state, KM_CORE_IT_BACK)) { - return true; + if (vk == KM_CORE_VKEY_BKSP) { + if (!state_has_action_type(state, KM_CORE_IT_BACK)) { + return true; + } } else if (vkey_to_contextreset[vk]) { return true; } diff --git a/core/src/state.hpp b/core/src/state.hpp index d2840fe49c6..38795cd2325 100644 --- a/core/src/state.hpp +++ b/core/src/state.hpp @@ -188,7 +188,7 @@ struct km_core_state : public km::core::state /** * Evaluate the state and vkey used. - * Determine whether the context should be cleared. + * Determine whether the context should be invalidated. * @param state A pointer to the opaque state object. * @param vk A virtual key that was processed. * @param modifier_state The combinations of modifier keys set at the time key `vk` was pressed, bitmask @@ -198,7 +198,7 @@ struct km_core_state : public km::core::state * @return true if this is a state which should clear the context */ bool -state_should_clear_context(km_core_state *state, +state_should_invalidate_context(km_core_state *state, km_core_virtual_key vk, uint16_t modifier_state, uint8_t is_key_down, diff --git a/core/tests/unit/ldml/invalid-keyboards/ik_000_null_invalid.xml b/core/tests/unit/ldml/invalid-keyboards/ik_000_null_invalid.xml index a16eb613468..6e10b734e97 100644 --- a/core/tests/unit/ldml/invalid-keyboards/ik_000_null_invalid.xml +++ b/core/tests/unit/ldml/invalid-keyboards/ik_000_null_invalid.xml @@ -1,4 +1,4 @@ - Please select a Keyman keyboard to find related fonts. - + + + + No fonts have been found as suggestions for Keyboard %1$s . diff --git a/windows/src/engine/keyman/viskbd/UfrmOSKFontHelper.pas b/windows/src/engine/keyman/viskbd/UfrmOSKFontHelper.pas index 02da0309ced..fd2c82e8f4f 100644 --- a/windows/src/engine/keyman/viskbd/UfrmOSKFontHelper.pas +++ b/windows/src/engine/keyman/viskbd/UfrmOSKFontHelper.pas @@ -1,18 +1,18 @@ (* Name: UfrmOSKFontHelper Copyright: Copyright (C) SIL International. - Documentation: - Description: + Documentation: + Description: Create Date: 27 Mar 2008 Modified Date: 25 Sep 2014 Authors: mcdurdin - Related Files: - Dependencies: + Related Files: + Dependencies: - Bugs: - Todo: - Notes: + Bugs: + Todo: + Notes: History: 27 Mar 2008 - mcdurdin - Initial version I1374 20 Jul 2008 - mcdurdin - I1533 - Show hint for non-Unicode keyboards 29 Mar 2010 - mcdurdin - I2199 - Shift+click @@ -447,39 +447,47 @@ procedure TfrmOSKFontHelper.DisplayKeyboardFonts; FKeyboard := FCheckFontKeyboards.Keyboards[FLastSelectedKeyboardID]; if (FLastSelectedKeyboardID <> '') and Assigned(FKeyboard) then begin - SetLength(FChars, Length(FKeyboard.Chars)); - J := 0; - I := 1; - while I <= Length(FKeyboard.Chars) do // I2712 + if FKeyboard.Fonts.Count > 0 then begin - ch := FKeyboard.Chars[I]; - if Uni_IsSurrogate1(ch) and (I < Length(FKeyboard.Chars)) and Uni_IsSurrogate2(FKeyboard.Chars[I+1]) then + SetLength(FChars, Length(FKeyboard.Chars)); + J := 0; + I := 1; + while I <= Length(FKeyboard.Chars) do // I2712 begin - ch2 := FKeyboard.Chars[I+1]; - FChars[J] := Uni_SurrogateToUTF32(ch, ch2); + ch := FKeyboard.Chars[I]; + if Uni_IsSurrogate1(ch) and (I < Length(FKeyboard.Chars)) and Uni_IsSurrogate2(FKeyboard.Chars[I+1]) then + begin + ch2 := FKeyboard.Chars[I+1]; + FChars[J] := Uni_SurrogateToUTF32(ch, ch2); + Inc(I); + end + else + FChars[J] := Ord(ch); Inc(I); - end - else - FChars[J] := Ord(ch); - Inc(I); - Inc(J); - end; + Inc(J); + end; - SetLength(FChars, J); + SetLength(FChars, J); - grid.ColCount := Length(FChars) + 2; - grid.RowCount := FKeyboard.Fonts.Count; + grid.ColCount := Length(FChars) + 2; + grid.RowCount := FKeyboard.Fonts.Count; - for i := 0 to FKeyboard.Fonts.Count - 1 do - if FKeyboard.Fonts[i].Coverage < 50 then - begin - grid.RowCount := i; - Break; - end; + for i := 0 to FKeyboard.Fonts.Count - 1 do + if FKeyboard.Fonts[i].Coverage < 50 then + begin + grid.RowCount := i; + Break; + end; - FSelectedKeyboard := FKeyboard; - FormatGrid; - SetDisplay(''); + FSelectedKeyboard := FKeyboard; + FormatGrid; + SetDisplay(''); + end + else + begin + FSelectedKeyboard := FKeyboard; + SetDisplay(MsgFromIdFormat(S_OSK_FontHelper_NoFonts, [FSelectedKeyboard.Name])); + end; end else begin From 985d49b85698229214c21dcd00731fd0f3595a56 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Mon, 22 Apr 2024 15:28:10 +0700 Subject: [PATCH 25/60] script to call another script without cleaning environment --- resources/build/xcode-wrap.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100755 resources/build/xcode-wrap.sh diff --git a/resources/build/xcode-wrap.sh b/resources/build/xcode-wrap.sh new file mode 100755 index 00000000000..d989e43a497 --- /dev/null +++ b/resources/build/xcode-wrap.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +echo "wrap script for arch $(arch)" +if [[ $(arch) == i386 ]] && [[ -f /usr/local/bin/bash ]]; then + /usr/local/bin/bash -l "$@" || exit $? +elif [[ $(arch) == arm64 ]] && [[ -f /opt/homebrew/bin/bash ]]; then + /opt/homebrew/bin/bash -l "$@" || exit $? +else + >&2 echo "Could not start build due to missing homebrew bash" + exit 55 +fi \ No newline at end of file From 71377c3754b6a9ed3fa8a8cc1e1b54ddf61ce2b0 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Tue, 23 Apr 2024 08:56:56 +1000 Subject: [PATCH 26/60] fix(windows): Still need to guard against out of bound index --- windows/src/engine/keyman/viskbd/UfrmOSKFontHelper.pas | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/windows/src/engine/keyman/viskbd/UfrmOSKFontHelper.pas b/windows/src/engine/keyman/viskbd/UfrmOSKFontHelper.pas index fd2c82e8f4f..cefd0ce01a4 100644 --- a/windows/src/engine/keyman/viskbd/UfrmOSKFontHelper.pas +++ b/windows/src/engine/keyman/viskbd/UfrmOSKFontHelper.pas @@ -413,6 +413,11 @@ procedure TfrmOSKFontHelper.FormatGrid; i: Integer; m: Integer; begin + if FSelectedKeyboard.Fonts.Count = 0 then + begin + Exit; // Exit as grid needs at least one font + end; + grid.DefaultColWidth := tbSize.Position; grid.DefaultRowHeight := tbSize.Position; From faa828d55aa399852ef23d9348a32e721de7445a Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Tue, 23 Apr 2024 10:44:09 +1000 Subject: [PATCH 27/60] fix(windows): remove space before full stop --- windows/src/desktop/kmshell/xml/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/src/desktop/kmshell/xml/strings.xml b/windows/src/desktop/kmshell/xml/strings.xml index 8f7202dbdf0..11a8ef02293 100644 --- a/windows/src/desktop/kmshell/xml/strings.xml +++ b/windows/src/desktop/kmshell/xml/strings.xml @@ -1189,7 +1189,7 @@ keyboard that you use in Windows. Keyman keyboards will adapt automatically to - No fonts have been found as suggestions for Keyboard %1$s . + No fonts have been found as suggestions for Keyboard %1$s. From 534741aff63855ab47d4bbc577389ceb1d5eb06f Mon Sep 17 00:00:00 2001 From: sgschantz Date: Tue, 23 Apr 2024 10:10:13 +0700 Subject: [PATCH 28/60] create separate script for setting the version of the bundle --- ios/engine/KMEI/KeymanEngine.xcodeproj/project.pbxproj | 2 +- resources/build/set-bundle-versions.sh | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100755 resources/build/set-bundle-versions.sh diff --git a/ios/engine/KMEI/KeymanEngine.xcodeproj/project.pbxproj b/ios/engine/KMEI/KeymanEngine.xcodeproj/project.pbxproj index 0490f265501..b3f1a031f6c 100644 --- a/ios/engine/KMEI/KeymanEngine.xcodeproj/project.pbxproj +++ b/ios/engine/KMEI/KeymanEngine.xcodeproj/project.pbxproj @@ -1354,7 +1354,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = "/usr/bin/env bash"; - shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n. \"$KEYMAN_ROOT/resources/build/xcode-utils.sh\"\n\nphaseSetBundleVersions true\n"; + shellScript = "\"$KEYMAN_ROOT/resources/build/xcode-wrap.sh\" \"$KEYMAN_ROOT/resources/build/set-bundle-versions.sh\"\n"; showEnvVarsInLog = 0; }; CEC0C66F2410B005003E1BCD /* Run Script - upload dsyms to Sentry */ = { diff --git a/resources/build/set-bundle-versions.sh b/resources/build/set-bundle-versions.sh new file mode 100755 index 00000000000..ec475b510b9 --- /dev/null +++ b/resources/build/set-bundle-versions.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# Calls script in xcode-utils to update the version + +source "$KEYMAN_ROOT/resources/build/xcode-utils.sh" +phaseSetBundleVersions true \ No newline at end of file From 28806614a58fbf65e0386d1dd25d0b91c5f59320 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Tue, 23 Apr 2024 12:32:28 +0700 Subject: [PATCH 29/60] tagged and untagged versions of set-bundle-versions script --- ios/engine/KMEI/KeymanEngine.xcodeproj/project.pbxproj | 2 +- ios/keyman/Keyman/Keyman.xcodeproj/project.pbxproj | 2 +- ...set-bundle-versions.sh => set-bundle-versions-tagged.sh} | 0 resources/build/set-bundle-versions-untagged.sh | 6 ++++++ 4 files changed, 8 insertions(+), 2 deletions(-) rename resources/build/{set-bundle-versions.sh => set-bundle-versions-tagged.sh} (100%) create mode 100755 resources/build/set-bundle-versions-untagged.sh diff --git a/ios/engine/KMEI/KeymanEngine.xcodeproj/project.pbxproj b/ios/engine/KMEI/KeymanEngine.xcodeproj/project.pbxproj index b3f1a031f6c..9dc49f1739e 100644 --- a/ios/engine/KMEI/KeymanEngine.xcodeproj/project.pbxproj +++ b/ios/engine/KMEI/KeymanEngine.xcodeproj/project.pbxproj @@ -1354,7 +1354,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = "/usr/bin/env bash"; - shellScript = "\"$KEYMAN_ROOT/resources/build/xcode-wrap.sh\" \"$KEYMAN_ROOT/resources/build/set-bundle-versions.sh\"\n"; + shellScript = "\"$KEYMAN_ROOT/resources/build/xcode-wrap.sh\" \"$KEYMAN_ROOT/resources/build/set-bundle-versions-tagged.sh\"\n"; showEnvVarsInLog = 0; }; CEC0C66F2410B005003E1BCD /* Run Script - upload dsyms to Sentry */ = { diff --git a/ios/keyman/Keyman/Keyman.xcodeproj/project.pbxproj b/ios/keyman/Keyman/Keyman.xcodeproj/project.pbxproj index d1c3f929be3..f9d4c9192a5 100644 --- a/ios/keyman/Keyman/Keyman.xcodeproj/project.pbxproj +++ b/ios/keyman/Keyman/Keyman.xcodeproj/project.pbxproj @@ -1020,7 +1020,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = "/usr/bin/env bash"; - shellScript = ". \"$KEYMAN_ROOT/resources/build/xcode-utils.sh\"\n\n# Calls resource script to update build products' versioning.\nphaseSetBundleVersions\n"; + shellScript = "\"$KEYMAN_ROOT/resources/build/xcode-wrap.sh\" \"$KEYMAN_ROOT/resources/build/set-bundle-versions-untagged.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ diff --git a/resources/build/set-bundle-versions.sh b/resources/build/set-bundle-versions-tagged.sh similarity index 100% rename from resources/build/set-bundle-versions.sh rename to resources/build/set-bundle-versions-tagged.sh diff --git a/resources/build/set-bundle-versions-untagged.sh b/resources/build/set-bundle-versions-untagged.sh new file mode 100755 index 00000000000..d28e6248e4a --- /dev/null +++ b/resources/build/set-bundle-versions-untagged.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# Calls script in xcode-utils to update the version + +source "$KEYMAN_ROOT/resources/build/xcode-utils.sh" +phaseSetBundleVersions \ No newline at end of file From 00e850c55724200880784b9f2cfc204e6fb651a2 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Tue, 23 Apr 2024 13:24:40 +0700 Subject: [PATCH 30/60] add script to update version string in settings --- ios/keyman/Keyman/Keyman.xcodeproj/project.pbxproj | 2 +- resources/build/set-bundle-versions-and-settings.sh | 11 +++++++++++ resources/build/set-bundle-versions-tagged.sh | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100755 resources/build/set-bundle-versions-and-settings.sh diff --git a/ios/keyman/Keyman/Keyman.xcodeproj/project.pbxproj b/ios/keyman/Keyman/Keyman.xcodeproj/project.pbxproj index f9d4c9192a5..af10e998d9a 100644 --- a/ios/keyman/Keyman/Keyman.xcodeproj/project.pbxproj +++ b/ios/keyman/Keyman/Keyman.xcodeproj/project.pbxproj @@ -1002,7 +1002,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = "/usr/bin/env bash"; - shellScript = ". \"$KEYMAN_ROOT/resources/build/xcode-utils.sh\"\n\n# Calls resource script to update build products' versioning.\n# true: applies VERSION_WITH_TAG to custom KeymanVersionWithTag plist member used for in-app display\nphaseSetBundleVersions true\n\n# Also updates the version string for Settings\nsetSettingsBundleVersion\n"; + shellScript = "\"$KEYMAN_ROOT/resources/build/xcode-wrap.sh\" \"$KEYMAN_ROOT/resources/build/set-bundle-versions-and-settings.sh\"\n"; showEnvVarsInLog = 0; }; CED3CFDA240E49DF001540A1 /* ShellScript */ = { diff --git a/resources/build/set-bundle-versions-and-settings.sh b/resources/build/set-bundle-versions-and-settings.sh new file mode 100755 index 00000000000..15a9aa9b2fa --- /dev/null +++ b/resources/build/set-bundle-versions-and-settings.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +# Calls script in xcode-utils to update the version +# true: applies VERSION_WITH_TAG to custom KeymanVersionWithTag plist member used for in-app display +# updates the version string for Settings + +source "$KEYMAN_ROOT/resources/build/xcode-utils.sh" + +phaseSetBundleVersions true + +setSettingsBundleVersion \ No newline at end of file diff --git a/resources/build/set-bundle-versions-tagged.sh b/resources/build/set-bundle-versions-tagged.sh index ec475b510b9..a4078ee99a8 100755 --- a/resources/build/set-bundle-versions-tagged.sh +++ b/resources/build/set-bundle-versions-tagged.sh @@ -1,6 +1,7 @@ #!/bin/bash # Calls script in xcode-utils to update the version +# true: applies VERSION_WITH_TAG to custom KeymanVersionWithTag plist member used for in-app display source "$KEYMAN_ROOT/resources/build/xcode-utils.sh" phaseSetBundleVersions true \ No newline at end of file From ba8dcad949aa16d44dde333dabfe676a506e563b Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Wed, 24 Apr 2024 08:22:41 -0500 Subject: [PATCH 31/60] Apply suggestions from code review Co-authored-by: Marc Durdin --- core/src/km_core_state_api.cpp | 11 ++++++++--- core/src/vkey_to_contextreset.cpp | 2 +- core/tests/unit/ldml/ldml.cpp | 4 ++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/core/src/km_core_state_api.cpp b/core/src/km_core_state_api.cpp index 9177dd82de9..0f3fd7f1126 100644 --- a/core/src/km_core_state_api.cpp +++ b/core/src/km_core_state_api.cpp @@ -385,11 +385,16 @@ state_should_invalidate_context(km_core_state *state, // if emit_keystroke is present, check if a context reset is needed if (state_has_action_type(state, KM_CORE_IT_EMIT_KEYSTROKE)) { if ( - // always reset on backspace + // when a backspace keystroke is emitted, it is because we are at the start of + // context, and we want to give the application the chance to process it, e.g. + // by moving to previous field. Note that context manipulation does not result + // in an emit_keystroke backspace action, as this is handled through the + // `code_points_to_delete` field. So we always invalidate context when a + // processor emits a backspace. vk == KM_CORE_VKEY_BKSP || - // certain modifiers reset + // certain modifiers invalidate context modifier_should_contextreset(modifier_state) || - // reset on frame keys + // most frame keys invalidate context vkey_should_contextreset(vk)) { return true; } diff --git a/core/src/vkey_to_contextreset.cpp b/core/src/vkey_to_contextreset.cpp index ffe6b3f7d81..914aa3e816b 100644 --- a/core/src/vkey_to_contextreset.cpp +++ b/core/src/vkey_to_contextreset.cpp @@ -3,7 +3,7 @@ namespace km { namespace core { -bool vkey_to_contextreset[vkey_to_contextreset_count] = { +bool vkey_should_invalidate_context[vkey_should_invalidate_context_count] = { true, //L"K_?00", // &H0 true, //L"K_LBUTTON", // &H1 true, //L"K_RBUTTON", // &H2 diff --git a/core/tests/unit/ldml/ldml.cpp b/core/tests/unit/ldml/ldml.cpp index 6b19bb57870..5d133a93c74 100644 --- a/core/tests/unit/ldml/ldml.cpp +++ b/core/tests/unit/ldml/ldml.cpp @@ -331,8 +331,8 @@ run_test(const km::core::path &source, const km::core::path &compiled, km::tests if (state_should_invalidate_context(test_state, p.vk, p.modifier_state | test_source.caps_lock_state(), key_down, KM_CORE_EVENT_FLAG_DEFAULT)) { - test_context.clear(); - text_store.clear(); + test_context.clear(); + text_store.clear(); } for (auto act = km_core_state_action_items(test_state, nullptr); act->type != KM_CORE_IT_END; act++) { apply_action(test_state, *act, text_store, test_context, test_source, test_context); From f516538b31875fa103dcc695931d5cc5646bcbc0 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Wed, 24 Apr 2024 08:39:35 -0500 Subject: [PATCH 32/60] chore(core): outdent test file per review comment --- core/tests/unit/ldml/ldml.cpp | 122 +++++++++++++++++----------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/core/tests/unit/ldml/ldml.cpp b/core/tests/unit/ldml/ldml.cpp index 5d133a93c74..9a5c7f60e34 100644 --- a/core/tests/unit/ldml/ldml.cpp +++ b/core/tests/unit/ldml/ldml.cpp @@ -195,72 +195,72 @@ apply_action( /** * verify the current context -*/ + */ void -verify_context(std::u16string& text_store, km_core_state* &test_state, std::vector &test_context) { - // Compare context and text store at each step - should be identical - size_t n = 0; - km_core_context_item* citems = nullptr; - try_status(km_core_context_get(km_core_state_context(test_state), &citems)); - try_status(context_items_to_utf16(citems, nullptr, &n)); - km_core_cp *buf = new km_core_cp[n]; - try_status(context_items_to_utf16(citems, buf, &n)); - std::cout << "context (raw): "; // output including markers (which aren't in 'buf' here) - for (auto ci = citems; ci->type != KM_CORE_CT_END; ci++) { - switch(ci->type) { - case KM_CORE_CT_CHAR: - std::cout << "U+" << std::setw(4) << std::hex << ci->character << std::dec << " "; - break; - case KM_CORE_CT_MARKER: - std::cout << "\\m{" << ci->character << "} "; - break; - default: - std::cout << "type#" << ci->type << " "; - } +verify_context(std::u16string &text_store, km_core_state *&test_state, std::vector &test_context) { + // Compare context and text store at each step - should be identical + size_t n = 0; + km_core_context_item *citems = nullptr; + try_status(km_core_context_get(km_core_state_context(test_state), &citems)); + try_status(context_items_to_utf16(citems, nullptr, &n)); + km_core_cp *buf = new km_core_cp[n]; + try_status(context_items_to_utf16(citems, buf, &n)); + std::cout << "context (raw): "; // output including markers (which aren't in 'buf' here) + for (auto ci = citems; ci->type != KM_CORE_CT_END; ci++) { + switch (ci->type) { + case KM_CORE_CT_CHAR: + std::cout << "U+" << std::setw(4) << std::hex << ci->character << std::dec << " "; + break; + case KM_CORE_CT_MARKER: + std::cout << "\\m{" << ci->character << "} "; + break; + default: + std::cout << "type#" << ci->type << " "; } - std::cout << std::endl; - std::cout << "context : " << string_to_hex(buf) << " [" << buf << "]" << std::endl; - std::cout << "testcontext "; - std::cout.fill('0'); - for (auto i = test_context.begin(); i < test_context.end(); i++) { - switch(i->type) { - case KM_CORE_CT_CHAR: - std::cout << "U+" << std::setw(4) << std::hex << i->character << std::dec << " "; - break; - case KM_CORE_CT_MARKER: - std::cout << "\\m{" << i->character << "} "; - break; - default: - std::cout << "type#" << i->type << " "; - } + } + std::cout << std::endl; + std::cout << "context : " << string_to_hex(buf) << " [" << buf << "]" << std::endl; + std::cout << "testcontext "; + std::cout.fill('0'); + for (auto i = test_context.begin(); i < test_context.end(); i++) { + switch (i->type) { + case KM_CORE_CT_CHAR: + std::cout << "U+" << std::setw(4) << std::hex << i->character << std::dec << " "; + break; + case KM_CORE_CT_MARKER: + std::cout << "\\m{" << i->character << "} "; + break; + default: + std::cout << "type#" << i->type << " "; } - std::cout << std::endl; - - // Verify that both our local test_context and the core's test_state.context have - // not diverged - auto ci = citems; - for (auto test_ci = test_context.begin(); ; ci++, test_ci++) { - // skip over markers, they won't be in test_context - while (ci->type == KM_CORE_CT_MARKER) { - ci++; - } - // exit if BOTH are at end. - if (ci->type == KM_CORE_CT_END && test_ci == test_context.end()) { - break; // success - } - // fail if only ONE is at end - assert(ci->type != KM_CORE_CT_END && test_ci != test_context.end()); - // fail if type and marker don't match. - assert(test_ci->type == ci->type && test_ci->marker == ci->marker); + } + std::cout << std::endl; + + // Verify that both our local test_context and the core's test_state.context have + // not diverged + auto ci = citems; + for (auto test_ci = test_context.begin();; ci++, test_ci++) { + // skip over markers, they won't be in test_context + while (ci->type == KM_CORE_CT_MARKER) { + ci++; } - - km_core_context_items_dispose(citems); - if (text_store != buf) { - std::cerr << "text store has diverged from buf" << std::endl; - std::cerr << "text store: " << string_to_hex(text_store) << " [" << text_store << "]" << std::endl; - assert(false); + // exit if BOTH are at end. + if (ci->type == KM_CORE_CT_END && test_ci == test_context.end()) { + break; // success } - delete[] buf; + // fail if only ONE is at end + assert(ci->type != KM_CORE_CT_END && test_ci != test_context.end()); + // fail if type and marker don't match. + assert(test_ci->type == ci->type && test_ci->marker == ci->marker); + } + + km_core_context_items_dispose(citems); + if (text_store != buf) { + std::cerr << "text store has diverged from buf" << std::endl; + std::cerr << "text store: " << string_to_hex(text_store) << " [" << text_store << "]" << std::endl; + assert(false); + } + delete[] buf; } int From 627703734a1cc163ad9854506e73bab0a5c6ff2a Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Wed, 24 Apr 2024 18:00:41 +0200 Subject: [PATCH 33/60] fix(linux): Fix icon for .kmp files It seems some Ubuntu versions ignore the `icon` field and only use `generic-icon`, so this change adds that field. This will fix displaying the icon on newer Ubuntu versions. And since we keep the `icon` field it should still work everywhere else. Fixes #11144. --- linux/keyman-config/resources/keyman.sharedmimeinfo | 1 + 1 file changed, 1 insertion(+) diff --git a/linux/keyman-config/resources/keyman.sharedmimeinfo b/linux/keyman-config/resources/keyman.sharedmimeinfo index 569866b403b..c1bb65e33da 100644 --- a/linux/keyman-config/resources/keyman.sharedmimeinfo +++ b/linux/keyman-config/resources/keyman.sharedmimeinfo @@ -5,6 +5,7 @@ + Keyman keyboard installation link From f40e1ff8d87e7bd44ce7e331d028afcfbf9855e6 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Thu, 25 Apr 2024 09:13:21 +0700 Subject: [PATCH 34/60] change all mac project settings minimum supported version from 10.10 Yosemite to 10.13 High Sierra --- mac/Keyman4Mac/Keyman4Mac.xcodeproj/project.pbxproj | 6 ++++-- mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj | 8 ++++---- .../KeymanEngine4Mac.xcodeproj/project.pbxproj | 6 ++++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/mac/Keyman4Mac/Keyman4Mac.xcodeproj/project.pbxproj b/mac/Keyman4Mac/Keyman4Mac.xcodeproj/project.pbxproj index ff087f05441..bd4cc6a16bb 100644 --- a/mac/Keyman4Mac/Keyman4Mac.xcodeproj/project.pbxproj +++ b/mac/Keyman4Mac/Keyman4Mac.xcodeproj/project.pbxproj @@ -399,7 +399,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.13; ONLY_ACTIVE_ARCH = NO; PRODUCT_BUNDLE_IDENTIFIER = org.sil.Keyman4Mac; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -425,7 +425,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.13; PRODUCT_BUNDLE_IDENTIFIER = org.sil.Keyman4Mac; PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_VERSION = 0.0.1; @@ -451,6 +451,7 @@ "@executable_path/../Frameworks", "@loader_path/../Frameworks", ); + MACOSX_DEPLOYMENT_TARGET = 10.13; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Keyman4Mac.app/Contents/MacOS/Keyman4Mac"; }; @@ -471,6 +472,7 @@ "@executable_path/../Frameworks", "@loader_path/../Frameworks", ); + MACOSX_DEPLOYMENT_TARGET = 10.13; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Keyman4Mac.app/Contents/MacOS/Keyman4Mac"; }; diff --git a/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj b/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj index cf83375ba81..3ba5904757b 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj +++ b/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj @@ -1314,7 +1314,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.13; ONLY_ACTIVE_ARCH = YES; OTHER_CODE_SIGN_FLAGS = "--timestamp --verbose"; PRODUCT_BUNDLE_IDENTIFIER = "keyman.inputmethod.$(PRODUCT_NAME:rfc1034identifier)"; @@ -1358,7 +1358,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.13; OTHER_CODE_SIGN_FLAGS = "--timestamp --verbose"; PRODUCT_BUNDLE_IDENTIFIER = "keyman.inputmethod.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1402,7 +1402,7 @@ "@loader_path/../Frameworks", "@loader_path/Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.13; PRODUCT_BUNDLE_IDENTIFIER = org.sil.consoleTestbed.KeymanTests; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1436,7 +1436,7 @@ "@executable_path/../Frameworks", "@loader_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.13; PRODUCT_BUNDLE_IDENTIFIER = org.sil.consoleTestbed.KeymanTests; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/mac/KeymanEngine4Mac/KeymanEngine4Mac.xcodeproj/project.pbxproj b/mac/KeymanEngine4Mac/KeymanEngine4Mac.xcodeproj/project.pbxproj index 0a46301b7f5..918dc733256 100644 --- a/mac/KeymanEngine4Mac/KeymanEngine4Mac.xcodeproj/project.pbxproj +++ b/mac/KeymanEngine4Mac/KeymanEngine4Mac.xcodeproj/project.pbxproj @@ -685,7 +685,7 @@ "$(PROJECT_DIR)/../../core/build/mac-x86_64/debug/subprojects/icu/source/i18n", "$(PROJECT_DIR)/../../core/build/mac/debug", ); - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.13; ONLY_ACTIVE_ARCH = NO; "OTHER_LDFLAGS[arch=*]" = "-lstdc++"; PRODUCT_BUNDLE_IDENTIFIER = org.sil.KeymanEngine4Mac; @@ -728,7 +728,7 @@ "$(PROJECT_DIR)/../../core/build/mac-x86_64/release/subprojects/icu/source/i18n", "$(PROJECT_DIR)/../../core/build/mac/release", ); - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.13; "OTHER_LDFLAGS[arch=*]" = "-lstdc++"; PRODUCT_BUNDLE_IDENTIFIER = org.sil.KeymanEngine4Mac; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -753,6 +753,7 @@ ); INFOPLIST_FILE = KeymanEngine4MacTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.13; PRODUCT_BUNDLE_IDENTIFIER = "Tavultesoft.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -768,6 +769,7 @@ ); INFOPLIST_FILE = KeymanEngine4MacTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.13; PRODUCT_BUNDLE_IDENTIFIER = "Tavultesoft.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; }; From 888ec56d5abce1baa0dce89695a9f886a7d163b5 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Thu, 25 Apr 2024 09:29:35 +0200 Subject: [PATCH 35/60] chore(linux): Prepare for stable release - Adjust branch name - Update Debian standards version - Update dependency name (`pkg-config` is deprecated and replaced by `pkgconf`) --- linux/debian/control | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/linux/debian/control b/linux/debian/control index 6eeb24450ab..611d586225c 100644 --- a/linux/debian/control +++ b/linux/debian/control @@ -23,7 +23,7 @@ Build-Depends: metacity, ninja-build, perl, - pkg-config, + pkgconf, python3-all (>= 3.5), python3-dbus, python3-gi, @@ -41,9 +41,9 @@ Build-Depends: python3-xdg, xserver-xephyr, xvfb, -Standards-Version: 4.6.2 -Vcs-Git: https://github.com/keymanapp/keyman.git -b beta [linux/debian] -Vcs-Browser: https://github.com/keymanapp/keyman/tree/beta/linux/debian +Standards-Version: 4.7.0 +Vcs-Git: https://github.com/keymanapp/keyman.git -b stable-17.0 [linux/debian] +Vcs-Browser: https://github.com/keymanapp/keyman/tree/stable-17.0/linux/debian Homepage: https://www.keyman.com Rules-Requires-Root: binary-targets From cd867ba80157ecb04f96a55dc45884fa8b74fe6c Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Thu, 25 Apr 2024 08:58:47 -0500 Subject: [PATCH 36/60] fix(core): update vkey_should_invalidate_context per comment Fixes #10955 --- core/src/vkey_to_contextreset.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/vkey_to_contextreset.hpp b/core/src/vkey_to_contextreset.hpp index b976d3ae8ac..c7c6b1953d0 100644 --- a/core/src/vkey_to_contextreset.hpp +++ b/core/src/vkey_to_contextreset.hpp @@ -6,13 +6,13 @@ namespace km { namespace core { -static const auto vkey_to_contextreset_count = 256; +static const auto vkey_should_invalidate_context_count = 256; /** true for any vkeys which require a context reset (such as frame keys) */ -extern bool vkey_to_contextreset[vkey_to_contextreset_count]; +extern bool vkey_should_invalidate_context[vkey_should_invalidate_context_count]; /** @return true for any vkeys which require a context reset (such as frame keys) */ inline bool vkey_should_contextreset(km_core_virtual_key vk) { - return ((vk < vkey_to_contextreset_count) && vkey_to_contextreset[vk]); + return ((vk < vkey_should_invalidate_context_count) && vkey_should_invalidate_context[vk]); } /** @return true for modifier states that are involved with context reset */ From fa1fd7515772ec3872f3dbc6bfd770864eb737aa Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Thu, 25 Apr 2024 16:59:20 -0500 Subject: [PATCH 37/60] fix(core): ldml fix for multiple marker deletion - current code only deletes a single marker and falls through - update the ldml test code, get rid of 'expected character' backspace logic (now that we have context object) - update test cases --- core/src/ldml/ldml_processor.cpp | 12 ++-- .../unit/ldml/keyboards/k_210_marker-test.xml | 61 +++++++++++++++++++ .../unit/ldml/keyboards/k_210_marker.xml | 12 +++- core/tests/unit/ldml/ldml.cpp | 61 ++++++++++--------- 4 files changed, 108 insertions(+), 38 deletions(-) diff --git a/core/src/ldml/ldml_processor.cpp b/core/src/ldml/ldml_processor.cpp index b39d80d56d0..f90fcfaa946 100644 --- a/core/src/ldml/ldml_processor.cpp +++ b/core/src/ldml/ldml_processor.cpp @@ -246,17 +246,15 @@ void ldml_event_state::emit_backspace() { // TODO-LDML: emoji backspace auto end = state->context().rbegin(); while (end != state->context().rend()) { - if ((*end).type == KM_CORE_CT_CHAR) { + if (end->type == KM_CORE_CT_CHAR) { actions.code_points_to_delete++; state->context().pop_back(); return; - } else if ((*end).type == KM_CORE_BT_MARKER) { - // remove any markers before char - state->context().pop_back(); - end++; - // loop again } - } + // else loop again + assert(end->type != KM_CORE_CT_END); // inappropriate here. + state->context().pop_back(); + } /* We couldn't find a character at end of context (context is empty), so we'll pass the backspace keystroke on to the app to process; the diff --git a/core/tests/unit/ldml/keyboards/k_210_marker-test.xml b/core/tests/unit/ldml/keyboards/k_210_marker-test.xml index 5a36d1941b3..22865b12c5c 100644 --- a/core/tests/unit/ldml/keyboards/k_210_marker-test.xml +++ b/core/tests/unit/ldml/keyboards/k_210_marker-test.xml @@ -62,4 +62,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/tests/unit/ldml/keyboards/k_210_marker.xml b/core/tests/unit/ldml/keyboards/k_210_marker.xml index 0d25de75ac6..6f2eb9021a9 100644 --- a/core/tests/unit/ldml/keyboards/k_210_marker.xml +++ b/core/tests/unit/ldml/keyboards/k_210_marker.xml @@ -17,14 +17,15 @@ + - + - + @@ -56,5 +57,12 @@ + + + + + + + diff --git a/core/tests/unit/ldml/ldml.cpp b/core/tests/unit/ldml/ldml.cpp index 6b19bb57870..13450c94672 100644 --- a/core/tests/unit/ldml/ldml.cpp +++ b/core/tests/unit/ldml/ldml.cpp @@ -39,8 +39,6 @@ namespace { bool g_beep_found = false; -bool g_already_complained = false; - km_core_option_item test_env_opts[] = { KM_CORE_OPTIONS_END @@ -115,49 +113,54 @@ apply_action( {(uint32_t)act.marker}}); break; case KM_CORE_IT_BACK: + { + // single char removed in context + km_core_usv ch = 0; + bool matched_text = false; + // assume the backspace came from set_action() and there's no further info. + assert(act.backspace.expected_type == KM_CORE_BT_CHAR); + assert(act.backspace.expected_value == 0); // It is valid for a backspace to be received with an empty text store // as the user can press backspace with no text in the store and Keyman // will pass that back to the client, as the client may do additional // processing at start of a text store, e.g. delete from a previous cell // in a table. Or, if Keyman has a cached context, then there may be // additional text in the text store that Keyman can't see. - if (act.backspace.expected_type == KM_CORE_BT_MARKER) { - assert(!context.empty()); - assert(context.back().type == KM_CORE_CT_MARKER); - context.pop_back(); - // no change to text store. - } else if (text_store.length() > 0) { + // If there's anything in the text store, pop it off. Two if a pair. + if (text_store.length() > 0) { assert(!context.empty() && !text_store.empty()); - km_core_usv ch = text_store.back(); + const auto ch1 = text_store.back(); text_store.pop_back(); - if (text_store.length() > 0 && Uni_IsSurrogate2(ch)) { - auto ch1 = text_store.back(); - if (Uni_IsSurrogate1(ch1)) { + if (text_store.length() > 0 && Uni_IsSurrogate2(ch1)) { + const auto ch2 = text_store.back(); + if (Uni_IsSurrogate1(ch2)) { // We'll only pop the next character off it is actually a // surrogate pair - ch = Uni_SurrogateToUTF32(ch1, ch); + ch = Uni_SurrogateToUTF32(ch2, ch1); // reverse order text_store.pop_back(); + } else { + ch = 0xFFFF; // unpaired } + } else { + ch = ch1; // single char } - if (act.backspace.expected_type == KM_CORE_BT_CHAR) { - if (act.backspace.expected_value == 0) { - // using set_action() doesn't provide for expected backspaces, so can't validate here - // only complain once. - if (!g_already_complained) { - std::cerr << "Note: TODO-LDML: not validating backspace.expected_value nor ch - no information available." << std::endl; - g_already_complained = true; - } - } else { - assert(ch == act.backspace.expected_value); - assert(context.back().character == ch); + } else { + matched_text = true; // no text to match as context is empty. + } + // now, we need to simulate what ldml_processor::emit_backspace() is going to do. + auto end = context.rbegin(); + while (end != context.rend()) { + if (end->type == KM_CORE_CT_CHAR) { + assert(!matched_text); + assert_equal(end->character, ch); // expect popped char to be same as what's in context + matched_text = true; + context.pop_back(); + break; // exit on first real char } - assert(context.back().type == KM_CORE_CT_CHAR); + assert(end->type != KM_CORE_CT_END); // inappropriate here. context.pop_back(); - } else { - // assume it's otherwise KM_CORE_BT_UNKNOWN - assert(act.backspace.expected_type == KM_CORE_BT_UNKNOWN); - assert(context.empty()); // if KM_CORE_BT_UNKNOWN, context should be empty. } + assert(matched_text); } break; case KM_CORE_IT_PERSIST_OPT: From 571fbb6c5001ecbcf85a7c25b72437fc3403579a Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 26 Apr 2024 10:07:01 +0700 Subject: [PATCH 38/60] fix(developer): don't include DTD in visual keyboard export The DTD reference at tavultesoft.com is no longer valid. In order for the .xml file to be parseable, we need to remove the DTD reference. This resolves the issue where the emitted .html file is blank, and adds an additional step of verifying that the .xml file loads successfully in the XML to HTML transform. --- .../VisualKeyboardExportHTML.pas | 23 ++++++++++++------- .../VisualKeyboardExportXML.pas | 15 ++++++------ 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/common/windows/delphi/visualkeyboard/VisualKeyboardExportHTML.pas b/common/windows/delphi/visualkeyboard/VisualKeyboardExportHTML.pas index 8272bf9f6e9..614f3df8d3d 100644 --- a/common/windows/delphi/visualkeyboard/VisualKeyboardExportHTML.pas +++ b/common/windows/delphi/visualkeyboard/VisualKeyboardExportHTML.pas @@ -1,18 +1,18 @@ (* Name: VisualKeyboardExportHTML Copyright: Copyright (C) SIL International. - Documentation: - Description: + Documentation: + Description: Create Date: 20 Jun 2006 Modified Date: 8 Jun 2012 Authors: mcdurdin - Related Files: - Dependencies: + Related Files: + Dependencies: - Bugs: - Todo: - Notes: + Bugs: + Todo: + Notes: History: 20 Jun 2006 - mcdurdin - Initial version 23 Aug 2006 - mcdurdin - Initial refactor for new visual keyboard 04 Dec 2006 - mcdurdin - Support new XML+XSLT OSK export @@ -162,7 +162,14 @@ procedure TVisualKeyboardExportHTML.ExportToFile(FileName: WideString); try doc.async := False; doc.validateOnParse := False; - doc.load(stemp); + if not doc.load(stemp) then + begin + if doc.parseError <> nil then + begin + ShowMessage('Could not load XML: '+doc.parseError.reason); + Exit; + end; + end; xsldoc := ComsFreeThreadedDOMDocument.Create; try xsldoc.async := False; diff --git a/common/windows/delphi/visualkeyboard/VisualKeyboardExportXML.pas b/common/windows/delphi/visualkeyboard/VisualKeyboardExportXML.pas index 3ef240bc466..9ee294f6cce 100644 --- a/common/windows/delphi/visualkeyboard/VisualKeyboardExportXML.pas +++ b/common/windows/delphi/visualkeyboard/VisualKeyboardExportXML.pas @@ -1,18 +1,18 @@ (* Name: VisualKeyboardExportXML Copyright: Copyright (C) SIL International. - Documentation: - Description: + Documentation: + Description: Create Date: 4 Dec 2006 Modified Date: 26 Jun 2012 Authors: mcdurdin - Related Files: - Dependencies: + Related Files: + Dependencies: - Bugs: - Todo: - Notes: + Bugs: + Todo: + Notes: History: 04 Dec 2006 - mcdurdin - Export to version 7, UTF-8, fix text encoding for key caps 22 Jan 2007 - mcdurdin - Export XML files to filename_xml_files subfolder 19 Mar 2007 - mcdurdin - I699 - Fix crash when exporting OSK to HTML/XML @@ -65,7 +65,6 @@ function TVisualKeyboardExportXML.XMLWideString(FileName: WideString): WideStrin nl: WideString = #13#10; begin s := '' + nl; - s := s + '' + nl; s := s + '' + nl; s := s + '
' + nl; s := s + ' '+SKeymanVersion70+'' + nl; From ebb6631ab62bb0500bb61aff61f558c79de2d572 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Fri, 26 Apr 2024 10:22:58 +0700 Subject: [PATCH 39/60] change macOS target version to 10.13, update versions in markdown files and Podfile --- mac/Keyman4Mac/Keyman4Mac.xcodeproj/project.pbxproj | 4 ++-- mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj | 4 ++-- mac/Keyman4MacIM/Podfile | 2 +- mac/Keyman4MacIM/Podfile.lock | 2 +- .../KeymanEngine4Mac.xcodeproj/project.pbxproj | 4 ++-- mac/help/about/requirements.md | 6 ++---- mac/help/common/os.md | 6 +++--- mac/help/common/requirements.md | 2 +- 8 files changed, 14 insertions(+), 16 deletions(-) diff --git a/mac/Keyman4Mac/Keyman4Mac.xcodeproj/project.pbxproj b/mac/Keyman4Mac/Keyman4Mac.xcodeproj/project.pbxproj index bd4cc6a16bb..25cc7ca8005 100644 --- a/mac/Keyman4Mac/Keyman4Mac.xcodeproj/project.pbxproj +++ b/mac/Keyman4Mac/Keyman4Mac.xcodeproj/project.pbxproj @@ -328,7 +328,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -375,7 +375,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; }; diff --git a/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj b/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj index 3ba5904757b..ad6e2710d05 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj +++ b/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj @@ -1227,7 +1227,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -1275,7 +1275,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; }; diff --git a/mac/Keyman4MacIM/Podfile b/mac/Keyman4MacIM/Podfile index cd8e971f23b..586f4ed8834 100644 --- a/mac/Keyman4MacIM/Podfile +++ b/mac/Keyman4MacIM/Podfile @@ -1,5 +1,5 @@ # Uncomment the next line to define a global platform for your project -platform :osx, '10.10' +platform :osx, '10.13' use_frameworks! target 'Keyman' do diff --git a/mac/Keyman4MacIM/Podfile.lock b/mac/Keyman4MacIM/Podfile.lock index a161db72ea0..e73768d2f75 100644 --- a/mac/Keyman4MacIM/Podfile.lock +++ b/mac/Keyman4MacIM/Podfile.lock @@ -19,6 +19,6 @@ CHECKOUT OPTIONS: SPEC CHECKSUMS: Sentry: 7d075cae43a9a518fdd51e258b6212f0527c51cd -PODFILE CHECKSUM: 521a56f741ba869ecf0fd64a7773173265973269 +PODFILE CHECKSUM: d1e1f991bca05599c1667234a03e9f365d109ed0 COCOAPODS: 1.11.2 diff --git a/mac/KeymanEngine4Mac/KeymanEngine4Mac.xcodeproj/project.pbxproj b/mac/KeymanEngine4Mac/KeymanEngine4Mac.xcodeproj/project.pbxproj index 918dc733256..d5c330e1f4d 100644 --- a/mac/KeymanEngine4Mac/KeymanEngine4Mac.xcodeproj/project.pbxproj +++ b/mac/KeymanEngine4Mac/KeymanEngine4Mac.xcodeproj/project.pbxproj @@ -594,7 +594,7 @@ ); INSTALL_PATH = ""; "LIBRARY_SEARCH_PATHS[arch=*]" = "$(PROJECT_DIR)/../../core/build/mac/debug"; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -647,7 +647,7 @@ ); INSTALL_PATH = ""; "LIBRARY_SEARCH_PATHS[arch=*]" = "$(PROJECT_DIR)/../../core/build/mac/release"; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; VERSIONING_SYSTEM = "apple-generic"; diff --git a/mac/help/about/requirements.md b/mac/help/about/requirements.md index 1775c0dd8c2..d92272a7304 100644 --- a/mac/help/about/requirements.md +++ b/mac/help/about/requirements.md @@ -6,19 +6,17 @@ title: System Requirements Keyman supports the following Mac operating systems: -* Mac OS X Yosemite (10.10) -* Mac OS X El Capitan (10.11) -* macOS Sierra (10.12) * macOS High Sierra (10.13) * macOS Mojave (10.14) * macOS Catalina (10.15) * macOS Big Sur (11.0) * macOS Monterey (12.0) * macOS Ventura (13.0) +* macOS Sonoma (14.0) Keyman should also work on future releases of macOS, even if they are not yet listed here. ## Resource Requirements Keyman for macOS has minimal resource requirements. Any computer running -Mac OS X 10.10 or later should be able to run Keyman for macOS without trouble. +Mac OS X 10.13 or later should be able to run Keyman for macOS without trouble. diff --git a/mac/help/common/os.md b/mac/help/common/os.md index e0c05096c43..4362eafaa73 100644 --- a/mac/help/common/os.md +++ b/mac/help/common/os.md @@ -6,10 +6,10 @@ title: Which versions does Keyman for macOS work with? Keyman supports the following Mac operating systems: -* Mac OS X Yosemite (10.10) -* Mac OS X El Capitan (10.11) -* macOS Sierra (10.12) * macOS High Sierra (10.13) * macOS Mojave (10.14) * macOS Catalina (10.15) * macOS Big Sur (11.0) +* macOS Monterey (12.0) +* macOS Ventura (13.0) +* macOS Sonoma (14.0) diff --git a/mac/help/common/requirements.md b/mac/help/common/requirements.md index b54aa64bfde..8b1c5f77592 100644 --- a/mac/help/common/requirements.md +++ b/mac/help/common/requirements.md @@ -3,4 +3,4 @@ title: What are Keyman's hardware requirements? --- Keyman for macOS has minimal resource requirements. Any computer running -Mac OS X 10.10 or later should be able to run Keyman for macOS without trouble. +Mac OS X 10.13 or later should be able to run Keyman for macOS without trouble. From e686dbe67d20814880af8e55549218ff08871921 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Fri, 26 Apr 2024 10:15:32 +0700 Subject: [PATCH 40/60] fix(web): longpress shortcut activation should be based on purely-northward component change(web): stricter threshold for up-flick shortcut --- .../engine/osk/src/input/gestures/specsForLayout.ts | 5 ++++- web/src/engine/osk/src/visualKeyboard.ts | 12 ++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/web/src/engine/osk/src/input/gestures/specsForLayout.ts b/web/src/engine/osk/src/input/gestures/specsForLayout.ts index 4fb8806e267..f9bc02f4614 100644 --- a/web/src/engine/osk/src/input/gestures/specsForLayout.ts +++ b/web/src/engine/osk/src/input/gestures/specsForLayout.ts @@ -464,7 +464,10 @@ export function longpressContactModel(params: GestureParams, enabledFlicks: bool * each side of due N in total. */ if((enabledFlicks && spec.permitsFlick(stats.lastSample.item)) && (stats.cardinalDirection?.indexOf('n') != -1 ?? false)) { - if(stats.netDistance > spec.flickDist) { + const baseDistance = stats.netDistance; + const angle = stats.angle; // from <0, -1> (straight up) going clockwise. + const verticalDistance = baseDistance * Math.cos(angle); + if(verticalDistance > spec.flickDist) { return 'resolve'; } } else if(resetForRoaming) { diff --git a/web/src/engine/osk/src/visualKeyboard.ts b/web/src/engine/osk/src/visualKeyboard.ts index 6b8af2e0c17..2edfc9fb374 100644 --- a/web/src/engine/osk/src/visualKeyboard.ts +++ b/web/src/engine/osk/src/visualKeyboard.ts @@ -1298,9 +1298,17 @@ export default class VisualKeyboard extends EventEmitter implements Ke Note: longpress.flickDist needs to be no greater than flick.startDist. Otherwise, the longpress up-flick shortcut will not work on keys that support flick gestures. (Such as sil_euro_latin 3.0+) + + Since it's also based on the purely northward component, it's best to + have it be slightly lower. 80% of flick.startDist gives a range of + about 37 degrees to each side before a flick-start would win, while + 70.7% gives 45 degrees. + + (The range _will_ be notably tighter on keys with both longpresses and + flicks as a result.) */ - this.gestureParams.longpress.flickDist = 0.25 * this.currentLayer.rowHeight; - this.gestureParams.flick.startDist = 0.25 * this.currentLayer.rowHeight; + this.gestureParams.longpress.flickDist = 0.24 * this.currentLayer.rowHeight; + this.gestureParams.flick.startDist = 0.30 * this.currentLayer.rowHeight; this.gestureParams.flick.dirLockDist = 0.35 * this.currentLayer.rowHeight; this.gestureParams.flick.triggerDist = 0.75 * this.currentLayer.rowHeight; } From 99be7c9c347d87272965ee796d4c3a8ed772a287 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Fri, 26 Apr 2024 14:30:09 +0700 Subject: [PATCH 41/60] updated version of Sentry to 8.24.0 --- mac/Keyman4MacIM/Podfile | 4 ++-- mac/Keyman4MacIM/Podfile.lock | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/mac/Keyman4MacIM/Podfile b/mac/Keyman4MacIM/Podfile index 586f4ed8834..5f203a69955 100644 --- a/mac/Keyman4MacIM/Podfile +++ b/mac/Keyman4MacIM/Podfile @@ -7,11 +7,11 @@ target 'Keyman' do # use_frameworks! # Pods for Keyman - pod 'Sentry', :git => 'https://github.com/getsentry/sentry-cocoa.git', :tag => '5.2.1' + pod 'Sentry', :git => 'https://github.com/getsentry/sentry-cocoa.git', :tag => '8.24.0' target 'KeymanTests' do inherit! :search_paths - pod 'Sentry', :git => 'https://github.com/getsentry/sentry-cocoa.git', :tag => '5.2.1' + pod 'Sentry', :git => 'https://github.com/getsentry/sentry-cocoa.git', :tag => '8.24.0' use_frameworks! # Pods for testing end diff --git a/mac/Keyman4MacIM/Podfile.lock b/mac/Keyman4MacIM/Podfile.lock index e73768d2f75..6eb733ea9ad 100644 --- a/mac/Keyman4MacIM/Podfile.lock +++ b/mac/Keyman4MacIM/Podfile.lock @@ -1,24 +1,24 @@ PODS: - - Sentry (5.2.1): - - Sentry/Core (= 5.2.1) - - Sentry/Core (5.2.1) + - Sentry (8.24.0): + - Sentry/Core (= 8.24.0) + - Sentry/Core (8.24.0) DEPENDENCIES: - - Sentry (from `https://github.com/getsentry/sentry-cocoa.git`, tag `5.2.1`) + - Sentry (from `https://github.com/getsentry/sentry-cocoa.git`, tag `8.24.0`) EXTERNAL SOURCES: Sentry: :git: https://github.com/getsentry/sentry-cocoa.git - :tag: 5.2.1 + :tag: 8.24.0 CHECKOUT OPTIONS: Sentry: :git: https://github.com/getsentry/sentry-cocoa.git - :tag: 5.2.1 + :tag: 8.24.0 SPEC CHECKSUMS: - Sentry: 7d075cae43a9a518fdd51e258b6212f0527c51cd + Sentry: 2f6baed15a3f8056b875fc903dc3dcb2903117f4 -PODFILE CHECKSUM: d1e1f991bca05599c1667234a03e9f365d109ed0 +PODFILE CHECKSUM: 483593d0b294fc5751c2490061e01211db3f9ecc -COCOAPODS: 1.11.2 +COCOAPODS: 1.15.2 From e88380230d02cc04b5a706515909a97a4804495a Mon Sep 17 00:00:00 2001 From: sgschantz Date: Fri, 26 Apr 2024 14:57:04 +0700 Subject: [PATCH 42/60] chore(mac): increase maximum size of dmg to 30MB When upgrading to Xcode 15.3 and a newer version of Sentry, the dmg template file was too small for the newly generated executable. --- mac/Keyman4MacIM/Keyman-template.dmg | Bin 14544896 -> 30044160 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman-template.dmg b/mac/Keyman4MacIM/Keyman-template.dmg index 8a67ad5da50c84ab434fc78a13693011ce8d4a83..f23b470e2cc4a7fecfe8fc0bacd2fbe344c1a044 100644 GIT binary patch delta 4282 zcmeI$+f$5T9Ki8?w{4}i+Cot|Z4^r(Q7Dm9i3(d$4&|&uNOEimIYqTo#OgHWt-<@TcG2<_IpPA3|yLj)u@743uw*8Q6+sYj(>I7+kDPQo@ zbqLO?%%-q*2}dwroB)$$sw_j|V$%6Zy=2nBHbtdSCg=p2x75*8rIyK}~4*k>=qZ!_Zcx#6&5K2Dw$Mp!cbf+UkQEZS9PP@74(l{nzAP%6z43wmL0G zohCpEE689CIXb}xonZ?*C}0l8124OIK;EN#`ied1>aQI^cMj`-#7=_UogCGQBEJ832;}MDpn21T3j4231 zIHn>3(=Z*8h(a`GU?yfkgBZjj4zn=_@kqd2%)@*vKq8W`5R0%FORyBnupBFpj1;6| zC01cI%>Qo<)?yvfu^t)NfJ|(}CTzwQY{fQYL5uC!fo$x=F6>4Q_FymeVLuKa7YA_& zdB{frbU2Jc6hV(8IErI9juR+G2~NU*Q#g$?C`B30;vCMS92amAmv9+Za1|A(#5Gjm zI;wF4M%=_L+{PW;MGfwu7WeT05Ag_(@dQut4A1cbb*RTnyuxcVpb>BI7ENfzJG9_E zKA;sJ@d=-e>a;H{Sw_P*&%|``77K_4!~$Xgv4B`WEFcyT3y1~80{;{UF3|Y?@2PK0 zv9GOBT9yJWAw`h}rwE(WxW9J^zjq6Nb_$l|LPv8&wX~!mG&eRpDPEn??)q!@pyjif JW$92V`~>4*F-iac delta 981 zcmWmB*L%$e0LF2@V-tGB-o$KZZM9dG*sDgV+M`AqdrQo;6p0{4?3vb1IjT0TReO)~ zaOuiz?(p$_p3nOayeV(9i>JKJEpYr+5XwzV4;p8D2x4Q;BrFc)QSf<`o0u8*K3Y2? zAry`bc^}OVBEiw<$My%qX@$ZEvZ663N1hFGGR7pu>BFKCTwNFfSSgrdYyjN*Jjm=eTNl2VkW3}q=tc`8tmN>ru_RjEdG;;2DQYEhdy z)a6U!sYiXj;%gevkVZ772~BB6bH1SkEont-+R&DEw5J0d>BP5m<~zF3l?1xcogVb0 z7rp62U;5FX0esIu1~Hf+{J>C#@gu|ei4lxs6r&l#SjI7)2~6Z?CNY^QOeK+D`262A zrZav5WNh-hc8>?8&@2p`h>qsM=^<=Ptjcg*5 z&1_*S+sI-&JJ`uCcC&}Q>|;L%ILINg`GY?>%n^=qjN_c(Bsu)WDNYmN41aT$e>lf^ zE^v`cT;>W_xyHZz$8~OSlUv;8f9`OXd)(&%4|&96p74}sJm&>3dBy8Ud{Xpj@+W3f BfLj0n From f71839dd776355adb7db0eddfcb1d158cf1f017b Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Fri, 26 Apr 2024 14:05:21 -0400 Subject: [PATCH 43/60] auto: increment beta version to 17.0.316 --- HISTORY.md | 9 +++++++++ VERSION.md | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 21d226c991d..16f382a88be 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,14 @@ # Keyman Version History +## 17.0.315 beta 2024-04-26 + +* fix(web): osk-view hidden by default on construction (#11258) +* fix(android): fixes kbd text zoom to prevent accessibility cross-effects (#11281) +* fix(developer): support export of visual keyboard when Keyman for Windows not installed (#11244) +* chore(linux): Prepare for stable release (#11301) +* fix(core): reset on frame keys (#11172) +* fix(core): ldml backspace processing should delete all markers (#11254) + ## 17.0.314 beta 2024-04-25 * fix(android/engine): URIEncode strings passed to Javascript (#11206) diff --git a/VERSION.md b/VERSION.md index 16cffc91ba1..48d9425de9e 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -17.0.315 \ No newline at end of file +17.0.316 \ No newline at end of file From 1a86ed28a94fcee3b68106c0b6071b1945622e35 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Sat, 27 Apr 2024 18:53:12 +0700 Subject: [PATCH 44/60] chore(ios): force new build --- ios/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ios/README.md b/ios/README.md index 0c70ccf326b..b60ee2ea5ee 100644 --- a/ios/README.md +++ b/ios/README.md @@ -77,3 +77,5 @@ The KeymanEngine project contains a demo app that demonstrates usage of the fram create a system keyboard. To build the samples, `cd` into the project directory and run `./build.sh`. + +. \ No newline at end of file From a59850e06358b3b69a3c1aed8126ab384372111d Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 29 Apr 2024 04:56:56 +0700 Subject: [PATCH 45/60] chore(ios): force new build --- ios/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/ios/README.md b/ios/README.md index b60ee2ea5ee..0c70ccf326b 100644 --- a/ios/README.md +++ b/ios/README.md @@ -77,5 +77,3 @@ The KeymanEngine project contains a demo app that demonstrates usage of the fram create a system keyboard. To build the samples, `cd` into the project directory and run `./build.sh`. - -. \ No newline at end of file From 8d2a1e8b93b5e2dc3e8382800ff01bad7a709544 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Mon, 29 Apr 2024 08:53:32 +0700 Subject: [PATCH 46/60] change(web): longpress up-flick now has two components, requires greater distance --- .../osk/src/input/gestures/specsForLayout.ts | 40 ++++++++++++++++--- web/src/engine/osk/src/visualKeyboard.ts | 9 +++-- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/web/src/engine/osk/src/input/gestures/specsForLayout.ts b/web/src/engine/osk/src/input/gestures/specsForLayout.ts index f9bc02f4614..213278277e4 100644 --- a/web/src/engine/osk/src/input/gestures/specsForLayout.ts +++ b/web/src/engine/osk/src/input/gestures/specsForLayout.ts @@ -31,10 +31,16 @@ export interface GestureParams { */ permitsFlick: (item?: Item) => boolean, + /** + * The minimum _net_ distance traveled before a longpress flick-shortcut will cancel any + * conflicting flick models. + */ + flickDistStart: number, + /** * The minimum _net_ distance traveled before a longpress flick-shortcut will trigger. */ - flickDist: number, + flickDistFinal: number, /** * The maximum amount of raw-distance movement allowed for a longpress before it is @@ -104,7 +110,8 @@ export const DEFAULT_GESTURE_PARAMS: GestureParams = { permitsFlick: () => true, // Note: actual runtime value is determined at runtime based upon row height. // See `VisualKeyboard.refreshLayout`, CTRL-F "Step 3". - flickDist: 5, + flickDistStart: 8, + flickDistFinal: 40, waitLength: 500, noiseTolerance: 10 }, @@ -349,11 +356,34 @@ export function instantContactResolutionModel(): ContactModel { }; } -export function flickStartContactModel(params: GestureParams): ContactModel { +export function flickStartContactModel(params: GestureParams): gestures.specs.ContactModel { + const flickParams = params.flick; + return { itemPriority: 1, pathModel: { - evaluate: (path) => path.stats.netDistance > params.flick.startDist ? 'resolve' : null + evaluate: (path, _, item) => { + const stats = path.stats; + const keySpec = item?.key.spec; + + if(keySpec && keySpec.sk) { + const flickSpec = keySpec.flick; + const hasUpFlick = flickSpec.nw || flickSpec.n || flickSpec.ne; + + if(!hasUpFlick) { + // Check for possible conflict with the longpress up-flick shortcut; + // it's supported on this key, as there is no true northish flick. + const baseDistance = stats.netDistance; + const angle = stats.angle; // from <0, -1> (straight up) going clockwise. + const verticalDistance = baseDistance * Math.cos(angle); + if(verticalDistance > params.longpress.flickDistStart) { + return 'reject'; + } + } + } + + return stats.netDistance > flickParams.startDist ? 'resolve' : null; + } }, pathResolutionAction: 'resolve', pathInheritance: 'partial' @@ -467,7 +497,7 @@ export function longpressContactModel(params: GestureParams, enabledFlicks: bool const baseDistance = stats.netDistance; const angle = stats.angle; // from <0, -1> (straight up) going clockwise. const verticalDistance = baseDistance * Math.cos(angle); - if(verticalDistance > spec.flickDist) { + if(verticalDistance > spec.flickDistFinal) { return 'resolve'; } } else if(resetForRoaming) { diff --git a/web/src/engine/osk/src/visualKeyboard.ts b/web/src/engine/osk/src/visualKeyboard.ts index 2edfc9fb374..97afe3352d8 100644 --- a/web/src/engine/osk/src/visualKeyboard.ts +++ b/web/src/engine/osk/src/visualKeyboard.ts @@ -1307,10 +1307,11 @@ export default class VisualKeyboard extends EventEmitter implements Ke (The range _will_ be notably tighter on keys with both longpresses and flicks as a result.) */ - this.gestureParams.longpress.flickDist = 0.24 * this.currentLayer.rowHeight; - this.gestureParams.flick.startDist = 0.30 * this.currentLayer.rowHeight; - this.gestureParams.flick.dirLockDist = 0.35 * this.currentLayer.rowHeight; - this.gestureParams.flick.triggerDist = 0.75 * this.currentLayer.rowHeight; + this.gestureParams.longpress.flickDistStart = 0.24 * this.currentLayer.rowHeight; + this.gestureParams.flick.startDist = 0.30 * this.currentLayer.rowHeight; + this.gestureParams.flick.dirLockDist = 0.35 * this.currentLayer.rowHeight; + this.gestureParams.flick.triggerDist = 0.75 * this.currentLayer.rowHeight; + this.gestureParams.longpress.flickDistFinal = 0.75 * this.currentLayer.rowHeight; } // Phase 4: Refresh the layout of the layer-group and active layer. From ec64a985629f9bab7da57d698ec1a54ded582fe6 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Mon, 29 Apr 2024 15:52:00 +0700 Subject: [PATCH 47/60] chore(ios): modify version scripts Wrap scripts for FirstVoices so that environment variables are retained --- ios/keyman/Keyman/Keyman.xcodeproj/project.pbxproj | 4 ++-- .../ios/FirstVoices.xcodeproj/project.pbxproj | 12 ++++++------ ...sh => set-bundle-versions-and-settings-tagged.sh} | 2 +- .../set-bundle-versions-and-settings-untagged.sh | 11 +++++++++++ resources/build/set-bundle-versions-tagged.sh | 2 +- resources/build/set-bundle-versions-untagged.sh | 2 +- resources/build/xcode-utils.sh | 2 ++ resources/build/xcode-wrap.sh | 2 +- 8 files changed, 25 insertions(+), 12 deletions(-) rename resources/build/{set-bundle-versions-and-settings.sh => set-bundle-versions-and-settings-tagged.sh} (93%) create mode 100755 resources/build/set-bundle-versions-and-settings-untagged.sh diff --git a/ios/keyman/Keyman/Keyman.xcodeproj/project.pbxproj b/ios/keyman/Keyman/Keyman.xcodeproj/project.pbxproj index af10e998d9a..2d58d7785fa 100644 --- a/ios/keyman/Keyman/Keyman.xcodeproj/project.pbxproj +++ b/ios/keyman/Keyman/Keyman.xcodeproj/project.pbxproj @@ -950,7 +950,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = "/usr/bin/env bash"; - shellScript = "verstr1=$(/usr/libexec/PlistBuddy -c \"Print CFBundleShortVersionString\" \"$SRCROOT/Keyman-Info.plist\")\nverstr2=$(/usr/libexec/PlistBuddy -c \"Print CFBundleVersion\" \"$SRCROOT/Keyman-Info.plist\")\n/usr/libexec/PlistBuddy \"$SRCROOT/Settings.bundle/Root.plist\" -c \"set PreferenceSpecifiers:0:DefaultValue $verstr1 (build $verstr2)\"\n\nif which swiftlint >/dev/null; then\n swiftlint --config ../../.swiftlint.yml\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; + shellScript = "#verstr1=$(/usr/libexec/PlistBuddy -c \"Print CFBundleShortVersionString\" \"$SRCROOT/Keyman-Info.plist\")\n#verstr2=$(/usr/libexec/PlistBuddy -c \"Print CFBundleVersion\" \"$SRCROOT/Keyman-Info.plist\")\n#/usr/libexec/PlistBuddy \"$SRCROOT/Settings.bundle/Root.plist\" -c \"set PreferenceSpecifiers:0:DefaultValue $verstr1 (build $verstr2)\"\n\nif which swiftlint >/dev/null; then\n swiftlint --config ../../.swiftlint.yml\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; showEnvVarsInLog = 0; }; CE002CB32408B372002026CE /* Run Script - upload dsyms to sentry */ = { @@ -1002,7 +1002,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = "/usr/bin/env bash"; - shellScript = "\"$KEYMAN_ROOT/resources/build/xcode-wrap.sh\" \"$KEYMAN_ROOT/resources/build/set-bundle-versions-and-settings.sh\"\n"; + shellScript = "\"$KEYMAN_ROOT/resources/build/xcode-wrap.sh\" \"$KEYMAN_ROOT/resources/build/set-bundle-versions-and-settings-tagged.sh\"\n"; showEnvVarsInLog = 0; }; CED3CFDA240E49DF001540A1 /* ShellScript */ = { diff --git a/oem/firstvoices/ios/FirstVoices.xcodeproj/project.pbxproj b/oem/firstvoices/ios/FirstVoices.xcodeproj/project.pbxproj index 7925b00543a..28613d80e39 100644 --- a/oem/firstvoices/ios/FirstVoices.xcodeproj/project.pbxproj +++ b/oem/firstvoices/ios/FirstVoices.xcodeproj/project.pbxproj @@ -439,8 +439,8 @@ outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = ". \"$KEYMAN_ROOT/resources/build/xcode-utils.sh\"\n\n# Calls resource script to update build products' versioning.\nphaseSetBundleVersions\n"; + shellPath = "/usr/bin/env bash"; + shellScript = "\"$KEYMAN_ROOT/resources/build/xcode-wrap.sh\" \"$KEYMAN_ROOT/resources/build/set-bundle-versions-untagged.sh\"\n"; showEnvVarsInLog = 0; }; 37DF007C24595F6F00C73128 /* ShellScript */ = { @@ -457,8 +457,8 @@ outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n\n. \"$KEYMAN_ROOT/resources/build/xcode-utils.sh\"\n\n# Calls resource script to update build products' versioning.\n# true: applies VERSION_WITH_TAG to custom KeymanVersionWithTag plist member used for in-app display\nphaseSetBundleVersions true\n\n# Also updates the version string for Settings\nsetSettingsBundleVersion\n"; + shellPath = "/usr/bin/env bash"; + shellScript = "\"$KEYMAN_ROOT/resources/build/xcode-wrap.sh\" \"$KEYMAN_ROOT/resources/build/set-bundle-versions-and-settings-untagged.sh\"\n"; showEnvVarsInLog = 0; }; 9800EC5D1C029FCD00BF0FB5 /* ShellScript */ = { @@ -471,8 +471,8 @@ outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "verstr1=$(/usr/libexec/PlistBuddy -c \"Print CFBundleShortVersionString\" \"$SRCROOT/FirstVoices/Info.plist\")\nverstr2=$(/usr/libexec/PlistBuddy -c \"Print CFBundleVersion\" \"$SRCROOT/FirstVoices/Info.plist\")\n/usr/libexec/PlistBuddy \"$SRCROOT/Settings.bundle/Root.plist\" -c \"set PreferenceSpecifiers:0:DefaultValue $verstr1 (build $verstr2)\"\n"; + shellPath = "/usr/bin/env bash"; + shellScript = "#verstr1=$(/usr/libexec/PlistBuddy -c \"Print CFBundleShortVersionString\" \"$SRCROOT/FirstVoices/Info.plist\")\n#verstr2=$(/usr/libexec/PlistBuddy -c \"Print CFBundleVersion\" \"$SRCROOT/FirstVoices/Info.plist\")\n#/usr/libexec/PlistBuddy \"$SRCROOT/Settings.bundle/Root.plist\" -c \"set PreferenceSpecifiers:0:DefaultValue $verstr1 (build $verstr2)\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ diff --git a/resources/build/set-bundle-versions-and-settings.sh b/resources/build/set-bundle-versions-and-settings-tagged.sh similarity index 93% rename from resources/build/set-bundle-versions-and-settings.sh rename to resources/build/set-bundle-versions-and-settings-tagged.sh index 15a9aa9b2fa..9ad0e9758c9 100755 --- a/resources/build/set-bundle-versions-and-settings.sh +++ b/resources/build/set-bundle-versions-and-settings-tagged.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Calls script in xcode-utils to update the version # true: applies VERSION_WITH_TAG to custom KeymanVersionWithTag plist member used for in-app display diff --git a/resources/build/set-bundle-versions-and-settings-untagged.sh b/resources/build/set-bundle-versions-and-settings-untagged.sh new file mode 100755 index 00000000000..38256c7a9a0 --- /dev/null +++ b/resources/build/set-bundle-versions-and-settings-untagged.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +# Calls script in xcode-utils to update the version +# true: applies VERSION_WITH_TAG to custom KeymanVersionWithTag plist member used for in-app display +# updates the version string for Settings + +source "$KEYMAN_ROOT/resources/build/xcode-utils.sh" + +phaseSetBundleVersions + +setSettingsBundleVersion \ No newline at end of file diff --git a/resources/build/set-bundle-versions-tagged.sh b/resources/build/set-bundle-versions-tagged.sh index a4078ee99a8..8b4075a037b 100755 --- a/resources/build/set-bundle-versions-tagged.sh +++ b/resources/build/set-bundle-versions-tagged.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Calls script in xcode-utils to update the version # true: applies VERSION_WITH_TAG to custom KeymanVersionWithTag plist member used for in-app display diff --git a/resources/build/set-bundle-versions-untagged.sh b/resources/build/set-bundle-versions-untagged.sh index d28e6248e4a..85ea09f9c34 100755 --- a/resources/build/set-bundle-versions-untagged.sh +++ b/resources/build/set-bundle-versions-untagged.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Calls script in xcode-utils to update the version diff --git a/resources/build/xcode-utils.sh b/resources/build/xcode-utils.sh index 91fc7d43f5d..ab357e66b35 100755 --- a/resources/build/xcode-utils.sh +++ b/resources/build/xcode-utils.sh @@ -7,6 +7,8 @@ # - echo "warning: foo" will generate an actual compile warning within Xcode: "foo" # - echo "error: bar" will likewise generate a compile error within Xcode: "bar" +set -eu + function buildWarning() { echo "warning: $1" } diff --git a/resources/build/xcode-wrap.sh b/resources/build/xcode-wrap.sh index d989e43a497..61d79ca24e9 100755 --- a/resources/build/xcode-wrap.sh +++ b/resources/build/xcode-wrap.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash echo "wrap script for arch $(arch)" if [[ $(arch) == i386 ]] && [[ -f /usr/local/bin/bash ]]; then From fbd4367f2bce8c73ca5432c01e73c761497a7dd9 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Tue, 30 Apr 2024 08:04:43 +0700 Subject: [PATCH 48/60] chore(ios): create script to upload sentry debug symbol file Wrap call to script with xcode-wrap.sh to retain env --- ios/keyman/Keyman/Keyman.xcodeproj/project.pbxproj | 2 +- resources/build/sentry-dsym-upload.sh | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100755 resources/build/sentry-dsym-upload.sh diff --git a/ios/keyman/Keyman/Keyman.xcodeproj/project.pbxproj b/ios/keyman/Keyman/Keyman.xcodeproj/project.pbxproj index 2d58d7785fa..fdeae450f0d 100644 --- a/ios/keyman/Keyman/Keyman.xcodeproj/project.pbxproj +++ b/ios/keyman/Keyman/Keyman.xcodeproj/project.pbxproj @@ -970,7 +970,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = "/usr/bin/env bash"; - shellScript = ". \"$KEYMAN_ROOT/resources/build/xcode-utils.sh\"\n\nif [ ${UPLOAD_SENTRY:-false} = true ]; then\n # Calls resource script to perform the dSYM upload\n phaseSentryDsymUpload \"keyman-ios\"\nfi\n"; + shellScript = ". \"$KEYMAN_ROOT/resources/build/xcode-utils.sh\"\n\nif [ ${UPLOAD_SENTRY:-false} = true ]; then\n # Calls resource script to perform the dSYM upload\n \"$KEYMAN_ROOT/resources/build/xcode-wrap.sh\" \"$KEYMAN_ROOT/resources/build/sentry-dsym-upload.sh\"\nfi\n"; }; CE06AA671F161422006D91C3 /* Run Script */ = { isa = PBXShellScriptBuildPhase; diff --git a/resources/build/sentry-dsym-upload.sh b/resources/build/sentry-dsym-upload.sh new file mode 100755 index 00000000000..47f73b7a771 --- /dev/null +++ b/resources/build/sentry-dsym-upload.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +# Calls resource script to perform the dSYM upload + +source "$KEYMAN_ROOT/resources/build/xcode-utils.sh" +phaseSentryDsymUpload "keyman-ios" \ No newline at end of file From 8ddd2eb04a17340ed950159f5fb0a2865bb1db42 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Tue, 30 Apr 2024 09:04:06 +0700 Subject: [PATCH 49/60] fix(web): failed gesture-model spinup should not lock the gesture engine --- .../gestures/matchers/matcherSelector.ts | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/matcherSelector.ts b/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/matcherSelector.ts index c8a2cefa1a1..8e7efc73886 100644 --- a/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/matcherSelector.ts +++ b/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/matcherSelector.ts @@ -409,10 +409,30 @@ export class MatcherSelector extends EventEmitter new GestureMatcher(model, unmatchedSource || priorMatcher)); + let newMatchers = gestureModelSet.map((model) => { + try { + /* + Spinning up a new gesture model means running code for that model and + path, which are defined outside of the engine. We should not allow + errors from engine-external code to prevent us from continuing with + unaffected models. + + It's also important to keep the overall flow going; this code is run + during touch-start spinup. An abrupt stop due to an unhandled error + here can lock up the AsyncDispatchQueue for touch events, locking up + the engine! + */ + return new GestureMatcher(model, unmatchedSource || priorMatcher) + } catch (err) { + console.error(err); + return null; + } + // Filter out any models that failed to 'spin-up' due to exceptions. + }).filter((entry) => !!entry); // If any newly-activating models are disqualified due to initial conditions, don't add them. newMatchers = newMatchers.filter((matcher) => !matcher.result || matcher.result.matched !== false); From 3ca69066d08f65adfa3b9ab2746ec8692ccc2395 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Tue, 30 Apr 2024 09:03:33 +0700 Subject: [PATCH 50/60] fix(web): invalid initial-state aborts further model processing --- .../engine/headless/gestures/matchers/gestureMatcher.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/gestureMatcher.ts b/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/gestureMatcher.ts index 9f909631ac8..a311548f0ec 100644 --- a/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/gestureMatcher.ts +++ b/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/gestureMatcher.ts @@ -477,6 +477,13 @@ export class GestureMatcher implements PredecessorMatch< here, as the decision is made due to a validation check against the initial item. */ this.finalize(false, 'cancelled'); + + /* + * There's no need to process the gesture-model any further... and the + * invalid state may correspond to assumptions in the path-model that + * will be invalidated if we continue. + */ + return; } } @@ -507,6 +514,7 @@ export class GestureMatcher implements PredecessorMatch< instantly fail and thus cancel. */ this.finalize(false, whileInitializing ? 'cancelled' : 'path'); + return; } // Standard path: trigger either resolution or rejection when the contact model signals either. From 456ab70322162c100c4cab14c515fd76e6403ad5 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Tue, 30 Apr 2024 09:04:06 +0700 Subject: [PATCH 51/60] fix(web): failed gesture-model spinup should not lock the gesture engine --- .../gestures/matchers/matcherSelector.ts | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/matcherSelector.ts b/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/matcherSelector.ts index c8a2cefa1a1..8e7efc73886 100644 --- a/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/matcherSelector.ts +++ b/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/matcherSelector.ts @@ -409,10 +409,30 @@ export class MatcherSelector extends EventEmitter new GestureMatcher(model, unmatchedSource || priorMatcher)); + let newMatchers = gestureModelSet.map((model) => { + try { + /* + Spinning up a new gesture model means running code for that model and + path, which are defined outside of the engine. We should not allow + errors from engine-external code to prevent us from continuing with + unaffected models. + + It's also important to keep the overall flow going; this code is run + during touch-start spinup. An abrupt stop due to an unhandled error + here can lock up the AsyncDispatchQueue for touch events, locking up + the engine! + */ + return new GestureMatcher(model, unmatchedSource || priorMatcher) + } catch (err) { + console.error(err); + return null; + } + // Filter out any models that failed to 'spin-up' due to exceptions. + }).filter((entry) => !!entry); // If any newly-activating models are disqualified due to initial conditions, don't add them. newMatchers = newMatchers.filter((matcher) => !matcher.result || matcher.result.matched !== false); From 3ff7664ca2af2aa61a6b49be49725ccafcf1a4a2 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Tue, 30 Apr 2024 09:03:33 +0700 Subject: [PATCH 52/60] fix(web): invalid initial-state aborts further model processing --- .../engine/headless/gestures/matchers/gestureMatcher.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/gestureMatcher.ts b/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/gestureMatcher.ts index 9f909631ac8..a311548f0ec 100644 --- a/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/gestureMatcher.ts +++ b/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/gestureMatcher.ts @@ -477,6 +477,13 @@ export class GestureMatcher implements PredecessorMatch< here, as the decision is made due to a validation check against the initial item. */ this.finalize(false, 'cancelled'); + + /* + * There's no need to process the gesture-model any further... and the + * invalid state may correspond to assumptions in the path-model that + * will be invalidated if we continue. + */ + return; } } @@ -507,6 +514,7 @@ export class GestureMatcher implements PredecessorMatch< instantly fail and thus cancel. */ this.finalize(false, whileInitializing ? 'cancelled' : 'path'); + return; } // Standard path: trigger either resolution or rejection when the contact model signals either. From 068437d818c9221e4b81f303ce1f0865b0b2f3ca Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Tue, 30 Apr 2024 09:14:08 +0700 Subject: [PATCH 53/60] fix(web): also prevent path-update crashes from causing issues --- .../engine/headless/gestures/matchers/gestureMatcher.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/gestureMatcher.ts b/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/gestureMatcher.ts index a311548f0ec..622f04fe0cc 100644 --- a/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/gestureMatcher.ts +++ b/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/gestureMatcher.ts @@ -524,6 +524,13 @@ export class GestureMatcher implements PredecessorMatch< } update() { - this.pathMatchers.forEach((matcher) => matcher.update()); + this.pathMatchers.forEach((matcher) => { + try { + matcher.update(); + } catch(err) { + console.error(err); + this.finalize(false, 'cancelled'); + } + }); } } \ No newline at end of file From 725b973bfd53bb5821cd74b0750f962b6cd22096 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Tue, 30 Apr 2024 09:31:15 +0700 Subject: [PATCH 54/60] chore(web): removes old doc that has completed its purpose --- .../docs/web-reintegration.md | 64 ------------------- 1 file changed, 64 deletions(-) delete mode 100644 common/web/gesture-recognizer/docs/web-reintegration.md diff --git a/common/web/gesture-recognizer/docs/web-reintegration.md b/common/web/gesture-recognizer/docs/web-reintegration.md deleted file mode 100644 index 1f5e85be4d7..00000000000 --- a/common/web/gesture-recognizer/docs/web-reintegration.md +++ /dev/null @@ -1,64 +0,0 @@ -# Web Re-integration Guide - -As this is based on refactored Keyman Engine for Web 15.0 code, there will eventually come a time to -integrate this module back into it and replace the old version. As there has been some refactoring, -this document will list notable changes to facilitate reintegration once this module is ready. - -## From feat/web/gesture-recognizer-main - -The OSK helper functions for `MouseEventEngine` and for `TouchEventEngine` have been disabled, as they -are references to components external to this module. - -## From feat/web/gesture-recognizer-base - -Starts work on a unified mouse+touch object - `GestureRecognizer` - and starts work on the unified -config object. - -Rather than specifying callback methods, we also shift to use of `EventEmitter` and an event-based model. -At this stage, the event parameters should be relatively easy to interpret and forward to the original methods. - -## From feat/web/gesture-recognizer-bounds - -This adds abstraction + generalization for gesture detection boundary logic. To translate the new config -parameters to KeymanWeb's VisualKeyboard... - -`inputStartBounds`: would be left undefined. Default behavior is a perfect match here. - -`maxRoamingBounds`: would be backed by an invisible VisualKeyboard-managed element. This element would be -and resized with the other VisualKeyboard elements. Represents the currently 1/3-a-row buffer above the -keyboard that supports continued interaction before cancelling it. - -Alternatively, this _could_ receive a custom wrapper implementation of the interface that simply appends -extra space to each side of the main target-element's `getBoundingClientRect` value. (One issue with this -approach is that the padding value may differ per device orientation.) -- This could be supported via paddedZoneSource with negative padding toward the top. - -`safeBounds`: would be left undefined. The default behavior is modeled directly after VisualKeyboard's -viewport-aware bounds detection & logic. - -`safeBoundsPadding` models the slightly-inset boundaries that are used to disable `safeBounds` near an edge -should the initial touch have started near that edge. - -## From feat/web/recognizer-multipoint-tracking - -This makes things a _bit_ more complicated than with gesture-recognizer-base. Now, the `GestureRecognizer` -object's lone event will yield an `TrackedInput` instance corresponding to the ongoing input. This object -contains a `TrackedPoint`, which tracks all data corresponding to its triggering `mousedown` or `touchstart`. -Further events for that "tracked point" are based on `TrackedPoint.path`. This approach provides the -perspective of each touch point individually for further processing... effectively splitting multi-touchpoint -events into multiple _individual_ events while keeping the metadata organized over each touchpoint's lifetime. - -## From change/web/internal-gesture-src-nomenclature - -In case someone has to trace this history on things: - -- `TrackedInput` is now `ComplexGestureSource`. -- `TrackedPoint` is now `SimpleGestureSource`. -- `TrackedPath` is now `GesturePath`. - -## From refactor/web/gesture-source-paradigm + its followup - -- `ComplexGestureSource` is now fully decommissioned; it made assumptions that were overly complicating -gesture state-machine / model-matching code. - -- Accordingly, `SimpleGestureSource` is now simply just `GestureSource`. Yay on that end! From e7b2855baaa960b16277e03d72111b03ca318b41 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Tue, 30 Apr 2024 10:09:18 +0700 Subject: [PATCH 55/60] chore(ios): change from set -eu to set -e Ignore unbound variables for now to get past script failure --- resources/build/xcode-utils.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/build/xcode-utils.sh b/resources/build/xcode-utils.sh index ab357e66b35..9476161ae63 100755 --- a/resources/build/xcode-utils.sh +++ b/resources/build/xcode-utils.sh @@ -7,7 +7,7 @@ # - echo "warning: foo" will generate an actual compile warning within Xcode: "foo" # - echo "error: bar" will likewise generate a compile error within Xcode: "bar" -set -eu +set -e function buildWarning() { echo "warning: $1" From 38339397e920060f5e4363a74692c6903f362739 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Tue, 30 Apr 2024 14:25:05 -0400 Subject: [PATCH 56/60] auto: increment beta version to 17.0.317 --- HISTORY.md | 4 ++++ VERSION.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 16f382a88be..ffa3a376492 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # Keyman Version History +## 17.0.316 beta 2024-04-30 + +* fix(windows): check font count display none found (#11282) + ## 17.0.315 beta 2024-04-26 * fix(web): osk-view hidden by default on construction (#11258) diff --git a/VERSION.md b/VERSION.md index 48d9425de9e..9669f5e8689 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -17.0.316 \ No newline at end of file +17.0.317 \ No newline at end of file From 9db13eda70ad95d244c68037c1be479595d5c6e9 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Wed, 1 May 2024 14:04:15 -0400 Subject: [PATCH 57/60] auto: increment beta version to 17.0.318 --- HISTORY.md | 6 ++++++ VERSION.md | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index ffa3a376492..efff32b1a47 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,11 @@ # Keyman Version History +## 17.0.317 beta 2024-05-01 + +* (#11322) +* (#11321) +* fix(linux): Fix icon for .kmp files (#11295) + ## 17.0.316 beta 2024-04-30 * fix(windows): check font count display none found (#11282) diff --git a/VERSION.md b/VERSION.md index 9669f5e8689..7f479d3db1c 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -17.0.317 \ No newline at end of file +17.0.318 \ No newline at end of file From 3abcb35733b1ff76894027cd639d41c467646693 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Thu, 2 May 2024 08:18:33 +0700 Subject: [PATCH 58/60] chore(ios): exit build phase script to experiment --- oem/firstvoices/ios/FirstVoices.xcodeproj/project.pbxproj | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/oem/firstvoices/ios/FirstVoices.xcodeproj/project.pbxproj b/oem/firstvoices/ios/FirstVoices.xcodeproj/project.pbxproj index 28613d80e39..31cae7af740 100644 --- a/oem/firstvoices/ios/FirstVoices.xcodeproj/project.pbxproj +++ b/oem/firstvoices/ios/FirstVoices.xcodeproj/project.pbxproj @@ -301,7 +301,7 @@ 9889E8B31BFA9CEC00019560 /* Frameworks */, 9889E8B41BFA9CEC00019560 /* Resources */, 98C9A8C81BFBF23C009E9A4F /* Embed App Extensions */, - 37DF007C24595F6F00C73128 /* ShellScript */, + 37DF007C24595F6F00C73128 /* Run Script */, 9800EC5D1C029FCD00BF0FB5 /* ShellScript */, 371C855D2288F3A50076612A /* Embed Frameworks */, ); @@ -443,7 +443,7 @@ shellScript = "\"$KEYMAN_ROOT/resources/build/xcode-wrap.sh\" \"$KEYMAN_ROOT/resources/build/set-bundle-versions-untagged.sh\"\n"; showEnvVarsInLog = 0; }; - 37DF007C24595F6F00C73128 /* ShellScript */ = { + 37DF007C24595F6F00C73128 /* Run Script */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -452,13 +452,14 @@ ); inputPaths = ( ); + name = "Run Script"; outputFileListPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = "/usr/bin/env bash"; - shellScript = "\"$KEYMAN_ROOT/resources/build/xcode-wrap.sh\" \"$KEYMAN_ROOT/resources/build/set-bundle-versions-and-settings-untagged.sh\"\n"; + shellScript = "exit 1\n\"$KEYMAN_ROOT/resources/build/xcode-wrap.sh\" \"$KEYMAN_ROOT/resources/build/set-bundle-versions-and-settings-untagged.sh\"\n"; showEnvVarsInLog = 0; }; 9800EC5D1C029FCD00BF0FB5 /* ShellScript */ = { From 42e54dafbf11d61f97035ce0dd96b362b9e4f001 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Thu, 2 May 2024 09:07:20 +0700 Subject: [PATCH 59/60] chore(ios): experiment -> change order of build task 'Embed Frameworks' --- oem/firstvoices/ios/FirstVoices.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/oem/firstvoices/ios/FirstVoices.xcodeproj/project.pbxproj b/oem/firstvoices/ios/FirstVoices.xcodeproj/project.pbxproj index 31cae7af740..f11f08ddbb0 100644 --- a/oem/firstvoices/ios/FirstVoices.xcodeproj/project.pbxproj +++ b/oem/firstvoices/ios/FirstVoices.xcodeproj/project.pbxproj @@ -301,9 +301,9 @@ 9889E8B31BFA9CEC00019560 /* Frameworks */, 9889E8B41BFA9CEC00019560 /* Resources */, 98C9A8C81BFBF23C009E9A4F /* Embed App Extensions */, + 371C855D2288F3A50076612A /* Embed Frameworks */, 37DF007C24595F6F00C73128 /* Run Script */, 9800EC5D1C029FCD00BF0FB5 /* ShellScript */, - 371C855D2288F3A50076612A /* Embed Frameworks */, ); buildRules = ( ); @@ -459,7 +459,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = "/usr/bin/env bash"; - shellScript = "exit 1\n\"$KEYMAN_ROOT/resources/build/xcode-wrap.sh\" \"$KEYMAN_ROOT/resources/build/set-bundle-versions-and-settings-untagged.sh\"\n"; + shellScript = "\"$KEYMAN_ROOT/resources/build/xcode-wrap.sh\" \"$KEYMAN_ROOT/resources/build/set-bundle-versions-and-settings-untagged.sh\"\n"; showEnvVarsInLog = 0; }; 9800EC5D1C029FCD00BF0FB5 /* ShellScript */ = { From f9c699e3dba2250bd7e01b5a9ba953337dbf8fdb Mon Sep 17 00:00:00 2001 From: sgschantz Date: Thu, 2 May 2024 09:53:40 +0700 Subject: [PATCH 60/60] chore(ios): allow underscore to avoid unexpected Xcode 15.3 lint error --- ios/.swiftlint.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ios/.swiftlint.yml b/ios/.swiftlint.yml index bfb08663e31..5abe0cedd10 100644 --- a/ios/.swiftlint.yml +++ b/ios/.swiftlint.yml @@ -12,3 +12,7 @@ identifier_name: min_length: warning: 0 error: 0 + +# allow underscore to avoid unexpected lint error in generated file in Xcode 15.3 +type_name: + allowed_symbols: "_"