Patch 8.0.1449
Problem:    Slow redrawing with DirectX.
Solution:   Avoid calling gui_mch_flush() unnecessarily, especially when
            updating the cursor. (Ken Takata, closes #2560)
Files:      runtime/doc/options.txt, src/channel.c, src/edit.c, src/getchar.c,
            src/gui.c, src/gui_dwrite.cpp, src/gui_dwrite.h, src/gui_w32.c,
            src/macros.h, src/main.c, src/message.c, src/netbeans.c,
            src/proto/gui.pro, src/proto/term.pro, src/screen.c, src/search.c,
            src/term.c, src/ui.c


*** ../vim-8.0.1448/runtime/doc/options.txt     2017-12-05 13:22:08.414402079 
+0100
--- runtime/doc/options.txt     2018-01-31 20:43:44.619740451 +0100
***************
*** 6017,6023 ****
                  geom      pixelGeometry       int     0 - 2 (see below)
                  renmode   renderingMode       int     0 - 6 (see below)
                  taamode   textAntialiasMode   int     0 - 3 (see below)
!                 scrlines  Scroll Lines        int     >= 0  (see below)
  
                See this URL for detail (except for scrlines):
                  https://msdn.microsoft.com/en-us/library/dd368190.aspx
--- 6122,6128 ----
                  geom      pixelGeometry       int     0 - 2 (see below)
                  renmode   renderingMode       int     0 - 6 (see below)
                  taamode   textAntialiasMode   int     0 - 3 (see below)
!                 scrlines  Scroll Lines        int     (deprecated)
  
                See this URL for detail (except for scrlines):
                  https://msdn.microsoft.com/en-us/library/dd368190.aspx
***************
*** 6051,6073 ****
                See this URL for detail:
                  https://msdn.microsoft.com/en-us/library/dd368170.aspx
  
!               For scrlines: threshold for lines to be scrolled.
!                   0 - Always use scrolling. (default)
!                   1 - Use full page redrawing.
!                 > 1 - If the lines to be scrolled is grater or equal to the
!                       specified value, use redrawing.  Otherwise use
!                       scrolling.
! 
!               If you feel scrolling a page (CTRL-F) is too slow with DirectX
!               renderer, try this "scrlines" option.
!               When set it "1", Vim uses full page redrawing instead of
!               scrolling.  Redrawing a page is faster than scrolling a
!               page in some environments.
!               After that, when you feel scrolling lines (CTRL-Y) becomes
!               slow, please try "2" or greater value for this option.
!               It works threshold line number to switch scrolling to
!               redrawing.  Scrolling a few lines might be faster than
!               redrawing a page in some environments.
  
                Example: >
                  set encoding=utf-8
--- 6156,6164 ----
                See this URL for detail:
                  https://msdn.microsoft.com/en-us/library/dd368170.aspx
  
!               For scrlines:
!               This was used for optimizing scrolling behavior, however this
!               is now deprecated.  If specified, it is simply ignored.
  
                Example: >
                  set encoding=utf-8
*** ../vim-8.0.1448/src/channel.c       2017-12-09 19:13:08.579678220 +0100
--- src/channel.c       2018-01-31 20:43:44.619740451 +0100
***************
*** 2207,2220 ****
        ex_redraw(&ea);
        showruler(FALSE);
        setcursor();
!       out_flush();
! #ifdef FEAT_GUI
!       if (gui.in_use)
!       {
!           gui_update_cursor(TRUE, FALSE);
!           gui_mch_flush();
!       }
! #endif
      }
      else if (STRCMP(cmd, "expr") == 0 || STRCMP(cmd, "call") == 0)
      {
--- 2207,2213 ----
        ex_redraw(&ea);
        showruler(FALSE);
        setcursor();
!       out_flush_cursor(TRUE, FALSE);
      }
      else if (STRCMP(cmd, "expr") == 0 || STRCMP(cmd, "call") == 0)
      {
*** ../vim-8.0.1448/src/edit.c  2017-11-28 20:47:36.782817313 +0100
--- src/edit.c  2018-01-31 20:43:44.623740392 +0100
***************
*** 3451,3457 ****
      compl_orig_text = NULL;
      compl_enter_selects = FALSE;
      /* clear v:completed_item */
!     set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
  }
  
  /*
--- 3451,3457 ----
      compl_orig_text = NULL;
      compl_enter_selects = FALSE;
      /* clear v:completed_item */
!     set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc_lock(VAR_FIXED));
  }
  
  /*
***************
*** 3553,3560 ****
        {
            /* Show the cursor after the match, not after the redrawn text. */
            setcursor();
!           out_flush();
!           gui_update_cursor(FALSE, FALSE);
        }
  #endif
        compl_restarting = TRUE;
