]> granicus.if.org Git - vim/commitdiff
patch 8.0.0753: no size reports to a job running in a terminal v8.0.0753
authorBram Moolenaar <Bram@vim.org>
Sat, 22 Jul 2017 20:32:56 +0000 (22:32 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 22 Jul 2017 20:32:56 +0000 (22:32 +0200)
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.

src/os_unix.c
src/proto/os_unix.pro
src/terminal.c
src/version.c

index 4caf38bb40cb5dba46fa274c436a82d29ff12f6f..f2ab7b15e2ba7b7c43b8dc65751fa7aaa5213eaf 100644 (file)
@@ -3918,6 +3918,44 @@ mch_get_shellsize(void)
     return OK;
 }
 
+#if defined(FEAT_TERMINAL) || defined(PROTO)
+/*
+ * Report the windows size "rows" and "cols" to tty "fd".
+ */
+    int
+mch_report_winsize(int fd, int rows, int cols)
+{
+# ifdef TIOCSWINSZ
+    struct winsize     ws;
+
+    ws.ws_col = cols;
+    ws.ws_row = rows;
+    ws.ws_xpixel = cols * 5;
+    ws.ws_ypixel = rows * 10;
+    if (ioctl(fd, TIOCSWINSZ, &ws) == 0)
+    {
+       ch_log(NULL, "ioctl(TIOCSWINSZ) success");
+       return OK;
+    }
+    ch_log(NULL, "ioctl(TIOCSWINSZ) failed");
+# else
+#  ifdef TIOCSSIZE
+    struct ttysize     ts;
+
+    ts.ts_cols = cols;
+    ts.ts_lines = rows;
+    if (ioctl(fd, TIOCSSIZE, &ws) == 0)
+    {
+       ch_log(NULL, "ioctl(TIOCSSIZE) success");
+       return OK;
+    }
+    ch_log(NULL, "ioctl(TIOCSSIZE) failed");
+#  endif
+# endif
+    return FAIL;
+}
+#endif
+
 /*
  * Try to set the window size to Rows and Columns.
  */
@@ -5473,6 +5511,10 @@ mch_stop_job(job_T *job, char_u *how)
        sig = SIGINT;
     else if (STRCMP(how, "kill") == 0)
        sig = SIGKILL;
+#ifdef SIGWINCH
+    else if (STRCMP(how, "winch") == 0)
+       sig = SIGWINCH;
+#endif
     else if (isdigit(*how))
        sig = atoi((char *)how);
     else
index 11191c95b66f26e3e1addd8ae4ce962b3e62c9da..cfdf0ed0d78c709ce9aab1c59655ebf40a8ad7e8 100644 (file)
@@ -53,6 +53,7 @@ void mch_setmouse(int on);
 void check_mouse_termcode(void);
 int mch_screenmode(char_u *arg);
 int mch_get_shellsize(void);
+int mch_report_winsize(int fd, int rows, int cols);
 void mch_set_shellsize(void);
 void mch_new_shellsize(void);
 int mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc);
index 212b4000d14b259fb25ffd2dd6a2c92c58a60237..f3cb12428095d71bf950043d2be47f880e77c563 100644 (file)
  *
  * There are three parts:
  * 1. Generic code for all systems.
+ *    Uses libvterm for the terminal emulator.
  * 2. The MS-Windows implementation.
- *    Uses a hidden console for the terminal emulator.
+ *    Uses winpty.
  * 3. The Unix-like implementation.
- *    Uses libvterm for the terminal emulator directly.
+ *    Uses pseudo-tty's (pty's).
  *
  * For each terminal one VTerm is constructed.  This uses libvterm.  A copy of
  * that library is in the libvterm directory.
@@ -32,8 +33,6 @@
  * while, if the terminal window is visible, the screen contents is drawn.
  *
  * TODO:
- * - When 'termsize' is set and dragging the separator the terminal gets messed
- *   up.
  * - set buffer options to be scratch, hidden, nomodifiable, etc.
  * - set buffer name to command, add (1) to avoid duplicates.
  * - Add a scrollback buffer (contains lines to scroll off the top).
@@ -605,9 +604,32 @@ term_update_window(win_T *wp)
      */
     if ((!term->tl_rows_fixed && term->tl_rows != wp->w_height)
            || (!term->tl_cols_fixed && term->tl_cols != wp->w_width))
-       vterm_set_size(vterm,
-               term->tl_rows_fixed ? term->tl_rows : wp->w_height,
-               term->tl_cols_fixed ? term->tl_cols : wp->w_width);
+    {
+       int rows = term->tl_rows_fixed ? term->tl_rows : wp->w_height;
+       int cols = term->tl_cols_fixed ? term->tl_cols : wp->w_width;
+
+       vterm_set_size(vterm, rows, cols);
+       ch_logn(term->tl_job->jv_channel, "Resizing terminal to %d lines",
+                                                                        rows);
+
+#if defined(UNIX)
+       /* Use an ioctl() to report the new window size to the job. */
+       if (term->tl_job != NULL && term->tl_job->jv_channel != NULL)
+       {
+           int fd = -1;
+           int part;
+
+           for (part = PART_OUT; part < PART_COUNT; ++part)
+           {
+               fd = term->tl_job->jv_channel->ch_part[part].ch_fd;
+               if (isatty(fd))
+                   break;
+           }
+           if (part < PART_COUNT && mch_report_winsize(fd, rows, cols) == OK)
+               mch_stop_job(term->tl_job, (char_u *)"winch");
+       }
+#endif
+    }
 
     /* The cursor may have been moved when resizing. */
     vterm_state_get_cursorpos(state, &pos);
index 9ea3d819e2b63db9f812aae8cfc011175481bc43..724e7c3e911ec888486f2ebe3eced5d13921e0b4 100644 (file)
@@ -769,6 +769,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    753,
 /**/
     752,
 /**/