@@ -196,6 +196,11 @@ static char_u *vim_tgetstr(char *s, char_u **pp);
196196
197197static int detected_8bit = FALSE; // detected 8-bit terminal
198198
199+ #if (defined(UNIX ) || defined(VMS ))
200+ static int focus_mode = FALSE; // xterm's "focus reporting" availability
201+ static int focus_state = FALSE; // TRUE if the terminal window gains focus
202+ #endif
203+
199204#ifdef FEAT_TERMRESPONSE
200205// When the cursor shape was detected these values are used:
201206// 1: block, 2: underline, 3: vertical bar
@@ -908,6 +913,10 @@ static struct builtin_term builtin_termcaps[] =
908913 {(int )KS_CRT , IF_EB ("\033[23;2t" , ESC_STR "[23;2t" )},
909914 {(int )KS_SSI , IF_EB ("\033[22;1t" , ESC_STR "[22;1t" )},
910915 {(int )KS_SRI , IF_EB ("\033[23;1t" , ESC_STR "[23;1t" )},
916+ # if (defined (UNIX ) || defined (VMS ))
917+ {(int )KS_FD , IF_EB ("\033[?1004l" , ESC_STR "[?1004l" )},
918+ {(int )KS_FE , IF_EB ("\033[?1004h" , ESC_STR "[?1004h" )},
919+ # endif
911920
912921 {K_UP , IF_EB ("\033O*A" , ESC_STR "O*A" )},
913922 {K_DOWN , IF_EB ("\033O*B" , ESC_STR "O*B" )},
@@ -2044,6 +2053,27 @@ set_termname(char_u *term)
20442053 set_mouse_termcode (KS_MOUSE , (char_u * )"\233M" );
20452054#endif
20462055
2056+ #if (defined(UNIX ) || defined(VMS ))
2057+ // focus reporting is supported by xterm compatible terminals and tmux.
2058+ if (use_xterm_like_mouse (term ))
2059+ {
2060+ char_u name [3 ];
2061+ name [0 ] = (int )KS_EXTRA ;
2062+ name [2 ] = NUL ;
2063+
2064+ // handle focus in event
2065+ name [1 ] = (int )KE_FOCUSGAINED ;
2066+ add_termcode (name , (char_u * )"\033[I" , FALSE);
2067+
2068+ // handle focus out event
2069+ name [1 ] = (int )KE_FOCUSLOST ;
2070+ add_termcode (name , (char_u * )"\033[O" , FALSE);
2071+
2072+ focus_mode = TRUE;
2073+ focus_state = TRUE;
2074+ }
2075+ #endif
2076+
20472077#ifdef USE_TERM_CONSOLE
20482078 // DEFAULT_TERM indicates that it is the machine console.
20492079 if (STRCMP (term , DEFAULT_TERM ) != 0 )
@@ -2519,7 +2549,10 @@ out_flush(void)
25192549 if (ch_log_output )
25202550 {
25212551 out_buf [len ] = NUL ;
2522- ch_log (NULL , "raw terminal output: \"%s\"" , out_buf );
2552+ ch_log (NULL , "raw %s output: \"%s\"" ,
2553+ (gui .in_use && !gui .dying && !gui .starting )
2554+ ? "GUI" : "terminal" ,
2555+ out_buf );
25232556 ch_log_output = FALSE;
25242557 }
25252558#endif
@@ -3582,6 +3615,13 @@ starttermcap(void)
35823615 out_str (T_CTI ); // start "raw" mode
35833616 out_str (T_KS ); // start "keypad transmit" mode
35843617 out_str (T_BE ); // enable bracketed paste mode
3618+
3619+ #if (defined(UNIX ) || defined(VMS ))
3620+ // enable xterm's focus reporting mode
3621+ if (focus_mode && * T_FE != NUL )
3622+ out_str (T_FE );
3623+ #endif
3624+
35853625 out_flush ();
35863626 termcap_active = TRUE;
35873627 screen_start (); // don't know where cursor is now
@@ -3633,6 +3673,13 @@ stoptermcap(void)
36333673#ifdef FEAT_JOB_CHANNEL
36343674 ch_log_output = TRUE;
36353675#endif
3676+
3677+ #if (defined(UNIX ) || defined(VMS ))
3678+ // disable xterm's focus reporting mode
3679+ if (focus_mode && * T_FD != NUL )
3680+ out_str (T_FD );
3681+ #endif
3682+
36363683 out_str (T_BD ); // disable bracketed paste mode
36373684 out_str (T_KE ); // stop "keypad transmit" mode
36383685 out_flush ();
@@ -5647,6 +5694,45 @@ check_termcode(
56475694# endif // !USE_ON_FLY_SCROLL
56485695#endif // FEAT_GUI
56495696
5697+ #if (defined(UNIX ) || defined(VMS ))
5698+ /*
5699+ * Handle FocusIn/FocusOut event sequences reported by XTerm.
5700+ * (CSI I/CSI O)
5701+ */
5702+ if (focus_mode
5703+ # ifdef FEAT_GUI
5704+ && !gui .in_use
5705+ # endif
5706+ && key_name [0 ] == KS_EXTRA
5707+ )
5708+ {
5709+ int did_aucmd = FALSE;
5710+
5711+ if (key_name [1 ] == KE_FOCUSGAINED && !focus_state )
5712+ {
5713+ did_aucmd = apply_autocmds (EVENT_FOCUSGAINED ,
5714+ NULL , NULL , FALSE, curbuf );
5715+ did_cursorhold = TRUE;
5716+ focus_state = TRUE;
5717+ key_name [1 ] = (int )KE_IGNORE ;
5718+ }
5719+ else if (key_name [1 ] == KE_FOCUSLOST && focus_state )
5720+ {
5721+ did_aucmd = apply_autocmds (EVENT_FOCUSLOST ,
5722+ NULL , NULL , FALSE, curbuf );
5723+ did_cursorhold = TRUE;
5724+ focus_state = FALSE;
5725+ key_name [1 ] = (int )KE_IGNORE ;
5726+ }
5727+ if (did_aucmd && (State & (NORMAL | INSERT | TERMINAL )))
5728+ {
5729+ // in case a message was displayed: reposition the cursor
5730+ setcursor ();
5731+ out_flush ();
5732+ }
5733+ }
5734+ #endif
5735+
56505736 /*
56515737 * Change <xHome> to <Home>, <xUp> to <Up>, etc.
56525738 */
0 commit comments