include/sfx2/LokControlHandler.hxx                       |   70 ++++++++++++---
 include/sfx2/viewsh.hxx                                  |    4 
 include/vcl/DocWindow.hxx                                |   30 ++++++
 include/vcl/IDialogRenderable.hxx                        |    6 +
 include/vcl/ctrl.hxx                                     |    3 
 include/vcl/svapp.hxx                                    |    2 
 include/vcl/window.hxx                                   |    2 
 sc/source/ui/inc/gridwin.hxx                             |    3 
 sc/source/ui/view/gridwin.cxx                            |    2 
 sd/source/ui/inc/Window.hxx                              |    4 
 sd/source/ui/unoidl/unomodel.cxx                         |   28 +++++-
 sd/source/ui/view/sdwindow.cxx                           |    2 
 sfx2/source/view/viewsh.cxx                              |    5 +
 svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx |    7 +
 svx/source/svdraw/svdpntv.cxx                            |    3 
 sw/source/uibase/docvw/edtwin.cxx                        |    2 
 sw/source/uibase/inc/edtwin.hxx                          |    4 
 sw/source/uibase/uno/unotxdoc.cxx                        |   21 ++++
 vcl/Library_vcl.mk                                       |    1 
 vcl/source/app/svapp.cxx                                 |    3 
 vcl/source/control/ctrl.cxx                              |   31 ++++++
 vcl/source/window/DocWindow.cxx                          |   40 ++++++++
 vcl/source/window/mouse.cxx                              |   24 -----
 23 files changed, 245 insertions(+), 52 deletions(-)

New commits:
commit 7adfecb0f5947ae258226c8d1652546f81577026
Author:     Marco Cecchetti <marco.cecche...@collabora.com>
AuthorDate: Sun Feb 5 17:47:34 2023 +0100
Commit:     Marco Cecchetti <marco.cecche...@collabora.com>
CommitDate: Tue Mar 7 19:30:11 2023 +0000

    lok: form controls: rendering and mouse event forwarding
    
    What we got
    - Most controls rendered on Writer and Impress (on Calc already
    implemented by Tomaž Vajngerl)
    - Text labels rendered correctly
    - Mouse events forwarded to controls
    - Control state changed on click for Writer and Calc
    - Control invalidation for all apps
    - Fixed broken LOK_CALLBACK_MOUSE_POINTER msg
    - Correct pointer style when mouse is hovering over a control
    
    Need to be improved
    - in impress click method for a control is not executed even if the
    mouse event is forwarded correctly
    - avoid not needed control invalidations (as the one occurring on
    document autosaving)
    
    Change-Id: I4d5012af7f90a2c726b6b6b5b068e2be1ed5568a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146569
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147320
    Tested-by: Jenkins
    Reviewed-by: Marco Cecchetti <marco.cecche...@collabora.com>

diff --git a/include/sfx2/LokControlHandler.hxx 
b/include/sfx2/LokControlHandler.hxx
index c422afc979cc..dc69787456e5 100644
--- a/include/sfx2/LokControlHandler.hxx
+++ b/include/sfx2/LokControlHandler.hxx
@@ -9,12 +9,13 @@
 
 #pragma once
 
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <sfx2/dllapi.h>
 #include <sfx2/lokhelper.hxx>
-#include <svx/svditer.hxx>
 #include <svx/svdouno.hxx>
-#include <tools/UnitConversion.hxx>
+#include <svx/svditer.hxx>
 #include <vcl/virdev.hxx>
-#include <vcl/window.hxx>
+#include <vcl/DocWindow.hxx>
 #include <com/sun/star/awt/PosSize.hpp>
 #include <com/sun/star/awt/XControl.hpp>
 #include <com/sun/star/awt/XWindow.hpp>
@@ -22,14 +23,22 @@
 #include <com/sun/star/awt/XGraphics.hpp>
 #include <com/sun/star/awt/XView.hpp>
 #include <toolkit/helper/vclunohelper.hxx>
