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
When a European layout is active, and the user presses AltGr, Windows
generates a simulated VK_LCONTROL event alongside the VK_RMENU event.
This was causing the OSK to show LCtrl as depressed alongside RAlt, so
the OSK would show the wrong modifier layer, which was unhelpful and
confusing to the end user.
It is possible to detect the simulated VK_LCONTROL in the WH_KEYBOARD_LL
hook, because the scan code generated is 0x21D, instead of 0x1D.
Warning: this is not a documented value. (But, this 0x21D scan code is
not passed to the WM_KEYDOWN event!) Therefore, we use Keyman's existing
kmnLowLevelKeyboardProc to pass modifier key events on to the visual
keyboard.
This patch handles only this specific scenario, by watching for that
specific scan code in the new handler in the UfrmOSKOnScreenKeyboard
module, together with some minor refactoring so that it fits neatly.
A future improvement would be to have all modifier key processing go
through this new handler, and eliminate the timer-based polling of the
keyboard. However, there is some additional risk around missing events,
leading to 'stuck modifiers'.
Fixes: #14890
Build-bot: skip release:windows
Change Keyman shortcuts to standard Windows shortcuts, rather than
advertised shortcuts, to work around a problem with advertised shortcuts,
elevated custom actions, and non-admin users, as described in #14791.
The problem is related to advertised shortcuts in Windows Installer. When
you have an advertised shortcut, the first use of the shortcut triggers a
repair to prepare the app for use in the new user's context. And now, with
Aug 2025 Windows security patch KB5063878, tweaked in Sep 2025, this
triggers an elevation dialog, which the non-admin user cannot work around.
This means that the shortcuts will be regular Windows shortcut files rather
than advertised shortcuts, and are added to
`%ProgramData%\Microsoft\Windows\Start Menu\Programs\Keyman for Windows`
(so, available for all users on that machine, but will not follow a user
across machines).
* DISABLEADVTSHORTCUTS: https://learn.microsoft.com/en-us/windows/win32/msi/disableadvtshortcuts
* Shortcut advertisement: https://learn.microsoft.com/en-us/windows/win32/msi/advertisement
Relates-to: #14809Fixes: #14791
Build-bot: skip release:windows
This was flagged years ago as a potential performance hotspot: each
locale is loaded at process start for any kmcomapi-involved process,
which takes quite a long time. This refactor moves the locale
enumeration out of kmcomapi and into the build process, so we have a
static list of locales put into locale/index.xml.
This includes a minor breaking change to Keyman Engine API on Windows:
`MessageFromID(id, locale)` now only allows the three ids
SKUILanguageName, SKUILanguageNameWithEnglish, and SKLanguageCode, for
performance reasons. At this point, only SKUILanguageNameWithEnglish is
actually used anywhere in Keyman, and it is unlikely that any other
consumers are requesting alternate IDs.
Fixes: #14787
Build-bot: skip release:windows
First run event is actually called from the setup installation package
this means the setup file will be locked and will not be removed
by the first run event. Therefore we need to remove the cache files
in idle state when we get kmshell events. This seems excesive but we
need to do it for the reason explained.
Fixes: #14577
It became apparent that we need to abort the "waitingtorestart" state
before promting the user if they want to install. Otherwise it is
confusing as to why nothing happens and Keyman just starts.
In doing that it was easier to refactor ReadyToInstall to validate the
cache, and check that automatic updates was still set.
It can now also trigger an abort clearing the cache and returning to
idle. This has slight flow on effect in that the HandleKMShell event
can still be called following in the exectution flow.
* Windows and Developer sources
* Fixes the report path to be fully qualified
* Adds the TeamCity report logger to remaining DUnitX automated tests
Fixes: #14197
Build-bot: skip build:windows,developer
Test-bot: skip
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
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
Adds documentation for various functions, removes unused functions (a
couple of simple, very lightly used functions were unDRYed; these could
go back the other way across all shell scripts if necessary). TODO items
noted for follow-up refactoring.
Fixes: #14275
Relates-to: #14269
Build-bot: build all
Test-bot: skip