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#5195.
Fixes KEYMAN-WINDOWS-M0.
The splash screen for Keyman would crash on start with the latest
Chromium update. This fix resolves the issue, which related to the
resize-to-content code, by removing the resize-to-content code and
instead hardcoding the window size in the .dfm.
This is a significant simplification of the browser host and I think it
is worthwhile. The only place the resizing code was still used was in
the splash screen.
Fixes#5166.
This introduces versioned management of sentry.dll for Keyman for
Windows, Keyman Engine and Keyman Developer. As sentry.dll's ABI is not
backwardly compatible, we have to maintain independent copies of each
DLL for each app.
sentry.dll (or sentry.x64.dll for x64 apps) will be found in the
sentry-0.4.9 folder relative to the running process, except when running
from within the keyman repo tree (based on presence of KEYMAN_ROOT env
var). In those cases, the windows/src/ext/sentry sentry.dll will be
used, allowing us to test new debug time sentry DLLs easily.
A little bit of cleanup and consolidation was also done in the
KeymanPaths.pas unit.
Fixes#4607.
The Sentry 0.4.9 update actually simplifies some things. It does only
build with VS2019 by default, which pushed me to update Keyman build to
the same version, but that's a good thing overall, and was fairly
painless anyway.
Previously, we had our own custom build of sentry-native to make sure
that the C++ runtime libraries were statically linked to sentry.dll, but
this is now configurable in the build options, so we were able to
abandon our fork of the project at
https://github.com/keymanapp/sentry-native, which is good news. (I will
leave the fork there just in case but we'll eventually delete it once we
are convinced that this is robust.)
I have updated sentry.pas to match sentry.h; most of the changes are in
comments but there are a handful of new functions and some small changes
to function signatures.
I retested the Sentry exception scenarios and results can be found at
https://docs.google.com/spreadsheets/d/19xfurbn4cGubSCD68EGuKhcR5HrjaUcY/edit#gid=170604584
There may be an issue with Delphi x64 programs missing symbols from my
machine; something to keep an eye on but not a blocker for this merging,
I think.
Fixes#519.
I have removed these .cfg, .dof, and .bdsproj files from the primary
projects in the Windows source. There is some ambiguity as to whether
.cfg files are used by the command line compiler (I checked with procmon
and they *are* read by dcc32.exe), so we will need to make sure that
no adverse changes have been made by this. In theory at least, the
.dproj data trumps .cfg data -- and all the projects in question have
a .dproj file -- so this should be a safe cleanup.
I have opted not to touch the /buildutils, /ext, /support and
/test folders at this point.
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.
UFixupMissingFile referred to an old MSI component code, which meant
that it would never actually fix the installation. This now refers to a
current component code.
I may backport this to stable-14.0 but would like to assess its
stability over time first.
Relates to #4700.
This simply adds some debug logging so that when the current crash
occurs, we can discover which windows have failed to automatically
close, which should give us enough detail to be able to reproduce the
problem, hopefully, and fix it.
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.
May fix#4889.
In some situations, Keyman is unable to precisely match the user's
default language with its own keyboard settings. In this situation,
Keyman may crash when attempting to install the TIP, or may give a
spurious error such as "Too many transient languages" or similar.
I have been unable to reproduce the crash described in #4889 on my
machines so this is an attempted fix.
This does fix a bug with default languages in any case so is a good fix
to include: if the user's default language is not found in Keyman's LCID
table, then Keyman would fail to install the TIP when the keyboard is
installed and would return an error message (but not crash).
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.
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#4558.
This makes a number of fixes to get the context help working correctly
in Keyman 14:
1. Adds support for `redirect:` header in help .md files so that we can
do redirects for the context content in Keyman for Windows help in the
lua filters.
2. Renames Keyman for Windows help files to .htm, because that's what
the .chm format is expecting, and what Delphi assumes for its .chm
integration, and thus splits the html and htm lua filters.
3. Renames and makes more consistent the various context help pages.
4. Adds redirects for all pages that have sufficient content on other
pages.
5. Fixes the instantiation of help in various Keyman for Windows forms.
6. Defaults to opening help from the Keyman source repo if the calling
app is running in the source repo (this is just a development-side
tweak that simplifies my life).
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.
Fixes#2241.
The `&CasedKeys` system store is a compiler feature that reduces the
repetitive nature of keyboard rules for `CAPS` and `NCAPS`. The
`&CasedKeys` system store defines a list of virtual keys for which
'normal' Caps Lock rules apply. This store has no default value, for
backward compatibility.
Once this store is defined, then you can define just the unshifted and
shifted versions of a rule, and Keyman Developer will synthesize the
`CAPS` and `NCAPS` versions of the rule. For example, you may have the
following rules:
```
store(&CasedKeys) [K_A]
+ [K_A] > 'α'
+ [SHIFT K_A] > 'Α'
```
These would be replaced by the compiler with:
```
store(&CasedKeys) [K_A]
+ [NCAPS K_A] > 'α'
+ [SHIFT CAPS K_A] > 'α'
+ [CAPS K_A] > 'Α'
+ [SHIFT NCAPS K_A] > 'Α'
```
You can also use this functionality with characters in the key part of
the rule:
```
store(&CasedKeys) 'a'..'c'
+ 'a' > 'α'
+ 'A' > 'Α'
```
and the compiled expansion would be similar:
```
store(&CasedKeys) [K_A] [K_B] [K_C]
+ [NCAPS K_A] > 'α'
+ [SHIFT CAPS K_A] > 'α'
+ [CAPS K_A] > 'Α'
+ [SHIFT NCAPS K_A] > 'Α'
```
This feature is backwardly compatible with Keyman 6.0, as it is entirely
implemented in the compiler.
This feature is not compatible with mnemonic layouts, and the keys
defined in the `&CasedKeys` store must be the unshifted base keys as
found on a US English keyboard, or you can use ISO9995 identifiers if
you prefer.
If you define a rule where you specify either `NCAPS` or `CAPS`, for a
key found in the store, then no change will be made to that rule. You
can also continue to define rules which use `NCAPS` or `CAPS` for keys
not found in the store.
As a side-benefit, this allows the visual designer to be used and
support Caps Lock, although at this stage, the `&CasedKeys` store is not
surfaced in the visual designer.
Relates to #2241.
Range expansions are a new language feature that reduce verbosity in
Keyman Keyboard Language (.kmn) files by making it possible to collapse
sequential ranges with a new `..` operator. It is envisioned that these
will be used primarily in stores.
Two kinds of expansions are available: character ranges, and virtual key
ranges.
The syntax is:
```
char '..' char
vkey '..' vkey
```
Where the `char` terminator is a single normal character, and the `vkey`
terminator is a single virtual key. `outs` is permissible for
terminators but no other statement is allowed. Whitespace is per normal
Keyman keyboard language syntax.
Character ranges will replace the range with the set of characters
between the terminators, based on the Unicode value of the terminators.
Examples:
```
store(alphabet) 'a' .. 'z'
store(alpha_not_bq) 'ac'..'pr'..'z'
store(capitals) U+0041 .. U+005A
```
Virtual key ranges work in a similar fashion, but with virtual keys. The
starting and terminating virtual key must have the same shift state.
This will be most useful for character and numeric virtual keys, as the
ranges are based on the numeric value of the virtual key as defined by
Windows, not its position on the keyboard.
Examples:
```
store(alphakeys) [K_A] .. [K_Z]
store(numkeys) [K_0] .. [K_9]
```
Ranges must be positive, that is, you cannot use `'z' .. 'a'`.
While this expansion is not expected to be very useful in rules, it is
still permitted. `context()` and other offsets are calculated on the
expanded form, not the collapsed form. Similarly, `any()`/`index()`
offsets are calculated on the expanded form.
'a' .. 'z' > context(3) c this produces 'c', not 'z'
Because ranges are expanded at compile time, ranges that are overly
long will result in an error, so you cannot use, for example:
```
store(AllUnicode) U+0020 .. U+10FFFF
```
The precise maximum length of a range is dependent on the context where
it is used.
The changes are entirely compiler-based; no change is made to the .kmx
file format or to the Keyman apps.
Fixes#4278.
When Keyman Developer is installed without Keyman for Windows, the
program silently crashes, because it is looking for libcef.dll in the
Keyman Desktop install folder rather than using its own copy of it.
This improves the search for libcef.dll and kmbrowserhost.exe, and
includes kmbrowserhost.exe with the Keyman Developer installation.
In the future, we could consider moving kmbrowserhost.exe into a common
folder (perhaps when we split Keyman for Windows and Keyman Developer
projects in 15.0).
I threw in a one-liner addressing a deprecated function warning in the
Developer build.
Fixes#2998.
Three parts to this:
* The package compiler will now give a warning if a keyboard in a
package does not contain any language metadata.
* Removed old canonicalization check during compile which is now handled
better in `TPackageInfoRefreshKeyboards`.
* Reduced non-canonical BCP 47 tag warnings in
`TPackageInfoRefreshKeyboards` to "info" so they do not block the
build.
Point 3 above is one part of the outcome of our BCP 47 discussion at:
https://docs.google.com/document/d/1N5CkTX7tlLlmUB9Mbd-LblY1ch1e642XxlTasC_WE_Q/edit#heading=h.fiy983iliay5
Fixes#4221.
When the Keyman Developer IDE calls out to the lexical model compiler,
it receives UTF-8 compiler message strings back but they are treated as
Windows-1252 strings. This fixes that.
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.
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.