[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.0' - 9 commits - desktop/inc desktop/source sc/source vcl/source

Ashod Nakashian (via logerrit) logerrit at kemper.freedesktop.org
Tue May 14 09:40:58 UTC 2019


 desktop/inc/lib/init.hxx      |    4 
 desktop/source/lib/init.cxx   |  578 +++++++++++++++++++++++-------------------
 sc/source/ui/view/tabview.cxx |   16 -
 vcl/source/app/svapp.cxx      |    9 
 vcl/source/window/dialog.cxx  |   19 +
 5 files changed, 367 insertions(+), 259 deletions(-)

New commits:
commit 53dca9c92fd8941b90b2fd83ba7ec0e46d7bb35b
Author:     Ashod Nakashian <ashod.nakashian at collabora.co.uk>
AuthorDate: Sun May 12 17:00:45 2019 -0400
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue May 14 11:39:48 2019 +0200

    LOK: sc: Issue DOCUMENT_SIZE_CHANGED only when size changes
    
    Issuing DOCUMENT_SIZE_CHANGED triggers document-loaded event.
    This is accidental and historic, but the end result is that
    the client assumes everything is invalidated and fires
    initialization handlers, which are normally invoked the
    first time a document is loaded. Undesirable when really
    nothing has changed.
    
    Change-Id: Ia4fa4479ca627b0f605e4ff5009f7e631a26f6d7

diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx
index 520dafa3cd18..febe50df5f73 100644
--- a/sc/source/ui/view/tabview.cxx
+++ b/sc/source/ui/view/tabview.cxx
@@ -2704,12 +2704,16 @@ OUString ScTabView::getRowColumnHeaders(const tools::Rectangle& rRectangle)
 
         if (pDocSh)
         {
-            // Provide size in the payload, so clients don't have to
-            // call lok::Document::getDocumentSize().
-            std::stringstream ss;
-            ss << aNewSize.Width() << ", " << aNewSize.Height();
-            OString sSize = ss.str().c_str();
-            aViewData.GetViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_DOCUMENT_SIZE_CHANGED, sSize.getStr());
+            if (aOldSize != aNewSize)
+            {
+                // Provide size in the payload, so clients don't have to
+                // call lok::Document::getDocumentSize().
+                std::stringstream ss;
+                ss << aNewSize.Width() << ", " << aNewSize.Height();
+                OString sSize = ss.str().c_str();
+                aViewData.GetViewShell()->libreOfficeKitViewCallback(
+                    LOK_CALLBACK_DOCUMENT_SIZE_CHANGED, sSize.getStr());
+            }
 
             // New area extended to the right of the sheet after last column
             // including overlapping area with aNewRowArea
commit 171a2300d37d73065e5e3bd4b77678e35f678adf
Author:     Ashod Nakashian <ashod.nakashian at collabora.co.uk>
AuthorDate: Thu May 9 22:49:37 2019 -0400
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue May 14 11:39:47 2019 +0200

    LOK: Do not offset window coordinates in LOK
    
    This fixes the issue with selecting the incorrect
    color when clicking on the color presets in the
    color picker window in LOK. Because the window
    coordinates are shifted in Core, and LOK client
    sends in absolute coordinates, the shift causes
    a different color to be selected.
    
    Change-Id: Ib818b83c0f0c727944068cb244f8d10666e5bc1d

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index a6ede4ba4e51..902dceb64f31 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -3253,7 +3253,7 @@ static void doc_postWindowMouseEvent(LibreOfficeKitDocument* /*pThis*/, unsigned
         return;
     }
 
-    Point aPos(nX, nY);
+    const Point aPos(nX, nY);
     MouseEvent aEvent(aPos, nCount, MouseEventModifiers::SIMPLECLICK, nButtons, nModifier);
 
     if (Dialog* pDialog = dynamic_cast<Dialog*>(pWindow.get()))
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index 70cc7287acec..ea094534833e 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -78,6 +78,7 @@
 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
 #include <comphelper/solarmutex.hxx>
 #include <osl/process.h>
+#include <comphelper/lok.hxx>
 
 #include <cassert>
 #include <utility>
@@ -935,8 +936,12 @@ ImplSVEvent* Application::PostMouseEvent( VclEventId nEvent, vcl::Window *pWin,
     {
         Point aTransformedPos( pMouseEvent->GetPosPixel() );
 
-        aTransformedPos.X() += pWin->GetOutOffXPixel();
-        aTransformedPos.Y() += pWin->GetOutOffYPixel();
+        // LOK uses (0, 0) as the origin of all windows; don't offset.
+        if (!comphelper::LibreOfficeKit::isActive())
+        {
+            aTransformedPos.X() += pWin->GetOutOffXPixel();
+            aTransformedPos.Y() += pWin->GetOutOffYPixel();
+        }
 
         const MouseEvent aTransformedEvent( aTransformedPos, pMouseEvent->GetClicks(), pMouseEvent->GetMode(),
                                             pMouseEvent->GetButtons(), pMouseEvent->GetModifier() );
commit d5b900630caefc4d3b62a31906117cf4acd623b1
Author:     Ashod Nakashian <ashod.nakashian at collabora.co.uk>
AuthorDate: Wed May 8 21:33:55 2019 -0400
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue May 14 11:39:46 2019 +0200

    LOK: Reduce and improve logging of event compression
    
    Change-Id: I84e0e8806eb6f4fbda063ebc29fafa791d472bb8

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 754d7dc589e9..a6ede4ba4e51 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1171,11 +1171,13 @@ void CallbackFlushHandler::queue(const int type, const char* data)
         // Dump the queue state and validate cached data.
         int i = 1;
         std::ostringstream oss;
-        oss << '\n';
+        if (m_queue.empty())
+            oss << "Empty";
+        else
+            oss << m_queue.size() << " items\n";
         for (const CallbackData& c : m_queue)
             oss << i++ << ": [" << c.Type << "] [" << c.PayloadString << "].\n";
-        const std::string aQueued = oss.str();
-        SAL_INFO("lok", "Current Queue: " << (aQueued.empty() ? "Empty" : aQueued));
+        SAL_INFO("lok", "Current Queue: " << oss.str());
         for (const CallbackData& c : m_queue)
             assert(c.validate());
     }
@@ -1393,45 +1395,53 @@ bool CallbackFlushHandler::processWindowEvent(CallbackData& aCallbackData)
                 const boost::property_tree::ptree& aOldTree = elem.getJson();
                 if (aOldTree.get<std::string>("action", "") == "invalidate")
                 {
-                    const unsigned nOldDialogId = aOldTree.get<unsigned>("id", 0);
-                    std::string aOldRectStr = aOldTree.get<std::string>("rectangle", "");
-                    // not possible that we encounter an empty
-                    // rectangle here; we already handled this
-                    // case before
-                    std::istringstream aOldRectStream(aOldRectStr);
+                    // Not possible that we encounter an empty rectangle here; we already handled this case above.
+                    std::istringstream aOldRectStream(aOldTree.get<std::string>("rectangle", ""));
                     long nOldLeft, nOldTop, nOldWidth, nOldHeight;
                     char nOldComma;
                     aOldRectStream >> nOldLeft >> nOldComma >> nOldTop >> nOldComma >> nOldWidth
                         >> nOldComma >> nOldHeight;
-                    tools::Rectangle aOldRect = tools::Rectangle(
+                    const tools::Rectangle aOldRect = tools::Rectangle(
                         nOldLeft, nOldTop, nOldLeft + nOldWidth, nOldTop + nOldHeight);
 
-                    if (nLOKWindowId == nOldDialogId)
+                    if (nLOKWindowId == aOldTree.get<unsigned>("id", 0))
                     {
+                        if (aNewRect == aOldRect)
+                        {
+                            SAL_INFO("lok.dialog", "Duplicate rect [" << aNewRect.toString()
+                                                                      << "]. Skipping new.");
+                            // We have a rectangle in the queue already that makes the current Callback useless.
+                            currentIsRedundant = true;
+                            return false;
+                        }
                         // new one engulfs the old one?
-                        if (aNewRect.IsInside(aOldRect))
+                        else if (aNewRect.IsInside(aOldRect))
                         {
-                            SAL_INFO("lok.dialog", "New " << aNewRect.toString() << " engulfs old "
-                                                          << aOldRect.toString() << ".");
+                            SAL_INFO("lok.dialog",
+                                     "New rect [" << aNewRect.toString() << "] engulfs old ["
+                                                  << aOldRect.toString() << "]. Replacing old.");
                             return true;
                         }
                         // old one engulfs the new one?
                         else if (aOldRect.IsInside(aNewRect))
                         {
-                            SAL_INFO("lok.dialog", "Old " << aOldRect.toString() << " engulfs new "
-                                                          << aNewRect.toString() << ".");
-                            // we have a rectangle in the queue
-                            // already that makes the current
-                            // Callback useless
+                            SAL_INFO("lok.dialog",
+                                     "Old rect [" << aOldRect.toString() << "] engulfs new ["
+                                                  << aNewRect.toString() << "]. Skipping new.");
+                            // We have a rectangle in the queue already that makes the current Callback useless.
                             currentIsRedundant = true;
                             return false;
                         }
                         else
                         {
-                            SAL_INFO("lok.dialog", "Merging " << aNewRect.toString() << " & "
-                                                              << aOldRect.toString());
+                            // Overlapping rects.
+                            const tools::Rectangle aPreMergeRect = aNewRect;
                             aNewRect.Union(aOldRect);
-                            SAL_INFO("lok.dialog", "Merged: " << aNewRect.toString());
+                            SAL_INFO("lok.dialog", "Merging rects ["
+                                                       << aPreMergeRect.toString() << "] & ["
+                                                       << aOldRect.toString() << "] = ["
+                                                       << aNewRect.toString()
+                                                       << "]. Replacing old.");
                             return true;
                         }
                     }
@@ -1443,12 +1453,7 @@ bool CallbackFlushHandler::processWindowEvent(CallbackData& aCallbackData)
 
             // Do not enqueue if redundant.
             if (currentIsRedundant)
-            {
-                SAL_INFO("lok.dialog", "Current payload is engulfed by one already in the queue. "
-                                       "Skipping redundant payload: "
-                                           << aNewRect.toString());
                 return true;
-            }
 
             aTree.put("rectangle", aNewRect.toString().getStr());
             aCallbackData.setJson(aTree);
commit 0bb310d7ce39421ecc4ff90518ffdf6aa01d1b02
Author:     Ashod Nakashian <ashod.nakashian at collabora.co.uk>
AuthorDate: Wed May 8 21:17:00 2019 -0400
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue May 14 11:39:46 2019 +0200

    LOK: Minor window event processing cleanup
    
    This reduces the number of json reads we do
    when compressing window events, which happens quite
    often.
    
    Change-Id: I1c85f28867b52cad85445fff8a031b990dad8b56

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index abb4ec547047..754d7dc589e9 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1328,7 +1328,8 @@ bool CallbackFlushHandler::processWindowEvent(CallbackData& aCallbackData)
 
     boost::property_tree::ptree& aTree = aCallbackData.setJson(payload);
     const unsigned nLOKWindowId = aTree.get<unsigned>("id", 0);
-    if (aTree.get<std::string>("action", "") == "invalidate")
+    const std::string aAction = aTree.get<std::string>("action", "");
+    if (aAction == "invalidate")
     {
         std::string aRectStr = aTree.get<std::string>("rectangle", "");
         // no 'rectangle' field => invalidate all of the window =>
@@ -1339,9 +1340,8 @@ bool CallbackFlushHandler::processWindowEvent(CallbackData& aCallbackData)
                 if (elem.Type == LOK_CALLBACK_WINDOW)
                 {
                     const boost::property_tree::ptree& aOldTree = elem.getJson();
-                    const unsigned nOldDialogId = aOldTree.get<unsigned>("id", 0);
-                    if (aOldTree.get<std::string>("action", "") == "invalidate"
-                        && nLOKWindowId == nOldDialogId)
+                    if (nLOKWindowId == aOldTree.get<unsigned>("id", 0)
+                        && aOldTree.get<std::string>("action", "") == "invalidate")
                     {
                         return true;
                     }
@@ -1360,9 +1360,8 @@ bool CallbackFlushHandler::processWindowEvent(CallbackData& aCallbackData)
                                        return false;
 
                                    const boost::property_tree::ptree& aOldTree = elem.getJson();
-                                   const unsigned nOldDialogId = aOldTree.get<unsigned>("id", 0);
-                                   if (aOldTree.get<std::string>("action", "") == "invalidate"
-                                       && nLOKWindowId == nOldDialogId
+                                   if (nLOKWindowId == aOldTree.get<unsigned>("id", 0)
+                                       && aOldTree.get<std::string>("action", "") == "invalidate"
                                        && aOldTree.get<std::string>("rectangle", "").empty())
                                    {
                                        return true;
@@ -1442,6 +1441,7 @@ bool CallbackFlushHandler::processWindowEvent(CallbackData& aCallbackData)
                 return false;
             });
 
+            // Do not enqueue if redundant.
             if (currentIsRedundant)
             {
                 SAL_INFO("lok.dialog", "Current payload is engulfed by one already in the queue. "
@@ -1455,7 +1455,7 @@ bool CallbackFlushHandler::processWindowEvent(CallbackData& aCallbackData)
             assert(aCallbackData.validate() && "Validation after setJson failed!");
         }
     }
-    else if (aTree.get<std::string>("action", "") == "created")
+    else if (aAction == "created")
     {
         // Remove all previous actions on same dialog, if we are creating it anew.
         removeAll([&nLOKWindowId](const queue_type::value_type& elem) {
@@ -1468,7 +1468,7 @@ bool CallbackFlushHandler::processWindowEvent(CallbackData& aCallbackData)
             return false;
         });
     }
-    else if (aTree.get<std::string>("action", "") == "size_changed")
+    else if (aAction == "size_changed")
     {
         // A size change is practically re-creation of the window.
         // But at a minimum it's a full invalidation.
commit 570a3c5361d58635e4d0ac8baf6df787bd2290ad
Author:     Ashod Nakashian <ashod.nakashian at collabora.co.uk>
AuthorDate: Wed May 8 11:45:49 2019 -0400
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue May 14 11:39:45 2019 +0200

    LOK: Refactor large event queueing cases
    
    This makes it more readable and reduces indentations.
    
    No functional change intended.
    
    Change-Id: I129ecff9083c459d633c0965eab6e06ba3dcf499

diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index b63794d2a9de..3587ba003e37 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -131,6 +131,8 @@ namespace desktop {
 
     private:
         bool removeAll(const std::function<bool (const queue_type::value_type&)>& rTestFunc);
+        bool processInvalidateTilesEvent(CallbackData& aCallbackData);
+        bool processWindowEvent(CallbackData& aCallbackData);
 
         queue_type m_queue;
         std::map<int, std::string> m_states;
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 2f68b1b44dfb..abb4ec547047 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1131,124 +1131,8 @@ void CallbackFlushHandler::queue(const int type, const char* data)
             break;
 
             case LOK_CALLBACK_INVALIDATE_TILES:
-            {
-                RectangleAndPart& rcNew = aCallbackData.setRectangleAndPart(payload);
-                if (rcNew.isEmpty())
-                {
-                    SAL_INFO("lok", "Skipping invalid event [" << type << "]: [" << payload << "].");
+                if (processInvalidateTilesEvent(aCallbackData))
                     return;
-                }
-
-                // If we have to invalidate all tiles, we can skip any new tile invalidation.
-                // Find the last INVALIDATE_TILES entry, if any to see if it's invalidate-all.
-                const auto& pos = std::find_if(m_queue.rbegin(), m_queue.rend(),
-                        [] (const queue_type::value_type& elem) { return (elem.Type == LOK_CALLBACK_INVALIDATE_TILES); });
-                if (pos != m_queue.rend())
-                {
-                    const RectangleAndPart& rcOld = pos->getRectangleAndPart();
-                    if (rcOld.isInfinite() && (rcOld.m_nPart == -1 || rcOld.m_nPart == rcNew.m_nPart))
-                    {
-                        SAL_INFO("lok", "Skipping queue [" << type << "]: [" << payload << "] since all tiles need to be invalidated.");
-                        return;
-                    }
-
-                    if (rcOld.m_nPart == -1 || rcOld.m_nPart == rcNew.m_nPart)
-                    {
-                        // If fully overlapping.
-                        if (rcOld.m_aRectangle.IsInside(rcNew.m_aRectangle))
-                        {
-                            SAL_INFO("lok", "Skipping queue [" << type << "]: [" << payload << "] since overlaps existing all-parts.");
-                            return;
-                        }
-                    }
-                }
-
-                if (rcNew.isInfinite())
-                {
-                    SAL_INFO("lok", "Have Empty [" << type << "]: [" << payload << "] so removing all with part " << rcNew.m_nPart << ".");
-                    removeAll(
-                        [&rcNew] (const queue_type::value_type& elem) {
-                            if (elem.Type == LOK_CALLBACK_INVALIDATE_TILES)
-                            {
-                                // Remove exiting if new is all-encompassing, or if of the same part.
-                                const RectangleAndPart rcOld = RectangleAndPart::Create(elem.PayloadString);
-                                return (rcNew.m_nPart == -1 || rcOld.m_nPart == rcNew.m_nPart);
-                            }
-
-                            // Keep others.
-                            return false;
-                        }
-                    );
-                }
-                else
-                {
-                    const auto rcOrig = rcNew;
-
-                    SAL_INFO("lok", "Have [" << type << "]: [" << payload << "] so merging overlapping.");
-                    removeAll(
-                        [&rcNew] (const queue_type::value_type& elem) {
-                            if (elem.Type == LOK_CALLBACK_INVALIDATE_TILES)
-                            {
-                                const RectangleAndPart& rcOld = elem.getRectangleAndPart();
-                                if (rcNew.m_nPart != -1 && rcOld.m_nPart != -1 && rcOld.m_nPart != rcNew.m_nPart)
-                                {
-                                    SAL_INFO("lok", "Nothing to merge between new: " << rcNew.toString() << ", and old: " << rcOld.toString());
-                                    return false;
-                                }
-
-                                if (rcNew.m_nPart == -1)
-                                {
-                                    // Don't merge unless fully overlaped.
-                                    SAL_INFO("lok", "New " << rcNew.toString() << " has " << rcOld.toString() << "?");
-                                    if (rcNew.m_aRectangle.IsInside(rcOld.m_aRectangle))
-                                    {
-                                        SAL_INFO("lok", "New " << rcNew.toString() << " engulfs old " << rcOld.toString() << ".");
-                                        return true;
-                                    }
-                                }
-                                else if (rcOld.m_nPart == -1)
-                                {
-                                    // Don't merge unless fully overlaped.
-                                    SAL_INFO("lok", "Old " << rcOld.toString() << " has " << rcNew.toString() << "?");
-                                    if (rcOld.m_aRectangle.IsInside(rcNew.m_aRectangle))
-                                    {
-                                        SAL_INFO("lok", "New " << rcNew.toString() << " engulfs old " << rcOld.toString() << ".");
-                                        return true;
-                                    }
-                                }
-                                else
-                                {
-                                    const tools::Rectangle rcOverlap = rcNew.m_aRectangle.GetIntersection(rcOld.m_aRectangle);
-                                    const bool bOverlap = !rcOverlap.IsEmpty();
-                                    SAL_INFO("lok", "Merging " << rcNew.toString() << " & " << rcOld.toString() << " => " <<
-                                            rcOverlap.toString() << " Overlap: " << bOverlap);
-                                    if (bOverlap)
-                                    {
-                                        rcNew.m_aRectangle.Union(rcOld.m_aRectangle);
-                                        SAL_INFO("lok", "Merged: " << rcNew.toString());
-                                        return true;
-                                    }
-                                }
-                            }
-
-                            // Keep others.
-                            return false;
-                        }
-                    );
-
-                    if (rcNew.m_aRectangle != rcOrig.m_aRectangle)
-                    {
-                        SAL_INFO("lok", "Replacing: " << rcOrig.toString() << " by " << rcNew.toString());
-                        if (rcNew.m_aRectangle.GetWidth() < rcOrig.m_aRectangle.GetWidth() ||
-                            rcNew.m_aRectangle.GetHeight() < rcOrig.m_aRectangle.GetHeight())
-                        {
-                            SAL_WARN("lok", "Error: merged rect smaller.");
-                        }
-                    }
-                }
-
-                aCallbackData.setRectangleAndPart(rcNew);
-            }
             break;
 
             // State changes with same name override previous ones with a different value.
@@ -1270,158 +1154,8 @@ void CallbackFlushHandler::queue(const int type, const char* data)
             break;
 
             case LOK_CALLBACK_WINDOW:
-            {
-                // reading JSON by boost might be slow?
-                boost::property_tree::ptree& aTree = aCallbackData.setJson(payload);
-                const unsigned nLOKWindowId = aTree.get<unsigned>("id", 0);
-                if (aTree.get<std::string>("action", "") == "invalidate")
-                {
-                    std::string aRectStr = aTree.get<std::string>("rectangle", "");
-                    // no 'rectangle' field => invalidate all of the window =>
-                    // remove all previous window part invalidations
-                    if (aRectStr.empty())
-                    {
-                        removeAll([&nLOKWindowId] (const queue_type::value_type& elem) {
-                                if (elem.Type == LOK_CALLBACK_WINDOW)
-                                {
-                                    const boost::property_tree::ptree& aOldTree = elem.getJson();
-                                    const unsigned nOldDialogId = aOldTree.get<unsigned>("id", 0);
-                                    if (aOldTree.get<std::string>("action", "") == "invalidate" &&
-                                        nLOKWindowId == nOldDialogId)
-                                    {
-                                        return true;
-                                    }
-                                }
-                                return false;
-                            });
-                    }
-                    else
-                    {
-                        // if we have to invalidate all of the window, ignore
-                        // any part invalidation message
-                        const auto& pos = std::find_if(
-                            m_queue.rbegin(), m_queue.rend(),
-                            [&nLOKWindowId](const queue_type::value_type& elem) {
-                                if (elem.Type != LOK_CALLBACK_WINDOW)
-                                    return false;
-
-                                const boost::property_tree::ptree& aOldTree = elem.getJson();
-                                const unsigned nOldDialogId = aOldTree.get<unsigned>("id", 0);
-                                if (aOldTree.get<std::string>("action", "") == "invalidate"
-                                    && nLOKWindowId == nOldDialogId
-                                    && aOldTree.get<std::string>("rectangle", "").empty())
-                                {
-                                    return true;
-                                }
-                                return false;
-                            });
-
-                        // we found a invalidate-all window callback
-                        if (pos != m_queue.rend())
-                        {
-                            SAL_INFO("lok.dialog", "Skipping queue [" << type << "]: [" << payload << "] since whole window needs to be invalidated.");
-                            return;
-                        }
-
-                        std::istringstream aRectStream(aRectStr);
-                        long nLeft, nTop, nWidth, nHeight;
-                        char nComma;
-                        aRectStream >> nLeft >> nComma >> nTop >> nComma >> nWidth >> nComma >> nHeight;
-                        tools::Rectangle aNewRect = tools::Rectangle(nLeft, nTop, nLeft + nWidth, nTop + nHeight);
-                        bool currentIsRedundant = false;
-                        removeAll([&aNewRect, &nLOKWindowId, &currentIsRedundant] (const queue_type::value_type& elem) {
-                                if (elem.Type != LOK_CALLBACK_WINDOW)
-                                    return false;
-
-                                const boost::property_tree::ptree& aOldTree = elem.getJson();
-                                if (aOldTree.get<std::string>("action", "") == "invalidate")
-                                {
-                                    const unsigned nOldDialogId = aOldTree.get<unsigned>("id", 0);
-                                    std::string aOldRectStr = aOldTree.get<std::string>("rectangle", "");
-                                    // not possible that we encounter an empty
-                                    // rectangle here; we already handled this
-                                    // case before
-                                    std::istringstream aOldRectStream(aOldRectStr);
-                                    long nOldLeft, nOldTop, nOldWidth, nOldHeight;
-                                    char nOldComma;
-                                    aOldRectStream >> nOldLeft >> nOldComma >> nOldTop >> nOldComma >> nOldWidth >> nOldComma >> nOldHeight;
-                                    tools::Rectangle aOldRect = tools::Rectangle(nOldLeft, nOldTop, nOldLeft + nOldWidth, nOldTop + nOldHeight);
-
-                                    if (nLOKWindowId == nOldDialogId)
-                                    {
-                                        // new one engulfs the old one?
-                                        if (aNewRect.IsInside(aOldRect))
-                                        {
-                                            SAL_INFO("lok.dialog", "New " << aNewRect.toString() << " engulfs old " << aOldRect.toString() << ".");
-                                            return true;
-                                        }
-                                        // old one engulfs the new one?
-                                        else if (aOldRect.IsInside(aNewRect))
-                                        {
-                                            SAL_INFO("lok.dialog", "Old " << aOldRect.toString() << " engulfs new " << aNewRect.toString() << ".");
-                                            // we have a rectangle in the queue
-                                            // already that makes the current
-                                            // Callback useless
-                                            currentIsRedundant = true;
-                                            return false;
-                                        }
-                                        else
-                                        {
-                                            SAL_INFO("lok.dialog", "Merging " << aNewRect.toString() << " & " << aOldRect.toString());
-                                            aNewRect.Union(aOldRect);
-                                            SAL_INFO("lok.dialog", "Merged: " << aNewRect.toString());
-                                            return true;
-                                        }
-                                    }
-                                }
-
-                                // keep rest
-                                return false;
-                            });
-
-                        if (currentIsRedundant)
-                        {
-                            SAL_INFO("lok.dialog", "Current payload is engulfed by one already in the queue. Skipping redundant payload: " << aNewRect.toString());
-                            return;
-                        }
-
-                        aTree.put("rectangle", aNewRect.toString().getStr());
-                        aCallbackData.setJson(aTree);
-                        assert(aCallbackData.validate() && "Validation after setJson failed!");
-                    }
-                }
-                else if (aTree.get<std::string>("action", "") == "created")
-                {
-                    // Remove all previous actions on same dialog, if we are creating it anew.
-                    removeAll([&nLOKWindowId](const queue_type::value_type& elem) {
-                        if (elem.Type == LOK_CALLBACK_WINDOW)
-                        {
-                            const boost::property_tree::ptree& aOldTree = elem.getJson();
-                            if (nLOKWindowId == aOldTree.get<unsigned>("id", 0))
-                                return true;
-                        }
-                        return false;
-                    });
-                }
-                else if (aTree.get<std::string>("action", "") == "size_changed")
-                {
-                    // A size change is practically re-creation of the window.
-                    // But at a minimum it's a full invalidation.
-                    removeAll([&nLOKWindowId](const queue_type::value_type& elem) {
-                        if (elem.Type == LOK_CALLBACK_WINDOW)
-                        {
-                            const boost::property_tree::ptree& aOldTree = elem.getJson();
-                            if (nLOKWindowId == aOldTree.get<unsigned>("id", 0))
-                            {
-                                const std::string aOldAction = aOldTree.get<std::string>("action", "");
-                                if (aOldAction == "invalidate")
-                                    return true;
-                            }
-                        }
-                        return false;
-                    });
-                }
-            }
+                if (processWindowEvent(aCallbackData))
+                    return;
             break;
         }
     }
@@ -1454,6 +1188,309 @@ void CallbackFlushHandler::queue(const int type, const char* data)
     }
 }
 
+bool CallbackFlushHandler::processInvalidateTilesEvent(CallbackData& aCallbackData)
+{
+    const std::string& payload = aCallbackData.PayloadString;
+    const int type = aCallbackData.Type;
+
+    RectangleAndPart& rcNew = aCallbackData.setRectangleAndPart(payload);
+    if (rcNew.isEmpty())
+    {
+        SAL_INFO("lok", "Skipping invalid event [" << type << "]: [" << payload << "].");
+        return true;
+    }
+
+    // If we have to invalidate all tiles, we can skip any new tile invalidation.
+    // Find the last INVALIDATE_TILES entry, if any to see if it's invalidate-all.
+    const auto& pos
+        = std::find_if(m_queue.rbegin(), m_queue.rend(), [](const queue_type::value_type& elem) {
+              return (elem.Type == LOK_CALLBACK_INVALIDATE_TILES);
+          });
+    if (pos != m_queue.rend())
+    {
+        const RectangleAndPart& rcOld = pos->getRectangleAndPart();
+        if (rcOld.isInfinite() && (rcOld.m_nPart == -1 || rcOld.m_nPart == rcNew.m_nPart))
+        {
+            SAL_INFO("lok", "Skipping queue [" << type << "]: [" << payload
+                                               << "] since all tiles need to be invalidated.");
+            return true;
+        }
+
+        if (rcOld.m_nPart == -1 || rcOld.m_nPart == rcNew.m_nPart)
+        {
+            // If fully overlapping.
+            if (rcOld.m_aRectangle.IsInside(rcNew.m_aRectangle))
+            {
+                SAL_INFO("lok", "Skipping queue [" << type << "]: [" << payload
+                                                   << "] since overlaps existing all-parts.");
+                return true;
+            }
+        }
+    }
+
+    if (rcNew.isInfinite())
+    {
+        SAL_INFO("lok", "Have Empty [" << type << "]: [" << payload
+                                       << "] so removing all with part " << rcNew.m_nPart << ".");
+        removeAll([&rcNew](const queue_type::value_type& elem) {
+            if (elem.Type == LOK_CALLBACK_INVALIDATE_TILES)
+            {
+                // Remove exiting if new is all-encompassing, or if of the same part.
+                const RectangleAndPart rcOld = RectangleAndPart::Create(elem.PayloadString);
+                return (rcNew.m_nPart == -1 || rcOld.m_nPart == rcNew.m_nPart);
+            }
+
+            // Keep others.
+            return false;
+        });
+    }
+    else
+    {
+        const auto rcOrig = rcNew;
+
+        SAL_INFO("lok", "Have [" << type << "]: [" << payload << "] so merging overlapping.");
+        removeAll([&rcNew](const queue_type::value_type& elem) {
+            if (elem.Type == LOK_CALLBACK_INVALIDATE_TILES)
+            {
+                const RectangleAndPart& rcOld = elem.getRectangleAndPart();
+                if (rcNew.m_nPart != -1 && rcOld.m_nPart != -1 && rcOld.m_nPart != rcNew.m_nPart)
+                {
+                    SAL_INFO("lok", "Nothing to merge between new: "
+                                        << rcNew.toString() << ", and old: " << rcOld.toString());
+                    return false;
+                }
+
+                if (rcNew.m_nPart == -1)
+                {
+                    // Don't merge unless fully overlaped.
+                    SAL_INFO("lok", "New " << rcNew.toString() << " has " << rcOld.toString()
+                                           << "?");
+                    if (rcNew.m_aRectangle.IsInside(rcOld.m_aRectangle))
+                    {
+                        SAL_INFO("lok", "New " << rcNew.toString() << " engulfs old "
+                                               << rcOld.toString() << ".");
+                        return true;
+                    }
+                }
+                else if (rcOld.m_nPart == -1)
+                {
+                    // Don't merge unless fully overlaped.
+                    SAL_INFO("lok", "Old " << rcOld.toString() << " has " << rcNew.toString()
+                                           << "?");
+                    if (rcOld.m_aRectangle.IsInside(rcNew.m_aRectangle))
+                    {
+                        SAL_INFO("lok", "New " << rcNew.toString() << " engulfs old "
+                                               << rcOld.toString() << ".");
+                        return true;
+                    }
+                }
+                else
+                {
+                    const tools::Rectangle rcOverlap
+                        = rcNew.m_aRectangle.GetIntersection(rcOld.m_aRectangle);
+                    const bool bOverlap = !rcOverlap.IsEmpty();
+                    SAL_INFO("lok", "Merging " << rcNew.toString() << " & " << rcOld.toString()
+                                               << " => " << rcOverlap.toString()
+                                               << " Overlap: " << bOverlap);
+                    if (bOverlap)
+                    {
+                        rcNew.m_aRectangle.Union(rcOld.m_aRectangle);
+                        SAL_INFO("lok", "Merged: " << rcNew.toString());
+                        return true;
+                    }
+                }
+            }
+
+            // Keep others.
+            return false;
+        });
+
+        if (rcNew.m_aRectangle != rcOrig.m_aRectangle)
+        {
+            SAL_INFO("lok", "Replacing: " << rcOrig.toString() << " by " << rcNew.toString());
+            if (rcNew.m_aRectangle.GetWidth() < rcOrig.m_aRectangle.GetWidth()
+                || rcNew.m_aRectangle.GetHeight() < rcOrig.m_aRectangle.GetHeight())
+            {
+                SAL_WARN("lok", "Error: merged rect smaller.");
+            }
+        }
+    }
+
+    aCallbackData.setRectangleAndPart(rcNew);
+    // Queue this one.
+    return false;
+}
+
+bool CallbackFlushHandler::processWindowEvent(CallbackData& aCallbackData)
+{
+    const std::string& payload = aCallbackData.PayloadString;
+    const int type = aCallbackData.Type;
+
+    boost::property_tree::ptree& aTree = aCallbackData.setJson(payload);
+    const unsigned nLOKWindowId = aTree.get<unsigned>("id", 0);
+    if (aTree.get<std::string>("action", "") == "invalidate")
+    {
+        std::string aRectStr = aTree.get<std::string>("rectangle", "");
+        // no 'rectangle' field => invalidate all of the window =>
+        // remove all previous window part invalidations
+        if (aRectStr.empty())
+        {
+            removeAll([&nLOKWindowId](const queue_type::value_type& elem) {
+                if (elem.Type == LOK_CALLBACK_WINDOW)
+                {
+                    const boost::property_tree::ptree& aOldTree = elem.getJson();
+                    const unsigned nOldDialogId = aOldTree.get<unsigned>("id", 0);
+                    if (aOldTree.get<std::string>("action", "") == "invalidate"
+                        && nLOKWindowId == nOldDialogId)
+                    {
+                        return true;
+                    }
+                }
+                return false;
+            });
+        }
+        else
+        {
+            // if we have to invalidate all of the window, ignore
+            // any part invalidation message
+            const auto& pos
+                = std::find_if(m_queue.rbegin(), m_queue.rend(),
+                               [&nLOKWindowId](const queue_type::value_type& elem) {
+                                   if (elem.Type != LOK_CALLBACK_WINDOW)
+                                       return false;
+
+                                   const boost::property_tree::ptree& aOldTree = elem.getJson();
+                                   const unsigned nOldDialogId = aOldTree.get<unsigned>("id", 0);
+                                   if (aOldTree.get<std::string>("action", "") == "invalidate"
+                                       && nLOKWindowId == nOldDialogId
+                                       && aOldTree.get<std::string>("rectangle", "").empty())
+                                   {
+                                       return true;
+                                   }
+                                   return false;
+                               });
+
+            // we found a invalidate-all window callback
+            if (pos != m_queue.rend())
+            {
+                SAL_INFO("lok.dialog", "Skipping queue ["
+                                           << type << "]: [" << payload
+                                           << "] since whole window needs to be invalidated.");
+                return true;
+            }
+
+            std::istringstream aRectStream(aRectStr);
+            long nLeft, nTop, nWidth, nHeight;
+            char nComma;
+            aRectStream >> nLeft >> nComma >> nTop >> nComma >> nWidth >> nComma >> nHeight;
+            tools::Rectangle aNewRect
+                = tools::Rectangle(nLeft, nTop, nLeft + nWidth, nTop + nHeight);
+            bool currentIsRedundant = false;
+            removeAll([&aNewRect, &nLOKWindowId,
+                       &currentIsRedundant](const queue_type::value_type& elem) {
+                if (elem.Type != LOK_CALLBACK_WINDOW)
+                    return false;
+
+                const boost::property_tree::ptree& aOldTree = elem.getJson();
+                if (aOldTree.get<std::string>("action", "") == "invalidate")
+                {
+                    const unsigned nOldDialogId = aOldTree.get<unsigned>("id", 0);
+                    std::string aOldRectStr = aOldTree.get<std::string>("rectangle", "");
+                    // not possible that we encounter an empty
+                    // rectangle here; we already handled this
+                    // case before
+                    std::istringstream aOldRectStream(aOldRectStr);
+                    long nOldLeft, nOldTop, nOldWidth, nOldHeight;
+                    char nOldComma;
+                    aOldRectStream >> nOldLeft >> nOldComma >> nOldTop >> nOldComma >> nOldWidth
+                        >> nOldComma >> nOldHeight;
+                    tools::Rectangle aOldRect = tools::Rectangle(
+                        nOldLeft, nOldTop, nOldLeft + nOldWidth, nOldTop + nOldHeight);
+
+                    if (nLOKWindowId == nOldDialogId)
+                    {
+                        // new one engulfs the old one?
+                        if (aNewRect.IsInside(aOldRect))
+                        {
+                            SAL_INFO("lok.dialog", "New " << aNewRect.toString() << " engulfs old "
+                                                          << aOldRect.toString() << ".");
+                            return true;
+                        }
+                        // old one engulfs the new one?
+                        else if (aOldRect.IsInside(aNewRect))
+                        {
+                            SAL_INFO("lok.dialog", "Old " << aOldRect.toString() << " engulfs new "
+                                                          << aNewRect.toString() << ".");
+                            // we have a rectangle in the queue
+                            // already that makes the current
+                            // Callback useless
+                            currentIsRedundant = true;
+                            return false;
+                        }
+                        else
+                        {
+                            SAL_INFO("lok.dialog", "Merging " << aNewRect.toString() << " & "
+                                                              << aOldRect.toString());
+                            aNewRect.Union(aOldRect);
+                            SAL_INFO("lok.dialog", "Merged: " << aNewRect.toString());
+                            return true;
+                        }
+                    }
+                }
+
+                // keep rest
+                return false;
+            });
+
+            if (currentIsRedundant)
+            {
+                SAL_INFO("lok.dialog", "Current payload is engulfed by one already in the queue. "
+                                       "Skipping redundant payload: "
+                                           << aNewRect.toString());
+                return true;
+            }
+
+            aTree.put("rectangle", aNewRect.toString().getStr());
+            aCallbackData.setJson(aTree);
+            assert(aCallbackData.validate() && "Validation after setJson failed!");
+        }
+    }
+    else if (aTree.get<std::string>("action", "") == "created")
+    {
+        // Remove all previous actions on same dialog, if we are creating it anew.
+        removeAll([&nLOKWindowId](const queue_type::value_type& elem) {
+            if (elem.Type == LOK_CALLBACK_WINDOW)
+            {
+                const boost::property_tree::ptree& aOldTree = elem.getJson();
+                if (nLOKWindowId == aOldTree.get<unsigned>("id", 0))
+                    return true;
+            }
+            return false;
+        });
+    }
+    else if (aTree.get<std::string>("action", "") == "size_changed")
+    {
+        // A size change is practically re-creation of the window.
+        // But at a minimum it's a full invalidation.
+        removeAll([&nLOKWindowId](const queue_type::value_type& elem) {
+            if (elem.Type == LOK_CALLBACK_WINDOW)
+            {
+                const boost::property_tree::ptree& aOldTree = elem.getJson();
+                if (nLOKWindowId == aOldTree.get<unsigned>("id", 0))
+                {
+                    const std::string aOldAction = aOldTree.get<std::string>("action", "");
+                    if (aOldAction == "invalidate")
+                        return true;
+                }
+            }
+            return false;
+        });
+    }
+
+    // Queue this one.
+    return false;
+}
+
 void CallbackFlushHandler::Invoke()
 {
     comphelper::ProfileZone aZone("CallbackFlushHander::Invoke");
commit 1a5af070d876b1ec4b69fe3be732426dba59b9af
Author:     Ashod Nakashian <ashod.nakashian at collabora.co.uk>
AuthorDate: Wed May 8 11:20:09 2019 -0400
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue May 14 11:39:45 2019 +0200

    LOK: Remove window invalidations prior to size_changed
    
    A window size change is a full invalidation anyway,
    so remove any prior invalidations as they are redundant.
    
    Change-Id: I439a1bc38989df17b671e064beb26eb88c402be3

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index de22b316b6f7..2f68b1b44dfb 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1403,6 +1403,24 @@ void CallbackFlushHandler::queue(const int type, const char* data)
                         return false;
                     });
                 }
+                else if (aTree.get<std::string>("action", "") == "size_changed")
+                {
+                    // A size change is practically re-creation of the window.
+                    // But at a minimum it's a full invalidation.
+                    removeAll([&nLOKWindowId](const queue_type::value_type& elem) {
+                        if (elem.Type == LOK_CALLBACK_WINDOW)
+                        {
+                            const boost::property_tree::ptree& aOldTree = elem.getJson();
+                            if (nLOKWindowId == aOldTree.get<unsigned>("id", 0))
+                            {
+                                const std::string aOldAction = aOldTree.get<std::string>("action", "");
+                                if (aOldAction == "invalidate")
+                                    return true;
+                            }
+                        }
+                        return false;
+                    });
+                }
             }
             break;
         }
