diff options
author | Neil <nyamatongwe@gmail.com> | 2021-05-08 15:20:59 +1000 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2021-05-08 15:20:59 +1000 |
commit | f0c53e7b25f12be66881acc110d815ec491f1533 (patch) | |
tree | e39ee8ce22b6f882ebcd2afcccf9fa1e71fd0a4e | |
parent | 9547147a9ca0f258d5d25a0b0b116373ed29533f (diff) | |
download | scintilla-mirror-f0c53e7b25f12be66881acc110d815ec491f1533.tar.gz |
Feature [feature-requests:1373]. Make idle actions smoother by measuring
per-byte and allowing just one line to be processed in a time slice.
Very long lines will not distort estimation or block interaction as much.
-rw-r--r-- | doc/ScintillaHistory.html | 7 | ||||
-rw-r--r-- | src/Document.cxx | 7 | ||||
-rw-r--r-- | src/Document.h | 2 | ||||
-rw-r--r-- | src/Editor.cxx | 34 | ||||
-rw-r--r-- | src/Editor.h | 2 |
5 files changed, 32 insertions, 20 deletions
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index ac055a088..67dd2133d 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -579,6 +579,13 @@ Released 23 April 2021. </li> <li> + Make idle actions wrapping and background styling smoother by + measuring per-byte instead of per-line and allowing just one line to be + processed in a time slice. + Very long lines will not distort estimation or block interaction as much. + <a href="https://sourceforge.net/p/scintilla/feature-requests/1373/">Feature #1373</a>. + </li> + <li> On GTK 3 with Wayland, fix primary selection. <a href="https://sourceforge.net/p/scintilla/bugs/2227/">Bug #2227</a>. </li> diff --git a/src/Document.cxx b/src/Document.cxx index 21d492a8e..acb9f14bd 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -113,7 +113,7 @@ size_t ActionDuration::ActionsInAllowedTime(double secondsAllowed) const noexcep Document::Document(int options) : cb((options & SC_DOCUMENTOPTION_STYLES_NONE) == 0, (options & SC_DOCUMENTOPTION_TEXT_LARGE) != 0), - durationStyleOneLine(0.00001, 0.000001, 0.0001) { + durationStyleOneByte(0.000001, 0.0000001, 0.00001) { refCount = 0; #ifdef _WIN32 eolMode = SC_EOL_CRLF; @@ -2287,11 +2287,10 @@ void Document::EnsureStyledTo(Sci::Position pos) { } void Document::StyleToAdjustingLineDuration(Sci::Position pos) { - const Sci::Line lineFirst = SciLineFromPosition(GetEndStyled()); + const Sci::Position stylingStart = GetEndStyled(); ElapsedPeriod epStyling; EnsureStyledTo(pos); - const Sci::Line lineLast = SciLineFromPosition(GetEndStyled()); - durationStyleOneLine.AddSample(lineLast - lineFirst, epStyling.Duration()); + durationStyleOneByte.AddSample(pos - stylingStart, epStyling.Duration()); } void Document::LexerChanged() { diff --git a/src/Document.h b/src/Document.h index 690871ba8..3e57d1449 100644 --- a/src/Document.h +++ b/src/Document.h @@ -282,7 +282,7 @@ public: bool useTabs; bool tabIndents; bool backspaceUnindents; - ActionDuration durationStyleOneLine; + ActionDuration durationStyleOneByte; std::unique_ptr<IDecorationList> decorations; diff --git a/src/Editor.cxx b/src/Editor.cxx index 59d5d54e6..bfe68bad7 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -113,7 +113,7 @@ static constexpr bool IsAllSpacesOrTabs(std::string_view sv) noexcept { return true; } -Editor::Editor() : durationWrapOneLine(0.00001, 0.000001, 0.0001) { +Editor::Editor() : durationWrapOneByte(0.000001, 0.0000001, 0.00001) { ctrlID = 0; stylesValid = false; @@ -1537,7 +1537,13 @@ bool Editor::WrapLines(WrapScope ws) { // as taking only one display line. lineToWrapEnd = lineDocTop; Sci::Line lines = LinesOnScreen() + 1; - while ((lineToWrapEnd < pcs->LinesInDoc()) && (lines>0)) { + constexpr double secondsAllowed = 0.1; + const size_t actionsInAllowedTime = std::clamp<Sci::Line>( + durationWrapOneByte.ActionsInAllowedTime(secondsAllowed), + 0x2000, 0x200000); + const Sci::Line lineLast = pdoc->LineFromPositionAfter(lineToWrap, actionsInAllowedTime); + const Sci::Line maxLine = std::min(lineLast, pcs->LinesInDoc()); + while ((lineToWrapEnd < maxLine) && (lines>0)) { if (pcs->GetVisible(lineToWrapEnd)) lines--; lineToWrapEnd++; @@ -1550,10 +1556,10 @@ bool Editor::WrapLines(WrapScope ws) { } else if (ws == WrapScope::wsIdle) { // Try to keep time taken by wrapping reasonable so interaction remains smooth. constexpr double secondsAllowed = 0.01; - const Sci::Line linesInAllowedTime = std::clamp<Sci::Line>( - static_cast<Sci::Line>(secondsAllowed / durationWrapOneLine.Duration()), - LinesOnScreen() + 50, 0x10000); - lineToWrapEnd = lineToWrap + linesInAllowedTime; + const size_t actionsInAllowedTime = std::clamp<Sci::Line>( + durationWrapOneByte.ActionsInAllowedTime(secondsAllowed), + 0x200, 0x20000); + lineToWrapEnd = pdoc->LineFromPositionAfter(lineToWrap, actionsInAllowedTime); } const Sci::Line lineEndNeedWrap = std::min(wrapPending.end, pdoc->LinesTotal()); lineToWrapEnd = std::min(lineToWrapEnd, lineEndNeedWrap); @@ -1572,7 +1578,7 @@ bool Editor::WrapLines(WrapScope ws) { if (surface) { //Platform::DebugPrintf("Wraplines: scope=%0d need=%0d..%0d perform=%0d..%0d\n", ws, wrapPending.start, wrapPending.end, lineToWrap, lineToWrapEnd); - const Sci::Line linesBeingWrapped = lineToWrapEnd - lineToWrap; + const size_t bytesBeingWrapped = pdoc->LineStart(lineToWrapEnd) - pdoc->LineStart(lineToWrap); ElapsedPeriod epWrapping; while (lineToWrap < lineToWrapEnd) { if (WrapOneLine(surface, lineToWrap)) { @@ -1581,7 +1587,7 @@ bool Editor::WrapLines(WrapScope ws) { wrapPending.Wrapped(lineToWrap); lineToWrap++; } - durationWrapOneLine.AddSample(linesBeingWrapped, epWrapping.Duration()); + durationWrapOneByte.AddSample(bytesBeingWrapped, epWrapping.Duration()); goodTopLine = pcs->DisplayFromDoc(lineDocTop) + std::min( subLineTop, static_cast<Sci::Line>(pcs->GetHeight(lineDocTop)-1)); @@ -5122,12 +5128,12 @@ Sci::Position Editor::PositionAfterMaxStyling(Sci::Position posMax, bool scrolli // When scrolling, allow less time to ensure responsive const double secondsAllowed = scrolling ? 0.005 : 0.02; - const Sci::Line linesToStyle = std::clamp( - static_cast<int>(secondsAllowed / pdoc->durationStyleOneLine.Duration()), - 10, 0x10000); - const Sci::Line stylingMaxLine = std::min( - pdoc->SciLineFromPosition(pdoc->GetEndStyled()) + linesToStyle, - pdoc->LinesTotal()); + const size_t actionsInAllowedTime = std::clamp<Sci::Line>( + pdoc->durationStyleOneByte.ActionsInAllowedTime(secondsAllowed), + 0x200, 0x20000); + const Sci::Line lineLast = pdoc->LineFromPositionAfter(pdoc->SciLineFromPosition(pdoc->GetEndStyled()), actionsInAllowedTime); + const Sci::Line stylingMaxLine = std::min(lineLast, pdoc->LinesTotal()); + return std::min(pdoc->LineStart(stylingMaxLine), posMax); } diff --git a/src/Editor.h b/src/Editor.h index eabd7517e..ae3f0ef5a 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -265,7 +265,7 @@ protected: // ScintillaBase subclass needs access to much of Editor // Wrapping support WrapPending wrapPending; - ActionDuration durationWrapOneLine; + ActionDuration durationWrapOneByte; bool convertPastes; |