mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 8.1.1125: libvterm does not handle the window position report
Problem: Libvterm does not handle the window position report. Solution: Let libvterm call the fallback CSI handler when not handling CSI sequence. Handle the window position report in Vim.
This commit is contained in:
parent
d9eefe3155
commit
fa1e90cd4d
@ -5985,20 +5985,14 @@ f_getwinpos(typval_T *argvars UNUSED, typval_T *rettv)
|
||||
|
||||
if (rettv_list_alloc(rettv) == FAIL)
|
||||
return;
|
||||
#ifdef FEAT_GUI
|
||||
if (gui.in_use)
|
||||
(void)gui_mch_get_winpos(&x, &y);
|
||||
# if defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)
|
||||
else
|
||||
# endif
|
||||
#endif
|
||||
#if defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)
|
||||
#if defined(FEAT_GUI) || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE))
|
||||
{
|
||||
varnumber_T timeout = 100;
|
||||
|
||||
if (argvars[0].v_type != VAR_UNKNOWN)
|
||||
timeout = tv_get_number(&argvars[0]);
|
||||
term_get_winpos(&x, &y, timeout);
|
||||
|
||||
(void)ui_get_winpos(&x, &y, timeout);
|
||||
}
|
||||
#endif
|
||||
list_append_number(rettv->vval.v_list, (varnumber_T)x);
|
||||
@ -6013,21 +6007,11 @@ f_getwinpos(typval_T *argvars UNUSED, typval_T *rettv)
|
||||
f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv)
|
||||
{
|
||||
rettv->vval.v_number = -1;
|
||||
#ifdef FEAT_GUI
|
||||
if (gui.in_use)
|
||||
#if defined(FEAT_GUI) || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE))
|
||||
{
|
||||
int x, y;
|
||||
|
||||
if (gui_mch_get_winpos(&x, &y) == OK)
|
||||
rettv->vval.v_number = x;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
if (term_get_winpos(&x, &y, (varnumber_T)100) == OK)
|
||||
if (ui_get_winpos(&x, &y, 100) == OK)
|
||||
rettv->vval.v_number = x;
|
||||
}
|
||||
#endif
|
||||
@ -6040,21 +6024,11 @@ f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv)
|
||||
f_getwinposy(typval_T *argvars UNUSED, typval_T *rettv)
|
||||
{
|
||||
rettv->vval.v_number = -1;
|
||||
#ifdef FEAT_GUI
|
||||
if (gui.in_use)
|
||||
#if defined(FEAT_GUI) || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE))
|
||||
{
|
||||
int x, y;
|
||||
|
||||
if (gui_mch_get_winpos(&x, &y) == OK)
|
||||
rettv->vval.v_number = y;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
if (term_get_winpos(&x, &y, (varnumber_T)100) == OK)
|
||||
if (ui_get_winpos(&x, &y, 100) == OK)
|
||||
rettv->vval.v_number = y;
|
||||
}
|
||||
#endif
|
||||
|
@ -905,6 +905,7 @@ static int on_csi(const char *leader, const long args[], int argcount, const cha
|
||||
int leader_byte = 0;
|
||||
int intermed_byte = 0;
|
||||
VTermPos oldpos = state->pos;
|
||||
int handled = 1;
|
||||
|
||||
/* Some temporaries for later code */
|
||||
int count, val;
|
||||
@ -1416,6 +1417,10 @@ static int on_csi(const char *leader, const long args[], int argcount, const cha
|
||||
case 8: /* CSI 8 ; rows ; cols t set size */
|
||||
if (argcount == 3)
|
||||
on_resize(CSI_ARG(args[1]), CSI_ARG(args[2]), state);
|
||||
break;
|
||||
default:
|
||||
handled = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1450,6 +1455,11 @@ static int on_csi(const char *leader, const long args[], int argcount, const cha
|
||||
break;
|
||||
|
||||
default:
|
||||
handled = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!handled) {
|
||||
if(state->fallbacks && state->fallbacks->csi)
|
||||
if((*state->fallbacks->csi)(leader, args, argcount, intermed, command, state->fbdata))
|
||||
return 1;
|
||||
|
@ -11,6 +11,7 @@ void suspend_shell(void);
|
||||
int ui_get_shellsize(void);
|
||||
void ui_set_shellsize(int mustset);
|
||||
void ui_new_shellsize(void);
|
||||
int ui_get_winpos(int *x, int *y, varnumber_T timeout);
|
||||
void ui_breakcheck(void);
|
||||
void ui_breakcheck_force(int force);
|
||||
void clip_init(int can_use);
|
||||
|
@ -3842,14 +3842,68 @@ parse_osc(const char *command, size_t cmdlen, void *user)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by libvterm when it cannot recognize a CSI sequence.
|
||||
* We recognize the window position report.
|
||||
*/
|
||||
static int
|
||||
parse_csi(
|
||||
const char *leader UNUSED,
|
||||
const long args[],
|
||||
int argcount,
|
||||
const char *intermed UNUSED,
|
||||
char command,
|
||||
void *user)
|
||||
{
|
||||
term_T *term = (term_T *)user;
|
||||
char buf[100];
|
||||
int len;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
win_T *wp;
|
||||
|
||||
// We recognize only CSI 13 t
|
||||
if (command != 't' || argcount != 1 || args[0] != 13)
|
||||
return 0; // not handled
|
||||
|
||||
// When getting the window position fails it results in zero/zero.
|
||||
(void)ui_get_winpos(&x, &y, (varnumber_T)100);
|
||||
|
||||
FOR_ALL_WINDOWS(wp)
|
||||
if (wp->w_buffer == term->tl_buffer)
|
||||
break;
|
||||
if (wp != NULL)
|
||||
{
|
||||
#ifdef FEAT_GUI
|
||||
if (gui.in_use)
|
||||
{
|
||||
x += wp->w_wincol * gui.char_width;
|
||||
y += W_WINROW(wp) * gui.char_height;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// We roughly estimate the position of the terminal window inside
|
||||
// the Vim window by assuing a 10 x 7 character cell.
|
||||
x += wp->w_wincol * 7;
|
||||
y += W_WINROW(wp) * 10;
|
||||
}
|
||||
}
|
||||
|
||||
len = vim_snprintf(buf, 100, "\x1b[3;%d;%dt", x, y);
|
||||
channel_send(term->tl_job->jv_channel, get_tty_part(term),
|
||||
(char_u *)buf, len, NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static VTermParserCallbacks parser_fallbacks = {
|
||||
NULL, /* text */
|
||||
NULL, /* control */
|
||||
NULL, /* escape */
|
||||
NULL, /* csi */
|
||||
parse_osc, /* osc */
|
||||
NULL, /* dcs */
|
||||
NULL /* resize */
|
||||
NULL, // text
|
||||
NULL, // control
|
||||
NULL, // escape
|
||||
parse_csi, // csi
|
||||
parse_osc, // osc
|
||||
NULL, // dcs
|
||||
NULL // resize
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1887,3 +1887,36 @@ func Test_terminal_statusline()
|
||||
au! BufLeave
|
||||
set statusline=
|
||||
endfunc
|
||||
|
||||
func Test_terminal_getwinpos()
|
||||
" split, go to the bottom-right window
|
||||
split
|
||||
wincmd j
|
||||
set splitright
|
||||
|
||||
call writefile([
|
||||
\ 'echo getwinpos()',
|
||||
\ ], 'XTest_getwinpos')
|
||||
let buf = RunVimInTerminal('-S XTest_getwinpos', {'cols': 60})
|
||||
call term_wait(buf)
|
||||
|
||||
" Find the output of getwinpos() in the bottom line.
|
||||
let rows = term_getsize(buf)[0]
|
||||
call WaitForAssert({-> assert_match('\[\d\+, \d\+\]', term_getline(buf, rows))})
|
||||
let line = term_getline(buf, rows)
|
||||
let xpos = str2nr(substitute(line, '\[\(\d\+\), \d\+\]', '\1', ''))
|
||||
let ypos = str2nr(substitute(line, '\[\d\+, \(\d\+\)\]', '\1', ''))
|
||||
|
||||
" Position must be bigger than the getwinpos() result of Vim itself.
|
||||
let [xroot, yroot] = getwinpos()
|
||||
call assert_inrange(xroot + 2, xroot + 1000, xpos)
|
||||
call assert_inrange(yroot + 2, yroot + 1000, ypos)
|
||||
|
||||
call term_wait(buf)
|
||||
call term_sendkeys(buf, ":q\<CR>")
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('XTest_getwinpos')
|
||||
exe buf . 'bwipe!'
|
||||
set splitright&
|
||||
only!
|
||||
endfunc
|
||||
|
21
src/ui.c
21
src/ui.c
@ -627,6 +627,27 @@ ui_new_shellsize(void)
|
||||
}
|
||||
}
|
||||
|
||||
#if (defined(FEAT_EVAL) \
|
||||
&& (defined(FEAT_GUI) \
|
||||
|| (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)))) \
|
||||
|| defined(PROTO)
|
||||
/*
|
||||
* Get the window position in pixels, if possible.
|
||||
* Return FAIL when not possible.
|
||||
*/
|
||||
int
|
||||
ui_get_winpos(int *x, int *y, varnumber_T timeout)
|
||||
{
|
||||
# ifdef FEAT_GUI
|
||||
if (gui.in_use)
|
||||
return gui_mch_get_winpos(x, y);
|
||||
# endif
|
||||
# if defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)
|
||||
return term_get_winpos(x, y, timeout);
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
ui_breakcheck(void)
|
||||
{
|
||||
|
@ -771,6 +771,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1125,
|
||||
/**/
|
||||
1124,
|
||||
/**/
|
||||
|
Loading…
x
Reference in New Issue
Block a user