commit d0fe740e10346cdca5519a03ed0c05247e1227ae
Author:     Ashod Nakashian <ashod.nakashian at collabora.co.uk>
AuthorDate: Sun May 5 20:26:42 2019 -0400
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue May 14 11:39:45 2019 +0200

    LOK: Window creation supersedes any events on same window
    
    This happens when we get multiple created events on
    same window, interspersed with invalidations.
    
    Change-Id: I2dbaa0f84306d770f1de047a23996209c28304fe

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 0c4b3f7237de..de22b316b6f7 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1390,6 +1390,19 @@ void CallbackFlushHandler::queue(const int type, const char* data)
                         assert(aCallbackData.validate() && "Validation after setJson failed!");
                     }
                 }
+                else if (aTree.get<std::string>("action", "") == "created")
+                {
+                    // Remove all previous actions on same dialog, if we are creating it anew.
+                    removeAll([&nLOKWindowId](const queue_type::value_type& elem) {
+                        if (elem.Type == LOK_CALLBACK_WINDOW)
+                        {
+                            const boost::property_tree::ptree& aOldTree = elem.getJson();
+                            if (nLOKWindowId == aOldTree.get<unsigned>("id", 0))
+                                return true;
+                        }
+                        return false;
+                    });
+                }
             }
             break;
         }
commit e5f7b22c4dd39871f3f6715b7ccff5348fbe2589
Author:     Ashod Nakashian <ashod.nakashian at collabora.co.uk>
AuthorDate: Sun May 5 12:57:43 2019 -0400
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue May 14 11:39:45 2019 +0200

    LOK: Reduce logging while processing events
    
    Change-Id: I8ca457387715fcd085bcbf3107839d2629580f7b

diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index 013162aa990f..b63794d2a9de 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -130,7 +130,7 @@ namespace desktop {
         typedef std::vector<CallbackData> queue_type;
 
     private:
-        void removeAll(const std::function<bool (const queue_type::value_type&)>& rTestFunc);
+        bool removeAll(const std::function<bool (const queue_type::value_type&)>& rTestFunc);
 
         queue_type m_queue;
         std::map<int, std::string> m_states;
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 93e49ec4447d..0c4b3f7237de 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1080,9 +1080,10 @@ void CallbackFlushHandler::queue(const int type, const char* data)
             case LOK_CALLBACK_GRAPHIC_SELECTION:
             case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
             case LOK_CALLBACK_INVALIDATE_TILES:
-                SAL_INFO("lok", "Removing dups of [" << type << "]: [" << payload << "].");
-                removeAll([type] (const queue_type::value_type& elem) { return (elem.Type == type); });
-            break;
+                if (removeAll(
+                        [type](const queue_type::value_type& elem) { return (elem.Type == type); }))
+                    SAL_INFO("lok", "Removed dups of [" << type << "]: [" << payload << "].");
+                break;
         }
     }
     else
