From fea358eb13327ade722910d6c45023ac408b48e9 Mon Sep 17 00:00:00 2001 From: igandrews Date: Sun, 10 Oct 2021 18:17:41 -0400 Subject: [PATCH 1/3] Change Wpf IME handling to only use the cursor pos when an adjacent character is new input --- CefSharp.Wpf/Internals/IMEHandler.cs | 22 +++++++++++++++++++--- CefSharp.Wpf/Internals/ImeNative.cs | 1 + 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/CefSharp.Wpf/Internals/IMEHandler.cs b/CefSharp.Wpf/Internals/IMEHandler.cs index 168d1313ff..bf2c741830 100644 --- a/CefSharp.Wpf/Internals/IMEHandler.cs +++ b/CefSharp.Wpf/Internals/IMEHandler.cs @@ -75,11 +75,12 @@ private static void GetCompositionInfo(IntPtr hwnd, uint lParam, string text, Li underlines.Clear(); + byte[] attributes = null; int targetStart = text.Length; int targetEnd = text.Length; if (IsParam(lParam, ImeNative.GCS_COMPATTR)) { - GetCompositionSelectionRange(hIMC, ref targetStart, ref targetEnd); + attributes = GetCompositionSelectionRange(hIMC, ref targetStart, ref targetEnd); } // Retrieve the selection range information. If CS_NOMOVECARET is specified @@ -98,6 +99,20 @@ private static void GetCompositionInfo(IntPtr hwnd, uint lParam, string text, Li compositionStart = 0; } + if (attributes != null && + ((compositionStart >= 0 && compositionStart < attributes.Length && attributes[compositionStart] == ImeNative.ATTR_INPUT) + || + (compositionStart >= 0 && compositionStart < attributes.Length && attributes[compositionStart] == ImeNative.ATTR_INPUT))) + { + // as MS does with their ime implementation we should only use the GCS_CURSORPOS if the character + // before or after is new input. + // https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/windows/Documents/ImmComposition.cs,1079 + } + else + { + compositionStart = text.Length; + } + if (IsParam(lParam, ImeNative.GCS_COMPCLAUSE)) { GetCompositionUnderlines(hIMC, targetStart, targetEnd, underlines); @@ -158,12 +173,12 @@ private static void GetCompositionUnderlines(IntPtr hIMC, int targetStart, int t } } - private static void GetCompositionSelectionRange(IntPtr hIMC, ref int targetStart, ref int targetEnd) + private static byte[] GetCompositionSelectionRange(IntPtr hIMC, ref int targetStart, ref int targetEnd) { var attributeSize = ImeNative.ImmGetCompositionString(hIMC, ImeNative.GCS_COMPATTR, null, 0); if (attributeSize <= 0) { - return; + return null; } int start = 0; @@ -191,6 +206,7 @@ private static void GetCompositionSelectionRange(IntPtr hIMC, ref int targetStar targetStart = start; targetEnd = end; + return attributeData; } private static bool IsSelectionAttribute(byte attribute) diff --git a/CefSharp.Wpf/Internals/ImeNative.cs b/CefSharp.Wpf/Internals/ImeNative.cs index 14e9bbbdf6..3d1045a5ac 100644 --- a/CefSharp.Wpf/Internals/ImeNative.cs +++ b/CefSharp.Wpf/Internals/ImeNative.cs @@ -19,6 +19,7 @@ public static class ImeNative internal const uint CS_NOMOVECARET = 0x4000; internal const uint NI_COMPOSITIONSTR = 0x0015; + internal const uint ATTR_INPUT = 0x00; internal const uint ATTR_TARGET_CONVERTED = 0x01; internal const uint ATTR_TARGET_NOTCONVERTED = 0x03; From 7c03944755cc28ddd0a658ca47fcd8c2c37d70f5 Mon Sep 17 00:00:00 2001 From: igandrews Date: Sun, 10 Oct 2021 18:23:55 -0400 Subject: [PATCH 2/3] Meant to change both character before and after --- CefSharp.Wpf/Internals/IMEHandler.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CefSharp.Wpf/Internals/IMEHandler.cs b/CefSharp.Wpf/Internals/IMEHandler.cs index bf2c741830..d08b7e0021 100644 --- a/CefSharp.Wpf/Internals/IMEHandler.cs +++ b/CefSharp.Wpf/Internals/IMEHandler.cs @@ -100,8 +100,10 @@ private static void GetCompositionInfo(IntPtr hwnd, uint lParam, string text, Li } if (attributes != null && - ((compositionStart >= 0 && compositionStart < attributes.Length && attributes[compositionStart] == ImeNative.ATTR_INPUT) + // character before + ((compositionStart >= 0 && (compositionStart - 1) < attributes.Length && attributes[compositionStart - 1] == ImeNative.ATTR_INPUT) || + // character after (compositionStart >= 0 && compositionStart < attributes.Length && attributes[compositionStart] == ImeNative.ATTR_INPUT))) { // as MS does with their ime implementation we should only use the GCS_CURSORPOS if the character From 9cfce9992a4f55655bb175db79aaa9e21b446d1b Mon Sep 17 00:00:00 2001 From: igandrews Date: Sun, 10 Oct 2021 18:38:40 -0400 Subject: [PATCH 3/3] Ensure the cursor pos is > 0 when checking the character before --- CefSharp.Wpf/Internals/IMEHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CefSharp.Wpf/Internals/IMEHandler.cs b/CefSharp.Wpf/Internals/IMEHandler.cs index d08b7e0021..1bcfdb8799 100644 --- a/CefSharp.Wpf/Internals/IMEHandler.cs +++ b/CefSharp.Wpf/Internals/IMEHandler.cs @@ -101,7 +101,7 @@ private static void GetCompositionInfo(IntPtr hwnd, uint lParam, string text, Li if (attributes != null && // character before - ((compositionStart >= 0 && (compositionStart - 1) < attributes.Length && attributes[compositionStart - 1] == ImeNative.ATTR_INPUT) + ((compositionStart > 0 && (compositionStart - 1) < attributes.Length && attributes[compositionStart - 1] == ImeNative.ATTR_INPUT) || // character after (compositionStart >= 0 && compositionStart < attributes.Length && attributes[compositionStart] == ImeNative.ATTR_INPUT)))