Commit graph

3848 commits

Author SHA1 Message Date
Darcy Wong
7072a516a4 fix(windows): Use double slash for debug path 2025-12-19 13:26:21 +07:00
Darcy Wong
f0fc8f9d13
Merge branch 'master' into chore/common/crowdin-pt 2025-12-19 06:02:14 +07:00
Darcy Wong
cbca7630e1 chore(common): Update crowdin strings for PT 2025-12-18 16:13:25 +07:00
Marc Durdin
a77518eb28 chore(windows): fix typo in error message
Build-bot: skip
Test-bot: skip
2025-12-17 05:41:20 +11:00
Marc Durdin
1332a9c3f7
Merge pull request #15351 from keymanapp/fix/windows/15345-use-thai-kedmanee-for-ralt-unit-test
chore(windows): correct kbda1 to kbdth0 in comment in unit test
2025-12-16 19:13:07 +01:00
Marc Durdin
a7b38dcf8b
Merge pull request #15335 from keymanapp/feat/windows/15218-report-low-level-hook-reinstall
feat(windows): report a sentry event when low level hook is reinstalled
2025-12-15 20:03:23 +01:00
Marc Durdin
49a3a1d643 chore(windows): correct kbda1 to kbdth0 in comment in unit test
Fixes: #15345
Test-bot: skip
Build-bot: skip
2025-12-14 03:54:26 +11:00
Marc Durdin
66a22754cb
Merge branch 'master' into feat/windows/15218-report-low-level-hook-reinstall 2025-12-11 21:22:38 +01:00
Marc Durdin
aeb7dc7934
Merge branch 'master' into chore/windows/remove-unused-variable 2025-12-11 21:22:32 +01:00
Marc Durdin
612a0173db fix(windows): use Thai Kedmanee instead of Arabic 101 in RightAltEmulationCheck.tests.cpp
Fixes: #15345
Test-bot: skip
2025-12-12 06:11:33 +11:00
Marc Durdin
6c7bfd3c55 chore(windows): remove unused variable
Test-bot: skip
2025-12-10 18:28:38 +08:00
Marc Durdin
930ae121c4 feat(windows): report a sentry event when low level hook is reinstalled
Reports also on errors during install / uninstall of the low level hook.

Fixes: #15218
Test-bot: skip
2025-12-10 08:27:12 +00:00
Marc Durdin
76e6a956ed chore(windows): simple bisect utility for checking setup-redist.exe file size
This could be used for various other bisect tasks in the future, as a
starting point.

Test-bot: skip
Build-bot: skip
2025-12-09 18:19:30 +00:00
Marc Durdin
acc86f5bce
Merge pull request #15280 from keymanapp/change/windows/add-shortcuts-to-install-dialog
change(windows): add shortcuts to 'Update Available' dialog
2025-12-05 07:11:05 +01:00
Marc Durdin
f813442c40
Merge pull request #15276 from keymanapp/revert-14799-change/windows/include-map2pdb-for-relevant-projects
change(windows): Revert "change(windows): include map2pdb generation for relevant Delphi projects"
2025-12-05 07:10:52 +01:00
Marc Durdin
6c07c48235 change(windows): add shortcuts to 'Update Available' dialog
`&X` means you can press Alt+X.

Test-bot: skip
Build-bot: skip
2025-12-04 04:32:18 +01:00
Marc Durdin
e9ac9c25a3
chore(windows): don't revert minor unrelated parts of map2pdb cleanup 2025-12-03 14:25:29 +01:00
Marc Durdin
6c99f33bcc
Revert "change(windows): include map2pdb generation for relevant Delphi projects" 2025-12-03 14:13:54 +01:00
Marc Durdin
c524db41b9 maint(common): use builder_launch for child builds
Fixes: #15130
Test-bot: skip
2025-12-02 06:17:31 +01:00
Marc Durdin
00d0ef5e28
Merge pull request #15246 from keymanapp/chore/windows/add-wow64kbd-explorer
chore(windows): add wow64kbd support app for researching WOW64 reqs
2025-11-28 10:48:59 +01:00
Marc Durdin
ff984c8144
chore: Update windows/src/engine/keyman32/RightAltEmulationCheck.cpp
Build-bot: skip

Co-authored-by: rc-swag <58423624+rc-swag@users.noreply.github.com>
2025-11-28 10:26:07 +01:00
Marc Durdin
ec8908ecc7 chore(windows): add wow64kbd support app for researching WOW64 reqs
This app reports on WOW64 identification function results, and reports
on kbdxx.dll file alignment by printing a hex dump of the first 44 bytes
(which is the 32 bit size of the structure). Manual review of the hex
dump should be possible to determine if we have the expected alignment,
which should be 32 bit on a 32 bit Windows installation, but 64 bit on
any 64 bit other Windows installations, even with a 32 bit process.

wow64kbd is not included in the normal build. Build when needed; you can
copy entire folder to a target computer and run `run.bat` to get a full
report.

`./build.sh test` will also run the same test on the local machine.

Test-bot: skip
Build-bot: skip
2025-11-27 11:06:01 +01:00
Marc Durdin
404a9ea244 refactor(windows): merge syskbdnt.cpp and syskbdnt64.cpp into RightAltEmulationCheck.cpp
Remove a number of unused bits and pieces, and merge the one remaining
function in syskbdnt.cpp, `KeyboardGivesCtrlRAltForRAlt` with the
corresponding function in syskbdnt64.cpp.

Add a unit test for `ReadAltGrFlagFromKbdDll` to ensure that it is
working correctly across various architectures.

Test-bot: skip
2025-11-27 09:37:59 +01:00
Marc Durdin
ca77e41d74 change(windows): add unit testing to keyman32 build
Rename keyman-engine-tests.vcxproj to keyman32.tests.vcxproj, move up a
folder, rename other files to match test filename conventions, update
vcxproj for vs2022, and build and run this from build.sh:test.

Also remove keyman-engine.vcxproj, instead integrating the static lib
version of keyman32 into keyman32.vcxproj. One day in the future, we
could split back the other way, and have the DLL be essentially a link
action from the .lib, but that's higher complexity to setup.

Add a configuration step to install NuGet packages for Google Test
specifically for keyman32.tests.vcxproj. If we add Google Test to other
msbuild projects, we could move the packages/ up to top level of the
repo in the future (similar to node_modules) to reduce number of
configuration downloads.

Build-bot: skip build:windows,developer
Test-bot: skip
2025-11-27 09:11:39 +01:00
Marc Durdin
565af2d30e fix(windows): escape backslashes in path in debugging message
Fixes: #15233
Test-bot: skip
Build-bot: skip
2025-11-26 05:53:02 +01:00
Marc Durdin
c3915928a6 chore(windows): use MultiThreaded library for fakefreeze 2025-11-19 06:28:04 +01:00
Marc Durdin
ef64af0155
Merge branch 'master' into fix/windows/8064-low-level-hook-watch-dog 2025-11-17 17:07:23 +01:00
Marc Durdin
711541be60 fix(windows): reinstall low level keyboard hook if it gets removed
This change improves the stability of Keyman for Windows by monitoring
the health of the low level keyboard hook. If keyman.exe is unresponsive
at any time, Windows can silently uninstall its low level keyboard hook,
which results in (at least) two problems:

* Keyman's hotkeys stop working
* A modifier key can become stuck, if it was pressed around the time
  Keyman became unresponsive.

The most common scenario in which Keyman can become unresponsive is high
system load, e.g. rendering graphics, videoconference calls, compiling
software.

Restarting Keyman always resolved both of these two issues in the past,
but with this patch, I hope that this will no longer be necessary.

A related 'fakefreeze' project is included for simulating a keyman.exe
hang by posting a `wm_keyman_control:KMC_WATCHDOG_FAKEFREEZE` message to
it, which keyman.exe responds to by `Sleep()`ing for 5 seconds. While
keyman.exe is freezing, any keystroke will cause the low level hook to
be uninstalled by Windows.

Logging has been updated; look for "LowLevelHookWatchDog" in the log for
related events.

One final small change in keyman32.cpp, as I refactored the
WH_KEYBOARD_LL hook installation/uninstallation, was to always clear out
hook variables when uninstalling a hook, because if the hook fails to
uninstall, there's really nothing we can do about it anyway, and we
probably shouldn't be trying again.

