summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2021-10-07 18:02:12 +0200
committerLuboš Luňák <l.lunak@collabora.com>2021-10-25 19:30:34 +0200
commit4bb6533d398cc76d7ff292a9e47dae87fac74f83 (patch)
tree6104d470627c2592624f315e8c8b32435ff5c109
parent9e3ec1b50052e687d6bc79db8e2ed5ebbd0eb24a (diff)
use pull model also for LOK text selection
Make LOK_CALLBACK_TEXT_SELECTION, LOK_CALLBACK_TEXT_SELECTION_START, LOK_CALLBACK_TEXT_SELECTION_END and LOK_CALLBACK_TEXT_VIEW_SELECTION also use pull model, i.e. LO core will only set a flag and when CallbackFlushHandler needs the actual data it'll use getLOKPayload(). This again avoids a large number of messages passed to CallbackFlushHandler only for them to be sooner or later discarded. Change-Id: Ia7528039be996a6e9e8491b4eba3f4133582fa56 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124146 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
-rw-r--r--desktop/qa/desktop_lib/test_desktop_lib.cxx12
-rw-r--r--desktop/source/lib/init.cxx56
-rw-r--r--sw/inc/viscrs.hxx2
-rw-r--r--sw/source/core/crsr/viscrs.cxx70
-rw-r--r--sw/source/uibase/uiview/viewsrch.cxx4
-rw-r--r--sw/source/uibase/wrtsh/wrtsh4.cxx5
-rw-r--r--test/source/lokcallback.cxx2
7 files changed, 121 insertions, 30 deletions
diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index cfa8e039a5d0..1144a5e48369 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -1545,6 +1545,7 @@ void DesktopLOKTest::testNotificationCompression()
LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
std::vector<std::tuple<int, std::string>> notifs;
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
+ handler->setViewId(SfxLokHelper::getView());
handler->queue(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, ""); // 0
handler->queue(LOK_CALLBACK_TEXT_SELECTION, "15, 25, 15, 10"); // Superseded.
@@ -1640,6 +1641,7 @@ void DesktopLOKTest::testTileInvalidationCompression()
{
std::vector<std::tuple<int, std::string>> notifs;
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
+ handler->setViewId(SfxLokHelper::getView());
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 239, 0");
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 239, 0");
@@ -1660,6 +1662,7 @@ void DesktopLOKTest::testTileInvalidationCompression()
{
std::vector<std::tuple<int, std::string>> notifs;
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
+ handler->setViewId(SfxLokHelper::getView());
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 239, 0");
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 200, 200, 1"); // Different part
@@ -1683,6 +1686,7 @@ void DesktopLOKTest::testTileInvalidationCompression()
{
std::vector<std::tuple<int, std::string>> notifs;
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
+ handler->setViewId(SfxLokHelper::getView());
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 239, 0"); // 0
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 200, 200, 1"); // 1: Different part
@@ -1709,6 +1713,7 @@ void DesktopLOKTest::testTileInvalidationCompression()
{
std::vector<std::tuple<int, std::string>> notifs;
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
+ handler->setViewId(SfxLokHelper::getView());
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 200, 200, 0"); // 0
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 100, 100, 1"); // 1: Different part
@@ -1744,6 +1749,7 @@ void DesktopLOKTest::testTileInvalidationCompression()
{
std::vector<std::tuple<int, std::string>> notifs;
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
+ handler->setViewId(SfxLokHelper::getView());
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 239, 0");
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "EMPTY, 0");
@@ -1768,6 +1774,7 @@ void DesktopLOKTest::testPartInInvalidation()
{
std::vector<std::tuple<int, std::string>> notifs;
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
+ handler->setViewId(SfxLokHelper::getView());
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "10, 10, 20, 10");
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "20, 10, 20, 10");
@@ -1783,6 +1790,7 @@ void DesktopLOKTest::testPartInInvalidation()
{
std::vector<std::tuple<int, std::string>> notifs;
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
+ handler->setViewId(SfxLokHelper::getView());
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "10, 10, 20, 10");
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "40, 10, 20, 10");
@@ -1802,6 +1810,7 @@ void DesktopLOKTest::testPartInInvalidation()
std::vector<std::tuple<int, std::string>> notifs;
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
+ handler->setViewId(SfxLokHelper::getView());
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "10, 10, 20, 10, 0");
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "20, 10, 20, 10, 0");
@@ -1820,6 +1829,7 @@ void DesktopLOKTest::testPartInInvalidation()
std::vector<std::tuple<int, std::string>> notifs;
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
+ handler->setViewId(SfxLokHelper::getView());
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "10, 10, 20, 10, 0");
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "20, 10, 20, 10, 1");
@@ -1848,6 +1858,7 @@ void DesktopLOKTest::testBinaryCallback()
{
std::vector<std::tuple<int, std::string>> notifs;
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackBinaryCallbackTest, &notifs));
+ handler->setViewId(SfxLokHelper::getView());
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, rect1String.c_str());
@@ -1860,6 +1871,7 @@ void DesktopLOKTest::testBinaryCallback()
{
std::vector<std::tuple<int, std::string>> notifs;
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackBinaryCallbackTest, &notifs));
+ handler->setViewId(SfxLokHelper::getView());
handler->libreOfficeKitViewInvalidateTilesCallback(&rect1, INT_MIN);
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index c38a6dd8d754..30bfd4594754 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -698,9 +698,17 @@ static bool lcl_isViewCallbackType(const int type)
}
}
-static bool isUpdatedType(int /*type*/)
+static bool isUpdatedType(int type)
{
- return false;
+ switch (type)
+ {
+ case LOK_CALLBACK_TEXT_SELECTION:
+ case LOK_CALLBACK_TEXT_SELECTION_START:
+ case LOK_CALLBACK_TEXT_SELECTION_END:
+ return true;
+ default:
+ return false;
+ }
}
static bool isUpdatedTypePerViewId(int type)
@@ -709,6 +717,7 @@ static bool isUpdatedTypePerViewId(int type)
{
case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
+ case LOK_CALLBACK_TEXT_VIEW_SELECTION:
return true;
default:
return false;
@@ -2121,31 +2130,53 @@ void CallbackFlushHandler::enqueueUpdatedTypes()
{
if( m_updatedTypes.empty() && m_updatedTypesPerViewId.empty())
return;
+ assert(m_viewId >= 0);
SfxViewShell* viewShell = SfxViewShell::GetFirst( false,
[this](const SfxViewShell* shell) { return shell->GetViewShellId().get() == m_viewId; } );
assert(viewShell != nullptr);
- for( size_t type = 0; type < m_updatedTypes.size(); ++type )
- {
- if(m_updatedTypes[ type ])
+
+ // First move data to local structures, so that callbacks don't possibly modify it.
+ std::vector<bool> updatedTypes;
+ std::swap(updatedTypes, m_updatedTypes);
+ std::unordered_map<int, std::vector<PerViewIdData>> updatedTypesPerViewId;
+ std::swap(updatedTypesPerViewId, m_updatedTypesPerViewId);
+
+ // Some types must always precede other types, for example
+ // LOK_CALLBACK_TEXT_SELECTION_START and LOK_CALLBACK_TEXT_SELECTION_END
+ // must always precede LOK_CALLBACK_TEXT_SELECTION if present.
+ // Only these types should be present (see isUpdatedType()) and should be processed in this order.
+ static const int orderedUpdatedTypes[] = {
+ LOK_CALLBACK_TEXT_SELECTION_START, LOK_CALLBACK_TEXT_SELECTION_END, LOK_CALLBACK_TEXT_SELECTION };
+ // Only these types should be present (see isUpdatedTypePerViewId()) and (as of now)
+ // the order doesn't matter.
+ static const int orderedUpdatedTypesPerViewId[] = {
+ LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR,
+ LOK_CALLBACK_INVALIDATE_VIEW_CURSOR,
+ LOK_CALLBACK_TEXT_VIEW_SELECTION };
+
+ for( int type : orderedUpdatedTypes )
+ {
+ if(o3tl::make_unsigned( type ) < updatedTypes.size() && updatedTypes[ type ])
{
- assert(isUpdatedType( type ));
enqueueUpdatedType( type, viewShell, m_viewId );
}
}
- for( const auto& it : m_updatedTypesPerViewId )
+ for( const auto& it : updatedTypesPerViewId )
{
int viewId = it.first;
const std::vector<PerViewIdData>& types = it.second;
- for( size_t type = 0; type < types.size(); ++type )
+ for( int type : orderedUpdatedTypesPerViewId )
{
- if(types[ type ].set)
+ if(o3tl::make_unsigned( type ) < types.size() && types[ type ].set)
{
- assert(isUpdatedTypePerViewId( type ));
SfxViewShell* sourceViewShell = viewShell;
const int sourceViewId = types[ type ].sourceViewId;
if( sourceViewId != m_viewId )
+ {
+ assert(sourceViewId >= 0);
sourceViewShell = SfxViewShell::GetFirst( false,
[sourceViewId](const SfxViewShell* shell) { return shell->GetViewShellId().get() == sourceViewId; } );
+ }
if(sourceViewShell == nullptr)
{
SAL_INFO("lok", "View #" << sourceViewId << " no longer found for updated event [" << type << "]");
@@ -2155,13 +2186,13 @@ void CallbackFlushHandler::enqueueUpdatedTypes()
}
}
}
- m_updatedTypes.clear();
- m_updatedTypesPerViewId.clear();
}
void CallbackFlushHandler::enqueueUpdatedType( int type, SfxViewShell* viewShell, int viewId )
{
OString payload = viewShell->getLOKPayload( type, viewId );
+ if(payload.isEmpty())
+ return; // No actual payload to send.
CallbackData callbackData(payload.getStr(), viewId);
m_queue1.emplace_back(type);
m_queue2.emplace_back(callbackData);
@@ -2178,6 +2209,7 @@ void CallbackFlushHandler::Invoke()
// Get any pending invalidate tile events. This will call our callbacks,
// so it must be done before taking the mutex.
+ assert(m_viewId >= 0);
if(SfxViewShell* viewShell = SfxViewShell::GetFirst( false,
[this](const SfxViewShell* shell) { return shell->GetViewShellId().get() == m_viewId; } ))
{
diff --git a/sw/inc/viscrs.hxx b/sw/inc/viscrs.hxx
index c8b8b356f7e3..3c355e01800c 100644
--- a/sw/inc/viscrs.hxx
+++ b/sw/inc/viscrs.hxx
@@ -113,6 +113,8 @@ public:
// Optional set the parameters pX, pY
static void Get1PixelInLogic( const SwViewShell& rSh,
tools::Long* pX = nullptr, tools::Long* pY = nullptr );
+
+ OString getLOKPayload(int nType, int nViewId) const;
};
class SW_DLLPUBLIC SwShellCursor : public virtual SwCursor, public SwSelPaintRects
diff --git a/sw/source/core/crsr/viscrs.cxx b/sw/source/core/crsr/viscrs.cxx
index 2c77e6d4dd87..d28dab2c7d98 100644
--- a/sw/source/core/crsr/viscrs.cxx
+++ b/sw/source/core/crsr/viscrs.cxx
@@ -478,25 +478,14 @@ void SwSelPaintRects::Show(std::vector<OString>* pSelectionRectangles)
// If pSelectionRectangles is set, we're just collecting the text selections -> don't emit start/end.
if (!empty() && !pSelectionRectangles)
{
- // The selection may be a complex polygon, emit the logical
- // start/end cursor rectangle of the selection as separate
- // events, if there is a real selection.
- // This can be used to easily show selection handles on the
- // client side.
SwRect aStartRect;
SwRect aEndRect;
FillStartEnd(aStartRect, aEndRect);
if (aStartRect.HasArea())
- {
- OString sRect = aStartRect.SVRect().toString();
- GetShell()->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION_START, sRect.getStr());
- }
+ SfxLokHelper::notifyUpdate(GetShell()->GetSfxViewShell(), LOK_CALLBACK_TEXT_SELECTION_START);
if (aEndRect.HasArea())
- {
- OString sRect = aEndRect.SVRect().toString();
- GetShell()->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION_END, sRect.getStr());
- }
+ SfxLokHelper::notifyUpdate(GetShell()->GetSfxViewShell(), LOK_CALLBACK_TEXT_SELECTION_END);
}
std::vector<OString> aRect;
@@ -509,13 +498,64 @@ void SwSelPaintRects::Show(std::vector<OString>* pSelectionRectangles)
OString sRect = comphelper::string::join("; ", aRect);
if (!pSelectionRectangles)
{
- GetShell()->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION, sRect.getStr());
- SfxLokHelper::notifyOtherViews(GetShell()->GetSfxViewShell(), LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", sRect);
+ SfxLokHelper::notifyUpdate(GetShell()->GetSfxViewShell(),LOK_CALLBACK_TEXT_SELECTION);
+ SfxLokHelper::notifyOtherViewsUpdatePerViewId(GetShell()->GetSfxViewShell(), LOK_CALLBACK_TEXT_VIEW_SELECTION);
}
else
pSelectionRectangles->push_back(sRect);
}
+OString SwSelPaintRects::getLOKPayload( int nType, int nViewId ) const
+{
+ switch( nType )
+ {
+ case LOK_CALLBACK_TEXT_SELECTION_START:
+ case LOK_CALLBACK_TEXT_SELECTION_END:
+ {
+ // The selection may be a complex polygon, emit the logical
+ // start/end cursor rectangle of the selection as separate
+ // events, if there is a real selection.
+ // This can be used to easily show selection handles on the
+ // client side.
+ SwRect aStartRect;
+ SwRect aEndRect;
+ FillStartEnd(aStartRect, aEndRect);
+
+ if( nType == LOK_CALLBACK_TEXT_SELECTION_START )
+ {
+ if (aStartRect.HasArea())
+ return aStartRect.SVRect().toString();
+ return OString();
+ }
+ else // LOK_CALLBACK_TEXT_SELECTION_END
+ {
+ if (aEndRect.HasArea())
+ return aEndRect.SVRect().toString();
+ return OString();
+ }
+ }
+ break;
+ case LOK_CALLBACK_TEXT_SELECTION:
+ case LOK_CALLBACK_TEXT_VIEW_SELECTION:
+ {
+ std::vector<OString> aRect;
+ aRect.reserve(size());
+ for (size_type i = 0; i < size(); ++i)
+ {
+ const SwRect& rRect = (*this)[i];
+ aRect.push_back(rRect.SVRect().toString());
+ }
+ OString sRect = comphelper::string::join("; ", aRect);
+ if( nType == LOK_CALLBACK_TEXT_SELECTION )
+ return sRect;
+ else // LOK_CALLBACK_TEXT_VIEW_SELECTION
+ return SfxLokHelper::makePayloadJSON(GetShell()->GetSfxViewShell(), nViewId, "selection", sRect);
+ }
+ break;
+ }
+ abort();
+}
+
void SwSelPaintRects::HighlightInputField()
{
std::vector< basegfx::B2DRange > aInputFieldRanges;
diff --git a/sw/source/uibase/uiview/viewsrch.cxx b/sw/source/uibase/uiview/viewsrch.cxx
index c6d42d7830dd..d2e1731bbc91 100644
--- a/sw/source/uibase/uiview/viewsrch.cxx
+++ b/sw/source/uibase/uiview/viewsrch.cxx
@@ -126,8 +126,8 @@ static void lcl_emitSearchResultCallbacks(SvxSearchItem const * pSearchItem, SwW
if(bHighlightAll)
{ // FindAll disables this during find, do it once when done.
- pWrtShell->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION, textSelection.getStr());
- SfxLokHelper::notifyOtherViews(pWrtShell->GetSfxViewShell(), LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", textSelection);
+ SfxLokHelper::notifyUpdate(pWrtShell->GetSfxViewShell(),LOK_CALLBACK_TEXT_SELECTION);
+ SfxLokHelper::notifyOtherViewsUpdatePerViewId(pWrtShell->GetSfxViewShell(), LOK_CALLBACK_TEXT_VIEW_SELECTION);
}
}
diff --git a/sw/source/uibase/wrtsh/wrtsh4.cxx b/sw/source/uibase/wrtsh/wrtsh4.cxx
index b80b41b41e54..0bafa1e75941 100644
--- a/sw/source/uibase/wrtsh/wrtsh4.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh4.cxx
@@ -241,6 +241,11 @@ OString SwWrtShell::getLOKPayload(int nType, int nViewId) const
case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
return GetVisibleCursor()->getLOKPayload(nType, nViewId);
+ case LOK_CALLBACK_TEXT_SELECTION:
+ case LOK_CALLBACK_TEXT_SELECTION_START:
+ case LOK_CALLBACK_TEXT_SELECTION_END:
+ case LOK_CALLBACK_TEXT_VIEW_SELECTION:
+ return GetCursor_()->getLOKPayload( nType, nViewId );
}
abort();
}
diff --git a/test/source/lokcallback.cxx b/test/source/lokcallback.cxx
index 6a39b9064470..90ca5f2c9203 100644
--- a/test/source/lokcallback.cxx
+++ b/test/source/lokcallback.cxx
@@ -143,7 +143,7 @@ void TestLokCallbackWrapper::flushLOKData()
return shell->GetViewShellId().get() == m_viewId;
});
assert(viewShell != nullptr);
- // First move data to local structures, so that notifyFromLOKCallback() doesn't modify it.
+ // First move data to local structures, so that callbacks don't possibly modify it.
std::vector<int> updatedTypes;
std::swap(updatedTypes, m_updatedTypes);
std::vector<PerViewIdData> updatedTypesPerViewId;