Merge pull request #4378 from keymanapp/fix/windows/4289-altgr-refresh-on-64-bit

fix(windows): Refresh settings on 64-bit apps
This commit is contained in:
Marc Durdin 2021-02-26 19:55:28 +11:00 • committed by GitHub
commit d496d266fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 64 additions and 52 deletions

View file

@ -679,9 +679,9 @@ BOOL UpdateRefreshTag(LONG tag) // I1835 - Reduce chatter
{
PKEYMAN64THREADDATA _td = ThreadGlobals();
if(!_td) return FALSE;
if(_td->RefreshTag_Process < tag)
if(_td->RefreshTag_Thread != tag)
{
_td->RefreshTag_Process = tag;
_td->RefreshTag_Thread = tag;
return TRUE;
}
return FALSE;
@ -695,9 +695,9 @@ void HandleRefresh(int code, LONG tag)
// This is sent by Keyman COM API, ApplyToRunningKeymanEngine
SendDebugMessageFormat(0, sdmGlobal, 0, "#### Refresh Requested ####");
// We ask any controller window to tell all instances of keyman32/keyman64
// that a refresh is coming through
Globals::PostControllers(wm_keyman_refresh, KR_PRE_REFRESH, 0);
// We ask the master controller window to tell all instances
// of keyman32/keyman64 that a refresh is coming through
Globals::PostMasterController(wm_keyman_refresh, KR_PRE_REFRESH, 0);
// We need to tell the controller windows to refresh themselves also
Globals::PostControllers(wm_keyman_control, KMC_REFRESH, 0);
@ -709,8 +709,9 @@ void HandleRefresh(int code, LONG tag)
// a double-broadcast which could happen if both keyman32 and keyman64
// receive the message, as they have independently managed RefreshTags
// All controllers will receive this message; only one need act on it
tag = InterlockedIncrement(Globals::RefreshTag());
// This RefreshTag is only ever incremented here by the master controller
// so this is a thread safe operation
tag = ++(*Globals::RefreshTag());
if (UpdateRefreshTag(tag)) {
// The Keyman process gets the update first
@ -726,8 +727,17 @@ void HandleRefresh(int code, LONG tag)
// refreshed after an update, but only once per
// refresh request
if (UpdateRefreshTag(tag)) {
// We'll update when we are called into action
ScheduleRefresh();
#ifdef _WIN64
if (Globals::get_InitialisingThread() == GetCurrentThreadId()) {
// If this is the keymanx64 thread, then we should
// go ahead and process the refresh immediately so
// that global settings are updated
RefreshKeyboards(FALSE);
}
else
#endif
// We'll update when we are called into action
ScheduleRefresh();
}
break;
}
@ -755,7 +765,7 @@ void LoadBaseLayoutSettings() { // I4552 // I4583
Globals::SetBaseKeyboardFlags(underlyingLayout, reg->ReadInteger(REGSZ_SimulateAltGr), !reg->ValueExists(REGSZ_DeadkeyConversionMode) || reg->ReadInteger(REGSZ_DeadkeyConversionMode));
} else {
Globals::SetBaseKeyboardFlags("", 0, 0);
Globals::SetBaseKeyboardFlags("", 0, 1);
}
delete reg;

View file

@ -1,18 +1,18 @@
/*
Name: globals
Copyright: Copyright (C) SIL International.
Documentation:
Description:
Documentation:
Description:
Create Date: 1 Aug 2006
Modified Date: 25 Oct 2016
Authors: mcdurdin
Related Files:
Dependencies:
Related Files:
Dependencies:
Bugs:
Todo:
Notes:
Bugs:
Todo:
Notes:
History: 01 Aug 2006 - mcdurdin - Add hotkeys
14 Sep 2006 - mcdurdin - Add UpdateActiveWindows function
16 May 2007 - mcdurdin - I819 - Test if Keyman is functioning
@ -83,7 +83,7 @@ public:
static DWORD *FSingleThread();
static DWORD *InitialisingThread(); // I4326
//static DWORD *ActiveKeymanID();
//static HKL *ActiveKeyboardLayout();
@ -98,7 +98,7 @@ public:
static HHOOK get_hhookGetMessage();
static HHOOK get_hhookCallWndProc();
#ifndef _WIN64
static HHOOK get_hhookLowLevelKeyboardProc(); // I4124
#endif
@ -134,7 +134,7 @@ public:
static LRESULT SendMasterController(UINT msg, WPARAM wParam, LPARAM lParam);
static void PostMasterController(UINT msg, WPARAM wParam, LPARAM lParam);
static BOOL ResetControllers();
static void PostControllers(UINT msg, WPARAM wParam, LPARAM lParam);
@ -220,12 +220,12 @@ typedef struct tagKEYMAN64THREADDATA
PKEYMANPROCESSOUTPUTFUNC TIPProcessOutput;
PKEYMANGETCONTEXTFUNC TIPGetContext;
BOOL TIPFUpdateable, TIPFPreserved; // I4290
BOOL FInRefreshKeyboards;
BOOL RefreshRequired;
LONG RefreshTag_Process; // TODO: we may be able to eliminate this with our delayed refresh pattern?
LONG RefreshTag_Thread; // TODO: we may be able to eliminate this with our delayed refresh pattern?
/* Addin Globals */
@ -254,7 +254,7 @@ typedef struct tagKEYMAN64THREADDATA
} KEYMAN64THREADDATA, *PKEYMAN64THREADDATA;
extern UINT
extern UINT
wm_keyman, // user message - ignore msg
wm_kmdebug, // " " " " - debugging
wm_keyman_control, // messages to main Keyman window - replaces WM_USER+*
@ -269,7 +269,7 @@ extern UINT
wm_keymanim_close,
wm_keymanim_contextchanged,
wm_test_keyman_functioning,
wm_keyman_keyevent; // for serialized input
wm_keyman_keyevent; // for serialized input
extern BOOL
flag_ShouldSerializeInput;

View file

@ -1,18 +1,18 @@
/*
Name: k32_globals
Copyright: Copyright (C) SIL International.
Documentation:
Description:
Documentation:
Description:
Create Date: 1 Aug 2006
Modified Date: 6 Feb 2015
Authors: mcdurdin
Related Files:
Dependencies:
Related Files:
Dependencies:
Bugs:
Todo:
Notes:
Bugs:
Todo:
Notes:
History: 01 Aug 2006 - mcdurdin - Add hotkeys globals
14 Sep 2006 - mcdurdin - Add IsKeymanSystemWindow and UpdateActiveWindows functions
04 Dec 2006 - mcdurdin - Add PostProcessControllers and IsControllerProcess functions
@ -69,7 +69,7 @@
/* */
/***************************************************************************/
UINT
UINT
//TODO: consolidate these messages -- they are probably not all required now
wm_keyman = 0, // user message - ignore msg // I3594
wm_keyman_keyevent = 0, // for serialized input
@ -86,7 +86,7 @@ UINT
wm_keymanim_close = 0,
wm_keymanim_contextchanged = 0,
wm_test_keyman_functioning = 0;
//HWND hwndIM = 0, hwndIMOldFocus = 0;
@ -100,7 +100,7 @@ static CRITICAL_SECTION csGlobals;
PKEYMAN64THREADDATA Globals_InitThread()
{
EnterCriticalSection(&csGlobals);
PKEYMAN64THREADDATA lpvData;
if(Globals::get_Keyman_Shutdown()) // I3092
@ -190,7 +190,7 @@ void Globals_UninitProcess()
PKEYMAN64THREADDATA ThreadGlobals()
{
EnterCriticalSection(&csGlobals);
PKEYMAN64THREADDATA lpvData = NULL;
if(dwTlsIndex != TLS_OUT_OF_INDEXES)
{
@ -220,7 +220,7 @@ BOOL Globals_ProcessInitialised()
//static INI // I3158 // I3524
// f_Ini = {0}; // KEYMAN.INI options
static HHOOK
static HHOOK
f_hhookGetMessage = NULL, // GETMESSAGE hook handle
f_hhookCallWndProc = NULL; // CALLWNDPROC hook handle
@ -236,7 +236,7 @@ static HWND
static UINT
f_WindowsVersion = 0; // Windows Version
static BOOL
static BOOL
f_Keyman_Initialised = FALSE,
f_Keyman_Shutdown = FALSE;
@ -280,14 +280,14 @@ __declspec(align(8)) static LONG
f_RefreshTag = 0;
#endif
static BOOL
f_debug_KeymanLog = FALSE,
static BOOL
f_debug_KeymanLog = FALSE,
f_debug_ToConsole = FALSE;
#pragma data_seg()
/***************************************************************************/
DWORD //static
DWORD //static
f_ShiftState = 0;
HANDLE f_hLockMutex = 0;
@ -364,13 +364,15 @@ void Globals::SetBaseKeyboardName(wchar_t *baseKeyboardName, wchar_t *baseKeyboa
}
void Globals::SetBaseKeyboardFlags(char *baseKeyboard, BOOL simulateAltGr, BOOL mnemonicDeadkeyConversionMode) { // I4583 // I4552
SendDebugMessageFormat(0, sdmAIDefault, 0, "Globals::SetBaseKeyboardFlags(baseKeyboard='%s', simulateAltGr=%d, mnemonicDeadkeyConversionMode=%d",
baseKeyboard, simulateAltGr, mnemonicDeadkeyConversionMode);
strcpy_s(f_BaseKeyboard, baseKeyboard);
f_SimulateAltGr = simulateAltGr;
f_MnemonicDeadkeyConversionMode = mnemonicDeadkeyConversionMode;
}
/**
Loads settings that are globally applied at application startup. These cannot
Loads settings that are globally applied at application startup. These cannot
be changed until Keyman is restarted.
*/
BOOL Globals::InitSettings() {
@ -392,7 +394,7 @@ BOOL Globals::Lock()
f_hLockMutex = CreateMutex(NULL, FALSE, "Tavultesoft_KeymanEngine_GlobalLock");
if(f_hLockMutex == 0) return FALSE;
}
if(WaitForSingleObject(f_hLockMutex, 1000) == WAIT_OBJECT_0) return TRUE; // I3183 // I3530
SetLastError(ERROR_TIMEOUT); // I3183 // I3530
return FALSE; // I3183 // I3530
@ -400,7 +402,7 @@ BOOL Globals::Lock()
BOOL Globals::InitHandles() // I3040
{
if(f_hLockMutex == 0)
if(f_hLockMutex == 0)
f_hLockMutex = CreateMutex(NULL, FALSE, "Tavultesoft_KeymanEngine_GlobalLock");
if(f_hLockMutex == 0) return FALSE;
SetObjectToLowIntegrity(f_hLockMutex);
@ -477,7 +479,7 @@ void Globals::PostProcessControllers(UINT msg, WPARAM wParam, LPARAM lParam)
for(int i = 0; i < f_MaxControllers; i++)
{
GetWindowThreadProcessId(f_ControllerWindow[i], &pid);
if(pid == GetCurrentProcessId())
if(pid == GetCurrentProcessId())
PostMessage(f_ControllerWindow[i], msg, wParam, lParam);
}
Unlock();
@ -492,7 +494,7 @@ BOOL Globals::IsControllerProcess()
{
GetWindowThreadProcessId(f_ControllerWindow[i], &pid);
if(pid == GetCurrentProcessId())
{
{
Unlock();
return TRUE;
}
@ -524,7 +526,7 @@ void Globals::PostMasterController(UINT msg, WPARAM wParam, LPARAM lParam)
Unlock();
return;
}
if(ShouldDebug(sdmGlobal))
{
char buf[64];
@ -552,7 +554,7 @@ LRESULT Globals::SendMasterController(UINT msg, WPARAM wParam, LPARAM lParam)
HWND hwnd = f_ControllerWindow[0];
Unlock();
if(ShouldDebug(sdmGlobal))
{
char buf[64];
@ -561,7 +563,7 @@ LRESULT Globals::SendMasterController(UINT msg, WPARAM wParam, LPARAM lParam)
SendDebugMessageFormat(f_ControllerWindow[0], sdmGlobal, 0, "SendMasterController %s [%x : %x, %x]", buf, msg, wParam, lParam);
}
// Window may be taken out of list between Lock and Unlock but let's not worry about this
// Window may be taken out of list between Lock and Unlock but let's not worry about this
SetLastError(ERROR_SUCCESS);
DWORD_PTR dwResult = 0;
@ -633,7 +635,7 @@ BOOL IsKeymanSystemWindow(HWND hwnd)
DWORD pidC, pidHWND;
GetWindowThreadProcessId(hwnd, &pidHWND);
if(!Globals::Lock()) return FALSE;
for(int i = 0; i < f_MaxControllers; i++)
@ -641,7 +643,7 @@ BOOL IsKeymanSystemWindow(HWND hwnd)
if(f_ControllerWindow[i] == hwnd)
{
Globals::Unlock();
return TRUE;
return TRUE;
}
GetWindowThreadProcessId(f_ControllerWindow[i], &pidC);
if(pidC == pidHWND)
@ -666,10 +668,10 @@ void UpdateActiveWindows()
GUITHREADINFO gti;
gti.cbSize = sizeof(GUITHREADINFO);
GetGUIThreadInfo(0, &gti);
if(IsKeymanSystemWindow(gti.hwndActive) || IsKeymanSystemWindow(gti.hwndFocus)) return;
if(IsTooltipWindow(gti.hwndActive) || IsTooltipWindow(gti.hwndFocus)) return;
*Globals::hLastActiveWnd() = gti.hwndActive;
*Globals::hLastFocusWnd() = gti.hwndFocus;