summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2018-01-31 20:51:47 +0100
committerBram Moolenaar <Bram@vim.org>2018-01-31 20:51:47 +0100
commita338adcf222b6a24e26ea5ae6a2ad27f914acb38 (patch)
tree0ffe28d0a3a60c2c1444a991514505c448d4335b
parent37badc898b8d167e11553b6d05908ffd35928a6e (diff)
patch 8.0.1449: slow redrawing with DirectXv8.0.1449
Problem: Slow redrawing with DirectX. Solution: Avoid calling gui_mch_flush() unnecessarily, especially when updating the cursor. (Ken Takata, closes #2560)
-rw-r--r--runtime/doc/options.txt22
-rw-r--r--src/channel.c9
-rw-r--r--src/edit.c12
-rw-r--r--src/getchar.c14
-rw-r--r--src/gui.c48
-rw-r--r--src/gui_dwrite.cpp98
-rw-r--r--src/gui_dwrite.h1
-rw-r--r--src/gui_w32.c41
-rw-r--r--src/macros.h17
-rw-r--r--src/main.c12
-rw-r--r--src/message.c2
-rw-r--r--src/netbeans.c48
-rw-r--r--src/proto/gui.pro3
-rw-r--r--src/proto/term.pro1
-rw-r--r--src/screen.c23
-rw-r--r--src/search.c10
-rw-r--r--src/term.c21
-rw-r--r--src/ui.c13
-rw-r--r--src/version.c2
19 files changed, 224 insertions, 173 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index f279de6aef..f933083559 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -6122,7 +6122,7 @@ A jump table for the options with a short description can be found at |Q_op|.
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)
+ scrlines Scroll Lines int (deprecated)
See this URL for detail (except for scrlines):
https://msdn.microsoft.com/en-us/library/dd368190.aspx
@@ -6156,23 +6156,9 @@ A jump table for the options with a short description can be found at |Q_op|.
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.
+ 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
diff --git a/src/channel.c b/src/channel.c
index f7eded21e2..138b12eceb 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -2207,14 +2207,7 @@ channel_exe_cmd(channel_T *channel, ch_part_T part, typval_T *argv)
ex_redraw(&ea);
showruler(FALSE);
setcursor();
- out_flush();
-#ifdef FEAT_GUI
- if (gui.in_use)
- {
- gui_update_cursor(TRUE, FALSE);
- gui_mch_flush();
- }
-#endif
+ out_flush_cursor(TRUE, FALSE);
}
else if (STRCMP(cmd, "expr") == 0 || STRCMP(cmd, "call") == 0)
{
diff --git a/src/edit.c b/src/edit.c
index bf2cf31404..9330a401da 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -3451,7 +3451,7 @@ ins_compl_clear(void)
compl_orig_text = NULL;
compl_enter_selects = FALSE;
/* clear v:completed_item */
- set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
+ set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc_lock(VAR_FIXED));
}
/*
@@ -3553,8 +3553,7 @@ ins_compl_new_leader(void)
{
/* Show the cursor after the match, not after the redrawn text. */
setcursor();
- out_flush();
- gui_update_cursor(FALSE, FALSE);
+ out_flush_cursor(FALSE, FALSE);
}
#endif
compl_restarting = TRUE;
@@ -4704,7 +4703,7 @@ ins_compl_delete(void)
* flicker, thus we can't do that. */
changed_cline_bef_curs();
/* clear v:completed_item */
- set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
+ set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc_lock(VAR_FIXED));
}
/*
@@ -4724,7 +4723,7 @@ ins_compl_insert(int in_compl_func)
/* Set completed item. */
/* { word, abbr, menu, kind, info } */
- dict = dict_alloc();
+ dict = dict_alloc_lock(VAR_FIXED);
if (dict != NULL)
{
dict_add_nr_str(dict, "word", 0L,
@@ -4936,8 +4935,7 @@ ins_compl_next(
{
/* Show the cursor after the match, not after the redrawn text. */
setcursor();
- out_flush();
- gui_update_cursor(FALSE, FALSE);
+ out_flush_cursor(FALSE, FALSE);
}
#endif
diff --git a/src/getchar.c b/src/getchar.c
index 18dc1a670d..70cf4f1727 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -2972,16 +2972,10 @@ inchar(
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
- }
+ out_flush_cursor(FALSE, FALSE);
+#if defined(FEAT_GUI) && defined(FEAT_MOUSESHAPE)
+ if (gui.in_use && postponed_mouseshape)
+ update_mouseshape(-1);
#endif
}
diff --git a/src/gui.c b/src/gui.c
index 3456f9246d..45bf49ac9c 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -55,6 +55,7 @@ enum {
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,7 +1977,7 @@ gui_write(
gui.dragged_sb = SBAR_NONE;
#endif
- gui_mch_flush(); /* In case vim decides to take a nap */
+ gui_may_flush(); /* In case vim decides to take a nap */
}
/*
@@ -2004,6 +2005,34 @@ gui_can_update_cursor(void)
* 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,7 +3711,6 @@ gui_update_tabline(void)
/* 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);
@@ -4122,8 +4150,7 @@ gui_drag_scrollbar(scrollbar_T *sb, long value, int still_dragging)
setcursor();
}
# endif
- out_flush();
- gui_update_cursor(FALSE, TRUE);
+ out_flush_cursor(FALSE, TRUE);
#else
add_to_input_buf(bytes, byte_count);
add_long_to_buf((long_u)value, bytes);
@@ -4486,7 +4513,9 @@ gui_do_scroll(void)
* 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,8 +4826,7 @@ gui_focus_change(int in_focus)
*/
#if 1
gui.in_focus = in_focus;
- out_flush(); /* make sure output has been written */
- gui_update_cursor(TRUE, FALSE);
+ out_flush_cursor(TRUE, FALSE);
# ifdef FEAT_XIM
xim_set_focus(in_focus);
@@ -5157,9 +5185,7 @@ gui_update_screen(void)
curwin->w_valid &= ~VALID_CROW;
}
# endif
- out_flush(); /* make sure output has been written */
- gui_update_cursor(TRUE, FALSE);
- gui_mch_flush();
+ out_flush_cursor(TRUE, FALSE);
}
#endif
@@ -5516,9 +5542,7 @@ gui_handle_drop(
maketitle();
#endif
setcursor();
- out_flush();
- gui_update_cursor(FALSE, FALSE);
- gui_mch_flush();
+ out_flush_cursor(FALSE, FALSE);
}
entered = FALSE;
diff --git a/src/gui_dwrite.cpp b/src/gui_dwrite.cpp
index 3c940a3042..8e03dff64e 100644
--- a/src/gui_dwrite.cpp
+++ b/src/gui_dwrite.cpp
@@ -286,6 +286,7 @@ struct DWriteContext {
ID2D1DCRenderTarget *mRT;
ID2D1GdiInteropRenderTarget *mGDIRT;
ID2D1SolidColorBrush *mBrush;
+ ID2D1Bitmap *mBitmap;
IDWriteFactory *mDWriteFactory;
#ifdef FEAT_DIRECTX_COLOR_EMOJI
@@ -319,6 +320,8 @@ struct DWriteContext {
void SetFont(HFONT hFont);
+ void Rebind();
+
void BindDC(HDC hdc, const RECT *rect);
HRESULT SetDrawingMode(DrawingMode mode);
@@ -335,6 +338,8 @@ struct DWriteContext {
void SetPixel(int x, int y, COLORREF color);
+ void Scroll(int x, int y, const RECT *rc);
+
void Flush();
void SetRenderingParams(
@@ -596,6 +601,7 @@ DWriteContext::DWriteContext() :
mRT(NULL),
mGDIRT(NULL),
mBrush(NULL),
+ mBitmap(NULL),
mDWriteFactory(NULL),
#ifdef FEAT_DIRECTX_COLOR_EMOJI
mDWriteFactory2(NULL),
@@ -616,9 +622,6 @@ DWriteContext::DWriteContext() :
_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,
@@ -662,6 +665,7 @@ DWriteContext::~DWriteContext()
#ifdef FEAT_DIRECTX_COLOR_EMOJI
SafeRelease(&mDWriteFactory2);
#endif
+ SafeRelease(&mBitmap);
SafeRelease(&mBrush);
SafeRelease(&mGDIRT);
SafeRelease(&mRT);
@@ -704,13 +708,7 @@ DWriteContext::CreateDeviceResources()
}
if (SUCCEEDED(hr))
- {
- if (mHDC != NULL)
- {
- mRT->BindDC(mHDC, &mBindRect);
- mRT->SetTransform(D2D1::IdentityMatrix());
- }
- }
+ Rebind();
return hr;
}
@@ -718,6 +716,7 @@ DWriteContext::CreateDeviceResources()
void
DWriteContext::DiscardDeviceResources()
{
+ SafeRelease(&mBitmap);
SafeRelease(&mBrush);
SafeRelease(&mGDIRT);
SafeRelease(&mRT);
@@ -899,13 +898,36 @@ DWriteContext::SetFont(HFONT hFont)
}
void
-DWriteContext::BindDC(HDC hdc, const RECT *rect)
+DWriteContext::Rebind()
{
- Flush();
- mRT->BindDC(hdc, rect);
+ 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,6 +1103,49 @@ DWriteContext::SetPixel(int x, int y, COLORREF color)
}
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,6 +1305,13 @@ DWriteContext_SetPixel(DWriteContext *ctx, int x, int y, COLORREF color)
}
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)
diff --git a/src/gui_dwrite.h b/src/gui_dwrite.h
index 9c98c4ce0d..5de06f92b1 100644
--- a/src/gui_dwrite.h
+++ b/src/gui_dwrite.h
@@ -74,6 +74,7 @@ void DWriteContext_FillRect(DWriteContext *ctx, const RECT *rc, COLORREF color);
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);
diff --git a/src/gui_w32.c b/src/gui_w32.c
index 3c745b4fe4..074954a6ca 100644
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -36,7 +36,6 @@
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);
@@ -61,7 +60,6 @@ gui_mch_set_rendering_options(char_u *s)
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; )
@@ -124,7 +122,7 @@ gui_mch_set_rendering_options(char_u *s)
}
else if (STRCMP(name, "scrlines") == 0)
{
- dx_scrlines = atoi((char *)value);
+ /* Deprecated. Simply ignore it. */
}
else
return FAIL;
@@ -159,7 +157,6 @@ gui_mch_set_rendering_options(char_u *s)
}
}
s_directx_enabled = dx_enable;
- s_directx_scrlines = dx_scrlines;
return OK;
# else
@@ -3129,9 +3126,6 @@ gui_mch_delete_lines(
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);
@@ -3141,16 +3135,10 @@ gui_mch_delete_lines(
#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);
+ DWriteContext_Scroll(s_dwc, 0, -num_lines * gui.char_height, &rc);
+ DWriteContext_Flush(s_dwc);
}
- if (!use_redraw)
+ else
#endif
{
intel_gpu_workaround();
@@ -3180,9 +3168,6 @@ gui_mch_insert_lines(
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);
@@ -3192,16 +3177,10 @@ gui_mch_insert_lines(
#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);
+ DWriteContext_Scroll(s_dwc, 0, num_lines * gui.char_height, &rc);
+ DWriteContext_Flush(s_dwc);
}
- if (!use_redraw)
+ else
#endif
{
intel_gpu_workaround();
@@ -4024,7 +4003,10 @@ _OnScroll(
* 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,6 +4633,7 @@ _OnMouseWheel(
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,6 +4642,8 @@ _OnMouseWheel(
}
else
_OnScroll(hwnd, hwndCtl, zDelta >= 0 ? SB_PAGEUP : SB_PAGEDOWN, 0);
+ mch_enable_flush();
+ gui_may_flush();
}
#ifdef USE_SYSMENU_FONT
diff --git a/src/macros.h b/src/macros.h
index 1b54b91bae..6e4b813c0a 100644
--- a/src/macros.h
+++ b/src/macros.h
@@ -365,6 +365,17 @@
* 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)
+#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
diff --git a/src/main.c b/src/main.c
index 877adaf5ba..9cf10bd781 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1242,7 +1242,11 @@ main_loop(
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,11 +1287,13 @@ main_loop(
|| 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,11 +4218,7 @@ eval_client_expr_to_string(char_u *expr)
/* 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
+ out_flush_cursor(FALSE, FALSE);
return res;
}
diff --git a/src/message.c b/src/message.c
index c40b6cf15b..211403384a 100644
--- a/src/message.c
+++ b/src/message.c
@@ -2316,7 +2316,9 @@ msg_scroll_up(void)
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 *)" "))
{
diff --git a/src/netbeans.c b/src/netbeans.c
index f4b42dc8ad..c906d28912 100644
--- a/src/netbeans.c
+++ b/src/netbeans.c
@@ -121,14 +121,7 @@ netbeans_close(void)
update_screen(CLEAR);
setcursor();
cursor_on();
- out_flush();
-#ifdef FEAT_GUI
- if (gui.in_use)
- {
- gui_update_cursor(TRUE, FALSE);
- gui_mch_flush();
- }
-#endif
+ out_flush_cursor(TRUE, FALSE);
}
#define NB_DEF_HOST "localhost"
@@ -1848,14 +1841,8 @@ nb_do_cmd(
update_screen(VALID);
setcursor();
cursor_on();
- out_flush();
-#ifdef FEAT_GUI
- if (gui.in_use)
- {
- gui_update_cursor(TRUE, FALSE);
- gui_mch_flush();
- }
-#endif
+ out_flush_cursor(TRUE, FALSE);
+
/* Quit a hit-return or more prompt. */
if (State == HITRETURN || State == ASKMORE)
{
@@ -2248,14 +2235,8 @@ nb_do_cmd(
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
+ out_flush_cursor(TRUE, FALSE);
+
/* Quit a hit-return or more prompt. */
if (State == HITRETURN || State == ASKMORE)
{
@@ -2307,15 +2288,7 @@ coloncmd(char *cmd, ...)
/* 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
+ out_flush_cursor(TRUE, FALSE);
}
@@ -2569,14 +2542,7 @@ netbeans_open(char *params, int doabort)
update_screen(CLEAR);
setcursor();
cursor_on();
- out_flush();
-#ifdef FEAT_GUI
- if (gui.in_use)
- {
- gui_update_cursor(TRUE, FALSE);
- gui_mch_flush();
- }
-#endif
+ out_flush_cursor(TRUE, FALSE);
}
/*
diff --git a/src/proto/gui.pro b/src/proto/gui.pro
index baad47fe40..4004bc7786 100644
--- a/src/proto/gui.pro
+++ b/src/proto/gui.pro
@@ -25,6 +25,9 @@ void gui_update_cursor_later(void);
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);
diff --git a/src/proto/term.pro b/src/proto/term.pro
index ef74f5647c..b0ad418e80 100644
--- a/src/proto/term.pro
+++ b/src/proto/term.pro
@@ -12,6 +12,7 @@ int term_is_gui(char_u *name);
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);
diff --git a/src/screen.c b/src/screen.c
index 6b69d13b63..9256fbd1e6 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -468,16 +468,14 @@ redraw_after_callback(int call_update_screen)
setcursor();
}
cursor_on();
- out_flush();
#ifdef FEAT_GUI
- if (gui.in_use)
- {
+ if (gui.in_use && !gui_mch_is_blink_off())
/* 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();
- }
+ out_flush_cursor(FALSE, FALSE);
+ else
+#else
+ out_flush();
#endif
--redrawing_for_callback;
@@ -800,9 +798,12 @@ update_screen(int type_arg)
* done. */
if (gui.in_use)
{
- out_flush(); /* required before updating the cursor */
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,9 +812,12 @@ update_screen(int type_arg)
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,8 +867,7 @@ update_finish(void)
* done. */
if (gui.in_use)
{
- out_flush(); /* required before updating the cursor */
- gui_update_cursor(FALSE, FALSE);
+ out_flush_cursor(FALSE, FALSE);
gui_update_scrollbars(FALSE);
}
# endif
diff --git a/src/search.c b/src/search.c
index 8bb5f3d97a..0aebea4f95 100644
--- a/src/search.c
+++ b/src/search.c
@@ -2675,14 +2675,8 @@ showmatch(
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
+ 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. */
diff --git a/src/term.c b/src/term.c
index ffa3944d69..6303e10d59 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2501,6 +2501,27 @@ out_flush(void)
}
}
+/*
+ * 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().
diff --git a/src/ui.c b/src/ui.c
index e410f68299..c77a8e029f 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -245,7 +245,7 @@ ui_wait_for_chars_or_timer(
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;
+ return FAIL;
if (wtime > 0)
remaining -= due_time;
}
@@ -578,11 +578,7 @@ clip_lose_selection(VimClipboard *cbd)
update_curbuf(INVERTED_ALL);
setcursor();
cursor_on();
- out_flush();
-# ifdef FEAT_GUI
- if (gui.in_use)
- gui_update_cursor(TRUE, FALSE);
-# endif
+ out_flush_cursor(TRUE, FALSE);
}
}
#endif
@@ -3331,13 +3327,10 @@ ui_focus_change(
setcursor();
}
cursor_on(); /* redrawing may have switched it off */
- out_flush();
+ out_flush_cursor(FALSE, TRUE);
# ifdef FEAT_GUI
if (gui.in_use)
- {
- gui_update_cursor(FALSE, TRUE);
gui_update_scrollbars(FALSE);
- }
# endif
}
#ifdef FEAT_TITLE
diff --git a/src/version.c b/src/version.c
index 1da5bbdc3b..d6082dff85 100644
--- a/src/version.c
+++ b/src/version.c
@@ -772,6 +772,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1449,
+/**/
1448,
/**/
1447,