From 21327496cbf98ad5199c8f65f4d42941829522d9 Mon Sep 17 00:00:00 2001 From: Marco Cecchetti Date: Tue, 11 Oct 2016 22:07:25 +0200 Subject: [PATCH] LOK: handle "EMPTY" invalid tile msg with part number in payload What's new: 1) RectangleAndPart handles "EMPTY" payloads 2) LOK_CALLBACK_INVALIDATE_TILES msg type with "EMPTY" payload are handled in CallbackFlushHandler::queue 3) gtktiledviewer handles "EMPTY" LOK_CALLBACK_INVALIDATE_TILES msg even if the part number is included in the payload Change-Id: I21f4a71ec875d24f4bbd100e4aacf8437d745ae4 --- desktop/source/lib/init.cxx | 108 ++++++++++++++++------- libreofficekit/source/gtk/lokdocview.cxx | 2 +- 2 files changed, 78 insertions(+), 32 deletions(-) diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 1b49e1f4ab8a..4e213bfa12b5 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -349,6 +349,15 @@ struct RectangleAndPart static RectangleAndPart Create(const std::string& rPayload) { + RectangleAndPart aRet; + if (rPayload.find("EMPTY") == 0) // payload starts with "EMPTY" + { + if (comphelper::LibreOfficeKit::isPartInInvalidation()) + aRet.m_nPart = std::stol(rPayload.substr(6)); + + return aRet; + } + std::istringstream aStream(rPayload); long nLeft, nTop, nRight, nBottom; long nPart = -1; @@ -357,7 +366,7 @@ struct RectangleAndPart aStream >> nLeft >> nComma >> nTop >> nComma >> nRight >> nComma >> nBottom >> nComma >> nPart; else aStream >> nLeft >> nComma >> nTop >> nComma >> nRight >> nComma >> nBottom; - RectangleAndPart aRet; + aRet.m_aRectangle = Rectangle(nLeft, nTop, nLeft + nRight, nTop + nBottom); aRet.m_nPart = nPart; return aRet; @@ -649,6 +658,24 @@ void CallbackFlushHandler::queue(const int type, const char* data) break; } + // if we have to invalidate all tiles, we can skip any new tile invalidation + if (type == LOK_CALLBACK_INVALIDATE_TILES) + { + const auto& pos = std::find_if(m_queue.rbegin(), m_queue.rend(), + [] (const queue_type::value_type& elem) { return (elem.first == LOK_CALLBACK_INVALIDATE_TILES); }); + + if (pos != m_queue.rend()) + { + RectangleAndPart rcOld = RectangleAndPart::Create(pos->second); + RectangleAndPart rcNew = RectangleAndPart::Create(payload); + if (rcOld.m_aRectangle.IsEmpty() && rcOld.m_nPart == rcNew.m_nPart) + { + //SAL_WARN("lok", "Skipping queue [" + std::to_string(type) + "]: [" + payload + "] since all tiles need to be invalidated."); + return; + } + } + } + if (type == LOK_CALLBACK_TEXT_SELECTION && payload.empty()) { const auto& posStart = std::find_if(m_queue.rbegin(), m_queue.rend(), @@ -730,37 +757,56 @@ void CallbackFlushHandler::queue(const int type, const char* data) { RectangleAndPart rcNew = RectangleAndPart::Create(payload); //SAL_WARN("lok", "New: " << rcNew.toString()); - const auto rcOrig = rcNew; - - removeAll( - [type, &rcNew] (const queue_type::value_type& elem) { - if (elem.first == type) - { - const RectangleAndPart rcOld = RectangleAndPart::Create(elem.second); - if (rcOld.m_nPart != rcNew.m_nPart) - return false; - //SAL_WARN("lok", "#" << i << " Old: " << rcOld.toString()); - const Rectangle rcOverlap = rcNew.m_aRectangle.GetIntersection(rcOld.m_aRectangle); - //SAL_WARN("lok", "#" << i << " Overlap: " << rcOverlap.toString()); - bool bOverlap = (rcOverlap.GetWidth() > 0 && rcOverlap.GetHeight() > 0); - if (bOverlap) - { - //SAL_WARN("lok", rcOld.toString() << " U " << rcNew.toString()); - rcNew.m_aRectangle.Union(rcOld.m_aRectangle); - } - return bOverlap; - } - else - { - return false; - } - } - ); - - if (rcNew.m_aRectangle != rcOrig.m_aRectangle) + if (rcNew.m_aRectangle.IsEmpty()) { - SAL_WARN("lok", "Replacing: " << rcOrig.toString() << " by " << rcNew.toString()); - payload = rcNew.toString().getStr(); + removeAll( + [type, &rcNew] (const queue_type::value_type& elem) { + if (elem.first == type) + { + const RectangleAndPart rcOld = RectangleAndPart::Create(elem.second); + return (rcOld.m_nPart == rcNew.m_nPart); + } + else + { + return false; + } + } + ); + } + else + { + const auto rcOrig = rcNew; + + removeAll( + [type, &rcNew] (const queue_type::value_type& elem) { + if (elem.first == type) + { + const RectangleAndPart rcOld = RectangleAndPart::Create(elem.second); + if (rcOld.m_nPart != rcNew.m_nPart) + return false; + //SAL_WARN("lok", "#" << i << " Old: " << rcOld.toString()); + const Rectangle rcOverlap = rcNew.m_aRectangle.GetIntersection(rcOld.m_aRectangle); + //SAL_WARN("lok", "#" << i << " Overlap: " << rcOverlap.toString()); + bool bOverlap = (rcOverlap.GetWidth() > 0 && rcOverlap.GetHeight() > 0); + if (bOverlap) + { + //SAL_WARN("lok", rcOld.toString() << " U " << rcNew.toString()); + rcNew.m_aRectangle.Union(rcOld.m_aRectangle); + } + return bOverlap; + } + else + { + return false; + } + } + ); + + if (rcNew.m_aRectangle != rcOrig.m_aRectangle) + { + SAL_WARN("lok", "Replacing: " << rcOrig.toString() << " by " << rcNew.toString()); + payload = rcNew.toString().getStr(); + } } } break; diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx index c4159b069c82..a08d93e8e3fa 100644 --- a/libreofficekit/source/gtk/lokdocview.cxx +++ b/libreofficekit/source/gtk/lokdocview.cxx @@ -1136,7 +1136,7 @@ callback (gpointer pData) { case LOK_CALLBACK_INVALIDATE_TILES: { - if (pCallback->m_aPayload != "EMPTY") + if (pCallback->m_aPayload.find("EMPTY") != 0) // payload doesn't start with "EMPTY" { GdkRectangle aRectangle = payloadToRectangle(pDocView, pCallback->m_aPayload.c_str()); setTilesInvalid(pDocView, aRectangle);