1
0
forked from aniani/vim

patch 8.2.2345: no focus events in a terminal

Problem:    No focus events in a terminal.
Solution:   Add the t_fd and t_fe termcap entries and implement detecting
            focus events. (Hayaki Saito, Magnus Groß, closes #7673,
            closes #609, closes #5526)
This commit is contained in:
Bram Moolenaar
2021-01-14 17:35:21 +01:00
parent 6601b62943
commit 681fc3fa78
5 changed files with 111 additions and 3 deletions

View File

@@ -373,6 +373,10 @@ Added by Vim (there are no standard codes for these):
t_Ri restore icon text from stack *t_Ri* *'t_Ri'* t_Ri restore icon text from stack *t_Ri* *'t_Ri'*
t_TE end of "raw" mode *t_TE* *'t_TE'* t_TE end of "raw" mode *t_TE* *'t_TE'*
t_TI put terminal into "raw" mode *t_TI* *'t_TI'* t_TI put terminal into "raw" mode *t_TI* *'t_TI'*
t_fd disable focus-event tracking *t_TI* *'t_TI'*
|xterm-focus-event|
t_fe enable focus-event tracking *t_TI* *'t_TI'*
|xterm-focus-event|
Some codes have a start, middle and end part. The start and end are defined Some codes have a start, middle and end part. The start and end are defined
by the termcap option, the middle part is text. by the termcap option, the middle part is text.
@@ -546,6 +550,16 @@ And run "xrdb -merge .Xresources" to make it effective. You can check the
value with the context menu (right mouse button while CTRL key is pressed), value with the context menu (right mouse button while CTRL key is pressed),
there should be a tick at allow-window-ops. there should be a tick at allow-window-ops.
*xterm-focus-event*
Some terminals including xterm support the focus event tracking feature.
If this feature is enabled by the 't_fe' sequence, special key sequences are
sent from the terminal to Vim every time the terminal gains or loses focus.
Vim fires focus events (|FocusGained|/|FocusLost|) by handling them accordingly.
Focus event tracking is disabled by a 't_fd' sequence when exiting "raw" mode.
If you would like to disable this feature, add the following to your .vimrc:
`set t_fd=`
`set t_fe=`
*termcap-colors* *termcap-colors*
Note about colors: The 't_Co' option tells Vim the number of colors available. Note about colors: The 't_Co' option tells Vim the number of colors available.
When it is non-zero, the 't_AB' and 't_AF' options are used to set the color. When it is non-zero, the 't_AB' and 't_AF' options are used to set the color.

View File

@@ -2957,6 +2957,8 @@ static struct vimoption options[] =
p_term("t_EC", T_CEC) p_term("t_EC", T_CEC)
p_term("t_EI", T_CEI) p_term("t_EI", T_CEI)
p_term("t_fs", T_FS) p_term("t_fs", T_FS)
p_term("t_fd", T_FD)
p_term("t_fe", T_FE)
p_term("t_GP", T_CGP) p_term("t_GP", T_CGP)
p_term("t_IE", T_CIE) p_term("t_IE", T_CIE)
p_term("t_IS", T_CIS) p_term("t_IS", T_CIS)

View File

@@ -196,6 +196,11 @@ static char_u *vim_tgetstr(char *s, char_u **pp);
static int detected_8bit = FALSE; // detected 8-bit terminal static int detected_8bit = FALSE; // detected 8-bit terminal
#if (defined(UNIX) || defined(VMS))
static int focus_mode = FALSE; // xterm's "focus reporting" availability
static int focus_state = FALSE; // TRUE if the terminal window gains focus
#endif
#ifdef FEAT_TERMRESPONSE #ifdef FEAT_TERMRESPONSE
// When the cursor shape was detected these values are used: // When the cursor shape was detected these values are used:
// 1: block, 2: underline, 3: vertical bar // 1: block, 2: underline, 3: vertical bar
@@ -908,6 +913,10 @@ static struct builtin_term builtin_termcaps[] =
{(int)KS_CRT, IF_EB("\033[23;2t", ESC_STR "[23;2t")}, {(int)KS_CRT, IF_EB("\033[23;2t", ESC_STR "[23;2t")},
{(int)KS_SSI, IF_EB("\033[22;1t", ESC_STR "[22;1t")}, {(int)KS_SSI, IF_EB("\033[22;1t", ESC_STR "[22;1t")},
{(int)KS_SRI, IF_EB("\033[23;1t", ESC_STR "[23;1t")}, {(int)KS_SRI, IF_EB("\033[23;1t", ESC_STR "[23;1t")},
# if (defined(UNIX) || defined(VMS))
{(int)KS_FD, IF_EB("\033[?1004l", ESC_STR "[?1004l")},
{(int)KS_FE, IF_EB("\033[?1004h", ESC_STR "[?1004h")},
# endif
{K_UP, IF_EB("\033O*A", ESC_STR "O*A")}, {K_UP, IF_EB("\033O*A", ESC_STR "O*A")},
{K_DOWN, IF_EB("\033O*B", ESC_STR "O*B")}, {K_DOWN, IF_EB("\033O*B", ESC_STR "O*B")},
@@ -2044,6 +2053,27 @@ set_termname(char_u *term)
set_mouse_termcode(KS_MOUSE, (char_u *)"\233M"); set_mouse_termcode(KS_MOUSE, (char_u *)"\233M");
#endif #endif
#if (defined(UNIX) || defined(VMS))
// focus reporting is supported by xterm compatible terminals and tmux.
if (use_xterm_like_mouse(term))
{
char_u name[3];
name[0] = (int)KS_EXTRA;
name[2] = NUL;
// handle focus in event
name[1] = (int)KE_FOCUSGAINED;
add_termcode(name, (char_u *)"\033[I", FALSE);
// handle focus out event
name[1] = (int)KE_FOCUSLOST;
add_termcode(name, (char_u *)"\033[O", FALSE);
focus_mode = TRUE;
focus_state = TRUE;
}
#endif
#ifdef USE_TERM_CONSOLE #ifdef USE_TERM_CONSOLE
// DEFAULT_TERM indicates that it is the machine console. // DEFAULT_TERM indicates that it is the machine console.
if (STRCMP(term, DEFAULT_TERM) != 0) if (STRCMP(term, DEFAULT_TERM) != 0)
@@ -2519,7 +2549,10 @@ out_flush(void)
if (ch_log_output) if (ch_log_output)
{ {
out_buf[len] = NUL; out_buf[len] = NUL;
ch_log(NULL, "raw terminal output: \"%s\"", out_buf); ch_log(NULL, "raw %s output: \"%s\"",
(gui.in_use && !gui.dying && !gui.starting)
? "GUI" : "terminal",
out_buf);
ch_log_output = FALSE; ch_log_output = FALSE;
} }
#endif #endif
@@ -3582,6 +3615,13 @@ starttermcap(void)
out_str(T_CTI); // start "raw" mode out_str(T_CTI); // start "raw" mode
out_str(T_KS); // start "keypad transmit" mode out_str(T_KS); // start "keypad transmit" mode
out_str(T_BE); // enable bracketed paste mode out_str(T_BE); // enable bracketed paste mode
#if (defined(UNIX) || defined(VMS))
// enable xterm's focus reporting mode
if (focus_mode && *T_FE != NUL)
out_str(T_FE);
#endif
out_flush(); out_flush();
termcap_active = TRUE; termcap_active = TRUE;
screen_start(); // don't know where cursor is now screen_start(); // don't know where cursor is now
@@ -3633,6 +3673,13 @@ stoptermcap(void)
#ifdef FEAT_JOB_CHANNEL #ifdef FEAT_JOB_CHANNEL
ch_log_output = TRUE; ch_log_output = TRUE;
#endif #endif
#if (defined(UNIX) || defined(VMS))
// disable xterm's focus reporting mode
if (focus_mode && *T_FD != NUL)
out_str(T_FD);
#endif
out_str(T_BD); // disable bracketed paste mode out_str(T_BD); // disable bracketed paste mode
out_str(T_KE); // stop "keypad transmit" mode out_str(T_KE); // stop "keypad transmit" mode
out_flush(); out_flush();
@@ -5647,6 +5694,45 @@ check_termcode(
# endif // !USE_ON_FLY_SCROLL # endif // !USE_ON_FLY_SCROLL
#endif // FEAT_GUI #endif // FEAT_GUI
#if (defined(UNIX) || defined(VMS))
/*
* Handle FocusIn/FocusOut event sequences reported by XTerm.
* (CSI I/CSI O)
*/
if (focus_mode
# ifdef FEAT_GUI
&& !gui.in_use
# endif
&& key_name[0] == KS_EXTRA
)
{
int did_aucmd = FALSE;
if (key_name[1] == KE_FOCUSGAINED && !focus_state)
{
did_aucmd = apply_autocmds(EVENT_FOCUSGAINED,
NULL, NULL, FALSE, curbuf);
did_cursorhold = TRUE;
focus_state = TRUE;
key_name[1] = (int)KE_IGNORE;
}
else if (key_name[1] == KE_FOCUSLOST && focus_state)
{
did_aucmd = apply_autocmds(EVENT_FOCUSLOST,
NULL, NULL, FALSE, curbuf);
did_cursorhold = TRUE;
focus_state = FALSE;
key_name[1] = (int)KE_IGNORE;
}
if (did_aucmd && (State & (NORMAL | INSERT | TERMINAL)))
{
// in case a message was displayed: reposition the cursor
setcursor();
out_flush();
}
}
#endif
/* /*
* Change <xHome> to <Home>, <xUp> to <Up>, etc. * Change <xHome> to <Home>, <xUp> to <Up>, etc.
*/ */

View File

@@ -109,10 +109,12 @@ enum SpecialKey
KS_CST, // save window title KS_CST, // save window title
KS_CRT, // restore window title KS_CRT, // restore window title
KS_SSI, // save icon text KS_SSI, // save icon text
KS_SRI // restore icon text KS_SRI, // restore icon text
KS_FD, // disable focus event tracking
KS_FE // enable focus event tracking
}; };
#define KS_LAST KS_SRI #define KS_LAST KS_FE
/* /*
* the terminal capabilities are stored in this array * the terminal capabilities are stored in this array
@@ -212,6 +214,8 @@ extern char_u *(term_strings[]); // current terminal strings
#define T_CRT (TERM_STR(KS_CRT)) // restore window title #define T_CRT (TERM_STR(KS_CRT)) // restore window title
#define T_SSI (TERM_STR(KS_SSI)) // save icon text #define T_SSI (TERM_STR(KS_SSI)) // save icon text
#define T_SRI (TERM_STR(KS_SRI)) // restore icon text #define T_SRI (TERM_STR(KS_SRI)) // restore icon text
#define T_FD (TERM_STR(KS_FD)) // disable focus event tracking
#define T_FE (TERM_STR(KS_FE)) // enable focus event tracking
typedef enum { typedef enum {
TMODE_COOK, // terminal mode for external cmds and Ex mode TMODE_COOK, // terminal mode for external cmds and Ex mode

View File

@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
2345,
/**/ /**/
2344, 2344,
/**/ /**/