From 5a4287a68d539b327dba93486d1bbd1154eea7b2 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 30 Oct 2020 14:20:00 +1100 Subject: [PATCH] fix(windows): disabling/enabling a profile could have wrong association Transient language profiles would get the wrong language association when they were disabled and re-enabled. Fixes #3798. --- .../com/keyboardlanguages/keymankeyboardlanguage.pas | 6 ++++++ .../keymankeyboardlanguageinstalled.pas | 12 ++++++++++-- ...yman.System.Process.KPInstallKeyboardLanguage.pas | 10 +++++----- .../processes/keyboard/kpinstallkeyboard.pas | 6 ++++-- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/windows/src/engine/kmcomapi/com/keyboardlanguages/keymankeyboardlanguage.pas b/windows/src/engine/kmcomapi/com/keyboardlanguages/keymankeyboardlanguage.pas index 09ebe8020d..bda311b8c4 100644 --- a/windows/src/engine/kmcomapi/com/keyboardlanguages/keymankeyboardlanguage.pas +++ b/windows/src/engine/kmcomapi/com/keyboardlanguages/keymankeyboardlanguage.pas @@ -26,6 +26,7 @@ type override; function GetLangName: string; virtual; + procedure SetLangID(Value: Integer); { IKeymanKeyboardLanguage } function Get_BCP47Code: WideString; safecall; @@ -146,4 +147,9 @@ begin 'langname', GetLangName]); end; +procedure TKeymanKeyboardLanguage.SetLangID(Value: Integer); +begin + FLangID := Value; +end; + end. diff --git a/windows/src/engine/kmcomapi/com/keyboardlanguages/keymankeyboardlanguageinstalled.pas b/windows/src/engine/kmcomapi/com/keyboardlanguages/keymankeyboardlanguageinstalled.pas index 836f90188e..b1da8d3b7c 100644 --- a/windows/src/engine/kmcomapi/com/keyboardlanguages/keymankeyboardlanguageinstalled.pas +++ b/windows/src/engine/kmcomapi/com/keyboardlanguages/keymankeyboardlanguageinstalled.pas @@ -133,6 +133,8 @@ begin with TKPUninstallKeyboardLanguage.Create(Context) do try UninstallTip(FOwner.ID, Get_LangID, Get_ProfileGUID, False); + if IsTransientLanguageID(Get_LangID) then + SetLangID(0); finally Free; end; @@ -189,12 +191,15 @@ procedure TKeymanKeyboardLanguageInstalled.InstallTip(LangID: Integer; const TemporaryKeyboardToRemove: WideString); var kp: TKPInstallKeyboardLanguage; + guid: TGUID; begin kp := TKPInstallKeyboardLanguage.Create(Context); try - kp.InstallTip(FOwner.ID, Get_BCP47Code, LangID); + kp.InstallTip(FOwner.ID, Get_BCP47Code, LangID, guid); if TemporaryKeyboardToRemove <> '' then kp.UninstallTemporaryLayout(TemporaryKeyboardToRemove); + Self.SetLangID(LangID); + Self.FProfileGUID := guid; finally kp.Free; end; @@ -226,11 +231,14 @@ begin end; procedure TKeymanKeyboardLanguageInstalled.Install; +var + guid: TGUID; begin if not Get_IsInstalled then with TKPInstallKeyboardLanguage.Create(Context) do try - InstallTip(FOwner.ID, Get_BCP47Code, Get_LangID); + InstallTip(FOwner.ID, Get_BCP47Code, Get_LangID, guid); + Self.FProfileGUID := guid; finally Free; end; diff --git a/windows/src/engine/kmcomapi/processes/keyboard/Keyman.System.Process.KPInstallKeyboardLanguage.pas b/windows/src/engine/kmcomapi/processes/keyboard/Keyman.System.Process.KPInstallKeyboardLanguage.pas index ead129c382..5f6f77c6cd 100644 --- a/windows/src/engine/kmcomapi/processes/keyboard/Keyman.System.Process.KPInstallKeyboardLanguage.pas +++ b/windows/src/engine/kmcomapi/processes/keyboard/Keyman.System.Process.KPInstallKeyboardLanguage.pas @@ -49,7 +49,8 @@ type /// Keyman keyboard to associate with TIP /// BCP47 tag associated with the TIP /// Language ID found with FindInstallationLangID - procedure InstallTip(const KeyboardID, BCP47Tag: string; LangID: Integer); + /// Profile GUID that is assigned on exit + procedure InstallTip(const KeyboardID, BCP47Tag: string; LangID: Integer; var guidProfile: TGUID); /// Removes a temporary keyboard layout that was installed by /// FindInstallationLangID. Current User. @@ -425,10 +426,9 @@ begin Context.Control.AutoApplyKeyman; end; -procedure TKPInstallKeyboardLanguage.InstallTip(const KeyboardID, BCP47Tag: string; LangID: Integer); +procedure TKPInstallKeyboardLanguage.InstallTip(const KeyboardID, BCP47Tag: string; LangID: Integer; var guidProfile: TGUID); var FIsAdmin: Boolean; - guid: TGUID; reg: TRegistry; RootPath, FLayoutInstallString: string; begin @@ -455,7 +455,7 @@ begin if not reg.ValueExists(SRegValue_KeymanProfileGUID) then ErrorFmt(KMN_E_ProfileInstall_RegistryCorrupt, VarArrayOf([KeyboardID])); - guid := StringToGuid(reg.ReadString(SRegValue_KeymanProfileGUID)); + guidProfile := StringToGuid(reg.ReadString(SRegValue_KeymanProfileGUID)); finally reg.Free; end; @@ -464,7 +464,7 @@ begin // Install the TIP into Windows // - FLayoutInstallString := GetLayoutInstallString(LangID, guid); + FLayoutInstallString := GetLayoutInstallString(LangID, guidProfile); if not InstallLayoutOrTip(PChar(FLayoutInstallString), 0) then // I4302 ErrorFmt(KMN_E_ProfileInstall_InstallLayoutOrTipFailed, VarArrayOf([KeyboardID])); diff --git a/windows/src/engine/kmcomapi/processes/keyboard/kpinstallkeyboard.pas b/windows/src/engine/kmcomapi/processes/keyboard/kpinstallkeyboard.pas index 4aa4f80a20..470649d995 100644 --- a/windows/src/engine/kmcomapi/processes/keyboard/kpinstallkeyboard.pas +++ b/windows/src/engine/kmcomapi/processes/keyboard/kpinstallkeyboard.pas @@ -275,12 +275,13 @@ procedure TKPInstallKeyboard.LegacyRegisterAndInstallLanguageProfile(Langs: arra var kpil: TKPInstallKeyboardLanguage; BCP47Tag: string; + guid: TGUID; begin BCP47Tag := TLanguageCodeUtils.TranslateWindowsLanguagesToBCP47(Langs[0]); kpil := TKPInstallKeyboardLanguage.Create(Context); try kpil.RegisterTip(KeyboardID, BCP47Tag, KeyboardName, Langs[0], IconFileName, ''); - kpil.InstallTip(KeyboardID, BCP47Tag, Langs[0]); + kpil.InstallTip(KeyboardID, BCP47Tag, Langs[0], guid); finally Free; end; @@ -291,6 +292,7 @@ var kpil: TKPInstallKeyboardLanguage; TemporaryKeyboardID: string; LangID: Integer; + guid: TGUID; begin Result := False; kpil := TKPInstallKeyboardLanguage.Create(Context); @@ -298,7 +300,7 @@ begin if kpil.FindInstallationLangID(BCP47Tag, LangID, TemporaryKeyboardID, []) then begin kpil.RegisterTip(KeyboardID, BCP47Tag, KeyboardID, LangID, IconFileName, ''); - kpil.InstallTip(KeyboardID, BCP47Tag, LangID); + kpil.InstallTip(KeyboardID, BCP47Tag, LangID, guid); Result := True; end; finally