diff --git a/windows/src/engine/kmcomapi/com/keyboardlanguages/keymankeyboardlanguageinstalled.pas b/windows/src/engine/kmcomapi/com/keyboardlanguages/keymankeyboardlanguageinstalled.pas index a195176f73..990386f0eb 100644 --- a/windows/src/engine/kmcomapi/com/keyboardlanguages/keymankeyboardlanguageinstalled.pas +++ b/windows/src/engine/kmcomapi/com/keyboardlanguages/keymankeyboardlanguageinstalled.pas @@ -134,9 +134,10 @@ begin try UninstallTip(FOwner.ID, Get_LangID, Get_ProfileGUID, False); if IsTransientLanguageID(Get_LangID) then - // TODO: this breaks re-enabling the keyboard because the reg entry is - // still referring to the old langid. + begin SetLangID(0); + FProfileGUID := GUID_NULL; + end; finally Free; end; diff --git a/windows/src/engine/kmcomapi/com/keyboardlanguages/keymankeyboardlanguagesinstalled.pas b/windows/src/engine/kmcomapi/com/keyboardlanguages/keymankeyboardlanguagesinstalled.pas index c9b6b75b9f..6f17470667 100644 --- a/windows/src/engine/kmcomapi/com/keyboardlanguages/keymankeyboardlanguagesinstalled.pas +++ b/windows/src/engine/kmcomapi/com/keyboardlanguages/keymankeyboardlanguagesinstalled.pas @@ -252,12 +252,47 @@ procedure TKeymanKeyboardLanguagesInstalled.DoRefresh; end; end; + // Adds custom transient profiles for a disabled + // keyboard which will not be found by enumerating + // LM values. + procedure RefreshDisabledProfiles; + var + reg: TRegistryErrorControlled; + RootPath: string; + ids: TStringList; + id: string; + begin + if FOwner.Loaded then + Exit; + + ids := TStringList.Create; + reg := TRegistryErrorControlled.Create(KEY_READ); + try + RootPath := GetRegistryKeyboardActiveKey_CU(FOwner.ID) + '\' + SRegSubKey_KeyboardLanguages; + if reg.OpenKeyReadOnly(RootPath) then + begin + reg.GetValueNames(ids); + for id in ids do + begin + if not HasLanguage(id) then + begin + FLanguages.Add(TKeymanKeyboardLanguageInstalled.Create(Context, FOwner, id, 0, GUID_NULL, '')); + end; + end; + end; + finally + reg.Free; + ids.Free; + end; + end; + begin KL.MethodEnter(Self, 'DoRefresh', []); try RefreshProfiles; RefreshTransientProfiles; RefreshSuggestedLanguages; + RefreshDisabledProfiles; finally KL.MethodExit(Self, 'DoRefresh'); 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 ef4c1c2e64..d4c8208c2f 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 @@ -326,6 +326,17 @@ begin Exit(False); end; + if PRIMARYLANGID(LangID) = 0 then + begin + // LocaleNameToLCID can return a recently uninstalled transient LangID, but + // attempts to use that LangID result in an 'unknown locale' being + // installed, or a default locale being associated with the keyboard. Given + // an installed transient language will always be found in the + // Win8LanguageList, we should then assume that LocaleNameToLCID is lying to + // us and look for a new transient language id to be applied instead. + Exit(False); + end; + case LangID of LOCALE_CUSTOM_DEFAULT,