3
3
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
4
4
5
5
using System ;
6
+ using System . Diagnostics ;
6
7
using System . Runtime . CompilerServices ;
7
8
using System . Threading ;
8
9
using System . Threading . Tasks ;
@@ -604,7 +605,12 @@ private void NoInliningConstructor()
604
605
605
606
browserSettings = Core . ObjectFactory . CreateBrowserSettings ( autoDispose : true ) ;
606
607
607
- WpfKeyboardHandler = new WpfKeyboardHandler ( this ) ;
608
+ SetupWpfKeyboardHandler ( ) ;
609
+
610
+ if ( WpfKeyboardHandler == null )
611
+ {
612
+ WpfKeyboardHandler = new WpfKeyboardHandler ( this ) ;
613
+ }
608
614
609
615
PresentationSource . AddSourceChangedHandler ( this , PresentationSourceChangedHandler ) ;
610
616
@@ -753,6 +759,8 @@ private void InternalDispose(bool disposing)
753
759
// is called.
754
760
LifeSpanHandler = null ;
755
761
762
+ UnsubscribeInputLanguageChanged ( ) ;
763
+
756
764
WpfKeyboardHandler ? . Dispose ( ) ;
757
765
WpfKeyboardHandler = null ;
758
766
@@ -769,6 +777,44 @@ private void InternalDispose(bool disposing)
769
777
Cef . RemoveDisposable ( this ) ;
770
778
}
771
779
780
+ /// <summary>
781
+ /// Setup the <see cref="WpfKeyboardHandler"/> used by this <see cref="ChromiumWebBrowser"/> instance.
782
+ /// There are two main keyboard handler implementations currently <see cref="WpfImeKeyboardHandler"/>
783
+ /// and <see cref="Internals.WpfKeyboardHandler"/>. If <see cref="WpfImeKeyboardHandler.UseImeKeyboardHandler"/>
784
+ /// returns true for the current <see cref="System.Globalization.CultureInfo.KeyboardLayoutId"/>
785
+ /// then the <see cref="WpfImeKeyboardHandler"/> instance will be used, otherwise the older
786
+ /// <see cref="Internals.WpfKeyboardHandler"/> instance will be used.
787
+ /// Override to provide your own custom keyboard handler.
788
+ /// </summary>
789
+ protected virtual void SetupWpfKeyboardHandler ( )
790
+ {
791
+ try
792
+ {
793
+ var inputLang = InputLanguageManager . Current . CurrentInputLanguage ;
794
+
795
+ var useImeKeyboardHandler = WpfImeKeyboardHandler . UseImeKeyboardHandler ( inputLang . KeyboardLayoutId ) ;
796
+
797
+ if ( useImeKeyboardHandler )
798
+ {
799
+ WpfKeyboardHandler = new WpfImeKeyboardHandler ( this ) ;
800
+ }
801
+ else
802
+ {
803
+ InputLanguageManager . Current . InputLanguageChanged += OnInputLanguageChanged ;
804
+
805
+ WpfKeyboardHandler = new WpfKeyboardHandler ( this ) ;
806
+ }
807
+ }
808
+ catch ( Exception ex )
809
+ {
810
+ //For now we'll ignore any errors
811
+ Trace . TraceError ( $ "Error initializing keyboard handler: { ex . ToString ( ) } ") ;
812
+
813
+ // For now we'll ignore any errors and just use the default keyboard handler
814
+ WpfKeyboardHandler = new WpfKeyboardHandler ( this ) ;
815
+ }
816
+ }
817
+
772
818
/// <summary>
773
819
/// Gets the ScreenInfo - currently used to get the DPI scale factor.
774
820
/// </summary>
@@ -1750,6 +1796,26 @@ private void OnDragEnter(object sender, DragEventArgs e)
1750
1796
}
1751
1797
}
1752
1798
1799
+ private void OnInputLanguageChanged ( object sender , InputLanguageEventArgs e )
1800
+ {
1801
+ // If we are already using the WpfImeKeyboardHandler then we'll ignore any changes
1802
+ if ( WpfKeyboardHandler ? . GetType ( ) == typeof ( WpfImeKeyboardHandler ) )
1803
+ {
1804
+ return ;
1805
+ }
1806
+
1807
+ var useImeKeyboardHandler = WpfImeKeyboardHandler . UseImeKeyboardHandler ( e . NewLanguage . KeyboardLayoutId ) ;
1808
+
1809
+ if ( useImeKeyboardHandler )
1810
+ {
1811
+ var oldKeyboardHandler = WpfKeyboardHandler ;
1812
+ WpfKeyboardHandler = new WpfImeKeyboardHandler ( this ) ;
1813
+ oldKeyboardHandler ? . Dispose ( ) ;
1814
+
1815
+ InputLanguageManager . Current . InputLanguageChanged -= OnInputLanguageChanged ;
1816
+ }
1817
+ }
1818
+
1753
1819
/// <summary>
1754
1820
/// PresentationSource changed handler.
1755
1821
/// </summary>
@@ -2858,5 +2924,35 @@ private async Task ResizeHackRun()
2858
2924
}
2859
2925
}
2860
2926
}
2927
+
2928
+ private void UnsubscribeInputLanguageChanged ( )
2929
+ {
2930
+ // If we are using WpfImeKeyboardHandler then we
2931
+ // shouldn't need to unsubsribe from the handler
2932
+ if ( WpfKeyboardHandler ? . GetType ( ) == typeof ( WpfImeKeyboardHandler ) )
2933
+ {
2934
+ return ;
2935
+ }
2936
+
2937
+ try
2938
+ {
2939
+ // Dispose can be called on non UI thread, InputLanguageManager.Current
2940
+ // is thread specific
2941
+ UiThreadRunAsync ( ( ) =>
2942
+ {
2943
+ var inputLangManager = InputLanguageManager . Current ;
2944
+
2945
+ if ( inputLangManager != null )
2946
+ {
2947
+ inputLangManager . InputLanguageChanged -= OnInputLanguageChanged ;
2948
+ }
2949
+ } ) ;
2950
+ }
2951
+ catch ( Exception ex )
2952
+ {
2953
+ //For now we'll ignore any errors
2954
+ Trace . TraceError ( $ "Error unsubscribing from InputLanguageChanged { ex . ToString ( ) } ") ;
2955
+ }
2956
+ }
2861
2957
}
2862
2958
}
0 commit comments