Mercurial > vim
comparison src/term.c @ 23606:f98939164e91 v8.2.2345
patch 8.2.2345: no focus events in a terminal
Commit: https://github.com/vim/vim/commit/681fc3fa782e99fe69ed2c83c3e29109d2d61e1a
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Jan 14 17:35:21 2021 +0100
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)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 14 Jan 2021 17:45:05 +0100 |
parents | ae3421daa981 |
children | 07f9e4a54178 |
comparison
equal
deleted
inserted
replaced
23605:bc6c4127f054 | 23606:f98939164e91 |
---|---|
193 # define TGETENT(b, t) tgetent((char *)(b), (char *)(t)) | 193 # define TGETENT(b, t) tgetent((char *)(b), (char *)(t)) |
194 static char_u *vim_tgetstr(char *s, char_u **pp); | 194 static char_u *vim_tgetstr(char *s, char_u **pp); |
195 #endif // HAVE_TGETENT | 195 #endif // HAVE_TGETENT |
196 | 196 |
197 static int detected_8bit = FALSE; // detected 8-bit terminal | 197 static int detected_8bit = FALSE; // detected 8-bit terminal |
198 | |
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 | |
198 | 203 |
199 #ifdef FEAT_TERMRESPONSE | 204 #ifdef FEAT_TERMRESPONSE |
200 // When the cursor shape was detected these values are used: | 205 // When the cursor shape was detected these values are used: |
201 // 1: block, 2: underline, 3: vertical bar | 206 // 1: block, 2: underline, 3: vertical bar |
202 static int initial_cursor_shape = 0; | 207 static int initial_cursor_shape = 0; |
906 {(int)KS_CBD, IF_EB("\033[?2004l", ESC_STR "[?2004l")}, | 911 {(int)KS_CBD, IF_EB("\033[?2004l", ESC_STR "[?2004l")}, |
907 {(int)KS_CST, IF_EB("\033[22;2t", ESC_STR "[22;2t")}, | 912 {(int)KS_CST, IF_EB("\033[22;2t", ESC_STR "[22;2t")}, |
908 {(int)KS_CRT, IF_EB("\033[23;2t", ESC_STR "[23;2t")}, | 913 {(int)KS_CRT, IF_EB("\033[23;2t", ESC_STR "[23;2t")}, |
909 {(int)KS_SSI, IF_EB("\033[22;1t", ESC_STR "[22;1t")}, | 914 {(int)KS_SSI, IF_EB("\033[22;1t", ESC_STR "[22;1t")}, |
910 {(int)KS_SRI, IF_EB("\033[23;1t", ESC_STR "[23;1t")}, | 915 {(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 | |
911 | 920 |
912 {K_UP, IF_EB("\033O*A", ESC_STR "O*A")}, | 921 {K_UP, IF_EB("\033O*A", ESC_STR "O*A")}, |
913 {K_DOWN, IF_EB("\033O*B", ESC_STR "O*B")}, | 922 {K_DOWN, IF_EB("\033O*B", ESC_STR "O*B")}, |
914 {K_RIGHT, IF_EB("\033O*C", ESC_STR "O*C")}, | 923 {K_RIGHT, IF_EB("\033O*C", ESC_STR "O*C")}, |
915 {K_LEFT, IF_EB("\033O*D", ESC_STR "O*D")}, | 924 {K_LEFT, IF_EB("\033O*D", ESC_STR "O*D")}, |
2042 } | 2051 } |
2043 #else | 2052 #else |
2044 set_mouse_termcode(KS_MOUSE, (char_u *)"\233M"); | 2053 set_mouse_termcode(KS_MOUSE, (char_u *)"\233M"); |
2045 #endif | 2054 #endif |
2046 | 2055 |
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 | |
2047 #ifdef USE_TERM_CONSOLE | 2077 #ifdef USE_TERM_CONSOLE |
2048 // DEFAULT_TERM indicates that it is the machine console. | 2078 // DEFAULT_TERM indicates that it is the machine console. |
2049 if (STRCMP(term, DEFAULT_TERM) != 0) | 2079 if (STRCMP(term, DEFAULT_TERM) != 0) |
2050 term_console = FALSE; | 2080 term_console = FALSE; |
2051 else | 2081 else |
2517 ui_write(out_buf, len); | 2547 ui_write(out_buf, len); |
2518 #ifdef FEAT_JOB_CHANNEL | 2548 #ifdef FEAT_JOB_CHANNEL |
2519 if (ch_log_output) | 2549 if (ch_log_output) |
2520 { | 2550 { |
2521 out_buf[len] = NUL; | 2551 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); | |
2523 ch_log_output = FALSE; | 2556 ch_log_output = FALSE; |
2524 } | 2557 } |
2525 #endif | 2558 #endif |
2526 } | 2559 } |
2527 } | 2560 } |
3580 #endif | 3613 #endif |
3581 out_str(T_TI); // start termcap mode | 3614 out_str(T_TI); // start termcap mode |
3582 out_str(T_CTI); // start "raw" mode | 3615 out_str(T_CTI); // start "raw" mode |
3583 out_str(T_KS); // start "keypad transmit" mode | 3616 out_str(T_KS); // start "keypad transmit" mode |
3584 out_str(T_BE); // enable bracketed paste mode | 3617 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 | |
3585 out_flush(); | 3625 out_flush(); |
3586 termcap_active = TRUE; | 3626 termcap_active = TRUE; |
3587 screen_start(); // don't know where cursor is now | 3627 screen_start(); // don't know where cursor is now |
3588 #ifdef FEAT_TERMRESPONSE | 3628 #ifdef FEAT_TERMRESPONSE |
3589 # ifdef FEAT_GUI | 3629 # ifdef FEAT_GUI |
3631 } | 3671 } |
3632 #endif | 3672 #endif |
3633 #ifdef FEAT_JOB_CHANNEL | 3673 #ifdef FEAT_JOB_CHANNEL |
3634 ch_log_output = TRUE; | 3674 ch_log_output = TRUE; |
3635 #endif | 3675 #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 | |
3636 out_str(T_BD); // disable bracketed paste mode | 3683 out_str(T_BD); // disable bracketed paste mode |
3637 out_str(T_KE); // stop "keypad transmit" mode | 3684 out_str(T_KE); // stop "keypad transmit" mode |
3638 out_flush(); | 3685 out_flush(); |
3639 termcap_active = FALSE; | 3686 termcap_active = FALSE; |
3640 cursor_on(); // just in case it is still off | 3687 cursor_on(); // just in case it is still off |
5644 if (i == 0) // not enough characters to make one | 5691 if (i == 0) // not enough characters to make one |
5645 return -1; | 5692 return -1; |
5646 } | 5693 } |
5647 # endif // !USE_ON_FLY_SCROLL | 5694 # endif // !USE_ON_FLY_SCROLL |
5648 #endif // FEAT_GUI | 5695 #endif // FEAT_GUI |
5696 | |
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 | |
5649 | 5735 |
5650 /* | 5736 /* |
5651 * Change <xHome> to <Home>, <xUp> to <Up>, etc. | 5737 * Change <xHome> to <Home>, <xUp> to <Up>, etc. |
5652 */ | 5738 */ |
5653 key = handle_x_keys(TERMCAP2KEY(key_name[0], key_name[1])); | 5739 key = handle_x_keys(TERMCAP2KEY(key_name[0], key_name[1])); |