summaryrefslogtreecommitdiff
path: root/desktop
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2022-01-18 17:04:15 +0000
committerMichael Meeks <michael.meeks@collabora.com>2022-01-20 12:06:32 +0100
commit02634fb7c7e8dc613ffc3717bb244f85cf81a7c6 (patch)
tree3d01bda9c41d3ded9b7744202b99d8183b823e34 /desktop
parent1284937bf2bd112197a99e844a5a1a961e2cf4fc (diff)
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/+/128539 Tested-by: Jenkins Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Diffstat (limited to 'desktop')
-rw-r--r--desktop/inc/lib/init.hxx2
-rw-r--r--desktop/source/lib/init.cxx49
2 files changed, 42 insertions, 9 deletions
diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index 636cf8ef9863..288fa8ebfcc0 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -87,6 +87,7 @@ namespace desktop {
static tools::Rectangle SanitizedRectangle(const tools::Rectangle& rect);
};
+ /// One instance of this per view, handles flushing callbacks
class DESKTOP_DLLPUBLIC CallbackFlushHandler final : public Idle, public SfxLokCallbackInterface
{
public:
@@ -191,6 +192,7 @@ namespace desktop {
queue_type1 m_queue1;
queue_type2 m_queue2;
std::map<int, std::string> m_states;
+ std::unordered_map<std::string, std::string> m_lastStateChange;
std::unordered_map<int, std::unordered_map<int, std::string>> 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 168fd820d54d..e6771b6d08f7 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1461,6 +1461,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),
@@ -2255,22 +2256,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())