From c37a4001883f8e7857d6dc64fab0bd08b8b33beb Mon Sep 17 00:00:00 2001
From: Benedikt Stebner <Gillibald@users.noreply.github.com>
Date: Tue, 4 Jun 2024 15:12:54 +0200
Subject: [PATCH] Make sure focus lost is delayed until IMM32 has finished up
 the composition on kill focus (#15907)

---
 .../Avalonia.Win32/WindowImpl.AppWndProc.cs   | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs
index d521f1ba3283..327a526793a7 100644
--- a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs
+++ b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs
@@ -19,6 +19,8 @@ namespace Avalonia.Win32
 {
     internal partial class WindowImpl
     {
+        private bool _killFocusRequested;
+
         [SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation",
             Justification = "Using Win32 naming for consistency.")]
         [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "We do .NET COM interop availability checks")]
@@ -680,7 +682,15 @@ protected virtual unsafe IntPtr AppWndProc(IntPtr hWnd, uint msg, IntPtr wParam,
                     }
 
                 case WindowsMessage.WM_KILLFOCUS:
-                    LostFocus?.Invoke();
+                    if (Imm32InputMethod.Current.IsComposing)
+                    {
+                        _killFocusRequested = true;
+                    }
+                    else
+                    {
+                        LostFocus?.Invoke();
+                    }
+                   
                     break;
 
                 case WindowsMessage.WM_INPUTLANGCHANGE:
@@ -725,6 +735,13 @@ protected virtual unsafe IntPtr AppWndProc(IntPtr hWnd, uint msg, IntPtr wParam,
                     {
                         Imm32InputMethod.Current.HandleCompositionEnd();
 
+                        if (_killFocusRequested)
+                        {
+                            LostFocus?.Invoke();
+
+                            _killFocusRequested = false;
+                        }
+
                         return IntPtr.Zero;
                     }
                 case WindowsMessage.WM_GETOBJECT: