From 62af1f0c1cad9b94d24908cb0653d3b418f4fad4 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Mon, 1 Dec 2025 09:47:05 +1000 Subject: [PATCH 1/6] fix(windows): ensure download is new process --- .../kmshell/main/Keyman.System.UpdateStateMachine.pas | 5 ++++- windows/src/desktop/kmshell/main/UfrmMain.pas | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas index e70a0c28672..b43b742aa31 100644 --- a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas +++ b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas @@ -774,7 +774,10 @@ procedure UpdateAvailableState.HandleAbort; procedure UpdateAvailableState.HandleInstallNow; begin bucStateContext.SetApplyNow(True); - ChangeState(DownloadingState); + //ChangeState(DownloadingState); + // we will use a new kmshell process to enable + // the download as background process. + StartDownloadProcess; end; { DownloadingState } diff --git a/windows/src/desktop/kmshell/main/UfrmMain.pas b/windows/src/desktop/kmshell/main/UfrmMain.pas index fdc1420b6b1..f3c31bbd72e 100644 --- a/windows/src/desktop/kmshell/main/UfrmMain.pas +++ b/windows/src/desktop/kmshell/main/UfrmMain.pas @@ -840,6 +840,9 @@ procedure TfrmMain.Update_ApplyNow; if not FResult then TKeymanSentryClient.Client.MessageEvent(Sentry.Client.SENTRY_LEVEL_ERROR, 'TrmfMain: Shell Execute Update_ApplyNow Failed'); + Close; + // Application.Terminate; + end; end; From e028b4c98fe4701e0bf708f621ba6d4e8959408f Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Wed, 3 Dec 2025 10:59:14 +1000 Subject: [PATCH 2/6] fix(windows): notes and psedo code to be fleshed out --- .../desktop/kmshell/main/Keyman.System.DownloadUpdate.pas | 3 +++ windows/src/desktop/kmshell/main/UfrmMain.pas | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/windows/src/desktop/kmshell/main/Keyman.System.DownloadUpdate.pas b/windows/src/desktop/kmshell/main/Keyman.System.DownloadUpdate.pas index 6ee1d454f3d..10a6f726bc7 100644 --- a/windows/src/desktop/kmshell/main/Keyman.System.DownloadUpdate.pas +++ b/windows/src/desktop/kmshell/main/Keyman.System.DownloadUpdate.pas @@ -29,6 +29,8 @@ TDownloadUpdate = class * download process. *) function DoDownloadUpdates(SavePath: string; Params: TUpdateCheckResponse): Boolean; + // pseduo code name this something more appropriate + procedure MyEventHandler(const Message: string; Position: Int64; Total: Int64); public @@ -100,6 +102,7 @@ function TDownloadUpdate.DoDownloadUpdates(SavePath: string; Params: TUpdateChec http.Request.Agent := API_UserAgent; http.Request.SetURL(url); + http.OnStatus := myeventhandler; http.Upload; if http.Response.StatusCode = 200 then begin diff --git a/windows/src/desktop/kmshell/main/UfrmMain.pas b/windows/src/desktop/kmshell/main/UfrmMain.pas index f3c31bbd72e..f4f47d24f0a 100644 --- a/windows/src/desktop/kmshell/main/UfrmMain.pas +++ b/windows/src/desktop/kmshell/main/UfrmMain.pas @@ -839,8 +839,9 @@ procedure TfrmMain.Update_ApplyNow; FResult := TUtilExecute.Shell(0, ShellPath, '', '-an'); if not FResult then TKeymanSentryClient.Client.MessageEvent(Sentry.Client.SENTRY_LEVEL_ERROR, - 'TrmfMain: Shell Execute Update_ApplyNow Failed'); - Close; + 'TrmfMain: Shell Execute Update_ApplyNow Failed') + else + ModalResult := mrAbort; // look into the most appropiate // Application.Terminate; end; From 10f1e2470e2d84bdd3477e45761e4d66c49f3899 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Tue, 6 Jan 2026 10:39:54 +1000 Subject: [PATCH 3/6] fix(windows): config frm result used to close splash The Configuration window will return a mrAbort result when we want the Splash screen to close. This is in the case the Installation now has been selected. --- .../main/Keyman.System.DownloadUpdate.pas | 4 ++-- windows/src/desktop/kmshell/main/UfrmMain.pas | 4 +++- windows/src/desktop/kmshell/main/initprog.pas | 4 ++-- .../desktop/kmshell/startup/UfrmSplash.pas | 20 ++++++++++++++++--- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/windows/src/desktop/kmshell/main/Keyman.System.DownloadUpdate.pas b/windows/src/desktop/kmshell/main/Keyman.System.DownloadUpdate.pas index 10a6f726bc7..a90d6a217e3 100644 --- a/windows/src/desktop/kmshell/main/Keyman.System.DownloadUpdate.pas +++ b/windows/src/desktop/kmshell/main/Keyman.System.DownloadUpdate.pas @@ -30,7 +30,7 @@ TDownloadUpdate = class *) function DoDownloadUpdates(SavePath: string; Params: TUpdateCheckResponse): Boolean; // pseduo code name this something more appropriate - procedure MyEventHandler(const Message: string; Position: Int64; Total: Int64); + //procedure MyEventHandler(const Message: string; Position: Int64; Total: Int64); public @@ -102,7 +102,7 @@ function TDownloadUpdate.DoDownloadUpdates(SavePath: string; Params: TUpdateChec http.Request.Agent := API_UserAgent; http.Request.SetURL(url); - http.OnStatus := myeventhandler; + //http.OnStatus := myeventhandler; http.Upload; if http.Response.StatusCode = 200 then begin diff --git a/windows/src/desktop/kmshell/main/UfrmMain.pas b/windows/src/desktop/kmshell/main/UfrmMain.pas index f4f47d24f0a..528a5d154eb 100644 --- a/windows/src/desktop/kmshell/main/UfrmMain.pas +++ b/windows/src/desktop/kmshell/main/UfrmMain.pas @@ -842,7 +842,9 @@ procedure TfrmMain.Update_ApplyNow; 'TrmfMain: Shell Execute Update_ApplyNow Failed') else ModalResult := mrAbort; // look into the most appropiate - // Application.Terminate; + // Maybe mrYes and mrNo. What we are after is that if we have a splash screen + // open when Install Now has run we want the result be value that the splash + // screen will be closed. end; end; diff --git a/windows/src/desktop/kmshell/main/initprog.pas b/windows/src/desktop/kmshell/main/initprog.pas index 1f02c696e3d..787cafddac6 100644 --- a/windows/src/desktop/kmshell/main/initprog.pas +++ b/windows/src/desktop/kmshell/main/initprog.pas @@ -70,7 +70,7 @@ interface Windows, Controls, SysUtils, Classes, ErrorControlledRegistry, Forms, MessageIdentifiers, MessageIdentifierConsts, keymanapi_TLB; procedure Run; -procedure Main(Owner: TComponent = nil); +function Main(Owner: TComponent = nil): Integer; type @@ -164,7 +164,7 @@ procedure ShowKeyboardWelcome(PackageName: WideString); forward; // I2569 procedure PrintKeyboard(KeyboardName: WideString); forward; // I2329 function ProcessBackgroundUpdate(FMode: TKMShellMode; FSilent: Boolean): Boolean; forward; -procedure Main(Owner: TComponent = nil); +function Main(Owner: TComponent = nil): Integer; var frmMain: TfrmMain; begin diff --git a/windows/src/desktop/kmshell/startup/UfrmSplash.pas b/windows/src/desktop/kmshell/startup/UfrmSplash.pas index 8d8e8f54e33..9c7ac10a645 100644 --- a/windows/src/desktop/kmshell/startup/UfrmSplash.pas +++ b/windows/src/desktop/kmshell/startup/UfrmSplash.pas @@ -139,6 +139,8 @@ procedure TfrmSplash.WMUser(var Message: TMessage); end; procedure TfrmSplash.WMUser_FormShown(var Message: TMessage); +var + configFrmResult: Integer; begin if (GetForegroundWindow <> Handle) and (GetWindowThreadProcessId(GetForegroundWindow) <> GetCurrentThreadId) then // I3730 @@ -152,15 +154,27 @@ procedure TfrmSplash.WMUser_FormShown(var Message: TMessage); if FShowConfigurationOnLoad then begin - Main(Self); - Do_Content_Render; + configFrmResult := Main(Self); + if configFrmResult = mrAbort then + Command_Exit + else + Do_Content_Render; end; end; procedure TfrmSplash.FireCommand(const command: WideString; params: TStringList); +var + configFrmResult: Integer; begin if command = 'start' then Command_Start - else if command = 'config' then begin Main(Self); Do_Content_Render; end // I4393 // I4396 + else if command = 'config' then + begin + configFrmResult := Main(Self); + if configFrmResult = mrAbort then + Command_Exit + else + Do_Content_Render; + end // I4393 // I4396 else if command = 'hidesplash' then FShouldDisplay := False else if command = 'showsplash' then FShouldDisplay := True else if command = 'exit' then Command_Exit From 0bbda82a0a9e95675a27234911e3e5653833dced Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Wed, 7 Jan 2026 13:25:50 +1000 Subject: [PATCH 4/6] fix(windows): fix to use TModalResult instead of integer --- windows/src/desktop/kmshell/main/UfrmMain.pas | 9 ++++----- windows/src/desktop/kmshell/main/initprog.pas | 6 +++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/windows/src/desktop/kmshell/main/UfrmMain.pas b/windows/src/desktop/kmshell/main/UfrmMain.pas index 528a5d154eb..6a631fb5461 100644 --- a/windows/src/desktop/kmshell/main/UfrmMain.pas +++ b/windows/src/desktop/kmshell/main/UfrmMain.pas @@ -841,11 +841,10 @@ procedure TfrmMain.Update_ApplyNow; TKeymanSentryClient.Client.MessageEvent(Sentry.Client.SENTRY_LEVEL_ERROR, 'TrmfMain: Shell Execute Update_ApplyNow Failed') else - ModalResult := mrAbort; // look into the most appropiate - // Maybe mrYes and mrNo. What we are after is that if we have a splash screen - // open when Install Now has run we want the result be value that the splash - // screen will be closed. - + ModalResult := mrAbort; + // If a splash screen is currently open when "Install Now" is executed, + // setting mrAbort ensures the splash screen is closed on the + // return of "Keyman Configuration". end; end; diff --git a/windows/src/desktop/kmshell/main/initprog.pas b/windows/src/desktop/kmshell/main/initprog.pas index 787cafddac6..61b684a9ce4 100644 --- a/windows/src/desktop/kmshell/main/initprog.pas +++ b/windows/src/desktop/kmshell/main/initprog.pas @@ -70,7 +70,7 @@ interface Windows, Controls, SysUtils, Classes, ErrorControlledRegistry, Forms, MessageIdentifiers, MessageIdentifierConsts, keymanapi_TLB; procedure Run; -function Main(Owner: TComponent = nil): Integer; +function Main(Owner: TComponent = nil): TModalResult; type @@ -164,7 +164,7 @@ procedure ShowKeyboardWelcome(PackageName: WideString); forward; // I2569 procedure PrintKeyboard(KeyboardName: WideString); forward; // I2329 function ProcessBackgroundUpdate(FMode: TKMShellMode; FSilent: Boolean): Boolean; forward; -function Main(Owner: TComponent = nil): Integer; +function Main(Owner: TComponent = nil): TModalResult; var frmMain: TfrmMain; begin @@ -180,7 +180,7 @@ function Main(Owner: TComponent = nil): Integer; begin with TfrmMain.Create(Owner) do try - ShowModal; + Result := ShowModal; finally Free; end; From 9c7b1a6ae6ddedbceff48ecb37a805e591abcaee Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Thu, 8 Jan 2026 17:19:34 +1000 Subject: [PATCH 5/6] fix(windows): remove dead code --- .../desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas index b43b742aa31..c50ecf14db9 100644 --- a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas +++ b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas @@ -774,9 +774,7 @@ procedure UpdateAvailableState.HandleAbort; procedure UpdateAvailableState.HandleInstallNow; begin bucStateContext.SetApplyNow(True); - //ChangeState(DownloadingState); - // we will use a new kmshell process to enable - // the download as background process. + // A new kmshell process will be used to download StartDownloadProcess; end; From d3942412eaae006c2c72a0ab6dbbc45b2209e6cc Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Thu, 8 Jan 2026 17:23:19 +1000 Subject: [PATCH 6/6] fix(windows): move event handler to diff PR --- .../src/desktop/kmshell/main/Keyman.System.DownloadUpdate.pas | 3 --- 1 file changed, 3 deletions(-) diff --git a/windows/src/desktop/kmshell/main/Keyman.System.DownloadUpdate.pas b/windows/src/desktop/kmshell/main/Keyman.System.DownloadUpdate.pas index a90d6a217e3..6ee1d454f3d 100644 --- a/windows/src/desktop/kmshell/main/Keyman.System.DownloadUpdate.pas +++ b/windows/src/desktop/kmshell/main/Keyman.System.DownloadUpdate.pas @@ -29,8 +29,6 @@ TDownloadUpdate = class * download process. *) function DoDownloadUpdates(SavePath: string; Params: TUpdateCheckResponse): Boolean; - // pseduo code name this something more appropriate - //procedure MyEventHandler(const Message: string; Position: Int64; Total: Int64); public @@ -102,7 +100,6 @@ function TDownloadUpdate.DoDownloadUpdates(SavePath: string; Params: TUpdateChec http.Request.Agent := API_UserAgent; http.Request.SetURL(url); - //http.OnStatus := myeventhandler; http.Upload; if http.Response.StatusCode = 200 then begin