@@ -597,6 +597,9 @@ where
597597 key_code,
598598 modifiers,
599599 } ) if state. is_focused => {
600+ if state. is_unicode_input {
601+ return Status :: Captured ;
602+ }
600603 let mod_no = calculate_modifier_number ( state) ;
601604 let escape_code = match key_code {
602605 KeyCode :: Insert => csi ( "2" , "~" , mod_no) ,
@@ -712,6 +715,10 @@ where
712715 state. modifiers = modifiers;
713716 }
714717 Event :: Keyboard ( KeyEvent :: CharacterReceived ( character) ) if state. is_focused => {
718+ if unicode_input ( character, state, & terminal) {
719+ return Status :: Captured ;
720+ }
721+
715722 match (
716723 state. modifiers . logo ( ) ,
717724 state. modifiers . control ( ) ,
@@ -1002,6 +1009,64 @@ where
10021009 }
10031010}
10041011
1012+ fn unicode_input ( character : char , state : & mut State , terminal : & Terminal ) -> bool {
1013+ match state. is_unicode_input {
1014+ false => {
1015+ //Should we enter unicode input mode
1016+ match (
1017+ state. modifiers . logo ( ) ,
1018+ state. modifiers . control ( ) ,
1019+ state. modifiers . alt ( ) ,
1020+ state. modifiers . shift ( ) ,
1021+ ) {
1022+ ( false , true , true , false ) if character == '\x15' => {
1023+ state. is_unicode_input = true ;
1024+ true
1025+ }
1026+ _ => false ,
1027+ }
1028+ }
1029+ true if state. modifiers . is_empty ( ) => {
1030+ if character. is_ascii_hexdigit ( ) {
1031+ state. unicode_input . push ( character) ;
1032+ } else if character == '\x1b' {
1033+ state. is_unicode_input = false ;
1034+ state. unicode_input . clear ( ) ;
1035+ } else {
1036+ if let Some ( unicode_char) = unicode_input_to_char ( state) {
1037+ let mut buf = [ 0 , 0 , 0 , 0 ] ;
1038+ let str = unicode_char. encode_utf8 ( & mut buf) ;
1039+ terminal. input_scroll ( str. as_bytes ( ) . to_vec ( ) ) ;
1040+ }
1041+ state. is_unicode_input = false ;
1042+ state. unicode_input . clear ( ) ;
1043+ }
1044+ true
1045+ }
1046+ true => {
1047+ //Exit unicode mode on any modifier
1048+ state. is_unicode_input = false ;
1049+ state. unicode_input . clear ( ) ;
1050+ true
1051+ }
1052+ }
1053+ }
1054+
1055+ fn unicode_input_to_char ( state : & mut State ) -> Option < char > {
1056+ if state. unicode_input . is_empty ( ) {
1057+ return None ;
1058+ }
1059+ let hex_str: String = state. unicode_input . iter ( ) . collect ( ) ;
1060+ state. unicode_input . clear ( ) ;
1061+ match u32:: from_str_radix ( & hex_str, 16 ) {
1062+ Ok ( value) => char:: from_u32 ( value) ,
1063+ Err ( err) => {
1064+ log:: error!( "Failed to convert hex string {hex_str} to a u32 value {err}" ) ;
1065+ None
1066+ }
1067+ }
1068+ }
1069+
10051070fn shade ( color : cosmic_text:: Color , is_focused : bool ) -> cosmic_text:: Color {
10061071 if is_focused {
10071072 color
@@ -1046,6 +1111,8 @@ pub struct State {
10461111 is_focused : bool ,
10471112 scroll_pixels : f32 ,
10481113 scrollbar_rect : Cell < Rectangle < f32 > > ,
1114+ unicode_input : Vec < char > ,
1115+ is_unicode_input : bool ,
10491116}
10501117
10511118impl State {
@@ -1058,6 +1125,8 @@ impl State {
10581125 is_focused : false ,
10591126 scroll_pixels : 0.0 ,
10601127 scrollbar_rect : Cell :: new ( Rectangle :: default ( ) ) ,
1128+ unicode_input : Vec :: with_capacity ( 6 ) ,
1129+ is_unicode_input : false ,
10611130 }
10621131 }
10631132}
0 commit comments