--- 3553,3559 ----
        {
            /* Show the cursor after the match, not after the redrawn text. */
            setcursor();
!           out_flush_cursor(FALSE, FALSE);
        }
  #endif
        compl_restarting = TRUE;
***************
*** 4704,4710 ****
       * flicker, thus we can't do that. */
      changed_cline_bef_curs();
      /* clear v:completed_item */
!     set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
  }
  
  /*
--- 4703,4709 ----
       * flicker, thus we can't do that. */
      changed_cline_bef_curs();
      /* clear v:completed_item */
!     set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc_lock(VAR_FIXED));
  }
  
  /*
***************
*** 4724,4730 ****
  
      /* Set completed item. */
      /* { word, abbr, menu, kind, info } */
!     dict = dict_alloc();
      if (dict != NULL)
      {
        dict_add_nr_str(dict, "word", 0L,
--- 4723,4729 ----
  
      /* Set completed item. */
      /* { word, abbr, menu, kind, info } */
!     dict = dict_alloc_lock(VAR_FIXED);
      if (dict != NULL)
      {
        dict_add_nr_str(dict, "word", 0L,
***************
*** 4936,4943 ****
        {
            /* Show the cursor after the match, not after the redrawn text. */
            setcursor();
!           out_flush();
!           gui_update_cursor(FALSE, FALSE);
        }
  #endif
  
--- 4935,4941 ----
        {
            /* Show the cursor after the match, not after the redrawn text. */
            setcursor();
!           out_flush_cursor(FALSE, FALSE);
        }
  #endif
  
*** ../vim-8.0.1448/src/getchar.c       2017-11-25 17:14:29.600189562 +0100
--- src/getchar.c       2018-01-31 20:43:44.623740392 +0100
***************
*** 2972,2987 ****
      if (wait_time == -1L || wait_time > 100L)  /* flush output before waiting 
*/
      {
        cursor_on();
!       out_flush();
! #ifdef FEAT_GUI
!       if (gui.in_use)
!       {
!           gui_update_cursor(FALSE, FALSE);
! # ifdef FEAT_MOUSESHAPE
!           if (postponed_mouseshape)
!               update_mouseshape(-1);
! # endif
!       }
  #endif
      }
  
--- 2972,2981 ----
      if (wait_time == -1L || wait_time > 100L)  /* flush output before waiting 
*/
      {
        cursor_on();
!       out_flush_cursor(FALSE, FALSE);
! #if defined(FEAT_GUI) && defined(FEAT_MOUSESHAPE)
!       if (gui.in_use && postponed_mouseshape)
!           update_mouseshape(-1);
  #endif
      }
  
*** ../vim-8.0.1448/src/gui.c   2017-12-19 19:42:37.385969952 +0100
--- src/gui.c   2018-01-31 20:43:44.623740392 +0100
***************
*** 55,60 ****
--- 55,61 ----
  static void gui_attempt_start(void);
  
  static int can_update_cursor = TRUE; /* can display the cursor */
+ static int disable_flush = 0; /* If > 0, gui_mch_flush() is disabled. */
  
  /*
   * The Athena scrollbars can move the thumb to after the end of the scrollbar,
***************
*** 1976,1982 ****
      gui.dragged_sb = SBAR_NONE;
  #endif
  
!     gui_mch_flush();              /* In case vim decides to take a nap */
  }
  
  /*
--- 1977,1983 ----
      gui.dragged_sb = SBAR_NONE;
  #endif
  
!     gui_may_flush();              /* In case vim decides to take a nap */
  }
  
  /*
***************
*** 2004,2009 ****
--- 2005,2038 ----
       * after scrolling. */
  }
  
+ /*
+  * Disable issuing gui_mch_flush().
+  */
+     void
+ gui_disable_flush(void)
+ {
+     ++disable_flush;
+ }
+ 
+ /*
+  * Enable issuing gui_mch_flush().
+  */
+     void
+ gui_enable_flush(void)
+ {
+     --disable_flush;
+ }
+ 
+ /*
+  * Issue gui_mch_flush() if it is not disabled.
+  */
+     void
+ gui_may_flush(void)
+ {
+     if (disable_flush == 0)
+       gui_mch_flush();
+ }
+ 
      static void
  gui_outstr(char_u *s, int len)
  {
***************
*** 3682,3688 ****
        /* Updating the tabline uses direct GUI commands, flush
         * outstanding instructions first. (esp. clear screen) */
        out_flush();
-       gui_mch_flush();
  
        if (!showit != !shown)
            gui_mch_show_tabline(showit);
--- 3711,3716 ----
***************
*** 4122,4129 ****
        setcursor();
      }
  # endif
!     out_flush();
!     gui_update_cursor(FALSE, TRUE);
  #else
      add_to_input_buf(bytes, byte_count);
      add_long_to_buf((long_u)value, bytes);
--- 4150,4156 ----
        setcursor();
      }
  # endif
