diff options
author | Neil <nyamatongwe@gmail.com> | 2019-03-05 08:35:51 +1100 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2019-03-05 08:35:51 +1100 |
commit | bd4e835624d38f922752c5f4b577502199f0b16f (patch) | |
tree | 6a56e1a909edf303f2be6bf1b7d69032d96c6941 | |
parent | b1cb174973ade513f60b90ed115d3650d0981394 (diff) | |
download | scintilla-mirror-bd4e835624d38f922752c5f4b577502199f0b16f.tar.gz |
Implement QueueIdleWork on Win32.
-rw-r--r-- | doc/ScintillaHistory.html | 3 | ||||
-rw-r--r-- | win32/ScintillaWin.cxx | 33 |
2 files changed, 35 insertions, 1 deletions
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 024d1216f..ad6ce07de 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -567,6 +567,9 @@ On Win32, removed special handling of non-0 wParam to WM_PAINT. </li> <li> + Implement high-priority idle on Win32 to make redraw smoother and more efficient. + </li> + <li> Avoid potential long hangs with idle styling for huge documents on Cocoa and GTK. </li> <ul> diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index a24a1ddfc..dadb5b9b6 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -117,7 +117,15 @@ #define MK_ALT 32 #endif -#define SC_WIN_IDLE 5001 +// Two idle messages SC_WIN_IDLE and SC_WORK_IDLE. + +// SC_WIN_IDLE is low priority so should occur after the next WM_PAINT +// It is for lengthy actions like wrapping and background styling +constexpr UINT SC_WIN_IDLE = 5001; +// SC_WORK_IDLE is high priority and should occur before the next WM_PAINT +// It is for shorter actions like restyling the text just inserted +// and delivering SCN_UPDATEUI +constexpr UINT SC_WORK_IDLE = 5002; #define SC_INDICATOR_INPUT INDIC_IME #define SC_INDICATOR_TARGET INDIC_IME+1 @@ -337,6 +345,8 @@ class ScintillaWin : UINT CodePageOfDocument() const; bool ValidCodePage(int codePage) const override; sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) override; + void IdleWork() override; + void QueueIdleWork(WorkNeeded::workItems items, Sci::Position upTo) override; bool SetIdle(bool on) override; UINT_PTR timers[tickDwell+1] {}; bool FineTickerRunning(TickReason reason) override; @@ -426,6 +436,7 @@ private: HBITMAP sysCaretBitmap; int sysCaretWidth; int sysCaretHeight; + bool styleIdleInQueue; }; HINSTANCE ScintillaWin::hInstance {}; @@ -472,6 +483,8 @@ ScintillaWin::ScintillaWin(HWND hwnd) { sysCaretWidth = 0; sysCaretHeight = 0; + styleIdleInQueue = false; + #if defined(USE_D2D) pRenderTarget = nullptr; renderTargetValid = true; @@ -1394,6 +1407,10 @@ sptr_t ScintillaWin::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam } break; + case SC_WORK_IDLE: + IdleWork(); + break; + case WM_GETMINMAXINFO: return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam); @@ -1839,6 +1856,20 @@ bool ScintillaWin::SetIdle(bool on) { return idler.state; } +void ScintillaWin::IdleWork() { + styleIdleInQueue = false; + Editor::IdleWork(); +} + +void ScintillaWin::QueueIdleWork(WorkNeeded::workItems items, Sci::Position upTo) { + Editor::QueueIdleWork(items, upTo); + if (!styleIdleInQueue) { + if (PostMessage(MainHWND(), SC_WORK_IDLE, 0, 0)) { + styleIdleInQueue = true; + } + } +} + void ScintillaWin::SetMouseCapture(bool on) { if (mouseDownCaptures) { if (on) { |