@@ -466,12 +466,7 @@ fn handle_keyup_msg(
466466}
467467
468468fn handle_char_msg ( wparam : WPARAM , state_ptr : Rc < WindowsWindowStatePtr > ) -> Option < isize > {
469- let Some ( input) = char:: from_u32 ( wparam. 0 as u32 )
470- . filter ( |c| !c. is_control ( ) )
471- . map ( String :: from)
472- else {
473- return Some ( 1 ) ;
474- } ;
469+ let input = parse_char_message ( wparam, & state_ptr) ?;
475470 with_input_handler ( & state_ptr, |input_handler| {
476471 input_handler. replace_text_in_range ( None , & input) ;
477472 } ) ;
@@ -1228,6 +1223,36 @@ fn handle_input_language_changed(
12281223 Some ( 0 )
12291224}
12301225
1226+ #[ inline]
1227+ fn parse_char_message ( wparam : WPARAM , state_ptr : & Rc < WindowsWindowStatePtr > ) -> Option < String > {
1228+ let code_point = wparam. loword ( ) ;
1229+ let mut lock = state_ptr. state . borrow_mut ( ) ;
1230+ // https://www.unicode.org/versions/Unicode16.0.0/core-spec/chapter-3/#G2630
1231+ match code_point {
1232+ 0xD800 ..=0xDBFF => {
1233+ // High surrogate, wait for low surrogate
1234+ lock. pending_surrogate = Some ( code_point) ;
1235+ None
1236+ }
1237+ 0xDC00 ..=0xDFFF => {
1238+ if let Some ( high_surrogate) = lock. pending_surrogate . take ( ) {
1239+ // Low surrogate, combine with pending high surrogate
1240+ String :: from_utf16 ( & [ high_surrogate, code_point] ) . ok ( )
1241+ } else {
1242+ // Invalid low surrogate without a preceding high surrogate
1243+ log:: warn!(
1244+ "Received low surrogate without a preceding high surrogate: {code_point:x}"
1245+ ) ;
1246+ None
1247+ }
1248+ }
1249+ _ => {
1250+ lock. pending_surrogate = None ;
1251+ String :: from_utf16 ( & [ code_point] ) . ok ( )
1252+ }
1253+ }
1254+ }
1255+
12311256#[ inline]
12321257fn translate_message ( handle : HWND , wparam : WPARAM , lparam : LPARAM ) {
12331258 let msg = MSG {
@@ -1270,6 +1295,10 @@ where
12701295 capslock : current_capslock ( ) ,
12711296 } ) )
12721297 }
1298+ VK_PACKET => {
1299+ translate_message ( handle, wparam, lparam) ;
1300+ None
1301+ }
12731302 VK_CAPITAL => {
12741303 let capslock = current_capslock ( ) ;
12751304 if state
0 commit comments