Commit graph

342 commits

Author SHA1 Message Date
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
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
Marc Durdin
07e9402f0c fix(windows): Refresh setings on 64-bit apps
Fixes #4289.

Some settings changes would not apply immediately for 64-bit apps, as
the refresh was not being processed until keymanx64 received focus (i.e.
never, as keymanx64 does not have a visible window!)
2021-02-01 07:42:20 +11:00
Marc Durdin
193478a492 fix(windows): Reverse order of backspaces
In order for the BK_SURROGATE and BK_DEADKEY flags to be matched with
the correct xstring elements in the context, we need to delete the
elements from the buffer in reverse order.

decxstr would previously assert if attempting to move before start of
string. This is undesirable behaviour as it should instead return NULL
to indicate that we've finished the string.

I also corretected a buffer underrun which would be possible if
malformed data was in the xstring.

I checked all uses of decxstr to ensure that the NULL return value is
being tested correctly.
2021-01-28 08:16:33 +11:00
Marc Durdin
098de3af78 fix(windows): SMP-aware deletion in TSF-aware apps
Fixes #4196.

When deleting characters in a TSF-aware app, we must delete both halves
of a surrogate pair. This behaviour differs from legacy apps, where a
single backspace is usually sufficient to delete both characters.

Truly ancient apps that do not know about Unicode surrogate pairs are
not going to delete both halves with a single backspace event.
Fortunately, these are few and far between; we would handle them on a
case-by-case basis if support questions for them arise.

When we come to integrating Keyman Core into Keyman for Windows, there
will need to be some careful checking of surrogate pair support, as it
is likely that the handling will need to change.
2021-01-28 07:37:05 +11:00
Marc Durdin
4bc1730eed fix(windows): improve support for strings.xml
Fixes #4264.

The Android strings.xml format that we now use with Keyman Desktop has a
number of escapes that must be supported in order for text strings to be
rendered correctly, including: @, ?, ', ". Furthermore, positional
parameters have a slightly different format which we should transform on
load.

This change includes a unit test androidstringtokeymanlocalestring.
2021-01-25 11:17:44 +11:00
Marc Durdin
b4fdc0920a fix(windows): context mismatch with if and dk
Fixes #4275.
2021-01-18 10:23:44 +11:00
Marc Durdin
40b235443b
Merge pull request #4209 from keymanapp/fix/developer/2690-3082-unhandled-keys-in-debugger
fix(developer): Allow unhandled keys to go through to debugger memo
2021-01-14 09:16:39 +11:00
Marc Durdin
b7fb5066bc
Merge pull request #4180 from keymanapp/fix/windows/1285-amharic-sinhala-tigrigna-mitigation
fix(windows): Update mitigation for Keyman 14 and Windows 10 19597
2021-01-14 09:15:50 +11:00
Marc Durdin
c1aae3a313
Merge pull request #4175 from keymanapp/fix/windows/4013-menu-popup-positions
fix(windows): fix menu popup position
2021-01-14 09:15:38 +11:00
Marc Durdin
dce865ed4e fix(developer): Allow unhandled keys to go through to debugger memo
Fixes #2690.
Fixes #3082.

In the debugger, key events such as Enter, Ctrl+C, Ctrl+V were being
swallowed by the debug engine if they did not have rules within the
keyboard. This change emits the key events so the debug memo can
process them normally.
2020-12-23 15:30:56 +11:00
Marc Durdin
f2fc0f0098 chore: address review comments 2020-12-23 09:56:39 +11:00
Marc Durdin
95a6e1b446 fix(windows): fixup mitigation for legacy keyboards
Fixes #4184.

If a package had a keyboard with language metadata, it would not
load that language data correctly, which then meant it would not
apply the mitigation correctly either, leading to a double elevation
dialog as Keyman tried to fallback to primary language.
2020-12-21 11:23:53 +11:00
Marc Durdin
227e023cdd fix(windows): disable mitigation for Windows 10 build 19597 and later
Fixes #1285.

If running Windows 10 19597 or later, the underlying issue has
been addressed, so disable the mitigation for new installs of
the keyboard. Does not attempt to change the language code if
the keyboard is already installed.
2020-12-21 08:56:34 +11:00
Marc Durdin
e9723251fb fix(windows/engine): Build 19597 update
Build 19597 of Windows 10 no longer causes the issue with Amharic,
Tigrinya and Sinhala keyboards failing to register and activate
correctly.
2020-12-21 08:23:51 +11:00
Marc Durdin
e83061ef80 fix(windows): ensure mitigation works with new registration strategy
The keyboard profile and registration strategy was not taking into
account the mitigation for Win10 1803 (#1285) and this meant that the
Amharic, Tigrigna and Sinhala keyboards would not install correctly.
2020-12-21 08:20:28 +11:00
Marc Durdin
3992a34ff4 chore(windows): don't change debug-manifest 2020-12-19 07:50:50 +11:00
Marc Durdin
2dd28f5cc3 fix(windows): ensure win7 compat, extra 2020-12-19 07:49:05 +11:00
Marc Durdin
9e06fc89a5 fix(windows): ensure win7 compat 2020-12-19 07:47:29 +11:00
Marc Durdin
1a80290fee fix(windows): fix menu popup position
Fixes #4013.

This turned out to be a lot more complicated than I expected, mostly due
to limitations in the Windows Shell API with regard to multiple monitors
and per-monitor DPI awareness (which we don't yet do in Keyman -- a
task for another day). Some of the Shell API functions are also
re-entrant, which is dangerous, so I avoided using those.

We now popup the menu relative to the Keyman icon far more precisely
which gives a much nicer feel to the menu interaction.
2020-12-19 07:31:17 +11:00
Marc Durdin
e664e93de7 fix(windows): Improve refresh reliablilty
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!
2020-12-18 08:06:03 +11:00
Marc Durdin
b561dc4721 fix(windows): Use timer-approach to refresh
Another thought: we could also try refreshing every 125msec for 5
seconds after the first change is detected. It's a bit yuck perf-wise
but would probably be pretty transparent to the user.

In testing, this looks good. It means the changes appear as soon as
ready, without substantial delays or performance issues. Polling this
makes me feel a bit dirty, but I'll just take a shower and be okay.
2020-12-17 13:43:31 +11:00
Marc Durdin
f6872e7919 fix(windows): OSK toolbar sync
As Keyman now monitors the Windows keyboard list from Control Panel, it
is no longer sufficient to refresh the toolbar only when a Keyman
keyboard is updated, as at that point Windows has not refreshed its own
language list in the registry. Instead, we need to monitor changes to
the relevant registry key and then refresh when those changes are
'complete'.

There is a problem: there does not appear to be a good way to monitor
for changes to Windows language settings. WM_SETTINGCHANGE is sent when
a language is added by the user in Settings, but the actual change
happens asynchronously, and we are not notified when the changes are
complete.

We also do not get notifications when languages are added via APIs.

Given the async nature of the language profile changes, this leads to
race conditions when we try to refresh the OSK toolbar. My preferred
solution currently is to monitor the relevant key in a separate thread,
and wait 1 second post-changes to actually do the refresh.
2020-12-17 13:23:05 +11:00
Marc Durdin
f73b2912ef fix(windows): exception handling list error
Fixes #4006.

This fixes the list error exception which was masking the actual cause
of #4006, which is already fixed by #4164.

Related issue #4119 is also fixed by #4164.
2020-12-17 11:54:39 +11:00
Marc Durdin
15d2182255 fix(windows): maintain use of refreshtag 2020-12-17 11:19:13 +11:00