Patch 8.0.1005
Problem:    Terminal without job updates slowly in GUI.
Solution:   Poll for input when a channel has the keep_open flag.
Files:      src/channel.c, src/proto/channel.pro, src/gui_gtk_x11.c


*** ../vim-8.0.1004/src/channel.c       2017-08-27 13:10:04.360022105 +0200
--- src/channel.c       2017-08-27 13:56:29.098603553 +0200
***************
*** 3555,3560 ****
--- 3555,3576 ----
  }
  # endif
  
+ # if defined(FEAT_GUI) || defined(PROTO)
+ /*
+  * Return TRUE when there is any channel with a keep_open flag.
+  */
+     int
+ channel_any_keep_open()
+ {
+     channel_T *channel;
+ 
+     for (channel = first_channel; channel != NULL; channel = channel->ch_next)
+       if (channel->ch_keep_open)
+           return TRUE;
+     return FALSE;
+ }
+ # endif
+ 
  /*
   * Set "channel"/"part" to non-blocking.
   * Only works for sockets and pipes.
*** ../vim-8.0.1004/src/proto/channel.pro       2017-08-26 22:02:45.869432874 
+0200
--- src/proto/channel.pro       2017-08-27 14:38:22.874521535 +0200
***************
*** 35,40 ****
--- 35,41 ----
  void common_channel_read(typval_T *argvars, typval_T *rettv, int raw);
  channel_T *channel_fd2channel(sock_T fd, ch_part_T *partp);
  void channel_handle_events(int only_keep_open);
+ int channel_any_keep_open(void);
  void channel_set_nonblock(channel_T *channel, ch_part_T part);
  int channel_send(channel_T *channel, ch_part_T part, char_u *buf_arg, int 
len_arg, char *fun);
  void ch_expr_common(typval_T *argvars, typval_T *rettv, int eval);
*** ../vim-8.0.1004/src/gui_gtk_x11.c   2017-08-26 22:02:45.869432874 +0200
--- src/gui_gtk_x11.c   2017-08-27 14:48:01.314799577 +0200
***************
*** 789,794 ****
--- 789,825 ----
  #endif /* defined(FEAT_CLIENTSERVER) */
  
  
+ #if GTK_CHECK_VERSION(3,0,0)
+ typedef gboolean timeout_cb_type;
+ #else
+ typedef gint timeout_cb_type;
+ #endif
+ 
+ /*
+  * Start a timer that will invoke the specified callback.
+  * Returns the ID of the timer.
+  */
+     static guint
+ timeout_add(int time, timeout_cb_type (*callback)(gpointer), int *flagp)
+ {
+ #if GTK_CHECK_VERSION(3,0,0)
+     return g_timeout_add((guint)time, (GSourceFunc)callback, flagp);
+ #else
+     return gtk_timeout_add((guint32)time, (GtkFunction)callback, flagp);
+ #endif
+ }
+ 
+     static void
+ timeout_remove(guint timer)
+ {
+ #if GTK_CHECK_VERSION(3,0,0)
+     g_source_remove(timer);
+ #else
+     gtk_timeout_remove(timer);
+ #endif
+ }
+ 
+ 
  /****************************************************************************
   * Focus handlers:
   */
