Commit graph

365 commits

Author SHA1 Message Date
Ross Cruickshank
f98cef1573 docs(windows): Update windows/engine/readme 2021-05-20 15:37:20 +10:00
Ross Cruickshank
5be6825721 docs(windows): Initial commit - README.md 2021-05-20 13:43:44 +10:00
Marc Durdin
c078661a0f chore(windows): remove unused keymanx64 parameter
With the recent refactor in #5060, we no longer need the main form
window handle parameter in keymanx64.
2021-05-11 16:03:19 +10:00
Marc Durdin
9c01777ece chore: add missing file 2021-05-11 15:51:20 +10:00
Marc Durdin
d26b01ad99 chore(windows): remove KMC_CHANGEUISTATE
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).
2021-05-11 15:19:01 +10:00
Marc Durdin
fbcfd62678 fix(windows): refactor controller windows
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.
2021-05-11 14:47:17 +10:00
Marc Durdin
cfea41382c chore(windows): remove unused utilrun unit 2021-05-11 08:38:07 +10:00
Marc Durdin
a6a658e8bc
Merge pull request #5002 from keymanapp/fix/windows/4976-redesign-keymanx64-lifecycle
fix(windows): make keymanx64 responsible for its own lifecycle
2021-05-10 19:46:12 +10:00
Marc Durdin
23505d8e7b chore: remove extra file 2021-05-07 17:19:43 +10:00
Marc Durdin
a23266a6b9 chore: address review comments 2021-05-07 17:17:48 +10:00
Marc Durdin
492394c4f6 chore: address review comment 2021-05-07 17:08:11 +10:00
Marc Durdin
ee6f8590a6 fix(windows): make keymanx64 responsible for its own lifecycle
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.
2021-04-30 15:02:18 +10:00
Marc Durdin
097ce9ac9a fix(windows): avoid disabling Keyman when speech recognition starts
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`.
2021-04-30 09:04:12 +10:00
Marc Durdin
a1066f13a1
chore(windows): review comments
Co-authored-by: rc-swag <58423624+rc-swag@users.noreply.github.com>
2021-04-28 11:06:22 +10:00
Marc Durdin
94b6e1a00f fix(windows): handle errors starting keymanx64
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.
2021-04-28 10:37:47 +10:00
Marc Durdin
3a59175465 fix(windows): avoid error if keyman32.dll renamed
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.)
2021-04-21 14:21:17 +10:00
Marc Durdin
568e4b2e7e fix(windows): help contents broken from tray menu
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).
2021-04-20 12:54:10 +10:00
Marc Durdin
2563189bfa fix(windows): Change TLangSwitchRefreshWatcher ownership
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.
2021-03-23 08:57:24 +11:00
Marc Durdin
aebfdecf7a chore(windows): breadcrumbs
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.
2021-03-16 06:57:57 +11:00
Marc Durdin
49f4514b1a
Merge pull request #4663 from keymanapp/fix/windows/4447-trigger-language-sync
fix(windows): Trigger language sync after changes
2021-03-16 05:20:29 +11:00
Marc Durdin
53df62f0b7 chore(windows): 17763 sdk version for kmrefresh 2021-03-15 10:42:21 +11:00
Marc Durdin
1c4e956a20 chore(windows): fixup engine makefile 2021-03-15 10:18:05 +11:00
Marc Durdin
6155b544ea fix(windows): Trigger language sync after changes
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.
2021-03-15 09:43:07 +11:00
Marc Durdin
aae0cb19c4 chore(windows): fully disable auto start task
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.
2021-03-12 16:45:30 +11:00
Marc Durdin
1311d100e6
Merge pull request #4635 from keymanapp/fix/windows/4490-4435-transient-profiles-and-invalid-language-codes
fix(windows): Handle disabled profiles and invalid language ids
2021-03-11 09:11:44 +11:00
Marc Durdin
7436643726
Merge pull request #4628 from keymanapp/fix/windows/4619-hotkeys-correctly-ignore-right-modifiers
fix(windows): hotkeys correctly ignore right modifier keys
2021-03-11 09:11:32 +11:00
Marc Durdin
67bfdb970b fix(windows): Handle disabled profiles and invalid language ids
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.
2021-03-10 10:34:55 +11:00
Marc Durdin
24ba51ad70
Merge pull request #4627 from keymanapp/fix/windows/4437-ensure-valid-base-layout-on-install
fix(windows): ensure valid base layout on install
2021-03-09 16:56:36 +11:00
Marc Durdin
5c8d21b204 fix(windows): hotkeys correctly ignore right modifier keys
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.
2021-03-09 16:02:14 +11:00
Marc Durdin
1536a5fe1c chore(windows): address review comments 2021-03-09 15:48:52 +11:00
Marc Durdin
54e7b6c8d2 fix(windows): ensure valid base layout on install
Fixes #4437.

Makes sure that we don't end up with a base layout that is not using
Latin script at install time.
2021-03-09 15:17:21 +11:00
Marc Durdin
4a74d4767f fix(windows): represerve keys on setfocus
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.
2021-03-09 08:19:23 +11:00
Marc Durdin
791edee8ba
Merge pull request #4596 from keymanapp/fix/windows/4591-incxstr-potential-buffer-overrun
fix(windows): incxstr could run over buffer with malformed data
2021-03-05 14:18:02 +11:00
Marc Durdin
fe2c1cd187 fix(windows): incxstr could run over buffer with malformed data
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.
2021-03-05 12:50:29 +11:00
Marc Durdin
bc47b53a9b fix(windows): PreservedKeyMap::MapUSCharToVK line order bug
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.
2021-03-05 06:55:14 +11:00
Marc Durdin
d496d266fa
Merge pull request #4378 from keymanapp/fix/windows/4289-altgr-refresh-on-64-bit
fix(windows): Refresh settings on 64-bit apps
2021-02-26 19:55:28 +11:00
Marc Durdin
d7e4e18987 fix(windows): Handle Caps Lock event correctly from TIP
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.
2021-02-26 10:54:30 +11:00
Marc Durdin
c98379789d
Merge pull request #4458 from keymanapp/chore/windows/3540-firstvoices-keyboards-configuration
chore(windows): FirstVoices Keyboards Configuration merge
2021-02-11 16:56:45 +11:00
Marc Durdin
32d42d7d31 fix(windows): Track modifier changes in UWP apps
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.
2021-02-11 10:17:21 +11:00
Marc Durdin
1171290877 fix(windows): update order of disabling keyboard
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.
2021-02-11 10:15:38 +11:00
Marc Durdin
558c8013ee feat(developer): improve BCP 47 canonicalization
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.
2021-02-05 16:56:21 +11:00
Marc Durdin
d603c77cd7
Merge pull request #4386 from keymanapp/fix/windows/4192-show-balloon-when-keyman-is-already-running
fix(windows): Show balloon when Keyman is already running
2021-02-03 07:08:00 +11:00
Marc Durdin
3850087109 fix(windows): rename RefreshTag_Process variable
`RefreshTag_Process` should be named `RefreshTag_Thread`.
2021-02-02 14:58:59 +11:00
Marc Durdin
ca7ab8a7d8 fix(windows): improve cross-process refresh
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.
2021-02-02 14:55:02 +11:00
Marc Durdin
7a16b07465
Merge pull request #4381 from keymanapp/fix/windows/4343-avoid-invalid-custom-languages
fix(windows): avoid invalid language codes in Add Language dialog
2021-02-02 08:41:35 +11:00
Marc Durdin
d81ff153b7
Merge pull request #4379 from keymanapp/fix/windows/4336-hotkey-show-keyboard-usage-plus-strings
fix(windows): remove Show Keyboard Usage hotkey
2021-02-02 08:41:28 +11:00
Marc Durdin
f83c8ebbe5 fix(windows): Show balloon when Keyman is already running
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.
2021-02-01 16:06:08 +11:00
Marc Durdin
348b29687e fix(windows): avoid invalid language codes in Add Language dialog
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).
2021-02-01 10:20:19 +11:00
Marc Durdin
fdcb8191a8 fix(windows): crash for Sinhala mitigation
Fixes #4337.

The Sinhala language installation mitigation needed the BCP 47 code as
well as the language code with the new language installation process.
2021-02-01 08:30:16 +11:00
Marc Durdin
335f06661d fix(windows): remove Show Keyboard Usage hotkey
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.
2021-02-01 07:58:05 +11:00