+#include <tools/UnitConversion.hxx>
+
+#include <sal/log.hxx>
+
+#include <optional>
 
 class LokControlHandler
 {
 public:
     static bool postMouseEvent(const SdrPage* pPage, const SdrView* pDrawView,
-                               vcl::Window const& rMainWindow, int nType, 
Point aPointHmm,
-                               int nCount, int nButtons, int nModifier)
+                               vcl::DocWindow& rMainWindow, int nType, Point 
aPointHmm, int nCount,
+                               int nButtons, int nModifier)
     {
+        static std::optional<PointerStyle> eDocPointerStyle;
+
+        o3tl::Length eControlUnitLength = 
MapToO3tlLength(rMainWindow.GetMapMode().GetMapUnit());
         SdrObjListIter aIterator(pPage, SdrIterMode::Flat);
         while (aIterator.IsMore())
         {
@@ -37,7 +46,10 @@ public:
             SdrUnoObj* pUnoObect = dynamic_cast<SdrUnoObj*>(pObject);
             if (pUnoObect)
             {
-                tools::Rectangle aControlRectHMM = pUnoObect->GetLogicRect();
+                tools::Rectangle aControlRect = pUnoObect->GetLogicRect();
+                tools::Rectangle aControlRectHMM
+                    = o3tl::convert(aControlRect, eControlUnitLength, 
o3tl::Length::mm100);
+
                 if (aControlRectHMM.Contains(aPointHmm))
                 {
                     css::uno::Reference<css::awt::XControl> xControl
@@ -55,6 +67,19 @@ public:
                     VclPtr<vcl::Window> pWindow = 
VCLUnoHelper::GetWindow(xWindowPeer);
                     if (pWindow)
                     {
+                        tools::Rectangle aControlRectPx
+                            = o3tl::convert(aControlRectHMM, 
o3tl::Length::mm100, o3tl::Length::px);
+                        // used by Control::LogicInvalidate
+                        pWindow->SetPosPixel(aControlRectPx.TopLeft());
+
+                        // when entering into control area save current 
pointer style
+                        // and set pointer style to arrow
+                        if (!eDocPointerStyle)
+                        {
+                            *eDocPointerStyle = rMainWindow.GetPointer();
+                            rMainWindow.SetPointer(pWindow->GetPointer());
+                        }
+
                         Point aControlRelativePositionHMM = aPointHmm - 
aControlRectHMM.TopLeft();
                         Point aControlRelativePosition = o3tl::convert(
                             aControlRelativePositionHMM, o3tl::Length::mm100, 
o3tl::Length::px);
@@ -62,13 +87,19 @@ public:
                         LokMouseEventData aMouseEventData(nType, 
aControlRelativePosition, nCount,
                                                           
MouseEventModifiers::SIMPLECLICK,
                                                           nButtons, nModifier);
-
                         SfxLokHelper::postMouseEventAsync(pWindow, 
aMouseEventData);
                         return true;
                     }
                 }
             }
         }
+
+        // when exiting from control area restore document pointer style
+        if (eDocPointerStyle)
+        {
+            rMainWindow.SetPointer(*eDocPointerStyle);
+            eDocPointerStyle.reset();
+        }
         return false;
     }
 
@@ -93,17 +124,26 @@ public:
         if (!xControlView.is())
             return;
 
-        tools::Rectangle aObjectRectHMM = pUnoObect->GetLogicRect();
+        o3tl::Length eControlUnitLength = 
MapToO3tlLength(rMainWindow.GetMapMode().GetMapUnit());
+        tools::Rectangle aControlRect = pUnoObect->GetLogicRect();
+        tools::Rectangle aObjectRectHMM
+            = o3tl::convert(aControlRect, eControlUnitLength, 
o3tl::Length::mm100);
+        tools::Rectangle aControltRectPx
+            = o3tl::convert(aObjectRectHMM, o3tl::Length::mm100, 
o3tl::Length::px);
+
         Point aOffsetFromTile(aObjectRectHMM.Left() - rTileRectHMM.Left(),
                               aObjectRectHMM.Top() - rTileRectHMM.Top());
         tools::Rectangle aRectangleHMM(aOffsetFromTile, 
aObjectRectHMM.GetSize());
         tools::Rectangle aRectanglePx
             = o3tl::convert(aRectangleHMM, o3tl::Length::mm100, 
o3tl::Length::px);
 
-        xControlWindow->setPosSize(0, 0, aRectanglePx.GetWidth(), 
aRectanglePx.GetHeight(),
+        xControlWindow->setPosSize(aControltRectPx.Left(), 
aControltRectPx.Top(),
+                                   aRectanglePx.GetWidth(), 
aRectanglePx.GetHeight(),
                                    css::awt::PosSize::POSSIZE);
 
         xControlView->setGraphics(xGraphics);
+        // required for getting text label rendered with the correct scale
+        xControlView->setZoom(1, 1);
 
         xControlView->draw(aRectanglePx.Left() * scaleX, aRectanglePx.Top() * 
scaleY);
     }
@@ -121,13 +161,15 @@ public:
         rDevice.Push(vcl::PushFlags::MAPMODE);
         MapMode aDeviceMapMode(rDevice.GetMapMode());
 