@@ -1104,7 +1105,9 @@ void CallbackFlushHandler::queue(const int type, const char* data)
             case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
             case LOK_CALLBACK_RULER_UPDATE:
             {
-                removeAll([type] (const queue_type::value_type& elem) { return (elem.Type == type); });
+                if (removeAll(
+                        [type](const queue_type::value_type& elem) { return (elem.Type == type); }))
+                    SAL_INFO("lok", "Removed dups of [" << type << "]: [" << payload << "].");
             }
             break;
 
@@ -1485,10 +1488,16 @@ void CallbackFlushHandler::Invoke()
     }
 }
 
-void CallbackFlushHandler::removeAll(const std::function<bool (const CallbackFlushHandler::queue_type::value_type&)>& rTestFunc)
+bool CallbackFlushHandler::removeAll(const std::function<bool (const CallbackFlushHandler::queue_type::value_type&)>& rTestFunc)
 {
     auto newEnd = std::remove_if(m_queue.begin(), m_queue.end(), rTestFunc);
-    m_queue.erase(newEnd, m_queue.end());
+    if (newEnd != m_queue.end())
+    {
+        m_queue.erase(newEnd, m_queue.end());
+        return true;
+    }
+
+    return false;
 }
 
 void CallbackFlushHandler::addViewStates(int viewId)
commit abd504c70b7b36b20082677a1b1eef6ff937a6f7
Author:     Ashod Nakashian <ashod.nakashian at collabora.co.uk>
AuthorDate: Wed May 8 08:15:52 2019 -0400
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue May 14 11:39:45 2019 +0200

    vcl: LOK: emmit size_changed after window creation
    
    This guarantees that the correct size of the window
    is set on the client side. Some windows are created
    with default (and invalid) size and rely on Resize
    to be called right after. This doesn't happen
    with message boxes and they need to get size_changed
    right after the window is fully created and ready.
    
    Change-Id: I8c281a31770de4b37b9de6d333159e5379344dff

diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index f050e33ffb16..d84838fd830c 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -875,7 +875,7 @@ bool Dialog::ImplStartExecuteModal()
 
     if (comphelper::LibreOfficeKit::isActive())
     {
-        if(const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier())
+        if (const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier())
         {
             std::vector<vcl::LOKPayloadItem> aItems;
             aItems.emplace_back("type", "dialog");
@@ -932,12 +932,27 @@ bool Dialog::ImplStartExecuteModal()
 
     pSVData->maAppData.mnModalMode++;
 
-    css::uno::Reference<css::frame::XGlobalEventBroadcaster> xEventBroadcaster(css::frame::theGlobalEventBroadcaster::get(xContext), css::uno::UNO_QUERY_THROW);
+    css::uno::Reference<css::frame::XGlobalEventBroadcaster> xEventBroadcaster(
+        css::frame::theGlobalEventBroadcaster::get(xContext), css::uno::UNO_QUERY_THROW);
     css::document::DocumentEvent aObject;
     aObject.EventName = "DialogExecute";
     xEventBroadcaster->documentEventOccured(aObject);
     UITestLogger::getInstance().log("DialogExecute");
 
+    if (comphelper::LibreOfficeKit::isActive())
+    {
+        if (const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier())
+        {
+            // Dialog boxes don't get the Resize call and they
+            // can have invalid size at 'created' message above.
+            // If there is no difference, the client should detect it and ignore us,
+            // otherwise, this should make sure that the window has the correct size.
+            std::vector<vcl::LOKPayloadItem> aItems;
+            aItems.emplace_back("size", GetSizePixel().toString());
+            pNotifier->notifyWindow(GetLOKWindowId(), "size_changed", aItems);
+        }
+    }
+
     return true;
 }
 


More information about the Libreoffice-commits mailing list