Commit graph

1167 commits

Author SHA1 Message Date
Marc Durdin
efad936105 feat(common): add KMX+ file reader in Typescript
Add a KMX+ file reader and tests, including a round-trip builder:reader
test.

Move basic-17.txt, basic-19.txt, and basic.xml to common test resources
folder so they can be used by unit tests in common and developer.

Test-bot: skip
2026-03-16 07:21:38 +01:00
Keyman Server
7b9864810f
Merge branch 'epic/embed-osk-in-kmx' into auto/A19S23-merge-master-into-embed-osk-in-kmx 2026-02-27 08:25:14 +01:00
Eberhard Beilharz
2237db95f6
test(core): add LDML baseline test with minimal keyboard
This replaces and enables the commented `k_000_null_keyboard` test which
didn't work because keys that are not on any layer don't produce output.
This instead defines a minimal keyboard with just two keys and then tests
typing a key that is on the keyboard followed by a key not on the keyboard.

Test-bot: skip
2026-02-20 12:09:08 +01:00
Eberhard Beilharz
b405bf5842
refactor(core): simplify loop for removing text
Instead of using an iterator to loop over the context items, incrementing
a counter on each iteration, and then finally removing the calculated
number of context items from the list, this change loops through the list
and looks at the last context item, removing it if necessary.

Follows: #15596
Test-bot: skip
2026-02-18 17:34:02 +01:00
Eberhard Beilharz
df2b675202
fix(core): changed ldml tests to use context list instead of vector
Production code uses a list of context items, so this change modifies
the tests to also use a list instead of a vector to more closely match
production code.

Addresses code review comment.

Test-bot: skip
2026-02-18 16:08:59 +01:00
Eberhard Beilharz
32bb1c8502
fix(core): fix iterator in backspace handling
This change replaces the reverse iterator loop that holds a stale iterator
across `pop_back()` calls with a pattern that directly accesses
`context.back()` on each iteration. This avoids undefined behavior from
iterator invalidation when mutating the list or vector.

While so far the previous code didn't show problems, it might still access
released memory depending on the implementation. The documentation for
`pop_back()` says "References and iterators to the erased element are
invalidated", so the previous implementation was clearly wrong.

Test-bot: skip
2026-02-18 15:58:45 +01:00
Keyman Server
7bdd4b5254
Merge branch 'epic/embed-osk-in-kmx' into auto/A19S22-merge-master-into-embed-osk-in-kmx 2026-02-13 04:58:57 +01:00
Marc Durdin
74d1bc8fc2 chore(core): address review comments
Co-authored-by: Darcy Wong <darcy_wong@sil.org>
Co-authored-by: Eberhard Beilharz <ermshiperete@users.noreply.github.com>
2026-02-01 06:47:49 +11:00
Marc Durdin
766c6992ed fix(core): normalization segment should end on NFC boundary, not NFD
When normalizing, we need to stop processing on an NFC boundary, not an
NFD boundary, to support normalizations such as in Bengali, where
appending `U+09D7` to a context of `U+0995 U+09C7` should result in
`U+0995 U+09CC`.

The specification is unclear on this; see https://unicode-org.atlassian.net/browse/CLDR-19218

This also updates the ldml keyboard unit test suite to support running
in full NFC mode (used in all Engine implementations) as well retaining
the NFD mode (now only used by the debugger).

Side note: the Bengali normalization failure case was picked up by the
improvements to the unit test suite, proving once again that good tests
are so valuable.

Fixes: #15491
Fixes: #15505
Follows: #15488
Relates-to: CLDR-19218
2026-01-28 14:32:25 +11:00
Marc Durdin
033e3eeb3f docs(core): add comments post review
Co-authored-by: srl295@gmail.com
2026-01-27 10:50:26 +11:00
Marc Durdin
f7cd0c41ba fix(core): handle backspace decomposition
Ensure that when a single backspace decomposes the last NFC character in
the app context, the remainder of the 'cluster' is preserved, matching
the implication of the CLDR keyboard specification.

This addresses the behavior in #15487 where the cached context became
out of sync with the app context after deleting an entire NFC cluster
such as ê, which caused a loop ending up with the entire context being
deleted, at which point the loop exited with a fail-safe.

Note that the LDML keyboard tests (ldml.cpp) do not currently exercise
the normalization code; this is a gap that should be addressed to ensure
that we are testing final application behavior.

Fixes: #15487
2026-01-25 07:24:15 +11:00
Marc Durdin
414092abf6
Merge branch 'epic/embed-osk-in-kmx' into auto/A19S20-merge-master-into-embed-osk-in-kmx 2026-01-16 08:39:08 +01:00
Marc Durdin
484acff8e8
Merge pull request #15353 from keymanapp/maint/win/15065-arm64-core-test
maint(windows): add GitHub Action for ARM64 test for Keyman Core 🦾
2025-12-16 18:49:57 +01:00
Marc Durdin
3048705c9b maint(windows): add GitHub Action for ARM64 test for Keyman Core
Add a GitHub action to test Keyman Core on Windows / ARM64. We do not
have a TeamCity ARM64 agent for this. There are a number of config
challenges in making this work as many deps do not yet support ARM64;
however the changes are isolated to the .yml.

Test-bot: skip
2025-12-16 06:48:25 +11:00
rc-swag
4ac24f7b7b chore(windows): Merge branch 'epic/win-arm' into feat/windows/64x-pure-forwarder-wix-3 2025-12-09 14:00:45 +10:00
Marc Durdin
d7f21e80ec chore: Merge remote-tracking branch 'origin/epic/win-arm' into auto/A19S17-merge-master-into-win-arm
Significant conflict resolution fixes required to:
*	windows/src/engine/keyman32/build.sh
*	windows/src/engine/keyman32/keyman-engine.vcxproj
*	windows/src/engine/keyman32/keyman32.vcxproj
*	windows/src/engine/keyman32/keyman32.vcxproj.filters
*	windows/src/engine/keyman32/tests/keyman32.tests.vcxproj
2025-12-05 10:16:37 +01:00
Keyman Server
2d29ef52e4
Merge branch 'epic/embed-osk-in-kmx' into auto/A19S17-merge-master-into-embed-osk-in-kmx 2025-12-05 07:58:49 +01:00
rc-swag
192a94e6c5 feat(windows): simplify vc config environment
With VS2022 the limitations for the -hostarch flag not being available
on arm environment and the -arch only having x86 and x64 has been
removed. There is now single command that works for 3 builds on either
host architecture.
Fixes: 15239
Test-bot: skip
2025-12-02 16:07:04 +10:00
Marc Durdin
9335a82530 maint(core): verify that keyman_core_ldml.h is in sync
Fixes: #15254
Test-bot: skip
Build-bot: skip build:linux,mac,windows
2025-12-01 17:11:57 +01:00
Marc Durdin
f50934bf69 chore(core): update keyman_core_ldml.h 2025-11-27 10:28:15 +01:00
Marc Durdin
12b77a5a78 feat(developer): convert .kvk into KMX+ and embed into .kmx
Implement the conversion from .kvk into KMX+ format, and embed the
result into the .kmx file. This change does not yet support &displaymap.

Move some virtual key modifier state helpers out of
visual-keyboard-compiler.ts and into shared module
modifier-key-constants.ts.

This change also flags the need to update the package compiler to
rewrite the font metadata into the KMX+ tables.

Test-bot: skip
2025-11-25 11:59:34 +01:00
Marc Durdin
75847a389f
Apply suggestions from code review
Co-authored-by: Eberhard Beilharz <ermshiperete@users.noreply.github.com>
2025-11-21 10:48:11 +01:00
rc-swag
ad34a44c9f chore(windows): Merge branch 'epic/win-arm' into feat/windows/11905/keymanx64-keymanarm64 2025-11-21 18:36:13 +10:00
Marc Durdin
45496aaf30
Merge branch 'epic/embed-osk-in-kmx' into feat/common/kmx-plus-osk-embed-support 2025-11-20 15:15:35 +01:00
Keyman Server
7ad056bf5f
Merge branch 'epic/embed-osk-in-kmx' into auto/A19S16-merge-master-into-embed-osk-in-kmx 2025-11-20 11:08:48 +01:00
rc-swag
c9753f6ba2 feat(windows): handle arch type in build.bat skip build.sh
Add a host check for build.bat and run the architecture tests
that match the host. for the meson builds from build.h
for now just skip the arm64 tests.
2025-11-19 11:50:57 +10:00
Marc Durdin
a53a1593ec feat(common): add v19 sections to KMX+ in Core and Developer
The disp and layr sections have new v19 layouts, to support the Keyman
OSK requirements for epic/embed-osk-in-kmx. This supports writing the
new versions of these sections in Developer and loading them into Core,
doing transformations where necessary so that Core always works with v19
structures after load.

This does not implement the transformations required to support the OSK
APIs; that will be implemented in a follow-up PR. Nor is support for
writing the OSK data from source .kvks and .keyman-touch-layout
supported; this is just the scaffolding for supporting the structures in
the KMX+ data.