-        const Fraction scale = conversionFract(o3tl::Length::px, 
o3tl::Length::mm100);
-        Fraction scaleX = Fraction(aOutputSize.Width(), 
aTileRectHMM.GetWidth()) * scale;
-        Fraction scaleY = Fraction(aOutputSize.Height(), 
aTileRectHMM.GetHeight()) * scale;
+        const Fraction scale = conversionFract(o3tl::Length::px, 
o3tl::Length::twip);
+        Fraction scaleX = Fraction(aOutputSize.Width(), rTileRect.GetWidth()) 
* scale;
+        Fraction scaleY = Fraction(aOutputSize.Height(), 
rTileRect.GetHeight()) * scale;
         aDeviceMapMode.SetScaleX(scaleX);
         aDeviceMapMode.SetScaleY(scaleY);
+        aDeviceMapMode.SetMapUnit(MapUnit::MapPixel);
         rDevice.SetMapMode(aDeviceMapMode);
 
+        o3tl::Length eControlUnitLength = 
MapToO3tlLength(rMainWindow.GetMapMode().GetMapUnit());
         SdrObjListIter aIterator(pPage, SdrIterMode::Flat);
 
         while (aIterator.IsMore())
@@ -136,7 +178,9 @@ public:
             SdrUnoObj* pUnoObect = dynamic_cast<SdrUnoObj*>(pObject);
             if (pUnoObect)
             {
-                tools::Rectangle aObjectRectHMM = pUnoObect->GetLogicRect();
+                tools::Rectangle aControlRect = pUnoObect->GetLogicRect();
+                tools::Rectangle aObjectRectHMM
+                    = o3tl::convert(aControlRect, eControlUnitLength, 
o3tl::Length::mm100);
 
                 // Check if we intersect with the tile rectangle and we
                 // need to draw the control.
diff --git a/include/sfx2/viewsh.hxx b/include/sfx2/viewsh.hxx
index 0465fd036d4b..de24ef3ef3c1 100644
--- a/include/sfx2/viewsh.hxx
+++ b/include/sfx2/viewsh.hxx
@@ -71,7 +71,7 @@ namespace com::sun::star::frame { class XModel; }
 namespace com::sun::star::ui { class XContextMenuInterceptor; }
 namespace com::sun::star::ui { struct ContextMenuExecuteEvent; }
 namespace com::sun::star::view { class XRenderable; }
-
+namespace tools { class Rectangle; }
 
 enum class SfxPrinterChangeFlags
 {
@@ -404,6 +404,8 @@ public:
     /// Get the DocId used by Mobile LOKit to load multiple documents.
     ViewShellDocId GetDocId() const override;
 
+    /// ILibreOfficeKitNotifier. Emits a LOK_CALLBACK_INVALIDATE_TILES.
+    virtual void notifyInvalidation(tools::Rectangle const *) const override;
     /// See OutlinerViewShell::NotifyOtherViews().
     void NotifyOtherViews(int nType, const OString& rKey, const OString& 
rPayload) override;
     /// See OutlinerViewShell::NotifyOtherView().
diff --git a/include/vcl/DocWindow.hxx b/include/vcl/DocWindow.hxx
new file mode 100644
index 000000000000..681ad110410d
--- /dev/null
+++ b/include/vcl/DocWindow.hxx
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#ifndef INCLUDED_VCL_DOCWINDOW_HXX
+#define INCLUDED_VCL_DOCWINDOW_HXX
+
+#include <vcl/window.hxx>
+
+namespace vcl
+{
+class VCL_DLLPUBLIC DocWindow : public Window
+{
+    // inherit all Window constructors
+    using Window::Window;
+
+public:
+    virtual void SetPointer(PointerStyle) override;
+};
+} // namespace vcl
+
+#endif // INCLUDED_VCL_DOCWINDOW_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/vcl/IDialogRenderable.hxx 
b/include/vcl/IDialogRenderable.hxx
index bb5480f1bf4f..d280aad3f006 100644
--- a/include/vcl/IDialogRenderable.hxx
+++ b/include/vcl/IDialogRenderable.hxx
@@ -13,11 +13,12 @@
 
 #include <config_options.h>
 #include <vcl/dllapi.h>
-
 #include <rtl/ustring.hxx>
 
 #include <vector>
 
+namespace tools { class Rectangle; }
+
 class SfxItemSet;
 
 namespace vcl
@@ -38,6 +39,9 @@ public:
                               const std::vector<LOKPayloadItem>& rPayload = 
std::vector<LOKPayloadItem>()) const = 0;
 
     virtual void libreOfficeKitViewCallback(int nType, const char* pPayload) 
const = 0;
+
+    /// Emits a LOK_CALLBACK_INVALIDATE_TILES.
+    virtual void notifyInvalidation(tools::Rectangle const *) const = 0;
 };
 
 } // namespace vcl
