From 7dee29f70acda58474bdd014e64c0478bce0eb5a Mon Sep 17 00:00:00 2001
From: Marek Roszko <mark.roszko@gmail.com>
Date: Sat, 25 May 2024 13:25:10 -0400
Subject: [PATCH] Hackfix some cases the IME on windows locks up

Asking the IME to cancel when the canvas takes focus fixes the case where:

- Windows input lang set to Chinese
- Input mode set to english instead of chinese
- You spam the M key while launching a sch/pcb from the kicad.exe until the editor opens
- The windows would then normally be frozen
---
 common/draw_panel_gal.cpp               | 1 +
 libs/kiplatform/gtk/ui.cpp              | 5 +++++
 libs/kiplatform/include/kiplatform/ui.h | 5 +++++
 libs/kiplatform/msw/ui.cpp              | 8 ++++++++
 libs/kiplatform/osx/ui.mm               | 5 +++++
 5 files changed, 24 insertions(+)

diff --git a/common/draw_panel_gal.cpp b/common/draw_panel_gal.cpp
index 34a6c416b0..5f42cc971e 100644
--- a/common/draw_panel_gal.cpp
+++ b/common/draw_panel_gal.cpp
@@ -186,6 +186,7 @@ EDA_DRAW_PANEL_GAL::~EDA_DRAW_PANEL_GAL()
 
 void EDA_DRAW_PANEL_GAL::SetFocus()
 {
+    KIPLATFORM::UI::ImeNotifyCancelComposition( this );
     wxScrolledCanvas::SetFocus();
     m_lostFocus = false;
 }
diff --git a/libs/kiplatform/gtk/ui.cpp b/libs/kiplatform/gtk/ui.cpp
index 37f3c36ab8..a472549a38 100644
--- a/libs/kiplatform/gtk/ui.cpp
+++ b/libs/kiplatform/gtk/ui.cpp
@@ -321,6 +321,11 @@ void KIPLATFORM::UI::ImmControl( wxWindow* aWindow, bool aEnable )
 }
 
 
+void KIPLATFORM::UI::ImeNotifyCancelComposition( wxWindow* aWindow )
+{
+}
+
+
 void KIPLATFORM::UI::SetFloatLevel( wxWindow* aWindow )
 {
 }
diff --git a/libs/kiplatform/include/kiplatform/ui.h b/libs/kiplatform/include/kiplatform/ui.h
index 9341b097c5..7e9e0510bf 100644
--- a/libs/kiplatform/include/kiplatform/ui.h
+++ b/libs/kiplatform/include/kiplatform/ui.h
@@ -158,6 +158,11 @@ namespace KIPLATFORM
          */
         void ImmControl( wxWindow* aWindow, bool aEnable );
 
+        /**
+         * Asks the IME to cancel
+         */
+        void ImeNotifyCancelComposition( wxWindow* aWindow );
+
         /**
          * On Wayland, restricts the pointer movement to a rectangle slightly bigger than the given `wxWindow`.
          * This way, the cursor doesn't exit the (bigger) application window and we retain control on it.
diff --git a/libs/kiplatform/msw/ui.cpp b/libs/kiplatform/msw/ui.cpp
index a376b46b9b..b3f45ddcb2 100644
--- a/libs/kiplatform/msw/ui.cpp
+++ b/libs/kiplatform/msw/ui.cpp
@@ -184,6 +184,14 @@ void KIPLATFORM::UI::ImmControl( wxWindow* aWindow, bool aEnable )
 }
 
 
+void KIPLATFORM::UI::ImeNotifyCancelComposition( wxWindow* aWindow )
+{
+    const HIMC himc = ImmGetContext( aWindow->GetHWND() );
+    ImmNotifyIME( himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0 );
+    ImmReleaseContext( aWindow->GetHWND(), himc );
+}
+
+
 bool KIPLATFORM::UI::InfiniteDragPrepareWindow( wxWindow* aWindow )
 {
     return true;
diff --git a/libs/kiplatform/osx/ui.mm b/libs/kiplatform/osx/ui.mm
index 61af484f21..6ff859d34b 100644
--- a/libs/kiplatform/osx/ui.mm
+++ b/libs/kiplatform/osx/ui.mm
@@ -184,6 +184,11 @@ void KIPLATFORM::UI::ImmControl( wxWindow* aWindow, bool aEnable )
 }
 
 
+void KIPLATFORM::UI::ImeNotifyCancelComposition( wxWindow* aWindow )
+{
+}
+
+
 bool KIPLATFORM::UI::InfiniteDragPrepareWindow( wxWindow* aWindow )
 {
     return true;