diff --git a/CefSharp.Wpf/ChromiumWebBrowser.cs b/CefSharp.Wpf/ChromiumWebBrowser.cs
index 7c1c9732e8..7ba1bfe8ca 100644
--- a/CefSharp.Wpf/ChromiumWebBrowser.cs
+++ b/CefSharp.Wpf/ChromiumWebBrowser.cs
@@ -3,6 +3,7 @@
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
using System;
+using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
@@ -604,7 +605,12 @@ private void NoInliningConstructor()
browserSettings = Core.ObjectFactory.CreateBrowserSettings(autoDispose: true);
- WpfKeyboardHandler = new WpfKeyboardHandler(this);
+ SetupWpfKeyboardHandler();
+
+ if (WpfKeyboardHandler == null)
+ {
+ WpfKeyboardHandler = new WpfKeyboardHandler(this);
+ }
PresentationSource.AddSourceChangedHandler(this, PresentationSourceChangedHandler);
@@ -753,6 +759,8 @@ private void InternalDispose(bool disposing)
// is called.
LifeSpanHandler = null;
+ UnsubscribeInputLanguageChanged();
+
WpfKeyboardHandler?.Dispose();
WpfKeyboardHandler = null;
@@ -769,6 +777,44 @@ private void InternalDispose(bool disposing)
Cef.RemoveDisposable(this);
}
+ ///
+ /// Setup the used by this instance.
+ /// There are two main keyboard handler implementations currently
+ /// and . If
+ /// returns true for the current
+ /// then the instance will be used, otherwise the older
+ /// instance will be used.
+ /// Override to provide your own custom keyboard handler.
+ ///
+ protected virtual void SetupWpfKeyboardHandler()
+ {
+ try
+ {
+ var inputLang = InputLanguageManager.Current.CurrentInputLanguage;
+
+ var useImeKeyboardHandler = WpfImeKeyboardHandler.UseImeKeyboardHandler(inputLang.KeyboardLayoutId);
+
+ if (useImeKeyboardHandler)
+ {
+ WpfKeyboardHandler = new WpfImeKeyboardHandler(this);
+ }
+ else
+ {
+ InputLanguageManager.Current.InputLanguageChanged += OnInputLanguageChanged;
+
+ WpfKeyboardHandler = new WpfKeyboardHandler(this);
+ }
+ }
+ catch (Exception ex)
+ {
+ //For now we'll ignore any errors
+ Trace.TraceError($"Error initializing keyboard handler: {ex.ToString()}");
+
+ // 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.
///
@@ -1750,6 +1796,26 @@ private void OnDragEnter(object sender, DragEventArgs e)
}
}
+ private void OnInputLanguageChanged(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 -= OnInputLanguageChanged;
+ }
+ }
+
///
/// PresentationSource changed handler.
///
@@ -2858,5 +2924,35 @@ private async Task ResizeHackRun()
}
}
}
+
+ private void UnsubscribeInputLanguageChanged()
+ {
+ // If we are using WpfImeKeyboardHandler then we
+ // shouldn't need to unsubsribe from the handler
+ if (WpfKeyboardHandler?.GetType() == typeof(WpfImeKeyboardHandler))
+ {
+ return;
+ }
+
+ try
+ {
+ // Dispose can be called on non UI thread, InputLanguageManager.Current
+ // is thread specific
+ UiThreadRunAsync(() =>
+ {
+ var inputLangManager = InputLanguageManager.Current;
+
+ if (inputLangManager != null)
+ {
+ inputLangManager.InputLanguageChanged -= OnInputLanguageChanged;
+ }
+ });
+ }
+ catch (Exception ex)
+ {
+ //For now we'll ignore any errors
+ Trace.TraceError($"Error unsubscribing from InputLanguageChanged {ex.ToString()}");
+ }
+ }
}
}
diff --git a/CefSharp.Wpf/Experimental/WpfIMEKeyboardHandler.cs b/CefSharp.Wpf/Experimental/WpfIMEKeyboardHandler.cs
index 852a056ea2..c92a382b66 100644
--- a/CefSharp.Wpf/Experimental/WpfIMEKeyboardHandler.cs
+++ b/CefSharp.Wpf/Experimental/WpfIMEKeyboardHandler.cs
@@ -354,7 +354,7 @@ private void CreateImeWindow(IntPtr hwnd)
}
}
- private int PrimaryLangId(int lgid)
+ private static int PrimaryLangId(int lgid)
{
return lgid & 0x3ff;
}
@@ -467,5 +467,25 @@ private FrameworkElement GetOutermostElement(FrameworkElement control)
return current as FrameworkElement;
}
+
+ ///
+ /// 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;
+ }
}
}