***************
*** 866,876 ****
  {
      if (blink_timer)
      {
! #if GTK_CHECK_VERSION(3,0,0)
!       g_source_remove(blink_timer);
! #else
!       gtk_timeout_remove(blink_timer);
! #endif
        blink_timer = 0;
      }
      if (blink_state == BLINK_OFF)
--- 897,903 ----
  {
      if (blink_timer)
      {
!       timeout_remove(blink_timer);
        blink_timer = 0;
      }
      if (blink_state == BLINK_OFF)
***************
*** 881,916 ****
      blink_state = BLINK_NONE;
  }
  
! #if GTK_CHECK_VERSION(3,0,0)
!     static gboolean
! #else
!     static gint
! #endif
  blink_cb(gpointer data UNUSED)
  {
      if (blink_state == BLINK_ON)
      {
        gui_undraw_cursor();
        blink_state = BLINK_OFF;
! #if GTK_CHECK_VERSION(3,0,0)
!       blink_timer = g_timeout_add((guint)blink_offtime,
!                                  (GSourceFunc) blink_cb, NULL);
! #else
!       blink_timer = gtk_timeout_add((guint32)blink_offtime,
!                                  (GtkFunction) blink_cb, NULL);
! #endif
      }
      else
      {
        gui_update_cursor(TRUE, FALSE);
        blink_state = BLINK_ON;
! #if GTK_CHECK_VERSION(3,0,0)
!       blink_timer = g_timeout_add((guint)blink_ontime,
!                                  (GSourceFunc) blink_cb, NULL);
! #else
!       blink_timer = gtk_timeout_add((guint32)blink_ontime,
!                                  (GtkFunction) blink_cb, NULL);
! #endif
      }
      gui_mch_flush();
  
--- 908,927 ----
      blink_state = BLINK_NONE;
  }
  
!     static timeout_cb_type
  blink_cb(gpointer data UNUSED)
  {
      if (blink_state == BLINK_ON)
      {
        gui_undraw_cursor();
        blink_state = BLINK_OFF;
!       blink_timer = timeout_add(blink_offtime, blink_cb, NULL);
      }
      else
      {
        gui_update_cursor(TRUE, FALSE);
        blink_state = BLINK_ON;
!       blink_timer = timeout_add(blink_ontime, blink_cb, NULL);
      }
      gui_mch_flush();
  
***************
*** 926,948 ****
  {
      if (blink_timer)
      {
! #if GTK_CHECK_VERSION(3,0,0)
!       g_source_remove(blink_timer);
! #else
!       gtk_timeout_remove(blink_timer);
! #endif
        blink_timer = 0;
      }
      /* Only switch blinking on if none of the times is zero */
      if (blink_waittime && blink_ontime && blink_offtime && gui.in_focus)
      {
! #if GTK_CHECK_VERSION(3,0,0)
!       blink_timer = g_timeout_add((guint)blink_waittime,
!                                  (GSourceFunc) blink_cb, NULL);
! #else
!       blink_timer = gtk_timeout_add((guint32)blink_waittime,
!                                  (GtkFunction) blink_cb, NULL);
! #endif
        blink_state = BLINK_ON;
        gui_update_cursor(TRUE, FALSE);
        gui_mch_flush();
--- 937,949 ----
  {
      if (blink_timer)
      {
!       timeout_remove(blink_timer);
        blink_timer = 0;
      }
      /* Only switch blinking on if none of the times is zero */
      if (blink_waittime && blink_ontime && blink_offtime && gui.in_focus)
      {
!       blink_timer = timeout_add(blink_waittime, blink_cb, NULL);
        blink_state = BLINK_ON;
        gui_update_cursor(TRUE, FALSE);
        gui_mch_flush();
***************
*** 1733,1739 ****
      return OK;
  }
  
- 
  /****************************************************************************
   * Mouse handling callbacks
   */
--- 1734,1739 ----
***************
*** 1745,1755 ****
  /*
   * Timer used to recognize multiple clicks of the mouse button
   */
! #if GTK_CHECK_VERSION(3,0,0)
!     static gboolean
! #else
!     static gint
! #endif
  mouse_click_timer_cb(gpointer data)
  {
      /* we don't use this information currently */
--- 1745,1751 ----
  /*
   * Timer used to recognize multiple clicks of the mouse button
   */
!     static timeout_cb_type
  mouse_click_timer_cb(gpointer data)
  {
      /* we don't use this information currently */
***************
*** 1759,1771 ****
      return FALSE;             /* don't happen again */
  }
  
! static guint motion_repeat_timer  = 0;
! static int   motion_repeat_offset = FALSE;
! #ifdef GTK_DEST_DEFAULT_ALL
! static gboolean  motion_repeat_timer_cb(gpointer);
! #else
! static gint  motion_repeat_timer_cb(gpointer);
! #endif
  
      static void
  process_motion_notify(int x, int y, GdkModifierType state)
--- 1755,1763 ----
      return FALSE;             /* don't happen again */
  }
  
! static guint          motion_repeat_timer  = 0;
! static int            motion_repeat_offset = FALSE;
! static timeout_cb_type        motion_repeat_timer_cb(gpointer);
  
      static void
  process_motion_notify(int x, int y, GdkModifierType state)
***************
*** 1853,1865 ****
  
        /* shoot again */
        if (!motion_repeat_timer)
! #if GTK_CHECK_VERSION(3,0,0)
!           motion_repeat_timer = g_timeout_add((guint)delay,
!                                               motion_repeat_timer_cb, NULL);
! #else
!           motion_repeat_timer = gtk_timeout_add((guint32)delay,
!                                               motion_repeat_timer_cb, NULL);
! #endif
      }
  }
  
--- 1845,1852 ----
  
        /* shoot again */
        if (!motion_repeat_timer)
!           motion_repeat_timer = timeout_add(delay, motion_repeat_timer_cb,
!                                                                        NULL);
      }
  }
  
***************
*** 1904,1914 ****
  /*
   * Timer used to recognize multiple clicks of the mouse button.
   */
! #if GTK_CHECK_VERSION(3,0,0)
!     static gboolean
! #else
!     static gint
! #endif
  motion_repeat_timer_cb(gpointer data UNUSED)
  {
      int                   x;
--- 1891,1897 ----
  /*
   * Timer used to recognize multiple clicks of the mouse button.
   */
!     static timeout_cb_type
  motion_repeat_timer_cb(gpointer data UNUSED)
  {
      int                   x;
***************
*** 2019,2041 ****
      /* Handle multiple clicks */
      if (!mouse_timed_out && mouse_click_timer)
      {
! #if GTK_CHECK_VERSION(3,0,0)
!       g_source_remove(mouse_click_timer);
! #else
!       gtk_timeout_remove(mouse_click_timer);
! #endif
        mouse_click_timer = 0;
        repeated_click = TRUE;
      }
  
      mouse_timed_out = FALSE;
! #if GTK_CHECK_VERSION(3,0,0)
!     mouse_click_timer = g_timeout_add((guint)p_mouset,
!                                 mouse_click_timer_cb, &mouse_timed_out);
! #else
!     mouse_click_timer = gtk_timeout_add((guint32)p_mouset,
!                                 mouse_click_timer_cb, &mouse_timed_out);
! #endif
  
      switch (event->button)
      {
--- 2002,2015 ----
      /* Handle multiple clicks */
      if (!mouse_timed_out && mouse_click_timer)
      {
!       timeout_remove(mouse_click_timer);
        mouse_click_timer = 0;
        repeated_click = TRUE;
      }
  
      mouse_timed_out = FALSE;
!     mouse_click_timer = timeout_add(p_mouset, mouse_click_timer_cb,
!                                                            &mouse_timed_out);
  
      switch (event->button)
      {
***************
*** 2129,2139 ****
         area .*/
      if (motion_repeat_timer)
      {
! #if GTK_CHECK_VERSION(3,0,0)
!       g_source_remove(motion_repeat_timer);
! #else
!       gtk_timeout_remove(motion_repeat_timer);
! #endif
        motion_repeat_timer = 0;
      }
  
--- 2103,2109 ----
         area .*/
      if (motion_repeat_timer)
      {
!       timeout_remove(motion_repeat_timer);
        motion_repeat_timer = 0;
      }
  
***************
*** 4578,4584 ****
   * scrollbar init.), actually do the standard hints and stop the timer.
   * We'll not let the default hints be set while this timer's active.
   */
!     static gboolean
  check_startup_plug_hints(gpointer data UNUSED)
  {
      if (init_window_hints_state == 1)
--- 4548,4554 ----
   * scrollbar init.), actually do the standard hints and stop the timer.
   * We'll not let the default hints be set while this timer's active.
   */
!     static timeout_cb_type
  check_startup_plug_hints(gpointer data UNUSED)
  {
      if (init_window_hints_state == 1)
***************
*** 4681,4687 ****
        {
            update_window_manager_hints(pixel_width, pixel_height);
            init_window_hints_state = 1;
!           g_timeout_add(1000, check_startup_plug_hints, NULL);
        }
      }
  
--- 4651,4657 ----
        {
            update_window_manager_hints(pixel_width, pixel_height);
            init_window_hints_state = 1;
!           timeout_add(1000, check_startup_plug_hints, NULL);
        }
      }
  
***************
*** 6584,6594 ****
        g_main_context_iteration(NULL, TRUE);
  }
  
! #if GTK_CHECK_VERSION(3,0,0)
!     static gboolean
! #else
!     static gint
! #endif
  input_timer_cb(gpointer data)
  {
      int *timed_out = (int *) data;
--- 6554,6560 ----
        g_main_context_iteration(NULL, TRUE);
  }
  
!     static timeout_cb_type
  input_timer_cb(gpointer data)
  {
      int *timed_out = (int *) data;
***************
*** 6599,6604 ****
--- 6565,6583 ----
      return FALSE;             /* don't happen again */
  }
  
+ #ifdef FEAT_JOB_CHANNEL
+     static timeout_cb_type
+ channel_poll_cb(gpointer data UNUSED)
+ {
+     /* Using an event handler for a channel that may be disconnected does
+      * not work, it hangs.  Instead poll for messages. */
+     channel_handle_events(TRUE);
+     parse_queued_messages();
+ 
+     return TRUE;              /* repeat */
+ }
+ #endif
+ 
  /*
   * GUI input routine called by gui_wait_for_chars().  Waits for a character
   * from the keyboard.
***************
*** 6615,6634 ****
      guint     timer;
      static int        timed_out;
      int               retval = FAIL;
  
      timed_out = FALSE;
  
      /* this timeout makes sure that we will return if no characters arrived in
       * time */
      if (wtime > 0)
! #if GTK_CHECK_VERSION(3,0,0)
!       timer = g_timeout_add((guint)wtime, input_timer_cb, &timed_out);
! #else
!       timer = gtk_timeout_add((guint32)wtime, input_timer_cb, &timed_out);
! #endif
      else
        timer = 0;
  
      focus = gui.in_focus;
  
      do
--- 6594,6619 ----
      guint     timer;
      static int        timed_out;
      int               retval = FAIL;
+ #ifdef FEAT_JOB_CHANNEL
+     guint     channel_timer = 0;
+ #endif
  
      timed_out = FALSE;
  
      /* this timeout makes sure that we will return if no characters arrived in
       * time */
      if (wtime > 0)
!       timer = timeout_add(wtime, input_timer_cb, &timed_out);
      else
        timer = 0;
  
+ #ifdef FEAT_JOB_CHANNEL
+     /* If there is a channel with the keep_open flag we need to poll for input
+      * on them. */
+     if (channel_any_keep_open())
+       channel_timer = timeout_add(20, channel_poll_cb, NULL);
+ #endif
+ 
      focus = gui.in_focus;
  
      do
***************
*** 6643,6654 ****
            focus = gui.in_focus;
        }
  
- # if defined(FEAT_JOB_CHANNEL)
-       /* Using an event handler for a channel that may be disconnected does
-        * not work, it hangs.  Instead poll for messages. */
-       channel_handle_events(TRUE);
- # endif
- 
  #ifdef MESSAGE_QUEUE
  # ifdef FEAT_TIMERS
        did_add_timer = FALSE;
--- 6628,6633 ----
***************
*** 6684,6693 ****
  
  theend:
      if (timer != 0 && !timed_out)
! #if GTK_CHECK_VERSION(3,0,0)
!       g_source_remove(timer);
! #else
!       gtk_timeout_remove(timer);
  #endif
  
      return retval;
--- 6663,6672 ----
  
  theend:
      if (timer != 0 && !timed_out)
!       timeout_remove(timer);
! #ifdef FEAT_JOB_CHANNEL
!     if (channel_timer != 0)
!       timeout_remove(channel_timer);
  #endif
  
      return retval;
*** ../vim-8.0.1004/src/version.c       2017-08-27 13:50:58.088678687 +0200
--- src/version.c       2017-08-27 13:58:08.129983124 +0200
***************
*** 771,772 ****
--- 771,774 ----
  {   /* Add new patch number below this line */
+ /**/
+     1005,
  /**/

-- 
How To Keep A Healthy Level Of Insanity:
9. As often as possible, skip rather than walk.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui