diff options
Diffstat (limited to 'desktop/inc')
-rw-r--r-- | desktop/inc/lib/init.hxx | 201 |
1 files changed, 10 insertions, 191 deletions
diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx index 5d3297733edc..3a5c5b7333c9 100644 --- a/desktop/inc/lib/init.hxx +++ b/desktop/inc/lib/init.hxx @@ -27,202 +27,21 @@ class LOKInteractionHandler; namespace desktop { - class CallbackFlushHandler : public Idle + class DESKTOP_DLLPUBLIC CallbackFlushHandler : public Idle { public: - explicit CallbackFlushHandler(LibreOfficeKitCallback pCallback, void* pData) - : Idle( "lokit timer callback" ), - m_pCallback(pCallback), - m_pData(pData), - m_bPartTilePainting(false) - { - SetPriority(SchedulerPriority::POST_PAINT); - - // Add the states that are safe to skip duplicates on, - // even when not consequent. - m_states.emplace(LOK_CALLBACK_TEXT_SELECTION_START, "NIL"); - m_states.emplace(LOK_CALLBACK_TEXT_SELECTION_END, "NIL"); - m_states.emplace(LOK_CALLBACK_TEXT_SELECTION, "NIL"); - m_states.emplace(LOK_CALLBACK_GRAPHIC_SELECTION, "NIL"); - m_states.emplace(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, "NIL"); - m_states.emplace(LOK_CALLBACK_STATE_CHANGED, "NIL"); - m_states.emplace(LOK_CALLBACK_MOUSE_POINTER, "NIL"); - m_states.emplace(LOK_CALLBACK_CELL_CURSOR, "NIL"); - m_states.emplace(LOK_CALLBACK_CELL_FORMULA, "NIL"); - m_states.emplace(LOK_CALLBACK_CURSOR_VISIBLE, "NIL"); - m_states.emplace(LOK_CALLBACK_SET_PART, "NIL"); - - Start(); - } - - virtual ~CallbackFlushHandler() - { - Stop(); - - // We might have important notification (.uno:save?). - flush(); - } - - virtual void Invoke() override - { - flush(); - } - - static - void callback(const int type, const char* payload, void* data) - { - CallbackFlushHandler* self = static_cast<CallbackFlushHandler*>(data); - if (self) - { - self->queue(type, payload); - } - } - - void queue(const int type, const char* data) - { - const std::string payload(data ? data : "(nil)"); - if (m_bPartTilePainting) - { - // We drop notifications when this is set, except for important ones. - // When we issue a complex command (such as .uno:InsertAnnotation) - // there will be multiple notifications. On the first invalidation - // we will start painting, but other events will get fired - // while the complex command in question executes. - // We don't want to supress everything here on the wrong assumption - // that no new events are fired during painting. - if (type != LOK_CALLBACK_STATE_CHANGED && - type != LOK_CALLBACK_INVALIDATE_TILES && - type != LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR && - type != LOK_CALLBACK_CURSOR_VISIBLE && - type != LOK_CALLBACK_TEXT_SELECTION) - { - //SAL_WARN("lokevt", "Skipping while painting [" + std::to_string(type) + "]: [" + payload + "]."); - return; - } - } - - // Supress invalid payloads. - if (type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR && - payload.find(", 0, 0, ") != std::string::npos) - { - // The cursor position is often the relative coordinates of the widget - // issueing it, instead of the absolute one that we expect. - // This is temporary however, and, once the control is created and initialized - // correctly, it eventually emits the correct absolute coordinates. - //SAL_WARN("lokevt", "Skipping invalid event [" + std::to_string(type) + "]: [" + payload + "]."); - return; - } - - std::unique_lock<std::mutex> lock(m_mutex); - - 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_WARN("lokevt", "Skipping duplicate [" + std::to_string(type) + "]: [" + payload + "]."); - return; - } - - stateIt->second = payload; - } - - if (type == LOK_CALLBACK_TEXT_SELECTION && payload.empty()) - { - // Removing text selection invalidates the start and end as well. - m_states[LOK_CALLBACK_TEXT_SELECTION_START] = ""; - m_states[LOK_CALLBACK_TEXT_SELECTION_END] = ""; - } - - m_queue.emplace_back(type, payload); - - // These are safe to use the latest state and ignore previous - // ones (if any) since the last overrides previous ones. - switch (type) - { - case LOK_CALLBACK_TEXT_SELECTION_START: - case LOK_CALLBACK_TEXT_SELECTION_END: - case LOK_CALLBACK_TEXT_SELECTION: - case LOK_CALLBACK_GRAPHIC_SELECTION: - case LOK_CALLBACK_MOUSE_POINTER: - case LOK_CALLBACK_CELL_CURSOR: - case LOK_CALLBACK_CELL_FORMULA: - case LOK_CALLBACK_CURSOR_VISIBLE: - case LOK_CALLBACK_SET_PART: - case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE: - removeAllButLast(type, false); - break; - - // These come with rects, so drop earlier - // only when the latter includes former ones. - case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR: - case LOK_CALLBACK_INVALIDATE_TILES: - if (payload.empty()) - { - // Invalidating everything means previously - // invalidated tiles can be dropped. - removeAllButLast(type, false); - } - else - { - removeAllButLast(type, true); - } - - break; - } - - lock.unlock(); - if (!IsActive()) - { - Start(); - } - } - - void setPartTilePainting(const bool bPartPainting) { m_bPartTilePainting = bPartPainting; } - bool isPartTilePainting() const { return m_bPartTilePainting; } + explicit CallbackFlushHandler(LibreOfficeKitCallback pCallback, void* pData); + virtual ~CallbackFlushHandler(); + virtual void Invoke() override; + static void callback(const int type, const char* payload, void* data); + void queue(const int type, const char* data); + void setPartTilePainting(const bool bPartPainting); + bool isPartTilePainting() const; private: - void flush() - { - if (m_pCallback) - { - std::unique_lock<std::mutex> lock(m_mutex); - for (auto& pair : m_queue) - { - m_pCallback(pair.first, pair.second.c_str(), m_pData); - } + void flush(); + void removeAllButLast(const int type, const bool identical); - m_queue.clear(); - } - } - - void removeAllButLast(const int type, const bool identical) - { - int i = m_queue.size() - 1; - std::string payload; - for (; i >= 0; --i) - { - if (m_queue[i].first == type) - { - payload = m_queue[i].second; - //SAL_WARN("lokevt", "Found [" + std::to_string(type) + "] at " + std::to_string(i) + ": [" + payload + "]."); - break; - } - } - - for (--i; i >= 0; --i) - { - if (m_queue[i].first == type && - (!identical || m_queue[i].second == payload)) - { - //SAL_WARN("lokevt", "Removing [" + std::to_string(type) + "] at " + std::to_string(i) + ": " + m_queue[i].second + "]."); - m_queue.erase(m_queue.begin() + i); - } - } - } - - private: std::vector<std::pair<int, std::string>> m_queue; std::map<int, std::string> m_states; LibreOfficeKitCallback m_pCallback; |