From 16d482b66c5bcd27736c785b0bba9231b4857870 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Tue, 14 Sep 2021 08:24:17 +1000 Subject: [PATCH] fix(windows): fallback to filename if `&name` not set Fixes #5683. If `store(&name)` is missing from a keyboard, then fallback to the filename of the keyboard (sans extension). This fixes a regression in 14.0 keyboard registration. I opted not to make this change in kmxfile but rather in places which use it in the Keyman Engine COM API, because I wanted kmxfile to remain truthful about all details of what it is reading from the file. Given that the COM API will now never return an empty string for the name of the keyboard, there are mitigations for this in Keyman Configuration which are unnecessary, but it is not harmful for them to remain there. Will cherry-pick to stable-14.0. --- .../com/keyboards/keymankeyboardfile.pas | 4 +++- .../processes/keyboard/kpinstallkeyboard.pas | 21 ++++++++++++------- .../src/engine/kmcomapi/util/utilkeyman.pas | 6 ++++-- .../global/delphi/general/RegKeyboards.pas | 6 +++++- 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/windows/src/engine/kmcomapi/com/keyboards/keymankeyboardfile.pas b/windows/src/engine/kmcomapi/com/keyboards/keymankeyboardfile.pas index b535ec731b..5ea1e74265 100644 --- a/windows/src/engine/kmcomapi/com/keyboards/keymankeyboardfile.pas +++ b/windows/src/engine/kmcomapi/com/keyboards/keymankeyboardfile.pas @@ -195,7 +195,9 @@ end; function TKeymanKeyboardFile.Get_Name: WideString; begin - Result := FKeyboardInfo.KeyboardName; + if FKeyboardInfo.KeyboardName = '' + then Result := Get_ID + else Result := FKeyboardInfo.KeyboardName; end; function TKeymanKeyboardFile.Get_Version: WideString; diff --git a/windows/src/engine/kmcomapi/processes/keyboard/kpinstallkeyboard.pas b/windows/src/engine/kmcomapi/processes/keyboard/kpinstallkeyboard.pas index e9561b172a..e91cab0eeb 100644 --- a/windows/src/engine/kmcomapi/processes/keyboard/kpinstallkeyboard.pas +++ b/windows/src/engine/kmcomapi/processes/keyboard/kpinstallkeyboard.pas @@ -316,7 +316,7 @@ var FLanguages: TArray; FLanguageInstalled: Boolean; ki: TKeyboardInfo; - kbdname: string; + KeyboardID: string; FDestPath: string; FDestFileName: string; FIconFileName: string; @@ -325,6 +325,7 @@ var i: Integer; kpil: TKPInstallKeyboardLanguage; ml: TMitigateWin10_1803.TMitigatedLanguage; + KeyboardName: string; type TWSLCallback = reference to procedure(r: TRegistryErrorControlled); @@ -367,7 +368,11 @@ begin FDefaultHKL := GetDefaultHKL; - kbdname := GetShortKeyboardName(FileName); + KeyboardID := GetShortKeyboardName(FileName); + + if ki.KeyboardName = '' + then KeyboardName := KeyboardID + else KeyboardName := ki.KeyboardName; if ikPartOfPackage in FInstallOptions then FDestPath := GetPackageInstallPath(PackageID) @@ -412,7 +417,7 @@ begin kpil := TKPInstallKeyboardLanguage.Create(Context); try if kpil.FindInstallationLangID(BCP47Tag, LangID, TemporaryKeyboardID, []) and not IsTransientLanguageID(LangID) then - kpil.RegisterTip(kbdname, BCP47Tag, ki.KeyboardName, LangID, FIconFileName, PackageLanguageMetadata[i].Name); + kpil.RegisterTip(KeyboardID, BCP47Tag, KeyboardName, LangID, FIconFileName, PackageLanguageMetadata[i].Name); finally kpil.Free; end; @@ -432,7 +437,7 @@ begin begin BCP47Tag := TCanonicalLanguageCodeUtils.FindBestTag(PackageLanguageMetadata[i].ID, True, True); if BCP47Tag <> '' then - FLanguageInstalled := LegacyRegisterAndInstallLanguageProfile(BCP47Tag, kbdname, ki.KeyboardName, FIconFileName, PackageLanguageMetadata[i].Name); + FLanguageInstalled := LegacyRegisterAndInstallLanguageProfile(BCP47Tag, KeyboardID, KeyboardName, FIconFileName, PackageLanguageMetadata[i].Name); if FLanguageInstalled then Break; end; @@ -443,7 +448,7 @@ begin // This is most likely to happen on Win7 where custom BCP 47 tags // are not allowed AddLanguage(HKLToLanguageID(FDefaultHKL)); - LegacyRegisterAndInstallLanguageProfile(FLanguages, kbdname, ki.KeyboardName, FIconFileName); // I3581 // I3707 + LegacyRegisterAndInstallLanguageProfile(FLanguages, KeyboardID, KeyboardName, FIconFileName); // I3581 // I3707 end; end; end @@ -466,7 +471,7 @@ begin if ikLegacyRegisterAndInstallProfiles in FInstallOptions then begin // Registers only the first language - LegacyRegisterAndInstallLanguageProfile(FLanguages, kbdname, ki.KeyboardName, FIconFileName); // I3581 // I3707 + LegacyRegisterAndInstallLanguageProfile(FLanguages, KeyboardID, KeyboardName, FIconFileName); // I3581 // I3707 end; // Save the list of preferred languages for the keyboard, translated to BCP47 tags @@ -490,7 +495,7 @@ begin kpil := TKPInstallKeyboardLanguage.Create(Context); try - kpil.RegisterTip(kbdname, BCP47Tag, ki.KeyboardName, FLanguages[i], FIconFileName, ''); //TODO: language name + kpil.RegisterTip(KeyboardID, BCP47Tag, KeyboardName, FLanguages[i], FIconFileName, ''); //TODO: language name finally kpil.Free; end; @@ -504,7 +509,7 @@ begin // Write the four transient language ID profiles kpil := TKPInstallKeyboardLanguage.Create(Context); try - kpil.RegisterTransientTips(kbdname, ki.KeyboardName, FIconFileName); + kpil.RegisterTransientTips(KeyboardID, KeyboardName, FIconFileName); finally kpil.Free; end; diff --git a/windows/src/engine/kmcomapi/util/utilkeyman.pas b/windows/src/engine/kmcomapi/util/utilkeyman.pas index 3da7af5b25..62e87acaa6 100644 --- a/windows/src/engine/kmcomapi/util/utilkeyman.pas +++ b/windows/src/engine/kmcomapi/util/utilkeyman.pas @@ -145,7 +145,8 @@ begin s := ReadString(SRegValue_KeymanFile); try GetKeyboardInfo(s, False, ki); - Result := ki.KeyboardName; + if ki.KeyboardName <> '' then + Result := ki.KeyboardName; except ; end; @@ -170,7 +171,8 @@ begin s := ReadString(SRegValue_KeymanFile); try GetKeyboardInfo(s, False, ki); - Result := ki.KeyboardName; + if ki.KeyboardName <> '' then + Result := ki.KeyboardName; except ; end; diff --git a/windows/src/global/delphi/general/RegKeyboards.pas b/windows/src/global/delphi/general/RegKeyboards.pas index f1b016625c..3e3ab5e224 100644 --- a/windows/src/global/delphi/general/RegKeyboards.pas +++ b/windows/src/global/delphi/general/RegKeyboards.pas @@ -408,7 +408,11 @@ begin Exit; end; end; - FKeyboardName := ki.KeyboardName; + + if ki.KeyboardName = '' + then FKeyboardName := GetShortKeyboardName(FName) + else FKeyboardName := ki.KeyboardName; + FEncodings := ki.Encodings; FIsRegistered := ki.IsRegistered; FMessage := ki.MessageString;