!     out_flush_cursor(FALSE, TRUE);
  #else
      add_to_input_buf(bytes, byte_count);
      add_long_to_buf((long_u)value, bytes);
***************
*** 4486,4492 ****
--- 4513,4521 ----
         * disappear when losing focus after a scrollbar drag. */
        if (wp->w_redr_type < type)
            wp->w_redr_type = type;
+       mch_disable_flush();
        updateWindow(wp);   /* update window, status line, and cmdline */
+       mch_enable_flush();
      }
  
  #ifdef FEAT_INS_EXPAND
***************
*** 4797,4804 ****
   */
  #if 1
      gui.in_focus = in_focus;
!     out_flush();              /* make sure output has been written */
!     gui_update_cursor(TRUE, FALSE);
  
  # ifdef FEAT_XIM
      xim_set_focus(in_focus);
--- 4826,4832 ----
   */
  #if 1
      gui.in_focus = in_focus;
!     out_flush_cursor(TRUE, FALSE);
  
  # ifdef FEAT_XIM
      xim_set_focus(in_focus);
***************
*** 5157,5165 ****
        curwin->w_valid &= ~VALID_CROW;
      }
  # endif
!     out_flush();              /* make sure output has been written */
!     gui_update_cursor(TRUE, FALSE);
!     gui_mch_flush();
  }
  #endif
  
--- 5185,5191 ----
        curwin->w_valid &= ~VALID_CROW;
      }
  # endif
!     out_flush_cursor(TRUE, FALSE);
  }
  #endif
  
***************
*** 5516,5524 ****
        maketitle();
  #endif
        setcursor();
!       out_flush();
!       gui_update_cursor(FALSE, FALSE);
!       gui_mch_flush();
      }
  
      entered = FALSE;
--- 5542,5548 ----
        maketitle();
  #endif
        setcursor();
!       out_flush_cursor(FALSE, FALSE);
      }
  
      entered = FALSE;
*** ../vim-8.0.1448/src/gui_dwrite.cpp  2017-12-14 13:15:12.722867837 +0100
--- src/gui_dwrite.cpp  2018-01-31 20:43:44.623740392 +0100
***************
*** 286,291 ****
--- 286,292 ----
      ID2D1DCRenderTarget *mRT;
      ID2D1GdiInteropRenderTarget *mGDIRT;
      ID2D1SolidColorBrush *mBrush;
+     ID2D1Bitmap *mBitmap;
  
      IDWriteFactory *mDWriteFactory;
  #ifdef FEAT_DIRECTX_COLOR_EMOJI
***************
*** 319,324 ****
--- 320,327 ----
  
      void SetFont(HFONT hFont);
  
+     void Rebind();
+ 
      void BindDC(HDC hdc, const RECT *rect);
  
      HRESULT SetDrawingMode(DrawingMode mode);
***************
*** 335,340 ****
--- 338,345 ----
  
      void SetPixel(int x, int y, COLORREF color);
  
+     void Scroll(int x, int y, const RECT *rc);
+ 
      void Flush();
  
      void SetRenderingParams(
***************
*** 596,601 ****
--- 601,607 ----
      mRT(NULL),
      mGDIRT(NULL),
      mBrush(NULL),
+     mBitmap(NULL),
      mDWriteFactory(NULL),
  #ifdef FEAT_DIRECTX_COLOR_EMOJI
      mDWriteFactory2(NULL),
***************
*** 616,624 ****
      _RPT2(_CRT_WARN, "D2D1CreateFactory: hr=%p p=%p\n", hr, mD2D1Factory);
  
      if (SUCCEEDED(hr))
-       hr = CreateDeviceResources();
- 
-     if (SUCCEEDED(hr))
      {
        hr = DWriteCreateFactory(
                DWRITE_FACTORY_TYPE_SHARED,
--- 622,627 ----
***************
*** 662,667 ****
--- 665,671 ----
  #ifdef FEAT_DIRECTX_COLOR_EMOJI
      SafeRelease(&mDWriteFactory2);
  #endif
+     SafeRelease(&mBitmap);
      SafeRelease(&mBrush);
      SafeRelease(&mGDIRT);
      SafeRelease(&mRT);
***************
*** 704,716 ****
      }
  
      if (SUCCEEDED(hr))
!     {
!       if (mHDC != NULL)
!       {
!           mRT->BindDC(mHDC, &mBindRect);
!           mRT->SetTransform(D2D1::IdentityMatrix());
!       }
!     }
  
      return hr;
  }
--- 708,714 ----
      }
  
      if (SUCCEEDED(hr))
!       Rebind();
  
      return hr;
  }