Fixes: #8064
2025-11-17 16:30:43 +01:00
Marc Durdin
bf4d707662 change(windows): use circular buffer for logging
Test-bot: skip
2025-11-14 05:23:32 +01:00
Marc Durdin
edca16f508 change(windows): include map2pdb generation for relevant Delphi projects
Adds a call to map2pdb for Delphi projects, if map2pdb is an executable
on the path. This way, we get .pdb files we can use for debugging and
for performance profiling. This also replaces tds2dbg.

If map2dbg is available, then the build and install actions will copy
the PDB to be alongside the corresponding executable, making most debug
actions relatively seamless for finding symbols.

Also fixes up setup.exe in Windows and Developer to extend setup.exe to
a 512-byte boundary after map2pdb patches the PE.

Relates-to: #14787
Build-bot: skip release:developer,windows
Test-bot: skip
2025-11-13 14:48:18 +01:00
Marc Durdin
54642dc86d fix(windows): disable OutputDebugString from DllMain
Following investigation, it seems that OutputDebugString can trigger a
loader lock as it throws an exception which can be handled by a global
exception handler, which may try and load/unload DLLs or perform other
unsafe tasks (e.g. StackWalk). The safest solution is to remove the
debug string logging altogether from code paths that run from DllMain.

It would be nice to further simplify DllMain but that would be a
significant amount of additional work.
2025-11-13 14:47:39 +01:00
Darcy Wong
f908546969
Merge pull request #15034 from keymanapp/chore/common/platform-rules
chore(common): Consolidate platformtest.js keyboard to `/common/test/keyboards/` 🚛
2025-11-06 13:24:14 +07:00
Marc Durdin
9e1fe8e6de chore(windows): upgrade VC++ projects to v143 (VS2022)
Test-bot: skip
Build-bot: skip release:developer,windows
2025-10-30 16:31:45 +01:00
Darcy Wong
5bf5a5941f chore(common): Move platformtest to common/test/keyboards 2025-10-28 07:18:49 +07: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
Darcy Wong
5f021e3884 chore(windows): Beautify platformtest.js 2025-10-24 14:10:57 +07:00
Darcy Wong
b1fe097a82 chore(windows): Update platformtest keyboard 2025-10-24 10:24:11 +07:00
Marc Durdin
96e7ed56b5
Merge pull request #14909 from keymanapp/fix/windows/14890-ctrl-ralt-on-osk
fix(windows): osk: handle simulated left Control event when AltGr pressed
2025-10-13 10:39:42 +02:00
Marc Durdin
03cd865c09
Apply suggestions from code review
Co-authored-by: rc-swag <58423624+rc-swag@users.noreply.github.com>
2025-10-13 10:37:35 +02:00
Darcy Wong
c38f488986 chore(common): Update crowdin strings for Vietnamese 2025-10-09 11:40:18 +07:00
Marc Durdin
c99e0c01c4 chore(windows): address warnings 2025-10-08 15:08:04 +02:00
Marc Durdin
cb6063a954 chore(windows): add test app for investigating low level keyboard events
Relates-to: #14890
2025-10-08 14:59:48 +02:00
Marc Durdin
50ffbb2722 fix(windows): osk: handle simulated left Control event when AltGr pressed
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
2025-10-08 14:32:40 +02:00
rc-swag
d769ef31b5
Merge pull request #14683 from keymanapp/fix/windows/14577/clean-cache-idle-state
fix(windows): remove cached files in idle state
2025-10-03 09:19:56 +10:00
Marc Durdin
881e08282a
Merge pull request #14795 from keymanapp/feat/windows/14787-improve-startup-time
feat(windows): improve startup time by caching locale names
2025-09-26 09:09:24 +02:00
rc-swag
96a28feeed
Merge pull request #13573 from keymanapp/fix/windows/13376-language-Selector-setup-is-not-sorted
fix(windows): sort setup UI language selector according to language names
2025-09-26 15:28:13 +10:00
Marc Durdin
39b4d630dd docs(windows): add documentation for localization functions
Build-bot: skip
2025-09-25 09:46:24 +02:00
Marc Durdin
914bf6a8a4 fix(windows): disable .msi shortcut advertisement
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: #14809
Fixes: #14791
Build-bot: skip release:windows
2025-09-25 09:04:37 +02:00
rc-swag
c5b82bd01a
fix(windows): minor review comments 2025-09-25 14:29:23 +10:00
Marc Durdin
ad9ab53c72 feat(windows): improve startup time by caching locale names
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
2025-09-19 14:11:37 +02:00