The `KMC_CHANGEUISTATE` flag for `wm_keyman_control` is no longer
processed anywhere. Removes it and the `UpdateKeymanUI` function which
called it.
The `#define` for the flag has been left, commented out, to clarify what
would otherwise be a gap in identifiers (use `git blame` to learn more).
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#4976.
Fixes KEYMAN-WINDOWS-2K.
Fixes KEYMAN-WINDOWS-3F.
Fixes KEYMAN-WINDOWS-5A.
Fixes KEYMAN-WINDOWS-3E.
This fix reworks keymanx64's lifecycle, moving responsibility for
process shutdown from keyman.exe to keymanx64.exe.
This eliminates the need for interprocess communication, and simplifies
the startup and shutdown of keymanx64.exe. Removing this means that we
can more safely handle situations where two instances of keymanx64 may
be started, as one of them will rapidly terminate when it discovers that
its parent process has disappeared.
Fixes#4965.
When speech recognition is enabled, it sometimes activates after a
Keyman keyboard is selected. This would cause Keyman to think it is
being deactivated. We needed to check in
`CKMTipTextService::OnActivated` that it was a keyboard-type TIP that
was being activated, and only deactivate the Keyman hooks in that
situation.
This commit also adds a little logging helper function, and removes an
unused variable `guidActiveProfile`.
Fixes#4988.
Fixes KEYMAN-WINDOWS-3F.
This relates to #4976 and is a stop-gap until we implement that. It will
reduce the number of reported errors (both to us and the end user) but
does not address the core issue, which requires a more significant
refactor.
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.)
Fixes#4874.
Opening product help from the tray menu would end up at a broken page.
Given the title of the link is "Help Contents", I have opted to open at
the help contents... (rather than the alternative of context/tray-menu).
Fixes#4751.
Fixes KEYMAN-WINDOWS-76.
Fixes KEYMAN-WINDOWS-79.
Fixes KEYMAN-WINDOWS-7B.
Fixes KEYMAN-WINDOWS-7E.
Fixes KEYMAN-WINDOWS-7F.
Fixes KEYMAN-WINDOWS-7K.
Fixes KEYMAN-WINDOWS-7N.
Fixes KEYMAN-WINDOWS-80.
This resolves an issue where the TLangSwitchRefreshWatcher thread would
terminate early on Win7 (as it had no work to do), and free itself, but
then the main form would reference it post-free. Responsibility for free
has been moved to the main form.
This would result in various exceptions as state is corrupted at this
point.
Some of our Sentry reports are difficult to track down. Adding user
interaction breadcrumbs to Keyman Configuration (to start with) may
simplify this. I may add more breadcrumbs to other projects now that
this is available.
Fixes#4447.
Fixes#4222.
The symptoms for these two issues are related: the language associations
change and keyboards stop functioning correctly. The issue is described
in detail in #4447.
Although this fix should be considered 'experimental', we should
probably include it in the release of 14.0, because it fixes a
longstanding issue with Keyman and Windows languages.
If the registry setting `HKCU\Software\Keyman
Engine\Debug:Flag_UseAutoStartTask[REG_WORD]` is not `0`, then the this
will enable the restart task. Otherwise, all aspects of it are disabled.
For Keyman 14.0 initial release, we will have this flag disabled. If we
can improve stability of it, we'll consider turning it on.
Fixes#4490.
Fixes#4435.
There are three parts to this:
1. Ensure that transient language profiles associated with a disabled
keyboard are enumerated correctly
2. Stop trusting `LocaleNameToLCID` when it returns a transient language
id, as it sometimes reports out-of-date values. We don't need to
trust it in these cases anyway, because we have already collected the
relevant transient language data from Win8Languages.
3. Finally, setting the profile GUID to `GUID_NULL` is simply tidyup,
which does not have impact on the running code currently but makes
state consistent.
I believe that part 2 fixes#4435 because the symptoms are identical.
But as I am unable to repro that particular issue on my machine thus
far, that is an assumption. Hopefully we can get a good test result from
@MakaraSok.
Fixes#4619.
The hotkey check in keyman32 would ignore right modifier keys, but the
behaviour was not quite right: it actually needs to take the modifier
into account, but just not treat it as a valid modifier.
While fixing this, I noticed that some of the tests in the
`KeyLanguageSwitchPress` function were using the wrong modifier flags. I
wish I had fewer different modifier flag sets but that ship has probably
sailed.
Fixes#4557.
When focus changes, we need to re-run `_PreserveAltKeys` as settings may
have changed, meaning we have to preserve a different set of keys. I
also made the `_PreserveAltKeys` function idempotent so that we don't
have to worry about cleanup before calling it -- by calling the cleanup
function internally instead.
Fixes#4591.
I fixed incxstr in 4 places:
1. Common/Core: kmx_xstring.cpp
2. Engine: xstring.cpp
3. Test project importkeyboard importkeyboard.cpp
4. Test project m-to-p m-to-p.cpp
I updated mcompile to remove its own copy of incxstr (identical to that
in xstring.cpp) to reduce WETness but opted not to do so for the test
apps, which are pretty much throwaway anyway.
I note that there is more work we could do here; we need to check every
character as we increment so we don't miss a `U+0000` end of string with
malformed data. But I would like to tackle that as a separate job at
some point in the future after Core integration.
I discovered this while working on #4586. The code in question was
updating `*puKey` and then trying to dereference the array on the basis
of its new value, which (a) would give the wrong result, and (b) could
be reading off the end of the array (although not crashing it seems),
e.g. for `"` -> `VK_QUOTE`, which has a value of `0xDE`.
I am guessing that the reason we have not seen any bug reports on this
is that the keystroke handler falls back to an alternate code path, so
in the vast majority of cases, keyboards would continue to work
correctly. Furthermore, the test was just for truthiness of the `BOOL`
so probably at least 50% of the time we'd have been okay anyway. Or
something. Anyway, I reckon this is better.
Fixes#4525.
This is a regression from #4468, which inadvertently added modifier
checks for `VK_CAPITAL` and `VK_NUMLOCK`, when it should not have done
so, as the flag was then being reset when the key was released rather
than toggled.
`ProcessModifierChange` pretended that it could handle `VK_CAPITAL` and
`VK_NUMLOCK` but it would never have worked, and the other caller (the
GetMessage hook) never passed those key events through, only Shift, Ctrl
and Alt, so that's now what the TIP handler does as well.
This leaves the rest of the fix from #4468 in place as that appears
correct.
I took the opportunity to move a repeated function declaration into
keyman64.h.
Fixes#4369.
When Keyman is not handling a particular virtual key, it does not
preserve the virtual key (TSF terminology, essentially reserves that
virtual key + modifier for Keyman). In this situation, Keyman still
receives and processes the virtual key event, but the modifier state
is not passed through by kmtip to keyman32. This is normally okay,
because our `GetMessage` hook is responsible for tracking modifiers.
However, in UWP apps, our `GetMessage` hook does not get run, and so
we lose the modifier keys. Thus, this update ensures that the modifier
keys are processed when received by the TSF TIP.
It does not hurt to process modifier events twice.
We should uninstall transient languages before disabling them
because once we have disabled them, we lose the language
association and cannot find the entry to uninstall. catch-22.
Ensures we get a canonical tag per langtags.json as far as we possibly
can. This is a breaking change for the compiler as tags which were
formerly regarded as canonical are no longer regarded that way. This
mostly relates to script subtag but a secondary bug meant that some
other tags would have lost data in the canonicalization process
(because we did a lookup based only on the language subtag previously,
which is a no-no).
See keymanapp/keyboards#1452 for related work.
Two changes here:
1. Only post the refresh message to the master controller, so that we
get a single refresh regardless of how many controllers are
registered.
2. When Keyman is restarted, the global RefreshTag is reset to 0, so we
need to do a `!=` comparison rather than a `<` comparison to ensure
that apps with an existing keyman32.dll/keyman64.dll in memory get
refresh notifications (as their local `RefreshTag_Process` will
likely already be greater than `0`).
Also a small additional debug statement.
Fixes#4192.
If Keyman is already running, and the user attempts to start Keyman
again, a balloon will be shown to direct the user to the right place on
the screen.
Note: this worked in earlier versions of Keyman but stopped working due
to name changes for windows in the app.
I have also added a new string for balloon that will need translation.
Fixes#4343.
This patch makes all language codes from the langtags.json dataset
visible through the Add Language dialog. This avoids situations where
an incomplete code such as "cmo" can result in an error (a script is
required for "cmo" as it is written in either Latn or Khmr).
Fixes#4337.
The Sinhala language installation mitigation needed the BCP 47 code as
well as the language code with the new language installation process.
Fixes#4336.
Removes the "Show Keyboard Usage Page" hotkey entry as it has no effect,
and cleans up Keyboard Usage and OSK Hint strings from all the current
locales.