***************
*** 718,723 ****
--- 716,722 ----
      void
  DWriteContext::DiscardDeviceResources()
  {
+     SafeRelease(&mBitmap);
      SafeRelease(&mBrush);
      SafeRelease(&mGDIRT);
      SafeRelease(&mRT);
***************
*** 899,911 ****
  }
  
      void
! DWriteContext::BindDC(HDC hdc, const RECT *rect)
  {
!     Flush();
!     mRT->BindDC(hdc, rect);
      mRT->SetTransform(D2D1::IdentityMatrix());
      mHDC = hdc;
      mBindRect = *rect;
  }
  
      HRESULT
--- 898,933 ----
  }
  
      void
! DWriteContext::Rebind()
  {
!     SafeRelease(&mBitmap);
! 
!     mRT->BindDC(mHDC, &mBindRect);
      mRT->SetTransform(D2D1::IdentityMatrix());
+ 
+     D2D1_BITMAP_PROPERTIES props = {
+       {DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE},
+       96.0f, 96.0f
+     };
+     mRT->CreateBitmap(
+           D2D1::SizeU(mBindRect.right - mBindRect.left,
+               mBindRect.bottom - mBindRect.top),
+           props, &mBitmap);
+ }
+ 
+     void
+ DWriteContext::BindDC(HDC hdc, const RECT *rect)
+ {
      mHDC = hdc;
      mBindRect = *rect;
+ 
+     if (mRT == NULL)
+       CreateDeviceResources();
+     else
+     {
+       Flush();
+       Rebind();
+     }
  }
  
      HRESULT
***************
*** 1081,1086 ****
--- 1103,1151 ----
  }
  
      void
+ DWriteContext::Scroll(int x, int y, const RECT *rc)
+ {
+     SetDrawingMode(DM_DIRECTX);
+     mRT->Flush();
+ 
+     D2D1_RECT_U srcRect;
+     D2D1_POINT_2U destPoint;
+     if (x >= 0)
+     {
+       srcRect.left = rc->left;
+       srcRect.right = rc->right - x;
+       destPoint.x = rc->left + x;
+     }
+     else
+     {
+       srcRect.left = rc->left - x;
+       srcRect.right = rc->right;
+       destPoint.x = rc->left;
+     }
+     if (y >= 0)
+     {
+       srcRect.top = rc->top;
+       srcRect.bottom = rc->bottom - y;
+       destPoint.y = rc->top + y;
+     }
+     else
+     {
+       srcRect.top = rc->top - y;
+       srcRect.bottom = rc->bottom;
+       destPoint.y = rc->top;
+     }
+     mBitmap->CopyFromRenderTarget(&destPoint, mRT, &srcRect);
+ 
+     D2D1_RECT_F destRect = {
+           FLOAT(destPoint.x), FLOAT(destPoint.y),
+           FLOAT(destPoint.x + srcRect.right - srcRect.left),
+           FLOAT(destPoint.y + srcRect.bottom - srcRect.top)
+     };
+     mRT->DrawBitmap(mBitmap, destRect, 1.0F,
+           D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, destRect);
+ }
+ 
+     void
  DWriteContext::Flush()
  {
      SetDrawingMode(DM_GDI);
***************
*** 1240,1245 ****
--- 1305,1317 ----
  }
  
      void
+ DWriteContext_Scroll(DWriteContext *ctx, int x, int y, const RECT *rc)
+ {
+     if (ctx != NULL)
+       ctx->Scroll(x, y, rc);
+ }
+ 
+     void
  DWriteContext_Flush(DWriteContext *ctx)
  {
      if (ctx != NULL)
*** ../vim-8.0.1448/src/gui_dwrite.h    2017-12-05 13:22:08.414402079 +0100
--- src/gui_dwrite.h    2018-01-31 20:43:44.623740392 +0100
***************
*** 74,79 ****
--- 74,80 ----
  void DWriteContext_DrawLine(DWriteContext *ctx, int x1, int y1, int x2, int 
y2,
        COLORREF color);
  void DWriteContext_SetPixel(DWriteContext *ctx, int x, int y, COLORREF color);
+ void DWriteContext_Scroll(DWriteContext *ctx, int x, int y, const RECT *rc);
  void DWriteContext_Flush(DWriteContext *ctx);
  void DWriteContext_Close(DWriteContext *ctx);
  
*** ../vim-8.0.1448/src/gui_w32.c       2017-12-14 13:15:12.722867837 +0100
--- src/gui_w32.c       2018-01-31 20:43:44.627740333 +0100
***************
*** 36,42 ****
  static DWriteContext *s_dwc = NULL;
  static int s_directx_enabled = 0;
  static int s_directx_load_attempted = 0;
- static int s_directx_scrlines = 0;
  # define IS_ENABLE_DIRECTX() (s_directx_enabled && s_dwc != NULL && enc_utf8)
  static int directx_enabled(void);
  static void directx_binddc(void);
--- 36,41 ----
***************
*** 61,67 ****
      int           dx_geom = 0;
      int           dx_renmode = 0;
      int           dx_taamode = 0;
-     int           dx_scrlines = 0;
  
      /* parse string as rendering options. */
      for (p = s; p != NULL && *p != NUL; )
--- 60,65 ----
***************
*** 124,130 ****
        }
        else if (STRCMP(name, "scrlines") == 0)
        {
!           dx_scrlines = atoi((char *)value);
        }
        else
            return FAIL;
