mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-08 18:05:32 +00:00
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.
This commit is contained in:
parent
c83f595622
commit
67bfdb970b
3 changed files with 49 additions and 2 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue