diff --git a/windows/src/engine/keyman/UfrmKeyman7Main.pas b/windows/src/engine/keyman/UfrmKeyman7Main.pas
index 8fdb620318..5154dc90db 100644
--- a/windows/src/engine/keyman/UfrmKeyman7Main.pas
+++ b/windows/src/engine/keyman/UfrmKeyman7Main.pas
@@ -1227,16 +1227,35 @@ end;
procedure TfrmKeyman7Main.SetTrayIcon(rp: TRunningProduct; kbd: IKeymanKeyboardInstalled);
var
cust: IKeymanCustomisation;
- bb: IPicture;
- h: OLE_HANDLE;
+ lskbd: TLangSwitchKeyboard;
+ icon: TIcon;
begin
if Assigned(rp) then
begin
- bb := kbd.Bitmap;
- if Assigned(bb) then
+ lskbd := LangSwitchManager.FindKeyboardByKeymanID(kbd.KeymanID);
+ if Assigned(lskbd) and (lskbd is TLangSwitchKeyboard_TIP) then
+ try
+ icon := TIcon.Create;
+ try
+ icon.Handle := (lskbd as TLangSwitchKeyboard_TIP).IconHandle;
+ rp.FTrayIcon.Icon.Assign(icon);
+ icon.ReleaseHandle;
+ finally
+ icon.Free;
+ end;
+ except
+ on E:Exception do
+ begin
+ // #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);
+ end;
+ end
+ else
begin
- bb.get_Handle(h);
- rp.FTrayIcon.Icon.Handle := CopyIcon(h);
+ // Use the default app icon
+ rp.FTrayIcon.Icon.Assign(FTrayIcon);
end;
if VisualKeyboardVisible then
diff --git a/windows/src/engine/keyman/langswitch/LangSwitchManager.pas b/windows/src/engine/keyman/langswitch/LangSwitchManager.pas
index e6a800fb1e..a3bcc723b9 100644
--- a/windows/src/engine/keyman/langswitch/LangSwitchManager.pas
+++ b/windows/src/engine/keyman/langswitch/LangSwitchManager.pas
@@ -186,6 +186,7 @@ type
procedure Refresh;
function FindKeyboard(FHKL: HKL; FProfileGuid: TGUID): TLangSwitchKeyboard; overload;
function FindKeyboard(id: string): TLangSwitchKeyboard; overload;
+ function FindKeyboardByKeymanID(id: Integer): TLangSwitchKeyboard; overload;
property Languages[Index: Integer]: TLangSwitchLanguage read GetLanguage;
property LanguageCount: Integer read GetLanguageCount;
property TotalKeyboardCount: Integer read GetTotalKeyboardCount; // I4606
@@ -594,6 +595,20 @@ begin
Result := nil;
end;
+function TLangSwitchManager.FindKeyboardByKeymanID(
+ id: Integer): TLangSwitchKeyboard;
+var
+ lang: TLangSwitchLanguage;
+ kbd: TLangSwitchKeyboard;
+begin
+ for lang in FLanguages do
+ for kbd in lang.FKeyboards do
+ if kbd.KeymanID = id then
+ Exit(kbd);
+
+ Result := nil;
+end;
+
function TLangSwitchManager.FindKeyboard(FHKL: HKL;
FProfileGuid: TGUID): TLangSwitchKeyboard;
var
diff --git a/windows/src/test/manual-tests/png-icon/README.md b/windows/src/test/manual-tests/png-icon/README.md
new file mode 100644
index 0000000000..ab5e87c707
--- /dev/null
+++ b/windows/src/test/manual-tests/png-icon/README.md
@@ -0,0 +1,6 @@
+# pngicon keyboard
+
+A keyboard with a PNG format icon - for testing #12905
+
+https://github.com/keymanapp/keyman/issues/12905
+
diff --git a/windows/src/test/manual-tests/png-icon/pngicon.kpj b/windows/src/test/manual-tests/png-icon/pngicon.kpj
new file mode 100644
index 0000000000..d3a678044b
--- /dev/null
+++ b/windows/src/test/manual-tests/png-icon/pngicon.kpj
@@ -0,0 +1,8 @@
+
+
+
+ 2.0
+ True
+ True
+
+
diff --git a/windows/src/test/manual-tests/png-icon/source/pngicon.ico b/windows/src/test/manual-tests/png-icon/source/pngicon.ico
new file mode 100644
index 0000000000..e65712af28
Binary files /dev/null and b/windows/src/test/manual-tests/png-icon/source/pngicon.ico differ
diff --git a/windows/src/test/manual-tests/png-icon/source/pngicon.kmn b/windows/src/test/manual-tests/png-icon/source/pngicon.kmn
new file mode 100644
index 0000000000..de695b9a0f
--- /dev/null
+++ b/windows/src/test/manual-tests/png-icon/source/pngicon.kmn
@@ -0,0 +1,12 @@
+c pngicon generated from template at 2026-08-13 11:08:13
+c with name "pngicon"
+store(&VERSION) '10.0'
+store(&NAME) 'pngicon'
+store(©RIGHT) 'Copyright ©'
+store(&KEYBOARDVERSION) '1.0'
+store(&TARGETS) 'windows'
+store(&BITMAP) 'pngicon.ico'
+
+begin Unicode > use(main)
+
+group(main) using keys
diff --git a/windows/src/test/manual-tests/png-icon/source/pngicon.kps b/windows/src/test/manual-tests/png-icon/source/pngicon.kps
new file mode 100644
index 0000000000..373e8276f3
--- /dev/null
+++ b/windows/src/test/manual-tests/png-icon/source/pngicon.kps
@@ -0,0 +1,41 @@
+
+
+
+ 18.0.249.0
+ 7.0
+
+
+
+
+
+
+
+
+
+
+
+
+ pngicon
+ Copyright ©
+
+ A keyboard with a PNG icon
+
+
+
+
+ ..\build\pngicon.kmx
+
+ 0
+ .kmx
+
+
+
+
+ pngicon
+
+ German
+
+
+
+
+