To: vim_dev@googlegroups.com Subject: Patch 8.2.2345 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.2345 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) Files: runtime/doc/term.txt, src/optiondefs.h, src/term.c, src/term.h *** ../vim-8.2.2344/runtime/doc/term.txt 2020-12-29 20:53:28.299402080 +0100 --- runtime/doc/term.txt 2021-01-14 17:20:23.946278238 +0100 *************** *** 372,377 **** --- 373,382 ---- t_Ri restore icon text from stack *t_Ri* *'t_Ri'* t_TE end of "raw" mode *t_TE* *'t_TE'* 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 by the termcap option, the middle part is text. *************** *** 545,550 **** --- 550,565 ---- value with the context menu (right mouse button while CTRL key is pressed), 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* 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. *** ../vim-8.2.2344/src/optiondefs.h 2020-08-11 21:58:12.585968185 +0200 --- src/optiondefs.h 2021-01-14 17:20:23.946278238 +0100 *************** *** 2957,2962 **** --- 2957,2964 ---- p_term("t_EC", T_CEC) p_term("t_EI", T_CEI) 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_IE", T_CIE) p_term("t_IS", T_CIS) *** ../vim-8.2.2344/src/term.c 2020-12-30 14:08:30.908689169 +0100 --- src/term.c 2021-01-14 17:33:48.443716246 +0100 *************** *** 196,201 **** --- 196,206 ---- 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 // When the cursor shape was detected these values are used: // 1: block, 2: underline, 3: vertical bar *************** *** 908,913 **** --- 913,922 ---- {(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_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_DOWN, IF_EB("\033O*B", ESC_STR "O*B")}, *************** *** 2044,2049 **** --- 2053,2079 ---- set_mouse_termcode(KS_MOUSE, (char_u *)"\233M"); #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 // DEFAULT_TERM indicates that it is the machine console. if (STRCMP(term, DEFAULT_TERM) != 0) *************** *** 2519,2525 **** if (ch_log_output) { out_buf[len] = NUL; ! ch_log(NULL, "raw terminal output: \"%s\"", out_buf); ch_log_output = FALSE; } #endif --- 2549,2558 ---- if (ch_log_output) { out_buf[len] = NUL; ! ch_log(NULL, "raw %s output: \"%s\"", ! (gui.in_use && !gui.dying && !gui.starting) ! ? "GUI" : "terminal", ! out_buf); ch_log_output = FALSE; } #endif *************** *** 3582,3587 **** --- 3615,3627 ---- out_str(T_CTI); // start "raw" mode out_str(T_KS); // start "keypad transmit" 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(); termcap_active = TRUE; screen_start(); // don't know where cursor is now *************** *** 3633,3638 **** --- 3673,3685 ---- #ifdef FEAT_JOB_CHANNEL ch_log_output = TRUE; #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_KE); // stop "keypad transmit" mode out_flush(); *************** *** 5647,5652 **** --- 5694,5738 ---- # endif // !USE_ON_FLY_SCROLL #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 to , to , etc. */ *** ../vim-8.2.2344/src/term.h 2020-05-31 16:41:04.646603340 +0200 --- src/term.h 2021-01-14 17:20:23.946278238 +0100 *************** *** 109,118 **** KS_CST, // save window title KS_CRT, // restore window title KS_SSI, // save icon text ! KS_SRI // restore icon text }; ! #define KS_LAST KS_SRI /* * the terminal capabilities are stored in this array --- 109,120 ---- KS_CST, // save window title KS_CRT, // restore window title KS_SSI, // save icon text ! KS_SRI, // restore icon text ! KS_FD, // disable focus event tracking ! KS_FE // enable focus event tracking }; ! #define KS_LAST KS_FE /* * the terminal capabilities are stored in this array *************** *** 212,217 **** --- 214,221 ---- #define T_CRT (TERM_STR(KS_CRT)) // restore window title #define T_SSI (TERM_STR(KS_SSI)) // save 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 { TMODE_COOK, // terminal mode for external cmds and Ex mode *** ../vim-8.2.2344/src/version.c 2021-01-13 21:46:53.832589880 +0100 --- src/version.c 2021-01-14 17:24:31.397508436 +0100 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 2345, /**/ -- hundred-and-one symptoms of being an internet addict: 141. You'd rather go to http://www.weather.com/ than look out your window. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///