[Libreoffice-commits] core.git: Branch 'distro/collabora/co-2021' - desktop/inc desktop/source include/editeng include/sfx2 include/test sfx2/source sw/source test/source

2022-08-31 Thread Luboš Luňák (via logerrit)
 desktop/inc/lib/init.hxx|1 +
 desktop/source/lib/init.cxx |6 ++
 include/editeng/outliner.hxx|1 +
 include/sfx2/lokcallback.hxx|3 +++
 include/sfx2/viewsh.hxx |5 +++--
 include/test/lokcallback.hxx|1 +
 sfx2/source/view/viewsh.cxx |   10 ++
 sw/source/core/view/viewimp.cxx |5 -
 test/source/lokcallback.cxx |6 ++
 9 files changed, 35 insertions(+), 3 deletions(-)

New commits:
commit fc856cd46ac475222772395c522dc34058bd89b9
Author: Luboš Luňák 
AuthorDate: Tue Jun 28 09:42:17 2022 +0200
Commit: Miklos Vajna 
CommitDate: Wed Aug 31 08:37:06 2022 +0200

lok: make sure flushPendingLOKInvalidateTiles() is called

SwViewShellImp::AddPendingLOKInvalidation() collects invalidations,
but this was relying on something eventually calling
flushPendingLOKInvalidateTiles(), which wasn't guaranteed.
If e.g. a spellchecker caused an invalidation from in idle callback
and nothing else changed, then the LOK callback handling code
didn't know there was something pending. So add an explicit
call to ensure to notify about these pending invalidations.

Change-Id: I0a9cb0d5aba2fdbbac126cd8a4a3412bef1cab25
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136533
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Miklos Vajna 

diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index 8b26e117c1fb..6a6f0bd350a3 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -115,6 +115,7 @@ namespace desktop {
 virtual void libreOfficeKitViewInvalidateTilesCallback(const 
tools::Rectangle* pRect, int nPart) override;
 virtual void libreOfficeKitViewUpdatedCallback(int nType) override;
 virtual void libreOfficeKitViewUpdatedCallbackPerViewId(int nType, int 
nViewId, int nSourceViewId) override;
+virtual void libreOfficeKitViewAddPendingInvalidateTiles() override;
 
 private:
 struct CallbackData
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 4abe6f2c5166..f22558d6d76e 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1477,6 +1477,12 @@ void 
CallbackFlushHandler::libreOfficeKitViewUpdatedCallbackPerViewId(int nType,
 setUpdatedTypePerViewId(nType, nViewId, nSourceViewId, true);
 }
 
+void CallbackFlushHandler::libreOfficeKitViewAddPendingInvalidateTiles()
+{
+// Invoke() will call flushPendingLOKInvalidateTiles(), so just make sure 
the timer is active.
+startTimer();
+}
+
 void CallbackFlushHandler::queue(const int type, const char* data)
 {
 CallbackData callbackData(data);
diff --git a/include/editeng/outliner.hxx b/include/editeng/outliner.hxx
index 8cc3e8c23247..e7e9720ad432 100644
--- a/include/editeng/outliner.hxx
+++ b/include/editeng/outliner.hxx
@@ -369,6 +369,7 @@ public:
 virtual void libreOfficeKitViewInvalidateTilesCallback(const 
tools::Rectangle* pRect, int nPart) const = 0;
 virtual void libreOfficeKitViewUpdatedCallback(int nType) const = 0;
 virtual void libreOfficeKitViewUpdatedCallbackPerViewId(int nType, int 
nViewId, int nSourceViewId) const = 0;
+virtual void libreOfficeKitViewAddPendingInvalidateTiles() = 0;
 virtual ViewShellId GetViewShellId() const = 0;
 virtual ViewShellDocId GetDocId() const = 0;
 /// Wrapper around SfxLokHelper::notifyOtherViews().
diff --git a/include/sfx2/lokcallback.hxx b/include/sfx2/lokcallback.hxx
index 6f59402d0cec..b1799386d42b 100644
--- a/include/sfx2/lokcallback.hxx
+++ b/include/sfx2/lokcallback.hxx
@@ -48,6 +48,9 @@ public:
 virtual void libreOfficeKitViewUpdatedCallbackPerViewId(int nType, int 
nViewId,
 int nSourceViewId)
 = 0;
+// There are pending invalidate tiles calls that need to be processed.
+// A call to SfxViewShell::flushPendingLOKInvalidateTiles() should be 
scheduled.
+virtual void libreOfficeKitViewAddPendingInvalidateTiles() = 0;
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/viewsh.hxx b/include/sfx2/viewsh.hxx
index 26a2324c7ca0..f2b0bf29080a 100644
--- a/include/sfx2/viewsh.hxx
+++ b/include/sfx2/viewsh.hxx
@@ -340,10 +340,11 @@ public:
 virtual void libreOfficeKitViewCallback(int nType, const char* pPayload) 
const override;
 virtual void libreOfficeKitViewCallbackWithViewId(int nType, const char* 
pPayload, int nViewId) const override;
 virtual void libreOfficeKitViewInvalidateTilesCallback(const 
tools::Rectangle* pRect, int nPart) const override;
-// Performs any pending calls to 
libreOfficeKitViewInvalidateTilesCallback() as necessary.
-virtual void flushPendingLOKInvalidateTiles();
 virtual void libreOfficeKitViewUpdatedCallback(int nType) const override;
 virtual void libreOfficeKitViewUpdatedCallbackPerViewId(int nType, int 
nViewId, int nSourceViewId) const override;
+// 

[Libreoffice-commits] core.git: Branch 'distro/collabora/co-2021' - desktop/inc desktop/source

2022-06-09 Thread Luboš Luňák (via logerrit)
 desktop/inc/lib/init.hxx|2 +-
 desktop/source/lib/init.cxx |8 
 2 files changed, 5 insertions(+), 5 deletions(-)

New commits:
commit e9dc2d59b0a362af512f4523ec7b120640ea7cf1
Author: Luboš Luňák 
AuthorDate: Wed Jun 8 15:23:22 2022 +0200
Commit: Andras Timar 
CommitDate: Thu Jun 9 21:16:23 2022 +0200

use recursive mutex for LOK queue

Callbacks may be invoked while calling getLOKPayload(), which
would try to lock the mutex again. I actually originally expected
this possibility, as the comment and moving the data to
temporaries in CallbackFlushHandler::enqueueUpdatedTypes()
shows, I just didn't realize the used mutex wasn't recursive
and so would deadlock.

Change-Id: I2b5c4b6b4c1a3933a32ae4641830877e085f2b6c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135499
Tested-by: Jenkins
Reviewed-by: Michael Meeks 
(cherry picked from commit 118bafcfd1ce4a26ec9df912197ebd466d1bd497)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135388
Tested-by: Andras Timar 
Reviewed-by: Andras Timar 

diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index c19e4c5b0ac1..8b26e117c1fb 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -219,7 +219,7 @@ namespace desktop {
 LibreOfficeKitCallback m_pCallback;
 void *m_pData;
 int m_nDisableCallbacks;
-std::mutex m_mutex;
+std::recursive_mutex m_mutex;
 class TimeoutIdle : public Timer
 {
 public:
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index e99dace9c24e..9d88234bdb21 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1464,7 +1464,7 @@ void 
CallbackFlushHandler::libreOfficeKitViewInvalidateTilesCallback(const tools
 void CallbackFlushHandler::libreOfficeKitViewUpdatedCallback(int nType)
 {
 assert(isUpdatedType( nType ));
-std::unique_lock lock(m_mutex);
+std::unique_lock lock(m_mutex);
 SAL_INFO("lok", "Updated: [" << nType << "]");
 setUpdatedType(nType, true);
 }
@@ -1472,7 +1472,7 @@ void 
CallbackFlushHandler::libreOfficeKitViewUpdatedCallback(int nType)
 void CallbackFlushHandler::libreOfficeKitViewUpdatedCallbackPerViewId(int 
nType, int nViewId, int nSourceViewId)
 {
 assert(isUpdatedTypePerViewId( nType ));
-std::unique_lock lock(m_mutex);
+std::unique_lock lock(m_mutex);
 SAL_INFO("lok", "Updated: [" << nType << "]");
 setUpdatedTypePerViewId(nType, nViewId, nSourceViewId, true);
 }
@@ -1543,7 +1543,7 @@ void CallbackFlushHandler::queue(const int type, 
CallbackData& aCallbackData)
 return;
 }
 
-std::unique_lock lock(m_mutex);
+std::unique_lock lock(m_mutex);
 
 // Update types should be received via the updated callbacks for 
performance,
 // getting them as normal callbacks is technically not wrong, but probably 
should be avoided.
@@ -2138,7 +2138,7 @@ void CallbackFlushHandler::Invoke()
 viewShell->flushPendingLOKInvalidateTiles();
 }
 
-std::scoped_lock lock(m_mutex);
+std::unique_lock lock(m_mutex);
 
 // Append messages for updated types, fetch them only now.
 enqueueUpdatedTypes();


[Libreoffice-commits] core.git: Branch 'distro/collabora/co-2021' - desktop/inc desktop/source

2022-02-28 Thread Luboš Luňák (via logerrit)
 desktop/inc/lib/init.hxx|1 +
 desktop/source/lib/init.cxx |   19 +--
 2 files changed, 14 insertions(+), 6 deletions(-)

New commits:
commit f509da33f2b63be957bb4897c1bb20db1d3fc2a2
Author: Luboš Luňák 
AuthorDate: Fri Feb 25 12:22:16 2022 +0100
Commit: Andras Timar 
CommitDate: Mon Feb 28 15:03:54 2022 +0100

make sure that LOK "updated types" start a timer as well

273a25c796fca9afa0dfadac57dc3f336831221c changed the handling of LOK
messages to only set up an "updated" flag for types and then
when flushing the value is fetched. This means that queue() is not
called for such updates, and so the timeout to flush the messages
wasn't started.

Change-Id: I3a7324c86a55697f509f80b6c54cb949fb1daa72
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130459
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Andras Timar 

diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index b2ba47239f2f..c19e4c5b0ac1 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -175,6 +175,7 @@ namespace desktop {
 typedef std::vector queue_type1;
 typedef std::vector queue_type2;
 
+void startTimer();
 bool removeAll(int type);
 bool removeAll(int type, const std::function& rTestFunc);
 bool removeAll(const std::function& 
rTestFunc);
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 2ae5fc89f731..ca65ec4ae2ca 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1402,6 +1402,8 @@ void CallbackFlushHandler::setUpdatedType( int nType, 
bool value )
 if( m_updatedTypes.size() <= o3tl::make_unsigned( nType ))
 m_updatedTypes.resize( nType + 1 ); // new are default-constructed, 
i.e. false
 m_updatedTypes[ nType ] = value;
+if(value)
+startTimer();
 }
 
 void CallbackFlushHandler::resetUpdatedType( int nType )
@@ -1416,6 +1418,8 @@ void CallbackFlushHandler::setUpdatedTypePerViewId( int 
nType, int nViewId, int
 if( types.size() <= o3tl::make_unsigned( nType ))
 types.resize( nType + 1 ); // new are default-constructed, i.e. 'set' 
is false
 types[ nType ] = PerViewIdData{ value, nSourceViewId };
+if(value)
+startTimer();
 }
 
 void CallbackFlushHandler::resetUpdatedTypePerViewId( int nType, int nViewId )
@@ -1745,12 +1749,7 @@ void CallbackFlushHandler::queue(const int type, 
CallbackData& aCallbackData)
 #endif
 
 lock.unlock();
-if (!IsActive())
-{
-Start();
-}
-if (!m_TimeoutIdle.IsActive())
-m_TimeoutIdle.Start();
+startTimer();
 }
 
 bool CallbackFlushHandler::processInvalidateTilesEvent(int type, CallbackData& 
aCallbackData)
@@ -2234,6 +2233,14 @@ void CallbackFlushHandler::Invoke()
 m_TimeoutIdle.Stop();
 }
 
+void CallbackFlushHandler::startTimer()
+{
+if (!IsActive())
+Start();
+if (!m_TimeoutIdle.IsActive())
+m_TimeoutIdle.Start();
+}
+
 bool CallbackFlushHandler::removeAll(int type)
 {
 bool bErased = false;


[Libreoffice-commits] core.git: Branch 'distro/collabora/co-2021' - desktop/inc desktop/source

2022-02-07 Thread Michael Meeks (via logerrit)
 desktop/inc/lib/init.hxx|2 +
 desktop/source/lib/init.cxx |   49 +++-
 2 files changed, 42 insertions(+), 9 deletions(-)

New commits:
commit 876be07b6dd61eb323428aca6c31c3e58a8488fd
Author: Michael Meeks 
AuthorDate: Tue Jan 18 17:04:15 2022 +
Commit: Michael Meeks 
CommitDate: Mon Feb 7 13:09:07 2022 +0100

lok: avoid duplicate emission of statechanged: messages.

We tend to get many of these per keystroke, with the same state.

Change-Id: I9d759f54aee8d6dabcef094997e8f352dd608ec3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128578
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Ashod Nakashian 

diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index bb560264743b..b2ba47239f2f 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -85,6 +85,7 @@ namespace desktop {
 static tools::Rectangle CheckedRectangle(const tools::Rectangle& rect);
 };
 
+/// One instance of this per view, handles flushing callbacks
 class DESKTOP_DLLPUBLIC CallbackFlushHandler final : public Idle, public 
SfxLokCallbackInterface
 {
 public:
@@ -190,6 +191,7 @@ namespace desktop {
 queue_type1 m_queue1;
 queue_type2 m_queue2;
 std::map m_states;
+std::unordered_map m_lastStateChange;
 std::unordered_map> 
m_viewStates;
 
 // For some types only the last message matters (see isUpdatedType()) 
or only the last message
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 4693e79ec3f6..2ae5fc89f731 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1350,6 +1350,7 @@ void CallbackFlushHandler::TimeoutIdle::Invoke()
 mHandler->Invoke();
 }
 
+// One of these is created per view to handle events cf. doc_registerCallback
 CallbackFlushHandler::CallbackFlushHandler(LibreOfficeKitDocument* pDocument, 
LibreOfficeKitCallback pCallback, void* pData)
 : Idle( "lokit idle callback" ),
   m_pDocument(pDocument),
@@ -2151,22 +2152,52 @@ void CallbackFlushHandler::Invoke()
 const auto& payload = it2->getPayload();
 const int viewId = lcl_isViewCallbackType(type) ? it2->getViewId() : 
-1;
 
+SAL_INFO("lok", "processing event: [" << type << ',' << viewId << "]: 
[" << payload << "].");
+
+// common code-path for events on this view:
 if (viewId == -1)
 {
-const auto stateIt = m_states.find(type);
-if (stateIt != m_states.end())
+size_t idx;
+// key-value pairs
+if (type == LOK_CALLBACK_STATE_CHANGED &&
+(idx = payload.find('=')) != std::string::npos)
 {
-// If the state didn't change, it's safe to ignore.
-if (stateIt->second == payload)
+std::string key = payload.substr(0, idx);
+std::string value = payload.substr(idx+1);
+const auto stateIt = m_lastStateChange.find(key);
+if (stateIt != m_lastStateChange.end())
 {
-SAL_INFO("lok", "Skipping duplicate [" << type << "]: [" 
<< payload << "].");
-continue;
+// If the value didn't change, it's safe to ignore.
+if (stateIt->second == value)
+{
+SAL_INFO("lok", "Skipping new state duplicate: [" << 
type << "]: [" << payload << "].");
+continue;
+}
+SAL_INFO("lok", "Replacing a state element [" << type << 
"]: [" << payload << "].");
+stateIt->second = value;
+}
+else
+{
+SAL_INFO("lok", "Inserted a new state element: [" << type 
<< "]: [" << payload << "]");
+m_lastStateChange.emplace(key, value);
+}
+}
+else
+{
+const auto stateIt = m_states.find(type);
+if (stateIt != m_states.end())
+{
+// If the state didn't change, it's safe to ignore.
+if (stateIt->second == payload)
+{
+SAL_INFO("lok", "Skipping duplicate [" << type << "]: 
[" << payload << "].");
+continue;
+}
+stateIt->second = payload;
 }
-
-stateIt->second = payload;
 }
 }
-else
+else // less common path for events relating to other views
 {
 const auto statesIt = m_viewStates.find(viewId);
 if (statesIt != m_viewStates.end())


[Libreoffice-commits] core.git: Branch 'distro/collabora/co-2021' - desktop/inc desktop/source

2021-12-16 Thread Luboš Luňák (via logerrit)
 desktop/inc/lib/init.hxx|4 +++-
 desktop/source/lib/init.cxx |   20 ++--
 2 files changed, 17 insertions(+), 7 deletions(-)

New commits:
commit 2c8f792bf839bd712e0301f087d339ffcc1d22f3
Author: Luboš Luňák 
AuthorDate: Wed Dec 15 15:22:45 2021 +0100
Commit: Andras Timar 
CommitDate: Thu Dec 16 09:33:51 2021 +0100

ensure invalidate tiles LOK message range checking

3db1ce30ab235ad22aed71c22e4f6f52b7b88829 added some range checking
on the rectangles, such as making sure (x,y) is not less than (0,0),
and it added it to converting string messages back to rectangles.
But then 3b729db05553c1a6d461fb41c89a05702f407448 avoided
the conversions from string messages back to rectangles, and thus
it avoided also these checks.

Change-Id: I73a08e418dc2e48ef5e89fe1aee0272851f7d363
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126864
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Ashod Nakashian 

diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index 5e1e23b2cdb5..bb560264743b 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -52,7 +52,7 @@ namespace desktop {
 }
 
 RectangleAndPart(const tools::Rectangle* pRect, int nPart)
-: m_aRectangle( pRect ? *pRect : emptyAllRectangle)
+: m_aRectangle( pRect ? CheckedRectangle(*pRect) : 
emptyAllRectangle)
 , m_nPart(nPart)
 {
 }
@@ -81,6 +81,8 @@ namespace desktop {
 }
 
 static RectangleAndPart Create(const std::string& rPayload);
+static tools::Rectangle CheckedRectangle(tools::Long nLeft, 
tools::Long nTop, tools::Long nWidth, tools::Long nHeight);
+static tools::Rectangle CheckedRectangle(const tools::Rectangle& rect);
 };
 
 class DESKTOP_DLLPUBLIC CallbackFlushHandler final : public Idle, public 
SfxLokCallbackInterface
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index bf4bd7883f4f..22523ecc2227 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -555,6 +555,13 @@ RectangleAndPart RectangleAndPart::Create(const 
std::string& rPayload)
 nPart = rtl_str_toInt64_WithLength(pos, 10, end - pos);
 }
 
+aRet.m_aRectangle = CheckedRectangle(nLeft, nTop, nWidth, nHeight);
+aRet.m_nPart = nPart;
+return aRet;
+}
+
+tools::Rectangle RectangleAndPart::CheckedRectangle(tools::Long nLeft, 
tools::Long nTop, tools::Long nWidth, tools::Long nHeight)
+{
 if (nWidth > 0 && nHeight > 0)
 {
 // The top-left corner starts at (0, 0).
@@ -572,14 +579,15 @@ RectangleAndPart RectangleAndPart::Create(const 
std::string& rPayload)
 }
 
 if (nWidth > 0 && nHeight > 0)
-{
-aRet.m_aRectangle = tools::Rectangle(nLeft, nTop, nLeft + nWidth, 
nTop + nHeight);
-}
+return tools::Rectangle(nLeft, nTop, nLeft + nWidth, nTop + 
nHeight);
 }
-// else leave empty rect.
+// Else set empty rect.
+return tools::Rectangle();
+}
 
-aRet.m_nPart = nPart;
-return aRet;
+tools::Rectangle RectangleAndPart::CheckedRectangle(const tools::Rectangle& 
rect)
+{
+return CheckedRectangle(rect.Left(), rect.Top(), rect.getWidth(), 
rect.getHeight());
 }
 
 const std::string& CallbackFlushHandler::CallbackData::getPayload() const


[Libreoffice-commits] core.git: Branch 'distro/collabora/co-2021' - desktop/inc desktop/source

2021-12-09 Thread Luboš Luňák (via logerrit)
 desktop/inc/lib/init.hxx|2 +-
 desktop/source/lib/init.cxx |2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

New commits:
commit 1fe6e08a1bba3a1b981218bbc485c8fa162ba162
Author: Luboš Luňák 
AuthorDate: Mon Oct 25 21:13:42 2021 +0200
Commit: Andras Timar 
CommitDate: Thu Dec 9 13:24:46 2021 +0100

make sure vector elements are initialized properly

Change-Id: If18268a26118ea587f474c21b7ca0f1fa4622744
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126442
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Andras Timar 

diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index 3f3802d17d4e..4499914839a0 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -197,7 +197,7 @@ namespace desktop {
 std::vector m_updatedTypes; // index is type, value is if set
 struct PerViewIdData
 {
-bool set; // value is if set
+bool set = false; // value is if set
 int sourceViewId;
 };
 // Flat_map is used in preference to unordered_map because the map is 
accessed very often.
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 16ffe6f097e7..3bd212195f4d 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1505,7 +1505,7 @@ void CallbackFlushHandler::setUpdatedTypePerViewId( int 
nType, int nViewId, int
 assert(isUpdatedTypePerViewId(nType));
 std::vector& types = m_updatedTypesPerViewId[ nViewId ];
 if( types.size() <= o3tl::make_unsigned( nType ))
-types.resize( nType + 1 ); // new are default-constructed, i.e. false
+types.resize( nType + 1 ); // new are default-constructed, i.e. 'set' 
is false
 types[ nType ] = PerViewIdData{ value, nSourceViewId };
 }
 


[Libreoffice-commits] core.git: Branch 'distro/collabora/co-2021' - desktop/inc desktop/source

2021-10-26 Thread Luboš Luňák (via logerrit)
 desktop/inc/lib/init.hxx|4 +++-
 desktop/source/lib/init.cxx |2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

New commits:
commit 6af4b4c8dcfde5c8e258fc356cbe2d6cf94490c8
Author: Luboš Luňák 
AuthorDate: Mon Oct 25 22:48:28 2021 +0200
Commit: Luboš Luňák 
CommitDate: Tue Oct 26 20:34:12 2021 +0200

use boost flat_map for faster map

setUpdatedTypePerViewId() gets called so often that even unordered_map
lookup and allocations show up in profiling. It seems that flat_map
can do better.

Change-Id: Id2e4f0c40d6973b51e557f84a08bf12feb58b3ce
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124191
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Luboš Luňák 

diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index 2035226bc059..3f3802d17d4e 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -16,6 +16,7 @@
 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -199,7 +200,8 @@ namespace desktop {
 bool set; // value is if set
 int sourceViewId;
 };
-std::unordered_map> 
m_updatedTypesPerViewId; // key is view, index is type
+// Flat_map is used in preference to unordered_map because the map is 
accessed very often.
+boost::container::flat_map> 
m_updatedTypesPerViewId; // key is view, index is type
 
 LibreOfficeKitDocument* m_pDocument;
 int m_viewId = -1; // view id of the associated SfxViewShell
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 20916a4ebd3b..a8517c3cbaba 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -2144,7 +2144,7 @@ void CallbackFlushHandler::enqueueUpdatedTypes()
 // First move data to local structures, so that callbacks don't possibly 
modify it.
 std::vector updatedTypes;
 std::swap(updatedTypes, m_updatedTypes);
-std::unordered_map> updatedTypesPerViewId;
+boost::container::flat_map> 
updatedTypesPerViewId;
 std::swap(updatedTypesPerViewId, m_updatedTypesPerViewId);
 
 // Some types must always precede other types, for example


[Libreoffice-commits] core.git: Branch 'distro/collabora/co-2021' - desktop/inc desktop/source include/editeng include/sfx2 include/test sc/qa sd/qa sfx2/source sw/inc sw/qa sw/source test/source

2021-10-23 Thread Luboš Luňák (via logerrit)
 desktop/inc/lib/init.hxx   |   23 +++
 desktop/source/lib/init.cxx|  148 +
 include/editeng/outliner.hxx   |2 
 include/sfx2/lokcallback.hxx   |   11 +
 include/sfx2/lokhelper.hxx |   18 ++-
 include/sfx2/viewsh.hxx|5 
 include/test/lokcallback.hxx   |   24 +++-
 sc/qa/unit/tiledrendering/tiledrendering.cxx   |   15 ++
 sd/qa/unit/tiledrendering/tiledrendering.cxx   |   15 ++
 sfx2/source/view/lokhelper.cxx |   69 +--
 sfx2/source/view/viewsh.cxx|   33 +
 sw/inc/view.hxx|1 
 sw/inc/viscrs.hxx  |3 
 sw/qa/core/txtnode/txtnode.cxx |2 
 sw/qa/extras/tiledrendering/tiledrendering.cxx |   72 
 sw/source/core/crsr/viscrs.cxx |   85 +-
 sw/source/uibase/inc/wrtsh.hxx |2 
 sw/source/uibase/uiview/view.cxx   |7 +
 sw/source/uibase/wrtsh/wrtsh4.cxx  |   13 ++
 test/source/lokcallback.cxx|  121 +++-
 20 files changed, 588 insertions(+), 81 deletions(-)

New commits:
commit d18d53da7cd554ed887ae53f5fb7c6ac1f7e4a98
Author: Luboš Luňák 
AuthorDate: Fri Oct 15 08:43:23 2021 +0200
Commit: Luboš Luňák 
CommitDate: Sun Oct 24 01:41:00 2021 +0200

change some LOK internal updates to be pull model instead of push

Some LOK messages may get called very often, such as updates about
cursor position. And since only the last one matters, they get
generated every time, which costs some time, and then later except
for one they get all discard again from CallbackFlushHandler queue,
which again costs time.

Change the model to instead only set an 'updated' flag, and
CallbackFlushHandler will request the actual message payload only
before flushing.

This commit changes LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR and
LOK_CALLBACK_INVALIDATE_VIEW_CURSOR to work this way.

Change-Id: I376be63176c0b4b5cb492fbf529c21ed01b35481
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124084
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Luboš Luňák 

diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index c43e82fdd430..2035226bc059 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -103,6 +103,8 @@ namespace desktop {
 virtual void libreOfficeKitViewCallback(int nType, const char* 
pPayload) override;
 virtual void libreOfficeKitViewCallbackWithViewId(int nType, const 
char* pPayload, int nViewId) override;
 virtual void libreOfficeKitViewInvalidateTilesCallback(const 
tools::Rectangle* pRect, int nPart) override;
+virtual void libreOfficeKitViewUpdatedCallback(int nType) override;
+virtual void libreOfficeKitViewUpdatedCallbackPerViewId(int nType, int 
nViewId, int nSourceViewId) override;
 
 private:
 struct CallbackData
@@ -171,6 +173,8 @@ namespace desktop {
 queue_type2::iterator toQueue2(queue_type1::iterator);
 queue_type2::reverse_iterator toQueue2(queue_type1::reverse_iterator);
 void queue(const int type, CallbackData& data);
+void enqueueUpdatedTypes();
+void enqueueUpdatedType( int type, SfxViewShell* sourceViewShell, int 
viewId );
 
 /** we frequently want to scan the queue, and mostly when we do so, we 
only care about the element type
 so we split the queue in 2 to make the scanning cache friendly. */
@@ -178,6 +182,25 @@ namespace desktop {
 queue_type2 m_queue2;
 std::map m_states;
 std::unordered_map> 
m_viewStates;
+
+// For some types only the last message matters (see isUpdatedType()) 
or only the last message
+// per each viewId value matters (see isUpdatedTypePerViewId()), so 
instead of using push model
+// where we'd get flooded by repeated messages (which might be costly 
to generate and process),
+// the preferred way is that libreOfficeKitViewUpdatedCallback()
+// or libreOfficeKitViewUpdatedCallbackPerViewId() get called to 
notify about such a message being
+// needed, and we'll set a flag here to fetch the actual message 
before flushing.
+void setUpdatedType( int nType, bool value );
+void setUpdatedTypePerViewId( int nType, int nViewId, int 
nSourceViewId, bool value );
+void resetUpdatedType( int nType);
+void resetUpdatedTypePerViewId( int nType, int nViewId );
+std::vector m_updatedTypes; // index is type, value is if set
+struct PerViewIdData
+{
+bool set; // value is if set
+int sourceViewId;
+};
+std::unordered_map> 
m_updatedTypesPerViewId; // key is view, index is type
+
 

[Libreoffice-commits] core.git: Branch 'distro/collabora/co-2021' - desktop/inc desktop/source

2021-09-28 Thread Luboš Luňák (via logerrit)
 desktop/inc/lib/init.hxx|9 +
 desktop/source/lib/init.cxx |   26 ++
 2 files changed, 31 insertions(+), 4 deletions(-)

New commits:
commit 3f6f1a45c1f4225817188f97721e6546e38871e2
Author: Luboš Luňák 
AuthorDate: Fri Sep 24 00:11:04 2021 +0200
Commit: Luboš Luňák 
CommitDate: Tue Sep 28 14:01:25 2021 +0200

add extra timeout with higher priority to LOK flushing

The normal idle has TaskPriority::POST_PAINT, which means that
if we get too busy, the idle won't be called for a long time,
meaning the queue will get longer and longer, making its processing
slower, and client interactivity will be very poor, with updates
possibly coming only when everything becomes idle.

The second timeout will flush the queue after a reasonable timeout.
I don't think there's an optimal value, so let's choose 100ms for now.

Change-Id: Ia1312a690aefd2c8628c82e0f42b2993802d8b1e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122737
Tested-by: Luboš Luňák 
Reviewed-by: Luboš Luňák 

diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index 6cbabd3b..eee6b0fb4d76 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -146,6 +146,15 @@ namespace desktop {
 void *m_pData;
 int m_nDisableCallbacks;
 std::mutex m_mutex;
+class TimeoutIdle : public Timer
+{
+public:
+TimeoutIdle( CallbackFlushHandler* handler );
+virtual void Invoke() override;
+private:
+CallbackFlushHandler* mHandler;
+};
+TimeoutIdle m_TimeoutIdle;
 };
 
 struct DESKTOP_DLLPUBLIC LibLODocument_Impl : public 
_LibreOfficeKitDocument
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 824f45b5d23f..3e09f2d8b5ab 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1392,12 +1392,28 @@ static OUString getGenerator()
 
 extern "C" {
 
+CallbackFlushHandler::TimeoutIdle::TimeoutIdle( CallbackFlushHandler* handler )
+: Timer( "lokit timer callback" )
+, mHandler( handler )
+{
+// A second timer with higher priority, it'll ensure we flush in 
reasonable time if we get too busy
+// to get POST_PAINT priority processing. Otherwise it could take a long 
time to flush.
+SetPriority(TaskPriority::DEFAULT);
+SetTimeout( 100 ); // 100 ms
+}
+
+void CallbackFlushHandler::TimeoutIdle::Invoke()
+{
+mHandler->Invoke();
+}
+
 CallbackFlushHandler::CallbackFlushHandler(LibreOfficeKitDocument* pDocument, 
LibreOfficeKitCallback pCallback, void* pData)
-: Idle( "lokit timer callback" ),
+: Idle( "lokit idle callback" ),
   m_pDocument(pDocument),
   m_pCallback(pCallback),
   m_pData(pData),
-  m_nDisableCallbacks(0)
+  m_nDisableCallbacks(0),
+  m_TimeoutIdle( this )
 {
 SetPriority(TaskPriority::POST_PAINT);
 
@@ -1414,8 +1430,6 @@ 
CallbackFlushHandler::CallbackFlushHandler(LibreOfficeKitDocument* pDocument, Li
 m_states.emplace(LOK_CALLBACK_CURSOR_VISIBLE, "NIL");
 m_states.emplace(LOK_CALLBACK_SET_PART, "NIL");
 m_states.emplace(LOK_CALLBACK_TABLE_SELECTED, "NIL");
-
-Start();
 }
 
 CallbackFlushHandler::~CallbackFlushHandler()
@@ -1696,6 +1710,8 @@ void CallbackFlushHandler::queue(const int type, const 
char* data)
 {
 Start();
 }
+if (!m_TimeoutIdle.IsActive())
+m_TimeoutIdle.Start();
 }
 
 bool CallbackFlushHandler::processInvalidateTilesEvent(int type, CallbackData& 
aCallbackData)
@@ -2059,6 +2075,8 @@ void CallbackFlushHandler::Invoke()
 
 m_queue1.clear();
 m_queue2.clear();
+Stop();
+m_TimeoutIdle.Stop();
 }
 
 bool CallbackFlushHandler::removeAll(int type)


[Libreoffice-commits] core.git: Branch 'distro/collabora/co-2021' - desktop/inc desktop/source

2021-09-22 Thread Noel Grandin (via logerrit)
 desktop/inc/lib/init.hxx|   23 ++---
 desktop/source/lib/init.cxx |  192 +---
 2 files changed, 123 insertions(+), 92 deletions(-)

New commits:
commit 475d6528a5ae1781c5b09cbcd3fd305c4180c168
Author: Noel Grandin 
AuthorDate: Wed Aug 4 13:01:22 2021 +0200
Commit: Luboš Luňák 
CommitDate: Thu Sep 23 00:09:00 2021 +0200

speed up scanning the LOK queue

we frequently scan the queue to caolesce events.
Most of the time we are scanning based on the event type.
So split the queue data into a compact queue that only contains the
type, and another queue for the rest of the data.
That makes the scanning __much__ more cache-friendly.

Change-Id: I92d0b95611cd139cac8532f9297eaabda71d5fe9
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119996
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Noel Grandin 
(cherry picked from commit acf9cf33d53e4bf598ddbdab102bfbd6bb14f8a3)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121558
Tested-by: Jenkins
(cherry picked from commit 3b3e4ee97af23f210fa39f1af3ddf1de63291371)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122434
Reviewed-by: Luboš Luňák 

diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index 3d95d4f602b4..ed35ebc2fa13 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -92,9 +92,8 @@ namespace desktop {
 
 struct CallbackData
 {
-CallbackData(int type, const std::string& payload)
-: Type(type)
-, PayloadString(payload)
+CallbackData(const std::string& payload)
+: PayloadString(payload)
 {
 }
 
@@ -117,7 +116,6 @@ namespace desktop {
 /// Returns true iff there is cached data.
 bool isCached() const { return PayloadObject.which() != 0; }
 
-int Type;
 std::string PayloadString;
 
 private:
@@ -125,14 +123,19 @@ namespace desktop {
 boost::variant PayloadObject;
 };
 
-typedef std::vector queue_type;
+typedef std::vector queue_type1;
+typedef std::vector queue_type2;
 
 private:
-bool removeAll(const std::function& rTestFunc);
-bool processInvalidateTilesEvent(CallbackData& aCallbackData);
-bool processWindowEvent(CallbackData& aCallbackData);
-
-queue_type m_queue;
+bool removeAll(const std::function& 
rTestFunc);
+bool processInvalidateTilesEvent(int type, CallbackData& 
aCallbackData);
+bool processWindowEvent(int type, CallbackData& aCallbackData);
+queue_type2::reverse_iterator toQueue2(queue_type1::reverse_iterator);
+
+/** we frequently want to scan the queue, and mostly when we do so, we 
only care about the element type
+so we split the queue in 2 to make the scanning cache friendly. */
+queue_type1 m_queue1;
+queue_type2 m_queue2;
 std::map m_states;
 std::unordered_map> 
m_viewStates;
 LibreOfficeKitDocument* m_pDocument;
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index c95de6ed4082..86c468df402f 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1438,13 +1438,19 @@ void CallbackFlushHandler::callback(const int type, 
const char* payload, void* d
 }
 }
 
+CallbackFlushHandler::queue_type2::reverse_iterator 
CallbackFlushHandler::toQueue2(CallbackFlushHandler::queue_type1::reverse_iterator
 pos)
+{
+int delta = std::distance(m_queue1.rbegin(), pos);
+return m_queue2.rbegin() + delta;
+}
+
 void CallbackFlushHandler::queue(const int type, const char* data)
 {
 comphelper::ProfileZone aZone("CallbackFlushHandler::queue");
 
-CallbackData aCallbackData(type, (data ? data : "(nil)"));
+CallbackData aCallbackData(data ? data : "(nil)");
 const std::string& payload = aCallbackData.PayloadString;
-SAL_INFO("lok", "Queue: [" << type << "]: [" << payload << "] on " << 
m_queue.size() << " entries.");
+SAL_INFO("lok", "Queue: [" << type << "]: [" << payload << "] on " << 
m_queue1.size() << " entries.");
 
 bool bIsChartActive = false;
 if (type == LOK_CALLBACK_GRAPHIC_SELECTION)
@@ -1523,10 +1529,10 @@ void CallbackFlushHandler::queue(const int type, const 
char* data)
 case LOK_CALLBACK_CALC_FUNCTION_LIST:
 case LOK_CALLBACK_INVALIDATE_SHEET_GEOMETRY:
 {
-const auto& pos = std::find_if(m_queue.rbegin(), m_queue.rend(),
-[type] (const queue_type::value_type& elem) { return 
(elem.Type == type); });
-
-if (pos != m_queue.rend() && pos->PayloadString == payload)
+const auto& pos = std::find_if(m_queue1.rbegin(), m_queue1.rend(),
+[type] (int elemType) { return (elemType == type); });
+auto pos2 = toQueue2(pos);
+if (pos !=