Patch 8.0.1405
Problem:    Duplicated code for getting a typed character. CursorHold is
            called too often in the GUI. (lilydjwg)
Solution:   Refactor code to move code up from mch_inchar().  Don't fire
            CursorHold if feedkeys() was used. (closes #2451)
Files:      src/gui.c, src/proto/gui.pro, src/main.c, src/ui.c,
            src/proto/ui.pro, src/os_unix.c


*** ../vim-8.0.1404/src/gui.c   2017-12-17 21:54:51.240060608 +0100
--- src/gui.c   2017-12-18 18:09:53.489250690 +0100
***************
*** 2886,2891 ****
--- 2886,2903 ----
  }
  
  /*
+  * Passed to ui_wait_for_chars_or_timer(), ignoring extra arguments.
+  */
+     static int
+ gui_wait_for_chars_3(
+     long wtime,
+     int *interrupted UNUSED,
+     int ignore_input UNUSED)
+ {
+     return gui_mch_wait_for_chars(wtime);
+ }
+ 
+ /*
   * Returns OK if a character was found to be available within the given time,
   * or FAIL otherwise.
   */
***************
*** 2893,2924 ****
  gui_wait_for_chars_or_timer(long wtime)
  {
  #ifdef FEAT_TIMERS
!     int           due_time;
!     long    remaining = wtime;
!     int           tb_change_cnt = typebuf.tb_change_cnt;
! 
!     /* When waiting very briefly don't trigger timers. */
!     if (wtime >= 0 && wtime < 10L)
!       return gui_mch_wait_for_chars(wtime);
! 
!     while (wtime < 0 || remaining > 0)
!     {
!       /* Trigger timers and then get the time in wtime until the next one is
!        * due.  Wait up to that time. */
!       due_time = check_due_timer();
!       if (typebuf.tb_change_cnt != tb_change_cnt)
!       {
!           /* timer may have used feedkeys() */
!           return FAIL;
!       }
!       if (due_time <= 0 || (wtime > 0 && due_time > remaining))
!           due_time = remaining;
!       if (gui_mch_wait_for_chars(due_time))
!           return OK;
!       if (wtime > 0)
!           remaining -= due_time;
!     }
!     return FAIL;
  #else
      return gui_mch_wait_for_chars(wtime);
  #endif
--- 2905,2911 ----
  gui_wait_for_chars_or_timer(long wtime)
  {
  #ifdef FEAT_TIMERS
!     return ui_wait_for_chars_or_timer(wtime, gui_wait_for_chars_3, NULL, 0);
  #else
      return gui_mch_wait_for_chars(wtime);
  #endif
***************
*** 2933,2942 ****
   * or FAIL otherwise.
   */
      int
! gui_wait_for_chars(long wtime)
  {
      int           retval;
-     int           tb_change_cnt = typebuf.tb_change_cnt;
  
  #ifdef FEAT_MENU
      /*
--- 2920,2928 ----
   * or FAIL otherwise.
   */
      int
! gui_wait_for_chars(long wtime, int tb_change_cnt)
  {
      int           retval;
  
  #ifdef FEAT_MENU
      /*
***************
*** 2974,2986 ****
      retval = FAIL;
      /*
       * We may want to trigger the CursorHold event.  First wait for
!      * 'updatetime' and if nothing is typed within that time put the
!      * K_CURSORHOLD key in the input buffer.
       */
      if (gui_wait_for_chars_or_timer(p_ut) == OK)
        retval = OK;
  #ifdef FEAT_AUTOCMD
!     else if (trigger_cursorhold())
      {
        char_u  buf[3];
  
--- 2960,2972 ----
      retval = FAIL;
      /*
       * We may want to trigger the CursorHold event.  First wait for
!      * 'updatetime' and if nothing is typed within that time, and feedkeys()
!      * wasn't used, put the K_CURSORHOLD key in the input buffer.
       */
      if (gui_wait_for_chars_or_timer(p_ut) == OK)
        retval = OK;
  #ifdef FEAT_AUTOCMD
!     else if (trigger_cursorhold() && typebuf.tb_change_cnt == tb_change_cnt)
      {
        char_u  buf[3];
  
***************
*** 3006,3011 ****
--- 2992,3013 ----
  }
  
  /*
+  * Equivalent of mch_inchar() for the GUI.
+  */
+     int
+ gui_inchar(
+     char_u  *buf,
+     int           maxlen,
+     long    wtime,            /* milli seconds */
+     int           tb_change_cnt)
+ {
+     if (gui_wait_for_chars(wtime, tb_change_cnt)
+           && !typebuf_changed(tb_change_cnt))
+       return read_from_input_buf(buf, (long)maxlen);
+     return 0;
+ }
+ 
+ /*
   * Fill p[4] with mouse coordinates encoded for check_termcode().
   */
      static void
*** ../vim-8.0.1404/src/proto/gui.pro   2016-09-12 13:04:25.000000000 +0200
--- src/proto/gui.pro   2017-12-18 18:00:51.755846325 +0100
***************
*** 29,35 ****
  void gui_undraw_cursor(void);
  void gui_redraw(int x, int y, int w, int h);
  int gui_redraw_block(int row1, int col1, int row2, int col2, int flags);
! int gui_wait_for_chars(long wtime);
  void gui_send_mouse_event(int button, int x, int y, int repeated_click, int_u 
modifiers);
  int gui_xy2colrow(int x, int y, int *colp);
  void gui_menu_cb(vimmenu_T *menu);
--- 29,36 ----
  void gui_undraw_cursor(void);
  void gui_redraw(int x, int y, int w, int h);
  int gui_redraw_block(int row1, int col1, int row2, int col2, int flags);
! int gui_wait_for_chars(long wtime, int tb_change_cnt);
! int gui_inchar(char_u *buf, int maxlen, long wtime, int tb_change_cnt);
  void gui_send_mouse_event(int button, int x, int y, int repeated_click, int_u 
modifiers);
  int gui_xy2colrow(int x, int y, int *colp);
  void gui_menu_cb(vimmenu_T *menu);
*** ../vim-8.0.1404/src/main.c  2017-12-18 16:21:40.660711890 +0100
--- src/main.c  2017-12-18 16:46:22.563494123 +0100
***************
*** 619,625 ****
  # ifdef FEAT_SUN_WORKSHOP
        if (!usingSunWorkShop)
  # endif
!           gui_wait_for_chars(50L);
        TIME_MSG("GUI delay");
      }
  #endif
--- 619,625 ----
  # ifdef FEAT_SUN_WORKSHOP
        if (!usingSunWorkShop)
  # endif
!           gui_wait_for_chars(50L, typebuf.tb_change_cnt);
        TIME_MSG("GUI delay");
      }
  #endif
*** ../vim-8.0.1404/src/ui.c    2017-11-25 17:14:29.608189513 +0100
--- src/ui.c    2017-12-18 18:01:43.399614597 +0100
***************
*** 32,38 ****
      {
        gui_write(s, len);
        if (p_wd)
!           gui_wait_for_chars(p_wd);
        return;
      }
  #endif
--- 32,38 ----
      {
        gui_write(s, len);
        if (p_wd)
!           gui_wait_for_chars(p_wd, typebuf.tb_change_cnt);
        return;
      }
  #endif
***************
*** 182,199 ****
  
  #ifdef FEAT_GUI
      if (gui.in_use)
!     {
!       if (gui_wait_for_chars(wtime) && !typebuf_changed(tb_change_cnt))
!           retval = read_from_input_buf(buf, (long)maxlen);
!     }
  #endif
  #ifndef NO_CONSOLE
  # ifdef FEAT_GUI
      else
  # endif
-     {
        retval = mch_inchar(buf, maxlen, wtime, tb_change_cnt);
-     }
  #endif
  
      if (wtime == -1 || wtime > 100L)
--- 182,194 ----
  
  #ifdef FEAT_GUI
      if (gui.in_use)
!       retval = gui_inchar(buf, maxlen, wtime, tb_change_cnt);
  #endif
  #ifndef NO_CONSOLE
  # ifdef FEAT_GUI
      else
  # endif
        retval = mch_inchar(buf, maxlen, wtime, tb_change_cnt);
  #endif
  
      if (wtime == -1 || wtime > 100L)
***************
*** 212,217 ****
--- 207,258 ----
      return retval;
  }
  
+ #if defined(FEAT_TIMERS) || defined(PROT)
+ /*
+  * Wait for a timer to fire or "wait_func" to return non-zero.
+  * Returns OK when something was read.
+  * Returns FAIL when it timed out or was interrupted.
+  */
+     int
+ ui_wait_for_chars_or_timer(
+     long    wtime,
+     int           (*wait_func)(long wtime, int *interrupted, int 
ignore_input),
+     int           *interrupted,
+     int           ignore_input)
+ {
+     int           due_time;
+     long    remaining = wtime;
+     int           tb_change_cnt = typebuf.tb_change_cnt;
+ 
+     /* When waiting very briefly don't trigger timers. */
+     if (wtime >= 0 && wtime < 10L)
+       return wait_func(wtime, NULL, ignore_input);
+ 
+     while (wtime < 0 || remaining > 0)
+     {
+       /* Trigger timers and then get the time in wtime until the next one is
+        * due.  Wait up to that time. */
+       due_time = check_due_timer();
+       if (typebuf.tb_change_cnt != tb_change_cnt)
+       {
+           /* timer may have used feedkeys() */
+           return FAIL;
+       }
+       if (due_time <= 0 || (wtime > 0 && due_time > remaining))
+           due_time = remaining;
+       if (wait_func(due_time, interrupted, ignore_input))
+           return OK;
+       if (interrupted != NULL && *interrupted)
+           /* Nothing available, but need to return so that side effects get
+            * handled, such as handling a message on a channel. */
+           return FALSE;
+       if (wtime > 0)
+           remaining -= due_time;
+     }
+     return FAIL;
+ }
+ #endif
+ 
  /*
   * return non-zero if a character is available
   */
***************
*** 245,251 ****
  {
  #ifdef FEAT_GUI
      if (gui.in_use && !ignoreinput)
!       gui_wait_for_chars(msec);
      else
  #endif
        mch_delay(msec, ignoreinput);
--- 286,292 ----
  {
  #ifdef FEAT_GUI
      if (gui.in_use && !ignoreinput)
!       gui_wait_for_chars(msec, typebuf.tb_change_cnt);
      else
  #endif
        mch_delay(msec, ignoreinput);
*** ../vim-8.0.1404/src/proto/ui.pro    2017-08-12 19:51:37.815214191 +0200
--- src/proto/ui.pro    2017-12-18 18:00:26.931956053 +0100
***************
*** 2,7 ****
--- 2,8 ----
  void ui_write(char_u *s, int len);
  void ui_inchar_undo(char_u *s, int len);
  int ui_inchar(char_u *buf, int maxlen, long wtime, int tb_change_cnt);
+ int ui_wait_for_chars_or_timer(long wtime, int (*wait_func)(long wtime, int 
*interrupted, int ignore_input), int *interrupted, int ignore_input);
  int ui_char_avail(void);
  void ui_delay(long msec, int ignoreinput);
  void ui_suspend(void);
*** ../vim-8.0.1404/src/os_unix.c       2017-11-18 22:13:04.749908702 +0100
--- src/os_unix.c       2017-12-18 17:56:15.404992051 +0100
***************
*** 5790,5825 ****
  WaitForChar(long msec, int *interrupted, int ignore_input)
  {
  #ifdef FEAT_TIMERS
!     long    due_time;
!     long    remaining = msec;
!     int           tb_change_cnt = typebuf.tb_change_cnt;
! 
!     /* When waiting very briefly don't trigger timers. */
!     if (msec >= 0 && msec < 10L)
!       return WaitForCharOrMouse(msec, NULL, ignore_input);
! 
!     while (msec < 0 || remaining > 0)
!     {
!       /* Trigger timers and then get the time in msec until the next one is
!        * due.  Wait up to that time. */
!       due_time = check_due_timer();
!       if (typebuf.tb_change_cnt != tb_change_cnt)
!       {
!           /* timer may have used feedkeys() */
!           return FALSE;
!       }
!       if (due_time <= 0 || (msec > 0 && due_time > remaining))
!           due_time = remaining;
!       if (WaitForCharOrMouse(due_time, interrupted, ignore_input))
!           return TRUE;
!       if (interrupted != NULL && *interrupted)
!           /* Nothing available, but need to return so that side effects get
!            * handled, such as handling a message on a channel. */
!           return FALSE;
!       if (msec > 0)
!           remaining -= due_time;
!     }
!     return FALSE;
  #else
      return WaitForCharOrMouse(msec, interrupted, ignore_input);
  #endif
--- 5790,5797 ----
  WaitForChar(long msec, int *interrupted, int ignore_input)
  {
  #ifdef FEAT_TIMERS
!     return ui_wait_for_chars_or_timer(
!                   msec, WaitForCharOrMouse, interrupted, ignore_input) == OK;
  #else
      return WaitForCharOrMouse(msec, interrupted, ignore_input);
  #endif
*** ../vim-8.0.1404/src/version.c       2017-12-18 16:21:40.660711890 +0100
--- src/version.c       2017-12-18 18:13:20.268197562 +0100
***************
*** 773,774 ****
--- 773,776 ----
  {   /* Add new patch number below this line */
+ /**/
+     1405,
  /**/

-- 
Would you care for a drink?   I mean, if it were, like,
disabled and you had to look after it?

 /// Bram Moolenaar -- b...@moolenaar.net -- 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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui