Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@
#define KMC_LANGUAGEHOTKEY 20
//TOUCH #define KMC_CONTEXT 19 // 9.0.450.0

// Cross-architecture comms
#define KMC_REGISTER_HOST_WINDOW_X64 23
#define KMC_REGISTER_HOST_WINDOW_ARM64 24

#define RWM_KEYMAN_CONTROL "WM_KEYMAN_CONTROL"
#define RWM_KEYMAN_CONTROL_W L"WM_KEYMAN_CONTROL"

#define khLanguageSwitch 8
25 changes: 14 additions & 11 deletions windows/src/desktop/kmshell/main/UfrmMain.pas
Original file line number Diff line number Diff line change
Expand Up @@ -623,20 +623,23 @@ procedure TfrmMain.AppEventsMessage(var Msg: tagMSG;
var Handled: Boolean);
begin
inherited;
if (Msg.message = wm_keyman_refresh) and (Msg.WParam = KR_SETTINGS_CHANGED) then
if Msg.message = wm_keyman_refresh then
begin
// If we generated this refresh ourselves, ignore it
if (kmcom <> nil) and (Msg.lParam <> KeymanEngineControl.LastRefreshToken) then
if Msg.WParam = KR_SETTINGS_CHANGED then
begin
// The refresh event was generated by another process or thread
//
// We may receive the notification multiple times because it is broadcast
// to all top-level windows and we probably have a bunch of them.
// So, if we've already processed it, don't do so again.
if Msg.lParam <> LastRefreshToken then
// If we generated this refresh ourselves, ignore it
if (kmcom <> nil) and (Msg.lParam <> KeymanEngineControl.LastRefreshToken) then
begin
LastRefreshToken := Msg.lParam;
DoRefresh;
// The refresh event was generated by another process or thread
//
// We may receive the notification multiple times because it is broadcast
// to all top-level windows and we probably have a bunch of them.
// So, if we've already processed it, don't do so again.
if Msg.lParam <> LastRefreshToken then
begin
LastRefreshToken := Msg.lParam;
DoRefresh;
end;
end;
end;
end;
Expand Down
5 changes: 2 additions & 3 deletions windows/src/desktop/kmshell/startup/help/UfrmTextEditor.pas
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ TfrmTextEditor = class(TfrmKeymanBase)
procedure editorKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
private
cefFonts: TframeCEFHost;
wm_keyman_control, wm_keyman_refresh: UINT;
wm_keyman_control: UINT;
FUpdating: Boolean;
FCheckFontsThread: TCheckFontsThread;
FCheckFontKeyboards: TCheckFontKeyboards;
Expand Down Expand Up @@ -248,7 +248,6 @@ procedure TfrmTextEditor.TntFormCreate(Sender: TObject);
begin
inherited;
wm_keyman_control := RegisterWindowMessage('WM_KEYMAN_CONTROL');
wm_keyman_refresh := RegisterWindowMessage('WM_KEYMANREFRESH');

HelpTopic := 'context/text-editor';
Caption := MsgFromId(SKTextEditorCaption);
Expand Down Expand Up @@ -724,7 +723,7 @@ procedure TfrmTextEditor.AlignButtonClick(Sender: TObject);
procedure TfrmTextEditor.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
begin
if (Msg.message = wm_keyman_refresh) and (Msg.wParam = KR_REFRESH) then
if (Msg.message = wm_keyman_control) and (Msg.wParam = KMC_REFRESH) then
begin
StartCheckFontsThread;
end;
Expand Down
17 changes: 8 additions & 9 deletions windows/src/desktop/kmshell/util/kmint.pas
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
(*
Name: kmint
Copyright: Copyright (C) SIL International.
Documentation:
Description:
Documentation:
Description:
Create Date: 1 Aug 2006

Modified Date: 26 Jun 2012
Authors: mcdurdin
Related Files:
Dependencies:
Related Files:
Dependencies:

Bugs:
Todo:
Notes:
Bugs:
Todo:
Notes:
History: 01 Aug 2006 - mcdurdin - Remove old Keyman 6 integration
01 Aug 2006 - mcdurdin - Look for pxx file in startup folder to determine product to start
05 Nov 2007 - mcdurdin - I937, I1128 - Repair COM object if it fails at startup
Expand Down Expand Up @@ -43,7 +43,6 @@ function LoadKMCOM: Boolean;

const
KEYMAN_LAYOUT_CUSTOM = $000005FE;
KR_REFRESH = 2;
KR_SETTINGS_CHANGED = 3;

const
Expand Down Expand Up @@ -136,7 +135,7 @@ function TestV8Interfaces(var msg: string): Boolean; // I2923, I2960
end;

procedure CoFreeUnusedLibrariesEx(dwUnloadDelay, dwReserved: DWORD); stdcall; external 'ole32.dll';

function LoadKMCOM: Boolean;
var
msg: string;
Expand Down
23 changes: 21 additions & 2 deletions windows/src/engine/keyman/UfrmKeyman7Main.pas
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ TfrmKeyman7Main = class(TForm)
wm_keyman_globalswitch, wm_keyman_globalswitch_process, wm_keyman_control, wm_keyman_control_internal, wm_test_keyman_functioning: Cardinal;

FEnableCrashTest: Boolean = False;
wm_keyman_refresh: Cardinal;

const
KMC_StartProduct = 0;
Expand Down Expand Up @@ -697,6 +698,10 @@ destructor TRunningProduct.Destroy;
end;

function TfrmKeyman7Main.AppMessage(var Message: TMessage): Boolean;
var
hwndTextEditor: THandle;
const
KR_PRE_REFRESH = 1;
begin
if Message.Msg = WM_ACTIVATEAPP then
begin
Expand Down Expand Up @@ -728,6 +733,19 @@ function TfrmKeyman7Main.AppMessage(var Message: TMessage): Boolean;
end;
Result := True;
end
else if Message.Msg = wm_keyman_refresh then
begin
if Message.WParam = KR_PRE_REFRESH then
begin
// The text editor needs a special prod for keyboard changes
hwndTextEditor := FindWindow('TfrmTextEditor', nil);
if hwndTextEditor <> 0 then
begin
PostMessage(hwndTextEditor, wm_keyman_control, KMC_REFRESH, 0);
end;
end;
Result := False;
end
else if Message.Msg = wm_keyman_control then
begin
Result := True;
Expand Down Expand Up @@ -1241,13 +1259,13 @@ procedure TfrmKeyman7Main.SetTrayIcon(rp: TRunningProduct; kbd: IKeymanKeyboardI
// #12905: icon is otherwise invalid
TKeymanSentryClient.ReportHandledException(E, 'SetTrayIcon: Invalid icon for keyboard "'+kbd.ID+'"; icon filename "'+kbd.IconFilename+'"');
// Use the default app icon
rp.FTrayIcon.Icon.Assign(FTrayIcon);
rp.FTrayIcon.Icon.Assign(FTrayIcon);
end;
end
else
begin
// Use the default app icon
rp.FTrayIcon.Icon.Assign(FTrayIcon);
rp.FTrayIcon.Icon.Assign(FTrayIcon);
end;

if VisualKeyboardVisible then
Expand Down Expand Up @@ -2119,6 +2137,7 @@ initialization
wm_keyman_globalswitch_process := RegisterWindowMessage('WM_KEYMAN_GLOBALSWITCH_PROCESS');
wm_keyman_control := RegisterWindowMessage('WM_KEYMAN_CONTROL');
wm_keyman_control_internal := RegisterWindowMessage('WM_KEYMAN_CONTROL_INTERNAL'); // I3933
wm_keyman_refresh := RegisterWindowMessage('WM_KEYMANREFRESH');

ChangeWindowMessageFilter(wm_keyman_control, MSGFLT_ADD);
ChangeWindowMessageFilter(wm_keyman_globalswitch, MSGFLT_ADD);
Expand Down
3 changes: 1 addition & 2 deletions windows/src/engine/keyman/kmint.pas
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ implementation
MessageIdentifiers;

const
KR_REQUEST_REFRESH = 0; // Send this to any window, which will make Keyman post a KR_REFRESH to all top-level windows
KR_REFRESH = 2; // Finally this message get sent to all the other top-level windows in the system.
KR_REQUEST_REFRESH = 0; // Send this to any window, which will make Keyman post a KR_PRE_REFRESH to controllers, which will cause all threads to eventually refresh keyboards list
KR_SETTINGS_CHANGED = 3;

function KeymanCustomisation: IKeymanCustomisation;
Expand Down
1 change: 1 addition & 0 deletions windows/src/engine/keyman32/appint/aiTIP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ extern "C" __declspec(dllexport) BOOL WINAPI TIPActivateKeyboard(GUID *profile)
PKEYMAN64THREADDATA _td = ThreadGlobals();
if(!_td) return FALSE;

RefreshThreadKeyboardsIfRequired();
RefreshToggleState();

if(profile != NULL) {
Expand Down
12 changes: 9 additions & 3 deletions windows/src/engine/keyman32/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,15 @@ class Globals

static DWORD *ShiftState();

#ifndef _WIN64
static LONG *RefreshTag();
static LONG get_RefreshTag();

#ifndef _WIN64
static HWND get_hwndHostX64();
static HWND get_hwndHostARM64();

static HWND *hwndHostX64();
static HWND *hwndHostARM64();
#endif

static HHOOK get_hhookGetMessage();
Expand Down Expand Up @@ -216,8 +223,7 @@ typedef struct tagKEYMAN64THREADDATA
BOOL CoreProcessEventRun; // True if core process event has been run

BOOL FInRefreshKeyboards;
BOOL RefreshRequired;
LONG RefreshTag_Thread; // TODO: we may be able to eliminate this with our delayed refresh pattern?
LONG RefreshTag_Thread;

/* Addin Globals */

Expand Down
27 changes: 23 additions & 4 deletions windows/src/engine/keyman32/k32_globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ BOOL isKeymanKeyboardActive = FALSE;
static DWORD dwTlsIndex = TLS_OUT_OF_INDEXES;
static CRITICAL_SECTION csGlobals;

// In order that every thread starts off needing a refresh, we set the starting
// refresh tag to 1, but the thread-level refresh tag will be 0 (initialized by
// `LocalAlloc(LPTR)`)
#define INITIAL_GLOBAL_REFRESH_TAG 1
#define INITIAL_THREAD_REFRESH_TAG 0

PKEYMAN64THREADDATA Globals_InitThread()
{
EnterCriticalSection(&csGlobals);
Expand Down Expand Up @@ -269,9 +275,13 @@ static wchar_t
__declspec(align(8)) static UINT
f_vk_prefix = 0;

#ifndef _WIN64
__declspec(align(8)) static LONG
f_RefreshTag = 0;
f_RefreshTag = INITIAL_GLOBAL_REFRESH_TAG;

#ifndef _WIN64
__declspec(align(8)) static HWND
f_hwndHostX64 = 0,
f_hwndHostARM64 = 0;
#endif

static BOOL
Expand Down Expand Up @@ -310,8 +320,15 @@ DWORD *Globals::InitialisingThread() { return &f_InitialisingThread; } // I43

DWORD *Globals::ShiftState() { return &f_ShiftState; }

#ifndef _WIN64
LONG *Globals::RefreshTag() { return &f_RefreshTag; }
LONG Globals::get_RefreshTag() { return f_RefreshTag; }

#ifndef _WIN64
HWND Globals::get_hwndHostX64() { return f_hwndHostX64; }
HWND *Globals::hwndHostX64() { return &f_hwndHostX64; }

HWND Globals::get_hwndHostARM64() { return f_hwndHostARM64; }
HWND *Globals::hwndHostARM64() { return &f_hwndHostARM64; }
#endif

HHOOK Globals::get_hhookCallWndProc() { return f_hhookCallWndProc; }
Expand Down Expand Up @@ -436,8 +453,10 @@ BOOL Globals::ResetControllers() // I3092
f_FSingleThread = FALSE;
f_hwndIM = 0;
f_hwndIMAlways = 0;
f_RefreshTag = INITIAL_GLOBAL_REFRESH_TAG;
#ifndef _WIN64
f_RefreshTag = 0;
f_hwndHostX64 = NULL;
f_hwndHostARM64 = NULL;
#endif

Globals::Unlock();
Expand Down
Loading