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]));