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>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user