--- 122,128 ----
        }
        else if (STRCMP(name, "scrlines") == 0)
        {
!           /* Deprecated.  Simply ignore it. */
        }
        else
            return FAIL;
***************
*** 159,165 ****
        }
      }
      s_directx_enabled = dx_enable;
-     s_directx_scrlines = dx_scrlines;
  
      return OK;
  # else
--- 157,162 ----
***************
*** 3129,3137 ****
      int           num_lines)
  {
      RECT      rc;
- #if defined(FEAT_DIRECTX)
-     int               use_redraw = 0;
- #endif
  
      rc.left = FILL_X(gui.scroll_region_left);
      rc.right = FILL_X(gui.scroll_region_right + 1);
--- 3126,3131 ----
***************
*** 3141,3156 ****
  #if defined(FEAT_DIRECTX)
      if (IS_ENABLE_DIRECTX())
      {
!       if (s_directx_scrlines > 0 && s_directx_scrlines <= num_lines)
!       {
!           gui_redraw(rc.left, rc.top,
!                   rc.right - rc.left + 1, rc.bottom - rc.top + 1);
!           use_redraw = 1;
!       }
!       else
!           DWriteContext_Flush(s_dwc);
      }
!     if (!use_redraw)
  #endif
      {
        intel_gpu_workaround();
--- 3135,3144 ----
  #if defined(FEAT_DIRECTX)
      if (IS_ENABLE_DIRECTX())
      {
!       DWriteContext_Scroll(s_dwc, 0, -num_lines * gui.char_height, &rc);
!       DWriteContext_Flush(s_dwc);
      }
!     else
  #endif
      {
        intel_gpu_workaround();
***************
*** 3180,3188 ****
      int               num_lines)
  {
      RECT      rc;
- #if defined(FEAT_DIRECTX)
-     int               use_redraw = 0;
- #endif
  
      rc.left = FILL_X(gui.scroll_region_left);
      rc.right = FILL_X(gui.scroll_region_right + 1);
--- 3168,3173 ----
***************
*** 3192,3207 ****
  #if defined(FEAT_DIRECTX)
      if (IS_ENABLE_DIRECTX())
      {
!       if (s_directx_scrlines > 0 && s_directx_scrlines <= num_lines)
!       {
!           gui_redraw(rc.left, rc.top,
!                   rc.right - rc.left + 1, rc.bottom - rc.top + 1);
!           use_redraw = 1;
!       }
!       else
!           DWriteContext_Flush(s_dwc);
      }
!     if (!use_redraw)
  #endif
      {
        intel_gpu_workaround();
--- 3177,3186 ----
  #if defined(FEAT_DIRECTX)
      if (IS_ENABLE_DIRECTX())
      {
!       DWriteContext_Scroll(s_dwc, 0, num_lines * gui.char_height, &rc);
!       DWriteContext_Flush(s_dwc);
      }
!     else
  #endif
      {
        intel_gpu_workaround();
***************
*** 4024,4030 ****
--- 4003,4012 ----
       * position, but don't actually scroll by setting "dont_scroll". */
      dont_scroll = !allow_scrollbar;
  
+     mch_disable_flush();
      gui_drag_scrollbar(sb, val, dragging);
+     mch_enable_flush();
+     gui_may_flush();
  
      s_busy_processing = FALSE;
      dont_scroll = dont_scroll_save;
***************
*** 4651,4656 ****
--- 4633,4639 ----
      if (mouse_scroll_lines == 0)
        init_mouse_wheel();
  
+     mch_disable_flush();
      if (mouse_scroll_lines > 0
            && mouse_scroll_lines < (size > 2 ? size - 2 : 1))
      {
***************
*** 4659,4664 ****
--- 4642,4649 ----
      }
      else
        _OnScroll(hwnd, hwndCtl, zDelta >= 0 ? SB_PAGEUP : SB_PAGEDOWN, 0);
+     mch_enable_flush();
+     gui_may_flush();
  }
  
  #ifdef USE_SYSMENU_FONT
*** ../vim-8.0.1448/src/macros.h        2017-10-28 21:08:38.983456981 +0200
--- src/macros.h        2018-01-31 20:43:44.627740333 +0100
***************
*** 365,370 ****
   * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer.
   * HI2DI() converts a hashitem pointer to a dictitem pointer.
   */
! # define DI2HIKEY(di) ((di)->di_key)
! # define HIKEY2DI(p)  ((dictitem_T *)(p - offsetof(dictitem_T, di_key)))
! # define HI2DI(hi)     HIKEY2DI((hi)->hi_key)
--- 365,381 ----
   * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer.
   * HI2DI() converts a hashitem pointer to a dictitem pointer.
   */
! #define DI2HIKEY(di) ((di)->di_key)
! #define HIKEY2DI(p)  ((dictitem_T *)(p - offsetof(dictitem_T, di_key)))
! #define HI2DI(hi)     HIKEY2DI((hi)->hi_key)
! 
! /*
!  * Flush control functions.
!  */
! #ifdef FEAT_GUI
! # define mch_enable_flush()   gui_enable_flush()
! # define mch_disable_flush()  gui_disable_flush()
! #else
! # define mch_enable_flush()
! # define mch_disable_flush()
! #endif
*** ../vim-8.0.1448/src/main.c  2017-12-18 18:14:43.455768463 +0100
--- src/main.c  2018-01-31 20:43:44.627740333 +0100
***************
*** 1242,1248 ****
--- 1242,1252 ----
            if (VIsual_active)
                update_curbuf(INVERTED);/* update inverted part */
            else if (must_redraw)
+           {
+               mch_disable_flush();    /* Stop issuing gui_mch_flush(). */
                update_screen(0);
+               mch_enable_flush();
+           }
            else if (redraw_cmdline || clear_cmdline)
                showmode();
            redraw_statuslines();
***************
*** 1283,1293 ****
--- 1287,1299 ----
                        || conceal_cursor_line(curwin)
                        || need_cursor_line_redraw))
            {
+               mch_disable_flush();    /* Stop issuing gui_mch_flush(). */
                if (conceal_old_cursor_line != conceal_new_cursor_line
                        && conceal_old_cursor_line
                                                <= curbuf->b_ml.ml_line_count)
                    update_single_line(curwin, conceal_old_cursor_line);
                update_single_line(curwin, conceal_new_cursor_line);
+               mch_enable_flush();
                curwin->w_valid &= ~VALID_CROW;
            }
  # endif
***************
*** 4212,4222 ****
      /* A client can tell us to redraw, but not to display the cursor, so do
       * that here. */
      setcursor();
!     out_flush();
! #ifdef FEAT_GUI
!     if (gui.in_use)
!       gui_update_cursor(FALSE, FALSE);
! #endif
  
      return res;
  }
--- 4218,4224 ----
      /* A client can tell us to redraw, but not to display the cursor, so do
       * that here. */
      setcursor();
!     out_flush_cursor(FALSE, FALSE);
  
      return res;
  }
