Fixes#5245.
Interfaces should remain stable between versions of Keyman, so that an
upgraded kmcomapi.dll or keyman32.dll will not crash older clients, even
if they may not behave entirely as expected.
Fixes#5004.
This cleans up the use of controller windows. A single window is now
given the responsibility of being the master controller, which receives
messages from Keyman32 and other components around UI activation, active
keyboard, etc.
The master controller is keyman.exe's `TApplication` window, which does
not get destroyed and recreated, unlike the main form window.
Any thread which has responsibility for Keyman UI (keyman.exe main
thread, keymanx64.exe main thread) is also registered as a controller
thread. A controller thread has special handling for interactions with
keyman32 around focus tracking.
Caveats:
* While keymanx64 does not have a visible window and thus probably does
not need to be registered as a controller thread, it doesn't really
hurt.
* Note that keymanx64 registers the 32-bit controller thread as well,
which again is probably unnecessary as the 64-bit process cannot
interact with the 32-bit thread.
* Keyman's main form still handles wm_keyman_control messages, as there
are a number of other components which post to that window (e.g. text
editor, com library visual keyboard interactions). Unlike the original
problem trigger, the reference handle is not stored long-term and so
there is unlikely to be a problem with main form window re-creation
causing an issue in these contexts.
There are several TODO items in this which I will address in follow-ups,
to reduce the scope of these changes.
I hope to cherry-pick this to stable-14.0, but will run for a while in
15.0 before doing so.
Fixes#4939.
Fixes KEYMAN-WINDOWS-70.
Fixes KEYMAN-WINDOWS-71.
Fixes KEYMAN-WINDOWS-BR.
Fixes KEYMAN-WINDOWS-6J.
I am speculating a little here, because the root cause is not visible in
the crash report, but it appears that if keyman32.dll is renamed, that
the UnregisterControllerWindows function attempts to reload keyman32.dll
which means that (a) it no longer has a list of registered controllers,
and (b) it may fail to reload.
Instead of throwing an exception, we now only log this error in
development mode. The error is not likely to cause significant trouble
for end users as they are shutting down Keyman anyway at this point.
The resolution if there is any uncertainty during an upgrade is to
restart Windows. This is less than ideal but avoids file locks and
problems with in-memory DLLs. (Future versions of Keyman will schedule
upgrades to happen automatically after a restart before Keyman has been
started, in an effort to avoid this kind of trauma.)
This change has three fixes to improve the reliability of notifying
Keyman Engine of updates to settings or keyboard installs:
1. It removes the closure pattern of the refresh thread, because that
was closing on a variable on a different thread (`RefreshHandle`) and
that could cause races and/or exceptions in the case of early free.
What's more, the closure was actually unnecessary as the variable was
really only used by the refresh thread!
2. It moves responsibility for setting the refresh token to the calling
thread so that the caller can depend on the token being the one that
is actually sent, removing a race.
3. Most important, the refresh thread now flushes all messages in its
queue, as there may be multiple messages relating to the window
construction that need to be processed before the wm_keyman_refresh
message can be handled. This greatly improves the chance of the
notification actually being sent!
Fixes#4011.
Fixes#4039.
Fixes#4121.
This change completes the immediate-change model for Keyman
Configuration, by refactoring the refresh of settings out of the render
phase and more appropriately splitting applying and refreshing. It adds
a new message flag for wm_keyman_refresh, KR_SETTINGS_CHANGED, which
uses a random token approach broadcast to all applications on the
desktop to ensure that the refresh is received and multiple
notifications for the same event can be appropriately coalesced.
Most of the files touched are stripping out the refresh flags from the
render phase.
There is one small bug resolved at the same time with the options
properties, which were not reset to default if they had been deleted
from the registry prior to a refresh (see utilkeymanoption.pas).
Fixes#3518.
Changes in Keyman Configuration will now apply immediately. This removes
the OK and Cancel buttons from the dialog and means that all actions
are consistent in when they are applied, unlike previously. This also
matches the Windows 10 Settings metaphor and metaphors for most modern
apps and devices.
For now, I have placed a message where the OK and Buttons were
previously, to help existing users understand the change. In time, I
expect us to be able to remove that message entirely.
Fixes#2450. When Keyman serialized input, it would cause the touch keyboard to cancel
because the touch keyboard thought the received event meant the user was touching the
physical keyboard. This resolves that problem, using a watch timer to check the visibility
of the touch input panel.