Test-bot: skip
2025-11-18 13:55:01 +01:00
Marc Durdin
fc0ff90684 refactor(developer): rename layr.lists to layr.forms
The name `form` better represents the semantic meaning of the
structure, and reduces confusion with the `list` section and other uses
of `list` in KMX+.

Test-bot: skip
2025-11-12 11:29:58 +01:00
Eberhard Beilharz
2d8a4aeebc
maint(core): fix option defaults for Meson >= 1.1
Meson 1.1 changed the name of the options file from `meson_options.txt`
to `meson.options`. Currently we're stuck with Meson 1.0 as minimum
Meson version because we still support Ubuntu 22.04 Jammy, but on some
machines a newer version of meson gets installed which causes the
options to be ignored.

The first attempt to simply symlink or copy `meson_options.txt` to
`meson.options` failed because git on Windows doesn't support symlinks
by default, and Meson complains if it finds two options files (#15127).

Fortunately not having an options file is only a problem for Core where
we have one option in the options file that defaults to true. The solution
implemented in this change is to always pass the option to Meson.

Test-bot: skip
2025-11-10 15:24:46 +01:00
rc-swag
1cf430bb98 chore(windows): Merge branch 'epic/win-arm' into feat/windows/11905/keymanx64-keymanarm64 2025-11-10 11:29:40 +10:00
Keyman Server
b7c93d9e37
Merge branch 'epic/embed-osk-in-kmx' into auto/A19S15-merge-master-into-embed-osk-in-kmx 2025-11-07 14:06:33 +01:00
Marc Durdin
df212364a2 maint(resources): add repository record for all published packages
While not documented as such, it appears that the repository record is
required with trusted publishing of npm packages.

Test-bot: skip
Build-bot: skip
2025-10-29 14:35:31 +01:00
Marc Durdin
ee4cb5a47e
Merge pull request #14994 from keymanapp/test/core/add-unit-tests-for-v19-kmx-plus
test(core): add unit tests for v19.0 kmx+ format 🔱
2025-10-29 11:04:22 +01:00
rc-swag
2f2df0bb8f feat(windows): fix typos entered into the build.bat 2025-10-28 17:08:47 +10:00
Marc Durdin
fe6e8e72a8
Merge pull request #15029 from keymanapp/maint/resources/14963-npm-publish-on-gha
maint(resources): move npm package publishing to GitHub Actions
2025-10-28 07:57:35 +01:00
rc-swag
d52b48cbbb feat(windows): handle arm64 complier environment
Update the build.bat to handle configuring the build
environment with vsdevcmd correctly for arm64 2019 doesn't
work very well so have to have pretty weird if statement.
also checked in some missed updates to function name change
2025-10-28 16:40:42 +10:00
Marc Durdin
e9705242c1 docs(core): add function comments
Build-bot: skip
2025-10-27 16:38:21 +01:00
Marc Durdin
ba411774f6 maint(resources): move NPM package publishing to GitHub Actions
Due to recent changes in NPM package publishing security requirements,
we have to move from TeamCity build to a GitHub Action to publish our
NPM packages, so we can take advantage of trusted publishing. This
change also consolidates and centralizes the npm publishing into
resources/build/ci/npm-publish.sh, which removes a lot of boilerplate
from each of the build.sh scripts, and ensures consistency.

Packages will be `npm pack`ed on PR and test builds, and published in
release builds.

Ref: https://docs.npmjs.com/trusted-publishers
Ref: https://github.blog/changelog/2025-09-29-strengthening-npm-security-important-changes-to-authentication-and-token-management/
Fixes: #14963
Test-bot: skip
Build-bot: release:developer
2025-10-27 16:31:55 +01:00
Marc Durdin
55d6efe482 fix(developer): prevent ANSI keyboards crashing debugger
Note: #11909 has some additional future cleanup we could do, but these
code paths are not currently accessible, so in the interest of moving
forward, am leaving them for now.

Fixes: #11909
Test-bot: skip
2025-10-24 14:45:17 +02:00
rc-swag
5f974775cd feat(windows): remove echo 2025-10-22 22:48:27 +10:00
Marc Durdin
66258e6b51
Merge branch 'feat/developer/add-targetversion-parameter' into test/core/add-unit-tests-for-v19-kmx-plus 2025-10-22 11:44:56 +02:00
Marc Durdin
77ea540fdd refactor(core): DRY out filling of sub-section data and fix cross-platform diffs
* Address cross-platform compiler warnings around shadowed pointers
  and non-virtual destructors.

* Refactor the offset calculations for sub-section data to reduce
  repetition both within each calculation, and the patterns of the
  calculations themselves. This mostly resolves possibility of typo
  errors when mapping the section data in, e.g. using the wrong count,
  as each variable and type is only referenced once, and compiler will
  catch most discrepancies - except for count vs type. This is also much
  easier to read and verify in code review, I hope!
2025-10-22 11:27:35 +02:00
Marc Durdin
d779274dc6 test(core): add unit tests for v19.0 kmx+ format 2025-10-22 05:48:24 +02:00
Marc Durdin
57e0e6941d refactor(core): add support for header.version to Core LDML
This substantial refactor reorganizes the header data for sections in
the Core LDML processor. The change was substantial because of
assumptions made about the binary layout of sections. In order to make
the code easier to maintain, safer, and more resilient to future
changes, I opted to make a consistent helper for each section, and copy
header data so that it could be transparently reused.

The principal changes are:

1. Support the version field in the COMP_KMXPLUS_HEADER struct, and
   split it into COMP_KMXPLUS_HEADER_17 and COMP_KMXPLUS_HEADER_19
   versions.
2. Establish a corresponding COMP_KMXPLUS_XXXX_Helper clas for each
   section.
3. Refactor the majority of rawData accesses into using helper
   functions, which reduces direct pointer manipulation and adds extra
   boundary checks.

A special-case exists for BKSP - it is identical to TRAN, except for
its section ident. In order to avoid a complicated pattern for handling
it, I have special-cased it in one place, adding an overloaded
`get_section_from_sect` function for COMP_KMXPLUS_BKSP.

An opportunity exists to refactor a bit further - reduce direct access
to the binary data (through the COMP_KMXPLUS_XXXX structs, and instead
promote use of the COMP_KMXPLUS_XXXX_Helper classes). This indirection
would  reduce duplication of data access and make it cleaner when we
start doing multi-version code.

Next commit will add unit tests for v19 format files.
2025-10-22 05:48:23 +02:00
Marc Durdin
693c741884 feat(common): add version header to KMX+ Typescript modules
Add support for header.version to KMX+ files, with differentiation
between v17 and v19 in the compiler, and associated tests. This does not
yet make the target version accessible to authors using `kmc`, but the
interfaces from `kmc-ldml` are available.

A v17 KMX+ file will have:
* comp_header.version = VERSION_17
* initial 'sect' section in KMX+ data
* no sect.header.version field in any section

A v19+ KMX+ file will have:
* comp_header.version = VERSION_19
* initial 'sec2' section in KMX+ data
* sect.header.version field for all sections
* each section 4 bytes larger to accommodate
* 'sec2' must have sect.header.version = KMXPlusVersion.Version19
* currently all other sections have sect.header.version = Version17
2025-10-17 11:23:09 +02:00
rc-swag
1340c4f9e5 feat(windows): add arm64 to wxs and core build
Add cross-arm64 and cross-x64 build
Add the arm64 binaries to the wxs installers with guids
update build.sh files
2025-10-14 16:00:40 +10:00
rc-swag
5ac167977b Merge branch 'epic/win-arm' into feat/windows/11905/keymanx64-keymanarm64 2025-10-01 14:11:23 +10:00
Marc Durdin
f3fb3ac87b maint(common): move build-utils-ci.inc.sh to ci/ci-publish.inc.sh
Removes a number of unused functions from the file, renames remaining
functions to match our builder script prefix patterns, removes unused
imports from various build scripts (e.g. Android).

Fixes: #14453
2025-08-05 12:54:56 +10:00
Marc Durdin
2726050601 maint(common): rename and move node-related script functions into node.inc.sh
Consolidates the node-related script functions into node.inc.sh, as part
of cleaning up the build scripts and making them easier to maintain into
the future.

Fixes: #14447
2025-08-02 13:34:29 +10:00
Marc Durdin
f394245636 maint(common): consolidate builder scripts
Clarifies the confusing builder.inc.sh / build-utils.sh distinction by
giving the scripts more appropriate names. Most build scripts should use
builder-full.inc.sh; some helper scripts can use builder-basic.inc.sh.
Documented in resources/build/README.md.

Renames:
* resources/build/builder.inc.sh to resources/build/builder-full.inc.sh
* resources/build/build-utils.sh to resources/build/builder-basic.inc.sh

Other changes:
* Moves Android-specific functions out of builder-basic.inc.sh and into
  android/build.sh.
* Renames functions in builder-basic.inc.sh

More functions may be moved from builder-basic.inc.sh into utils.inc.sh
or other scripts in the future.

Fixes: #14065
Build-bot: build all
Test-bot: skip
2025-08-02 08:11:24 +10:00