*** ../vim-8.0.1448/src/message.c       2017-11-18 18:51:08.121770760 +0100
--- src/message.c       2018-01-31 20:43:44.627740333 +0100
***************
*** 2316,2322 ****
--- 2316,2324 ----
        gui_undraw_cursor();
  #endif
      /* scrolling up always works */
+     mch_disable_flush();
      screen_del_lines(0, 0, 1, (int)Rows, TRUE, 0, NULL);
+     mch_enable_flush();
  
      if (!can_clear((char_u *)" "))
      {
*** ../vim-8.0.1448/src/netbeans.c      2017-11-18 22:13:04.745908763 +0100
--- src/netbeans.c      2018-01-31 20:43:44.631740274 +0100
***************
*** 121,134 ****
      update_screen(CLEAR);
      setcursor();
      cursor_on();
!     out_flush();
! #ifdef FEAT_GUI
!     if (gui.in_use)
!     {
!       gui_update_cursor(TRUE, FALSE);
!       gui_mch_flush();
!     }
! #endif
  }
  
  #define NB_DEF_HOST "localhost"
--- 121,127 ----
      update_screen(CLEAR);
      setcursor();
      cursor_on();
!     out_flush_cursor(TRUE, FALSE);
  }
  
  #define NB_DEF_HOST "localhost"
***************
*** 1848,1861 ****
            update_screen(VALID);
            setcursor();
            cursor_on();
!           out_flush();
! #ifdef FEAT_GUI
!           if (gui.in_use)
!           {
!               gui_update_cursor(TRUE, FALSE);
!               gui_mch_flush();
!           }
! #endif
            /* Quit a hit-return or more prompt. */
            if (State == HITRETURN || State == ASKMORE)
            {
--- 1841,1848 ----
            update_screen(VALID);
            setcursor();
            cursor_on();
!           out_flush_cursor(TRUE, FALSE);
! 
            /* Quit a hit-return or more prompt. */
            if (State == HITRETURN || State == ASKMORE)
            {
***************
*** 2248,2261 ****
        update_screen(NOT_VALID);
        setcursor();
        cursor_on();
!       out_flush();
! #ifdef FEAT_GUI
!       if (gui.in_use)
!       {
!           gui_update_cursor(TRUE, FALSE);
!           gui_mch_flush();
!       }
! #endif
        /* Quit a hit-return or more prompt. */
        if (State == HITRETURN || State == ASKMORE)
        {
--- 2235,2242 ----
        update_screen(NOT_VALID);
        setcursor();
        cursor_on();
!       out_flush_cursor(TRUE, FALSE);
! 
        /* Quit a hit-return or more prompt. */
        if (State == HITRETURN || State == ASKMORE)
        {
***************
*** 2307,2321 ****
  /*     ALT_INPUT_LOCK_OFF; */
  
      setcursor();              /* restore the cursor position */
!     out_flush();              /* make sure output has been written */
! 
! #ifdef FEAT_GUI
!     if (gui.in_use)
!     {
!       gui_update_cursor(TRUE, FALSE);
!       gui_mch_flush();
!     }
! #endif
  }
  
  
--- 2288,2294 ----
  /*     ALT_INPUT_LOCK_OFF; */
  
      setcursor();              /* restore the cursor position */
!     out_flush_cursor(TRUE, FALSE);
  }
  
  
***************
*** 2569,2582 ****
      update_screen(CLEAR);
      setcursor();
      cursor_on();
!     out_flush();
! #ifdef FEAT_GUI
!     if (gui.in_use)
!     {
!       gui_update_cursor(TRUE, FALSE);
!       gui_mch_flush();
!     }
! #endif
  }
  
  /*
--- 2542,2548 ----
      update_screen(CLEAR);
      setcursor();
      cursor_on();
!     out_flush_cursor(TRUE, FALSE);
  }
  
  /*
*** ../vim-8.0.1448/src/proto/gui.pro   2017-12-18 18:14:43.451768484 +0100
--- src/proto/gui.pro   2018-01-31 20:43:44.631740274 +0100
***************
*** 25,30 ****
--- 25,33 ----
  void gui_write(char_u *s, int len);
  void gui_dont_update_cursor(int undraw);
  void gui_can_update_cursor(void);
+ void gui_disable_flush(void);
+ void gui_enable_flush(void);
+ void gui_may_flush(void);
  int gui_outstr_nowrap(char_u *s, int len, int flags, guicolor_T fg, 
guicolor_T bg, int back);
  void gui_undraw_cursor(void);
  void gui_redraw(int x, int y, int w, int h);
*** ../vim-8.0.1448/src/proto/term.pro  2017-10-15 21:44:40.357078773 +0200
--- src/proto/term.pro  2018-01-31 20:43:44.631740274 +0100
***************
*** 12,17 ****
--- 12,18 ----
  char_u *tltoa(unsigned long i);
  void termcapinit(char_u *name);
  void out_flush(void);
+ void out_flush_cursor(int force, int clear_selection);
  void out_flush_check(void);
  void out_trash(void);
  void out_char(unsigned c);
*** ../vim-8.0.1448/src/screen.c        2017-12-22 21:12:28.415253582 +0100
--- src/screen.c        2018-01-31 20:43:44.631740274 +0100
***************
*** 468,483 ****
        setcursor();
      }
      cursor_on();
-     out_flush();
  #ifdef FEAT_GUI
!     if (gui.in_use)
!     {
        /* Don't update the cursor when it is blinking and off to avoid
         * flicker. */
!       if (!gui_mch_is_blink_off())
!           gui_update_cursor(FALSE, FALSE);
!       gui_mch_flush();
!     }
  #endif
  
      --redrawing_for_callback;
--- 468,481 ----
        setcursor();
      }
      cursor_on();
  #ifdef FEAT_GUI
!     if (gui.in_use && !gui_mch_is_blink_off())
        /* Don't update the cursor when it is blinking and off to avoid
         * flicker. */
!       out_flush_cursor(FALSE, FALSE);
!     else
! #else
!       out_flush();
  #endif
  
      --redrawing_for_callback;
***************
*** 800,808 ****
       * done. */
      if (gui.in_use)
      {
-       out_flush();    /* required before updating the cursor */
        if (did_undraw && !gui_mch_is_blink_off())
        {
            /* Put the GUI position where the cursor was, gui_update_cursor()
             * uses that. */
            gui.col = gui_cursor_col;
--- 798,809 ----
       * done. */
      if (gui.in_use)
      {
        if (did_undraw && !gui_mch_is_blink_off())
        {
+           mch_disable_flush();
+           out_flush();        /* required before updating the cursor */
+           mch_enable_flush();
+ 
            /* Put the GUI position where the cursor was, gui_update_cursor()
             * uses that. */
            gui.col = gui_cursor_col;
***************
*** 811,819 ****
--- 812,823 ----
            gui.col = mb_fix_col(gui.col, gui.row);
  # endif
            gui_update_cursor(FALSE, FALSE);
+           gui_may_flush();
            screen_cur_col = gui.col;
            screen_cur_row = gui.row;
        }
+       else
+           out_flush();
        gui_update_scrollbars(FALSE);
      }
  #endif
***************
*** 863,870 ****
       * done. */
      if (gui.in_use)
      {
!       out_flush();    /* required before updating the cursor */
!       gui_update_cursor(FALSE, FALSE);
        gui_update_scrollbars(FALSE);
      }
  # endif
--- 867,873 ----
       * done. */
      if (gui.in_use)
      {
!       out_flush_cursor(FALSE, FALSE);
        gui_update_scrollbars(FALSE);
      }
  # endif
*** ../vim-8.0.1448/src/search.c        2017-11-16 22:20:35.028615026 +0100
--- src/search.c        2018-01-31 20:43:44.631740274 +0100
***************
*** 2675,2688 ****
            showruler(FALSE);
            setcursor();
            cursor_on();                /* make sure that the cursor is shown */
!           out_flush();
! #ifdef FEAT_GUI
!           if (gui.in_use)
!           {
!               gui_update_cursor(TRUE, FALSE);
!               gui_mch_flush();
!           }
! #endif
            /* Restore dollar_vcol(), because setcursor() may call curs_rows()
             * which resets it if the matching position is in a previous line
             * and has a higher column number. */
--- 2675,2682 ----
            showruler(FALSE);
            setcursor();
            cursor_on();                /* make sure that the cursor is shown */
!           out_flush_cursor(TRUE, FALSE);
! 
            /* Restore dollar_vcol(), because setcursor() may call curs_rows()
             * which resets it if the matching position is in a previous line
             * and has a higher column number. */
*** ../vim-8.0.1448/src/term.c  2017-12-09 15:11:20.387922557 +0100
--- src/term.c  2018-01-31 20:43:44.631740274 +0100
***************
*** 2501,2506 ****
--- 2501,2527 ----
      }
  }
  
+ /*
+  * out_flush_cursor(): flush the output buffer and redraw the cursor
+  */
+     void
+ out_flush_cursor(
+     int           force UNUSED,   /* when TRUE, update cursor even when not 
moved */
+     int           clear_selection UNUSED) /* clear selection under cursor */
+ {
+     mch_disable_flush();
+     out_flush();
+     mch_enable_flush();
+ #ifdef FEAT_GUI
+     if (gui.in_use)
+     {
+       gui_update_cursor(force, clear_selection);
+       gui_may_flush();
+     }
+ #endif
+ }
+ 
+ 
  #if defined(FEAT_MBYTE) || defined(PROTO)
  /*
   * Sometimes a byte out of a multi-byte character is written with out_char().
*** ../vim-8.0.1448/src/ui.c    2017-12-18 18:14:43.455768463 +0100
--- src/ui.c    2018-01-31 20:43:44.631740274 +0100
***************
*** 245,251 ****
        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;
      }
--- 245,251 ----
        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 FAIL;
        if (wtime > 0)
            remaining -= due_time;
      }
***************
*** 578,588 ****
            update_curbuf(INVERTED_ALL);
            setcursor();
            cursor_on();
!           out_flush();
! # ifdef FEAT_GUI
!           if (gui.in_use)
!               gui_update_cursor(TRUE, FALSE);
! # endif
        }
      }
  #endif
--- 578,584 ----
            update_curbuf(INVERTED_ALL);
            setcursor();
            cursor_on();
!           out_flush_cursor(TRUE, FALSE);
        }
      }
  #endif
***************
*** 3331,3343 ****
            setcursor();
        }
        cursor_on();        /* redrawing may have switched it off */
!       out_flush();
  # ifdef FEAT_GUI
        if (gui.in_use)
-       {
-           gui_update_cursor(FALSE, TRUE);
            gui_update_scrollbars(FALSE);
-       }
  # endif
      }
  #ifdef FEAT_TITLE
--- 3327,3336 ----
            setcursor();
        }
        cursor_on();        /* redrawing may have switched it off */
!       out_flush_cursor(FALSE, TRUE);
  # ifdef FEAT_GUI
        if (gui.in_use)
            gui_update_scrollbars(FALSE);
  # endif
      }
  #ifdef FEAT_TITLE
*** ../vim-8.0.1448/src/version.c       2018-01-31 20:15:25.675643331 +0100
--- src/version.c       2018-01-31 20:44:36.502991020 +0100
***************
*** 773,774 ****
--- 773,776 ----
  {   /* Add new patch number below this line */
+ /**/
+     1449,
  /**/

-- 
   They now pass three KNIGHTS impaled to a tree.  With their feet off the
   ground,  with one lance through the lot of them, they are skewered up
   like a barbecue.
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// 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