diff --git a/include/vcl/ctrl.hxx b/include/vcl/ctrl.hxx
index 6300e27a747a..c71105731cb1 100644
--- a/include/vcl/ctrl.hxx
+++ b/include/vcl/ctrl.hxx
@@ -229,6 +229,9 @@ public:
 
     vcl::Font       GetUnzoomedControlPointFont() const;
     void            SetShowAccelerator (bool val);
+
+    /// Notify the LOK client about an invalidated area.
+    virtual void LogicInvalidate( const tools::Rectangle* pRectangle ) 
override;
 };
 
 #endif // INCLUDED_VCL_CTRL_HXX
diff --git a/include/vcl/svapp.hxx b/include/vcl/svapp.hxx
index 326b8b3761ea..eacf9e779b5e 100644
--- a/include/vcl/svapp.hxx
+++ b/include/vcl/svapp.hxx
@@ -1365,6 +1365,8 @@ public:
                               const OUString& rAction,
                               const std::vector<vcl::LOKPayloadItem>& rPayload 
= std::vector<vcl::LOKPayloadItem>()) const override;
     virtual void libreOfficeKitViewCallback(int nType, const char* pPayload) 
const override;
+    virtual void notifyInvalidation(tools::Rectangle const *) const override;
+
 
 private:
     DECL_DLLPRIVATE_STATIC_LINK( Application, PostEventHandler, void*, void );
diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx
index 18c590ac9c5c..e595a2ba1690 100644
--- a/include/vcl/window.hxx
+++ b/include/vcl/window.hxx
@@ -1018,7 +1018,7 @@ public:
     void                                ReleaseMouse();
     bool                                IsMouseCaptured() const;
 
-    void                                SetPointer( PointerStyle );
+    virtual void                        SetPointer( PointerStyle );
     PointerStyle                        GetPointer() const;
     void                                EnableChildPointerOverwrite( bool 
bOverwrite );
     void                                SetPointerPosPixel( const Point& rPos 
);
diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx
index d88a9462918d..70a6efa616cc 100644
--- a/sc/source/ui/inc/gridwin.hxx
+++ b/sc/source/ui/inc/gridwin.hxx
@@ -19,6 +19,7 @@
 
 #pragma once
 
+#include <vcl/DocWindow.hxx>
 #include <vcl/transfer.hxx>
 #include "viewutil.hxx"
 #include "viewdata.hxx"
@@ -85,7 +86,7 @@ namespace sdr::overlay { class OverlayObjectList; }
 
 class ScFilterListBox;
 
