Skip to content

Commit b13501f

Browse files
committed
patch 8.0.0753: no size reports to a job running in a terminal
Problem: A job running in a terminal does not get notified of changes in the terminal size. Solution: Use ioctl() and SIGWINCH to report the terminal size.
1 parent d7d3cbe commit b13501f

4 files changed

Lines changed: 74 additions & 7 deletions

File tree

src/os_unix.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3918,6 +3918,44 @@ mch_get_shellsize(void)
39183918
return OK;
39193919
}
39203920

3921+
#if defined(FEAT_TERMINAL) || defined(PROTO)
3922+
/*
3923+
* Report the windows size "rows" and "cols" to tty "fd".
3924+
*/
3925+
int
3926+
mch_report_winsize(int fd, int rows, int cols)
3927+
{
3928+
# ifdef TIOCSWINSZ
3929+
struct winsize ws;
3930+
3931+
ws.ws_col = cols;
3932+
ws.ws_row = rows;
3933+
ws.ws_xpixel = cols * 5;
3934+
ws.ws_ypixel = rows * 10;
3935+
if (ioctl(fd, TIOCSWINSZ, &ws) == 0)
3936+
{
3937+
ch_log(NULL, "ioctl(TIOCSWINSZ) success");
3938+
return OK;
3939+
}
3940+
ch_log(NULL, "ioctl(TIOCSWINSZ) failed");
3941+
# else
3942+
# ifdef TIOCSSIZE
3943+
struct ttysize ts;
3944+
3945+
ts.ts_cols = cols;
3946+
ts.ts_lines = rows;
3947+
if (ioctl(fd, TIOCSSIZE, &ws) == 0)
3948+
{
3949+
ch_log(NULL, "ioctl(TIOCSSIZE) success");
3950+
return OK;
3951+
}
3952+
ch_log(NULL, "ioctl(TIOCSSIZE) failed");
3953+
# endif
3954+
# endif
3955+
return FAIL;
3956+
}
3957+
#endif
3958+
39213959
/*
39223960
* Try to set the window size to Rows and Columns.
39233961
*/
@@ -5473,6 +5511,10 @@ mch_stop_job(job_T *job, char_u *how)
54735511
sig = SIGINT;
54745512
else if (STRCMP(how, "kill") == 0)
54755513
sig = SIGKILL;
5514+
#ifdef SIGWINCH
5515+
else if (STRCMP(how, "winch") == 0)
5516+
sig = SIGWINCH;
5517+
#endif
54765518
else if (isdigit(*how))
54775519
sig = atoi((char *)how);
54785520
else

src/proto/os_unix.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ void mch_setmouse(int on);
5353
void check_mouse_termcode(void);
5454
int mch_screenmode(char_u *arg);
5555
int mch_get_shellsize(void);
56+
int mch_report_winsize(int fd, int rows, int cols);
5657
void mch_set_shellsize(void);
5758
void mch_new_shellsize(void);
5859
int mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc);

src/terminal.c

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@
1212
*
1313
* There are three parts:
1414
* 1. Generic code for all systems.
15+
* Uses libvterm for the terminal emulator.
1516
* 2. The MS-Windows implementation.
16-
* Uses a hidden console for the terminal emulator.
17+
* Uses winpty.
1718
* 3. The Unix-like implementation.
18-
* Uses libvterm for the terminal emulator directly.
19+
* Uses pseudo-tty's (pty's).
1920
*
2021
* For each terminal one VTerm is constructed. This uses libvterm. A copy of
2122
* that library is in the libvterm directory.
@@ -32,8 +33,6 @@
3233
* while, if the terminal window is visible, the screen contents is drawn.
3334
*
3435
* TODO:
35-
* - When 'termsize' is set and dragging the separator the terminal gets messed
36-
* up.
3736
* - set buffer options to be scratch, hidden, nomodifiable, etc.
3837
* - set buffer name to command, add (1) to avoid duplicates.
3938
* - Add a scrollback buffer (contains lines to scroll off the top).
@@ -605,9 +604,32 @@ term_update_window(win_T *wp)
605604
*/
606605
if ((!term->tl_rows_fixed && term->tl_rows != wp->w_height)
607606
|| (!term->tl_cols_fixed && term->tl_cols != wp->w_width))
608-
vterm_set_size(vterm,
609-
term->tl_rows_fixed ? term->tl_rows : wp->w_height,
610-
term->tl_cols_fixed ? term->tl_cols : wp->w_width);
607+
{
608+
int rows = term->tl_rows_fixed ? term->tl_rows : wp->w_height;
609+
int cols = term->tl_cols_fixed ? term->tl_cols : wp->w_width;
610+
611+
vterm_set_size(vterm, rows, cols);
612+
ch_logn(term->tl_job->jv_channel, "Resizing terminal to %d lines",
613+
rows);
614+
615+
#if defined(UNIX)
616+
/* Use an ioctl() to report the new window size to the job. */
617+
if (term->tl_job != NULL && term->tl_job->jv_channel != NULL)
618+
{
619+
int fd = -1;
620+
int part;
621+
622+
for (part = PART_OUT; part < PART_COUNT; ++part)
623+
{
624+
fd = term->tl_job->jv_channel->ch_part[part].ch_fd;
625+
if (isatty(fd))
626+
break;
627+
}
628+
if (part < PART_COUNT && mch_report_winsize(fd, rows, cols) == OK)
629+
mch_stop_job(term->tl_job, (char_u *)"winch");
630+
}
631+
#endif
632+
}
611633

612634
/* The cursor may have been moved when resizing. */
613635
vterm_state_get_cursorpos(state, &pos);

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,8 @@ static char *(features[]) =
769769

770770
static int included_patches[] =
771771
{ /* Add new patch number below this line */
772+
/**/
773+
753,
772774
/**/
773775
752,
774776
/**/

0 commit comments

Comments
 (0)