From fb2033aa7a91c727d806be9d590a7c60330bbffd Mon Sep 17 00:00:00 2001 From: Alex Maitland Date: Thu, 16 Mar 2023 13:17:17 +1000 Subject: [PATCH] WPF - Use WpfImeKeyboardHandler for supported KeyboardLayoutIds --- CefSharp.Wpf/ChromiumWebBrowser.cs | 55 ++++++++++++++++++- .../Experimental/WpfIMEKeyboardHandler.cs | 22 +++++++- 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/CefSharp.Wpf/ChromiumWebBrowser.cs b/CefSharp.Wpf/ChromiumWebBrowser.cs index b7a2f8cd00..325332ec9b 100644 --- a/CefSharp.Wpf/ChromiumWebBrowser.cs +++ b/CefSharp.Wpf/ChromiumWebBrowser.cs @@ -608,7 +608,7 @@ private void NoInliningConstructor() browserSettings = Core.ObjectFactory.CreateBrowserSettings(autoDispose: true); - WpfKeyboardHandler = new WpfKeyboardHandler(this); + SetupWpfKeyboardHandler(); PresentationSource.AddSourceChangedHandler(this, PresentationSourceChangedHandler); @@ -753,6 +753,13 @@ private void InternalDispose(bool disposing) // is called. LifeSpanHandler = null; + var inputLangManager = InputLanguageManager.Current; + + if (inputLangManager != null) + { + inputLangManager.InputLanguageChanged -= OnInputLangageChanged; + } + WpfKeyboardHandler?.Dispose(); WpfKeyboardHandler = null; @@ -769,6 +776,32 @@ private void InternalDispose(bool disposing) Cef.RemoveDisposable(this); } + private void SetupWpfKeyboardHandler() + { + try + { + var inputLang = InputLanguageManager.Current.CurrentInputLanguage; + + var useImeKeyboardHandler = WpfImeKeyboardHandler.UseImeKeyboardHandler(inputLang.KeyboardLayoutId); + + if (useImeKeyboardHandler) + { + WpfKeyboardHandler = new WpfImeKeyboardHandler(this); + } + else + { + InputLanguageManager.Current.InputLanguageChanged += OnInputLangageChanged; + + WpfKeyboardHandler = new WpfKeyboardHandler(this); + } + } + catch (Exception) + { + // For now we'll ignore any errors and just use the default keyboard handler + WpfKeyboardHandler = new WpfKeyboardHandler(this); + } + } + /// /// Gets the ScreenInfo - currently used to get the DPI scale factor. /// @@ -1719,6 +1752,26 @@ private void OnDragEnter(object sender, DragEventArgs e) } } + private void OnInputLangageChanged(object sender, InputLanguageEventArgs e) + { + // If we are already using the WpfImeKeyboardHandler then we'll ignore any changes + if (WpfKeyboardHandler?.GetType() == typeof(WpfImeKeyboardHandler)) + { + return; + } + + var useImeKeyboardHandler = WpfImeKeyboardHandler.UseImeKeyboardHandler(e.NewLanguage.KeyboardLayoutId); + + if (useImeKeyboardHandler) + { + var oldKeyboardHandler = WpfKeyboardHandler; + WpfKeyboardHandler = new WpfImeKeyboardHandler(this); + oldKeyboardHandler?.Dispose(); + + InputLanguageManager.Current.InputLanguageChanged -= OnInputLangageChanged; + } + } + /// /// PresentationSource changed handler. /// diff --git a/CefSharp.Wpf/Experimental/WpfIMEKeyboardHandler.cs b/CefSharp.Wpf/Experimental/WpfIMEKeyboardHandler.cs index a5b1c05bcb..432e490cd5 100644 --- a/CefSharp.Wpf/Experimental/WpfIMEKeyboardHandler.cs +++ b/CefSharp.Wpf/Experimental/WpfIMEKeyboardHandler.cs @@ -346,7 +346,7 @@ private void CreateImeWindow(IntPtr hwnd) } } - private int PrimaryLangId(int lgid) + private static int PrimaryLangId(int lgid) { return lgid & 0x3ff; } @@ -440,5 +440,25 @@ private void UpdateCaretPosition(int index) { MoveImeWindow(source.Handle); } + + /// + /// Based on the determine if we + /// should be using IME. + /// + /// Keyboard Layout Id (obtained from + /// + /// returns true if the keyboard layout matches one of our listed that support IME, otherwise false. + /// + public static bool UseImeKeyboardHandler(int keyboardLayoutId) + { + var langId = PrimaryLangId(keyboardLayoutId); + + if (langId == ImeNative.LANG_KOREAN || langId == ImeNative.LANG_JAPANESE || langId == ImeNative.LANG_CHINESE) + { + return true; + } + + return false; + } } }