-class SAL_DLLPUBLIC_RTTI ScGridWindow : public vcl::Window, public 
DropTargetHelper, public DragSourceHelper
+class SAL_DLLPUBLIC_RTTI ScGridWindow : public vcl::DocWindow, public 
DropTargetHelper, public DragSourceHelper
 {
     // ScFilterListBox is always used for selection list
     friend class ScFilterListBox;
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 3f5172ad6a50..c25ba587ae03 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -348,7 +348,7 @@ static bool lcl_GetHyperlinkCell(
 
 //  WB_DIALOGCONTROL needed for UNO-Controls
 ScGridWindow::ScGridWindow( vcl::Window* pParent, ScViewData& rData, 
ScSplitPos eWhichPos )
-:           Window( pParent, WB_CLIPCHILDREN | WB_DIALOGCONTROL ),
+:           DocWindow( pParent, WB_CLIPCHILDREN | WB_DIALOGCONTROL ),
             DropTargetHelper( this ),
             DragSourceHelper( this ),
             maVisibleRange(rData.GetDocument()),
diff --git a/sd/source/ui/inc/Window.hxx b/sd/source/ui/inc/Window.hxx
index 0464ad32e19e..9763f24e8895 100644
--- a/sd/source/ui/inc/Window.hxx
+++ b/sd/source/ui/inc/Window.hxx
@@ -21,7 +21,7 @@
 
 #include <tools/gen.hxx>
 #include <tools/long.hxx>
-#include <vcl/window.hxx>
+#include <vcl/DocWindow.hxx>
 #include <vcl/transfer.hxx>
 
 class OutlinerView;
@@ -41,7 +41,7 @@ class ViewShell;
     member of the <type>OutputDevice</type> base class.  It is calculated to
     be an integer percent value.
 */
-class Window : public vcl::Window, public ::DropTargetHelper
+class Window : public vcl::DocWindow, public ::DropTargetHelper
 {
 public:
     Window(vcl::Window* pParent);
diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx
index 230633d66ad1..a955e02e3da6 100644
--- a/sd/source/ui/unoidl/unomodel.cxx
+++ b/sd/source/ui/unoidl/unomodel.cxx
@@ -124,6 +124,7 @@
 #include <drawinglayer/primitive2d/structuretagprimitive2d.hxx>
 
 #include <sfx2/lokcomponenthelpers.hxx>
+#include <sfx2/LokControlHandler.hxx>
 #include <tools/gen.hxx>
 #include <tools/debug.hxx>
 #include <comphelper/diagnose_ex.hxx>
@@ -2192,6 +2193,9 @@ void SdXImpressDocument::paintTile( VirtualDevice& 
rDevice,
     if (!pViewSh)
         return;
 
+    // we need to skip tile invalidation for controls on rendering
+    comphelper::LibreOfficeKit::setTiledPainting(true);
+
     // Setup drawing layer to work properly. Since we use a custom 
VirtualDevice
     // for the drawing, SdrPaintView::BeginCompleteRedraw() will call 
FindPaintWindow()
     // unsuccessfully and use a temporary window that doesn't keep state. So 
patch
@@ -2260,6 +2264,17 @@ void SdXImpressDocument::paintTile( VirtualDevice& 
rDevice,
 
     if(patchedPageWindow != nullptr)
         patchedPageWindow->unpatchPaintWindow(previousPaintWindow);
+
+    // Draw Form controls
+    SdrView* pDrawView = pViewSh->GetDrawView();
+    SdrPageView* pPageView = pDrawView->GetSdrPageView();
+    SdrPage* pPage = pPageView->GetPage();
+    ::sd::Window* pActiveWin = pViewSh->GetActiveWindow();
+    ::tools::Rectangle aTileRect(Point(nTilePosX, nTilePosY), Size(nTileWidth, 
nTileHeight));
+    Size aOutputSize(nOutputWidth, nOutputHeight);
+    LokControlHandler::paintControlTile(pPage, pDrawView, *pActiveWin, 
rDevice, aOutputSize, aTileRect);
+
+    comphelper::LibreOfficeKit::setTiledPainting(false);
 }
 
 void SdXImpressDocument::selectPart(int nPart, int nSelect)
@@ -2561,8 +2576,17 @@ void SdXImpressDocument::postMouseEvent(int nType, int 
nX, int nY, int nCount, i
             pViewShell->GetViewShell(), nType, nX, nY, nCount, nButtons, 
nModifier, fScale, fScale))
         return;
 
-    const Point aPos(Point(convertTwipToMm100(nX), convertTwipToMm100(nY)));
-    LokMouseEventData aMouseEventData(nType, aPos, nCount, 
MouseEventModifiers::SIMPLECLICK,
+    // try to forward mouse event to control
+    const Point aPointTwip(nX, nY);
+    const Point aPointHMM = o3tl::convert(aPointTwip, o3tl::Length::twip, 
o3tl::Length::mm100);
+    SdrView* pDrawView = pViewShell->GetDrawView();
+    SdrPageView* pPageView = pDrawView->GetSdrPageView();
+    SdrPage* pPage = pPageView->GetPage();
+    ::sd::Window* pActiveWin = pViewShell->GetActiveWindow();
+    if (LokControlHandler::postMouseEvent(pPage, pDrawView, *pActiveWin, 
nType, aPointHMM, nCount, nButtons, nModifier))
+            return;
+
+    LokMouseEventData aMouseEventData(nType, aPointHMM, nCount, 
MouseEventModifiers::SIMPLECLICK,
                                       nButtons, nModifier);
     SfxLokHelper::postMouseEventAsync(pViewShell->GetActiveWindow(), 
aMouseEventData);
 }
diff --git a/sd/source/ui/view/sdwindow.cxx b/sd/source/ui/view/sdwindow.cxx
index 1ccd7461d7bc..6d5481318e8e 100644
--- a/sd/source/ui/view/sdwindow.cxx
+++ b/sd/source/ui/view/sdwindow.cxx
@@ -60,7 +60,7 @@ namespace sd {
 #define MAX_ZOOM           3000     ///< maximal zoom factor
 
 Window::Window(vcl::Window* pParent)
-    : vcl::Window(pParent, WinBits(WB_CLIPCHILDREN | WB_DIALOGCONTROL)),
+    : vcl::DocWindow(pParent, WinBits(WB_CLIPCHILDREN | WB_DIALOGCONTROL)),
       DropTargetHelper( this ),
       maWinPos(0, 0),           // precautionary; but the values should be set
       maViewOrigin(0, 0),       // again from the owner of the window
diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx
index 09e4b4a32284..b4e94994f9ee 100644
--- a/sfx2/source/view/viewsh.cxx
+++ b/sfx2/source/view/viewsh.cxx
@@ -1628,6 +1628,11 @@ ViewShellDocId SfxViewShell::GetDocId() const
     return pImpl->m_nDocId;
 }
 
+void SfxViewShell::notifyInvalidation(tools::Rectangle const* pRect) const
+{
+    SfxLokHelper::notifyInvalidation(this, pRect);
+}
+
 void SfxViewShell::NotifyOtherViews(int nType, const OString& rKey, const 
OString& rPayload)
 {
     SfxLokHelper::notifyOtherViews(this, nType, rKey, rPayload);
diff --git a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx 
b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx
index 46d2dc9980e2..db458e1245fa 100644
--- a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx
+++ b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx
@@ -44,10 +44,10 @@
 #include <com/sun/star/container/XContainerListener.hpp>
 #include <com/sun/star/container/XContainer.hpp>
 
-#include <utility>
 #include <vcl/canvastools.hxx>
 #include <vcl/svapp.hxx>
 #include <vcl/window.hxx>
+#include <comphelper/lok.hxx>
 #include <comphelper/processfactory.hxx>
 #include <comphelper/scopeguard.hxx>
 #include <cppuhelper/implbase.hxx>
@@ -58,6 +58,7 @@
 #include <basegfx/matrix/b2dhommatrixtools.hxx>
 #include <drawinglayer/primitive2d/controlprimitive2d.hxx>
 
+#include <utility>
 /*
 
 Form controls (more precise: UNO Controls) in the drawing layer are ... prone 
to breakage, since they have some
@@ -279,6 +280,10 @@ namespace sdr::contact {
     static void adjustControlGeometry_throw( const ControlHolder& _rControl, 
const tools::Rectangle& _rLogicBoundingRect,
         const basegfx::B2DHomMatrix& _rViewTransformation, const 
::basegfx::B2DHomMatrix& _rZoomLevelNormalization )
     {
+        // In the LOK case, control geometry is handled by LokControlHandler
+        if (comphelper::LibreOfficeKit::isActive())
+            return;
+
         OSL_PRECOND( _rControl.is(), 
"UnoControlContactHelper::adjustControlGeometry_throw: illegal control!" );
         if ( !_rControl.is() )
             return;
diff --git a/svx/source/svdraw/svdpntv.cxx b/svx/source/svdraw/svdpntv.cxx
index 901ddd8c0aaf..c9a0df5291e9 100644
--- a/svx/source/svdraw/svdpntv.cxx
+++ b/svx/source/svdraw/svdpntv.cxx
@@ -629,7 +629,8 @@ void SdrPaintView::EndCompleteRedraw(SdrPaintWindow& 
rPaintWindow, bool bPaintFo
     {
         // draw postprocessing, only for known devices
         // it is necessary to always paint FormLayer
-        if(bPaintFormLayer)
+        // In the LOK case control rendering is performed through 
LokControlHandler
+        if(!comphelper::LibreOfficeKit::isActive() && bPaintFormLayer)
         {
             ImpFormLayerDrawing(rPaintWindow);
         }
diff --git a/sw/source/uibase/docvw/edtwin.cxx 
b/sw/source/uibase/docvw/edtwin.cxx
index afdf7fc5a756..b7a63bda7a38 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -5344,7 +5344,7 @@ void SwEditWin::SetApplyTemplate(const SwApplyTemplate 
&rTempl)
  * Ctor
  */
 SwEditWin::SwEditWin(vcl::Window *pParent, SwView &rMyView):
-    Window(pParent, WinBits(WB_CLIPCHILDREN | WB_DIALOGCONTROL)),
+    DocWindow(pParent, WinBits(WB_CLIPCHILDREN | WB_DIALOGCONTROL)),
     DropTargetHelper( this ),
     DragSourceHelper( this ),
 
diff --git a/sw/source/uibase/inc/edtwin.hxx b/sw/source/uibase/inc/edtwin.hxx
index b5e09726a0b3..aac86d4f8807 100644
--- a/sw/source/uibase/inc/edtwin.hxx
+++ b/sw/source/uibase/inc/edtwin.hxx
@@ -24,7 +24,7 @@
 #include <svx/svdobj.hxx>
 #include <tools/link.hxx>
 #include <vcl/timer.hxx>
-#include <vcl/window.hxx>
+#include <vcl/DocWindow.hxx>
 #include <vcl/transfer.hxx>
 #include <swevent.hxx>
 #include <swtypes.hxx>
@@ -56,7 +56,7 @@ class SwTextFrame;
     To translate the pixel positions from the buffer OutputDevice to the real
     pixel positions, use the PixelToLogic methods of this class.
   */
-class SW_DLLPUBLIC SwEditWin final : public vcl::Window,
+class SW_DLLPUBLIC SwEditWin final : public vcl::DocWindow,
                 public DropTargetHelper, public DragSourceHelper
 {
     static  QuickHelpData* s_pQuickHlpData;
diff --git a/sw/source/uibase/uno/unotxdoc.cxx 
b/sw/source/uibase/uno/unotxdoc.cxx
index 42ab3bc9b344..b2eec7838274 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -30,6 +30,7 @@
 #include <sfx2/bindings.hxx>
 #include <sfx2/viewfrm.hxx>
 #include <sfx2/lokhelper.hxx>
+#include <sfx2/LokControlHandler.hxx>
 #include <sfx2/docfile.hxx>
 #include <sfx2/printer.hxx>
 #include <toolkit/helper/vclunohelper.hxx>
@@ -3113,6 +3114,17 @@ void SwXTextDocument::paintTile( VirtualDevice &rDevice,
 
     LokChartHelper::PaintAllChartsOnTile(rDevice, nOutputWidth, nOutputHeight,
                                          nTilePosX, nTilePosY, nTileWidth, 
nTileHeight);
+
+    // Draw Form controls
+    comphelper::LibreOfficeKit::setTiledPainting(true);
+    SwDrawModel* pDrawLayer = 
m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
+    SdrPage* pPage = pDrawLayer->GetPage(sal_uInt16(0));
+    SdrView* pDrawView = pViewShell->GetDrawView();
+    SwEditWin& rEditWin = m_pDocShell->GetView()->GetEditWin();
+    tools::Rectangle aTileRect(Point(nTilePosX, nTilePosY), Size(nTileWidth, 
nTileHeight));
+    Size aOutputSize(nOutputWidth, nOutputHeight);
+    LokControlHandler::paintControlTile(pPage, pDrawView, rEditWin, rDevice, 
aOutputSize, aTileRect);
+    comphelper::LibreOfficeKit::setTiledPainting(false);
 }
 
 Size SwXTextDocument::getDocumentSize()
@@ -3664,7 +3676,16 @@ void SwXTextDocument::postMouseEvent(int nType, int nX, 
int nY, int nCount, int
             m_pDocShell->GetView(), nType, nX, nY, nCount, nButtons, 
nModifier, fScale, fScale))
         return;
 
+    // try to forward mouse event to controls
+    SwDrawModel* pDrawLayer = 
m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
+    SdrPage* pPage = pDrawLayer->GetPage(sal_uInt16(0));
+    SdrView* pDrawView = pWrtViewShell->GetDrawView();
     SwEditWin& rEditWin = m_pDocShell->GetView()->GetEditWin();
+    Point aPointTwip(nX, nY);
+    Point aPointHMMDraw = o3tl::convert(aPointTwip, o3tl::Length::twip, 
o3tl::Length::mm100);
+    if (LokControlHandler::postMouseEvent(pPage, pDrawView, rEditWin, nType, 
aPointHMMDraw, nCount, nButtons, nModifier))
+            return;
+
     LokMouseEventData aMouseEventData(nType, Point(nX, nY), nCount,
                                       MouseEventModifiers::SIMPLECLICK,
                                       nButtons, nModifier);
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 27197d70b026..9eca7534218e 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -134,6 +134,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
     vcl/source/window/dockingarea \
     vcl/source/window/dockmgr \
     vcl/source/window/dockwin \
+    vcl/source/window/DocWindow \
     vcl/source/window/event \
     vcl/source/window/floatwin \
     $(if $(ENABLE_WASM_STRIP_SPLASH),,vcl/source/window/introwin) \
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index a580a8215cdb..f503310949f2 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -333,6 +333,9 @@ void Application::libreOfficeKitViewCallback(int nType, 
const char* pPayload) co
     }
 }
 
+void Application::notifyInvalidation(tools::Rectangle const* /*pRect*/) const
+{
+}
 
 namespace
 {
diff --git a/vcl/source/control/ctrl.cxx b/vcl/source/control/ctrl.cxx
index 6d6843b9c6e4..46d1507eb40b 100644
--- a/vcl/source/control/ctrl.cxx
+++ b/vcl/source/control/ctrl.cxx
@@ -17,6 +17,7 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include <comphelper/lok.hxx>
 #include <o3tl/safeint.hxx>
 #include <vcl/svapp.hxx>
 #include <vcl/event.hxx>
@@ -25,6 +26,7 @@
 #include <vcl/mnemonic.hxx>
 #include <vcl/settings.hxx>
 #include <vcl/uitest/logger.hxx>
+#include <vcl/DocWindow.hxx>
 #include <sal/log.hxx>
 
 #include <textlayout.hxx>
@@ -493,4 +495,33 @@ Control::GetUnzoomedControlPointFont() const
     return aFont;
 }
 
+void Control::LogicInvalidate(const tools::Rectangle* pRectangle)
+{
+    // avoid endless paint/invalidate loop in Impress
+    if (comphelper::LibreOfficeKit::isTiledPainting())
+        return;
+
+    VclPtr<vcl::Window> pParent = GetParentWithLOKNotifier();
+    if (!pParent)
+        return;
+
+    // invalidate only controls that belong to a DocWindow
+    if (!dynamic_cast<vcl::DocWindow*>(GetParent()))
+        return;
+
+    tools::Rectangle aResultRectangle;
+    if (!pRectangle)
+    {
+        // we have to invalidate the whole control area not the whole document
+        aResultRectangle = tools::Rectangle(GetPosPixel(), GetSizePixel());
+    }
+    else
+    {
+        aResultRectangle = *pRectangle;
+    }
+
+    aResultRectangle = PixelToLogic(aResultRectangle, 
MapMode(MapUnit::MapTwip));
+    pParent->GetLOKNotifier()->notifyInvalidation(&aResultRectangle);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/window/DocWindow.cxx b/vcl/source/window/DocWindow.cxx
new file mode 100644
index 000000000000..6123246c5e48
--- /dev/null
+++ b/vcl/source/window/DocWindow.cxx
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+
+#include <sal/log.hxx>
+#include <vcl/DocWindow.hxx>
+#include <vcl/ITiledRenderable.hxx>
+
+namespace vcl
+{
+void DocWindow::SetPointer(PointerStyle nPointer)
+{
+    Window::SetPointer(nPointer);
+
+    VclPtr<vcl::Window> pWin = GetParentWithLOKNotifier();
+    if (!pWin)
+        return;
+
+    PointerStyle aPointer = GetPointer();
+    // We don't map all possible pointers hence we need a default
+    OString aPointerString = "default";
+    auto aIt = vcl::gaLOKPointerMap.find(aPointer);
+    if (aIt != vcl::gaLOKPointerMap.end())
+    {
+        aPointerString = aIt->second;
+    }
+
+    
pWin->GetLOKNotifier()->libreOfficeKitViewCallback(LOK_CALLBACK_MOUSE_POINTER,
+                                                       
aPointerString.getStr());
+}
+} // namespace vcl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/window/mouse.cxx b/vcl/source/window/mouse.cxx
index fe9e2b0f2444..943543ce0d16 100644
--- a/vcl/source/window/mouse.cxx
+++ b/vcl/source/window/mouse.cxx
@@ -493,30 +493,6 @@ void Window::SetPointer( PointerStyle nPointer )
     // possibly immediately move pointer
     if ( !mpWindowImpl->mpFrameData->mbInMouseMove && 
ImplTestMousePointerSet() )
         mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
-
-    VclPtr<vcl::Window> pWin = GetParentWithLOKNotifier();
-    if (!pWin)
-        return;
-
-    PointerStyle aPointer = GetPointer();
-    // We don't map all possible pointers hence we need a default
-    OString aPointerString = "default";
-    auto aIt = vcl::gaLOKPointerMap.find(aPointer);
-    if (aIt != vcl::gaLOKPointerMap.end())
-    {
-        aPointerString = aIt->second;
-    }
-
-    // issue mouse pointer events only for document windows
-    // Doc windows' immediate parent SfxFrameViewWindow_Impl is the one with
-    // parent notifier set during initialization
-    if ((ImplGetFrameData()->mbDragging &&
-         ImplGetFrameData()->mpMouseDownWin == this) ||
-        (GetParent()->ImplGetWindowImpl()->mbLOKParentNotifier &&
-         GetParent()->ImplGetWindowImpl()->mnLOKWindowId == 0))
-    {
-        
pWin->GetLOKNotifier()->libreOfficeKitViewCallback(LOK_CALLBACK_MOUSE_POINTER, 
aPointerString.getStr());
-    }
 }
 
 void Window::EnableChildPointerOverwrite( bool bOverwrite )

Reply via email to