@@ -1353,6 +1353,10 @@ impl<U: EventListener> Crosswords<U> {
13531353 } ;
13541354 info ! ( "Setting keyboard mode to {new_mode:?}" ) ;
13551355 self . keyboard_mode_stack [ self . keyboard_mode_idx ] = new_mode;
1356+
1357+ // Sync self.mode with keyboard_mode_stack
1358+ self . mode &= !Mode :: KITTY_KEYBOARD_PROTOCOL ;
1359+ self . mode |= Mode :: from ( KeyboardModes :: from_bits_truncate ( new_mode) ) ;
13561360 }
13571361
13581362 /// Find the beginning of the current line across linewraps.
@@ -2243,6 +2247,10 @@ impl<U: EventListener> Handler for Crosswords<U> {
22432247 self . keyboard_mode_idx %= KEYBOARD_MODE_STACK_MAX_DEPTH ;
22442248 }
22452249 self . keyboard_mode_stack [ self . keyboard_mode_idx ] = mode. bits ( ) ;
2250+
2251+ // Sync self.mode with keyboard_mode_stack
2252+ self . mode &= !Mode :: KITTY_KEYBOARD_PROTOCOL ;
2253+ self . mode |= Mode :: from ( mode) ;
22462254 }
22472255
22482256 #[ inline]
@@ -2251,6 +2259,7 @@ impl<U: EventListener> Handler for Crosswords<U> {
22512259 if usize:: from ( to_pop) >= KEYBOARD_MODE_STACK_MAX_DEPTH {
22522260 self . keyboard_mode_stack . fill ( KeyboardModes :: NO_MODE . bits ( ) ) ;
22532261 self . keyboard_mode_idx = 0 ;
2262+ self . mode &= !Mode :: KITTY_KEYBOARD_PROTOCOL ;
22542263 return ;
22552264 }
22562265 for _ in 0 ..to_pop {
@@ -2261,6 +2270,11 @@ impl<U: EventListener> Handler for Crosswords<U> {
22612270 if self . keyboard_mode_idx >= KEYBOARD_MODE_STACK_MAX_DEPTH {
22622271 self . keyboard_mode_idx %= KEYBOARD_MODE_STACK_MAX_DEPTH ;
22632272 }
2273+
2274+ // Sync self.mode with keyboard_mode_stack
2275+ let current_mode = self . keyboard_mode_stack [ self . keyboard_mode_idx ] ;
2276+ self . mode &= !Mode :: KITTY_KEYBOARD_PROTOCOL ;
2277+ self . mode |= Mode :: from ( KeyboardModes :: from_bits_truncate ( current_mode) ) ;
22642278 }
22652279
22662280 #[ inline]
@@ -3988,4 +4002,79 @@ mod tests {
39884002 other => panic ! ( "Expected PtyWrite event, got {:?}" , other) ,
39894003 }
39904004 }
4005+
4006+ #[ test]
4007+ fn test_keyboard_mode_syncs_with_mode ( ) {
4008+ let size = CrosswordsSize :: new ( 10 , 10 ) ;
4009+ let window_id = WindowId :: from ( 0 ) ;
4010+ let mut term =
4011+ Crosswords :: new ( size, CursorShape :: Block , VoidListener { } , window_id, 0 ) ;
4012+
4013+ // Initially, no keyboard mode should be set
4014+ assert ! ( !term. mode( ) . contains( Mode :: DISAMBIGUATE_ESC_CODES ) ) ;
4015+ assert ! ( !term. mode( ) . contains( Mode :: REPORT_ALL_KEYS_AS_ESC ) ) ;
4016+
4017+ // Push DISAMBIGUATE_ESC_CODES
4018+ Handler :: push_keyboard_mode ( & mut term, KeyboardModes :: DISAMBIGUATE_ESC_CODES ) ;
4019+ assert ! (
4020+ term. mode( ) . contains( Mode :: DISAMBIGUATE_ESC_CODES ) ,
4021+ "mode() should contain DISAMBIGUATE_ESC_CODES after push"
4022+ ) ;
4023+ assert ! ( !term. mode( ) . contains( Mode :: REPORT_ALL_KEYS_AS_ESC ) ) ;
4024+
4025+ // Push REPORT_ALL_KEYS_AS_ESC (replaces previous mode at this stack level)
4026+ Handler :: push_keyboard_mode ( & mut term, KeyboardModes :: REPORT_ALL_KEYS_AS_ESC ) ;
4027+ assert ! (
4028+ term. mode( ) . contains( Mode :: REPORT_ALL_KEYS_AS_ESC ) ,
4029+ "mode() should contain REPORT_ALL_KEYS_AS_ESC after push"
4030+ ) ;
4031+ assert ! ( !term. mode( ) . contains( Mode :: DISAMBIGUATE_ESC_CODES ) ,
4032+ "mode() should not contain DISAMBIGUATE_ESC_CODES after pushing different mode"
4033+ ) ;
4034+
4035+ // Pop back to previous level
4036+ Handler :: pop_keyboard_modes ( & mut term, 1 ) ;
4037+ assert ! (
4038+ term. mode( ) . contains( Mode :: DISAMBIGUATE_ESC_CODES ) ,
4039+ "mode() should contain DISAMBIGUATE_ESC_CODES after pop"
4040+ ) ;
4041+ assert ! (
4042+ !term. mode( ) . contains( Mode :: REPORT_ALL_KEYS_AS_ESC ) ,
4043+ "mode() should not contain REPORT_ALL_KEYS_AS_ESC after pop"
4044+ ) ;
4045+
4046+ // Test set_keyboard_mode with Union
4047+ Handler :: set_keyboard_mode (
4048+ & mut term,
4049+ KeyboardModes :: REPORT_EVENT_TYPES ,
4050+ KeyboardModesApplyBehavior :: Union ,
4051+ ) ;
4052+ assert ! (
4053+ term. mode( ) . contains( Mode :: DISAMBIGUATE_ESC_CODES ) ,
4054+ "mode() should still contain DISAMBIGUATE_ESC_CODES after union"
4055+ ) ;
4056+ assert ! (
4057+ term. mode( ) . contains( Mode :: REPORT_EVENT_TYPES ) ,
4058+ "mode() should contain REPORT_EVENT_TYPES after union"
4059+ ) ;
4060+
4061+ // Test set_keyboard_mode with Replace
4062+ Handler :: set_keyboard_mode (
4063+ & mut term,
4064+ KeyboardModes :: REPORT_ALTERNATE_KEYS ,
4065+ KeyboardModesApplyBehavior :: Replace ,
4066+ ) ;
4067+ assert ! (
4068+ term. mode( ) . contains( Mode :: REPORT_ALTERNATE_KEYS ) ,
4069+ "mode() should contain REPORT_ALTERNATE_KEYS after replace"
4070+ ) ;
4071+ assert ! (
4072+ !term. mode( ) . contains( Mode :: DISAMBIGUATE_ESC_CODES ) ,
4073+ "mode() should not contain DISAMBIGUATE_ESC_CODES after replace"
4074+ ) ;
4075+ assert ! (
4076+ !term. mode( ) . contains( Mode :: REPORT_EVENT_TYPES ) ,
4077+ "mode() should not contain REPORT_EVENT_TYPES after replace"
4078+ ) ;
4079+ }
39914080}
0 commit comments