[Libreoffice-commits] core.git: extensions/source include/svx include/vcl svx/source vcl/inc vcl/source vcl/unx

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Thu Dec 19 21:08:20 UTC 2019


 extensions/source/propctrlr/browserline.cxx    |    6 
 extensions/source/propctrlr/browserline.hxx    |    2 
 extensions/source/propctrlr/browserlistbox.cxx |    6 
 extensions/source/propctrlr/browserlistbox.hxx |    3 
 extensions/source/propctrlr/browserpage.cxx    |    8 
 extensions/source/propctrlr/browserpage.hxx    |    4 
 extensions/source/propctrlr/browserview.cxx    |    4 
 extensions/source/propctrlr/browserview.hxx    |    2 
 extensions/source/propctrlr/handlerhelper.cxx  |   14 -
 extensions/source/propctrlr/handlerhelper.hxx  |    2 
 extensions/source/propctrlr/propcontroller.cxx |    5 
 extensions/source/propctrlr/propcontroller.hxx |    1 
 extensions/source/propctrlr/propertyeditor.cxx |    7 
 extensions/source/propctrlr/propertyeditor.hxx |    3 
 include/svx/sidebar/PanelLayout.hxx            |    2 
 include/vcl/svapp.hxx                          |    3 
 include/vcl/sysdata.hxx                        |    1 
 svx/source/sidebar/PanelLayout.cxx             |   15 +
 vcl/inc/salinst.hxx                            |    2 
 vcl/inc/salobj.hxx                             |    1 
 vcl/inc/unx/gtk/gtkframe.hxx                   |    2 
 vcl/inc/unx/gtk/gtkinst.hxx                    |    1 
 vcl/inc/unx/gtk/gtkobject.hxx                  |   62 ++++-
 vcl/source/app/salvtables.cxx                  |    7 
 vcl/source/window/builder.cxx                  |    2 
 vcl/source/window/stacking.cxx                 |   17 +
 vcl/unx/gtk3/gtk3gtkinst.cxx                   |   27 ++
 vcl/unx/gtk3/gtk3gtkobject.cxx                 |  282 ++++++++++++++++++++++---
 28 files changed, 390 insertions(+), 101 deletions(-)

New commits:
commit e3a002c53a544de02e5119c5b0a2fd4f972156a8
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Tue Dec 17 17:27:30 2019 +0000
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Thu Dec 19 22:07:19 2019 +0100

    get native gtk widgets in sidebars working
    
    Change-Id: If65aef1249f54a87d7854c3fa2db4319a24a5a05
    Reviewed-on: https://gerrit.libreoffice.org/85326
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/extensions/source/propctrlr/browserline.cxx b/extensions/source/propctrlr/browserline.cxx
index 10beadbc3ba7..9b45c0c9e3f5 100644
--- a/extensions/source/propctrlr/browserline.cxx
+++ b/extensions/source/propctrlr/browserline.cxx
@@ -52,11 +52,9 @@ namespace pcr
     namespace PropertyLineElement = ::com::sun::star::inspection::PropertyLineElement;
 
     OBrowserLine::OBrowserLine(const OUString& rEntryName, weld::Container* pParent, weld::SizeGroup* pLabelGroup,
-                               weld::Container* pInitialControlParent, bool bInterimBuilder)
+                               weld::Container* pInitialControlParent)
         : m_sEntryName(rEntryName)
-        , m_xBuilder(bInterimBuilder
-                     ? Application::CreateInterimBuilder(pParent, "modules/spropctrlr/ui/browserline.ui")
-                     : Application::CreateBuilder(pParent, "modules/spropctrlr/ui/browserline.ui"))
+        , m_xBuilder(Application::CreateBuilder(pParent, "modules/spropctrlr/ui/browserline.ui"))
         , m_xContainer(m_xBuilder->weld_container("BrowserLine"))
         , m_xFtTitle(m_xBuilder->weld_label("label"))
         , m_xBrowseButton(m_xBuilder->weld_button("browse"))
diff --git a/extensions/source/propctrlr/browserline.hxx b/extensions/source/propctrlr/browserline.hxx
index e3e668a26bb7..cbe577e58da6 100644
--- a/extensions/source/propctrlr/browserline.hxx
+++ b/extensions/source/propctrlr/browserline.hxx
@@ -70,7 +70,7 @@ namespace pcr
 
     public:
         OBrowserLine(const OUString& rEntryName, weld::Container* pParent, weld::SizeGroup* pLabelGroup,
-                     weld::Container* pInitialControlParent, bool bInterimBuilder);
+                     weld::Container* pInitialControlParent);
         ~OBrowserLine();
 
         void setControl( const css::uno::Reference< css::inspection::XPropertyControl >& rxControl );
diff --git a/extensions/source/propctrlr/browserlistbox.cxx b/extensions/source/propctrlr/browserlistbox.cxx
index b626731b3c4c..a50d93c6f4aa 100644
--- a/extensions/source/propctrlr/browserlistbox.cxx
+++ b/extensions/source/propctrlr/browserlistbox.cxx
@@ -298,7 +298,7 @@ namespace pcr
         }
     }
 
-    OBrowserListBox::OBrowserListBox(weld::Builder& rBuilder, weld::Container* pContainer, bool bInterimBuilder)
+    OBrowserListBox::OBrowserListBox(weld::Builder& rBuilder, weld::Container* pContainer)
         : m_xScrolledWindow(rBuilder.weld_scrolled_window("scrolledwindow"))
         , m_xLinesPlayground(rBuilder.weld_container("playground"))
         , m_xSizeGroup(rBuilder.create_size_group())
@@ -308,7 +308,6 @@ namespace pcr
         , m_pControlObserver( nullptr )
         , m_nTheNameSize(0)
         , m_nRowHeight(0)
-        , m_bInterimBuilder(bInterimBuilder)
         , m_pControlContextImpl( new PropertyControlContext_Impl( *this ) )
     {
         m_xScrolledWindow->set_size_request(-1, m_xScrolledWindow->get_text_height() * 20);
@@ -465,8 +464,7 @@ namespace pcr
     {
         // create a new line
         BrowserLinePointer pBrowserLine(new OBrowserLine(rPropertyData.sName, m_xLinesPlayground.get(),
-                                                         m_xSizeGroup.get(), m_pInitialControlParent,
-                                                         m_bInterimBuilder));
+                                                         m_xSizeGroup.get(), m_pInitialControlParent));
 
         // check that the name is unique
         for (auto const& line : m_aLines)
diff --git a/extensions/source/propctrlr/browserlistbox.hxx b/extensions/source/propctrlr/browserlistbox.hxx
index 1a1b63aaf2ef..ad0a3aab6c64 100644
--- a/extensions/source/propctrlr/browserlistbox.hxx
+++ b/extensions/source/propctrlr/browserlistbox.hxx
@@ -84,7 +84,6 @@ namespace pcr
                                     m_xActiveControl;
         sal_uInt16                  m_nTheNameSize;
         int                         m_nRowHeight;
-        bool                        m_bInterimBuilder;
         ::rtl::Reference< PropertyControlContext_Impl >
                                     m_pControlContextImpl;
 
@@ -92,7 +91,7 @@ namespace pcr
         void    ShowEntry(sal_uInt16 nPos);
 
     public:
-        explicit OBrowserListBox(weld::Builder& rBuilder, weld::Container* pContainer, bool bInterimBuilder);
+        explicit OBrowserListBox(weld::Builder& rBuilder, weld::Container* pContainer);
         ~OBrowserListBox();
 
         void                        SetListener( IPropertyLineListener* _pListener );
diff --git a/extensions/source/propctrlr/browserpage.cxx b/extensions/source/propctrlr/browserpage.cxx
index 9bba600f6a0d..183743ee0e04 100644
--- a/extensions/source/propctrlr/browserpage.cxx
+++ b/extensions/source/propctrlr/browserpage.cxx
@@ -22,13 +22,11 @@
 
 namespace pcr
 {
-    OBrowserPage::OBrowserPage(weld::Container* pParent, weld::Container* pInitialControlContainer, bool bInterimBuilder)
+    OBrowserPage::OBrowserPage(weld::Container* pParent, weld::Container* pInitialControlContainer)
         : m_pParent(pParent)
-        , m_xBuilder(bInterimBuilder
-                     ? Application::CreateInterimBuilder(pParent, "modules/spropctrlr/ui/browserpage.ui")
-                     : Application::CreateBuilder(pParent, "modules/spropctrlr/ui/browserpage.ui"))
+        , m_xBuilder(Application::CreateBuilder(pParent, "modules/spropctrlr/ui/browserpage.ui"))
         , m_xContainer(m_xBuilder->weld_container("BrowserPage"))
-        , m_xListBox(std::make_unique<OBrowserListBox>(*m_xBuilder, pInitialControlContainer, bInterimBuilder))
+        , m_xListBox(std::make_unique<OBrowserListBox>(*m_xBuilder, pInitialControlContainer))
     {
     }
 
diff --git a/extensions/source/propctrlr/browserpage.hxx b/extensions/source/propctrlr/browserpage.hxx
index 4018a6b6c3e6..8ab95cb17115 100644
--- a/extensions/source/propctrlr/browserpage.hxx
+++ b/extensions/source/propctrlr/browserpage.hxx
@@ -36,8 +36,8 @@ namespace pcr
         OUString m_aPageTitle;
 
     public:
-        // if bInterimBuilder wasn't needed this could inherit from BuilderPage
-        explicit OBrowserPage(weld::Container* pParent, weld::Container* pContainer, bool bInterimBuilder);
+        // TODO inherit from BuilderPage
+        explicit OBrowserPage(weld::Container* pParent, weld::Container* pContainer);
         ~OBrowserPage();
 
         void SetPageTitle(const OUString& rPageTitle) { m_aPageTitle = rPageTitle; }
diff --git a/extensions/source/propctrlr/browserview.cxx b/extensions/source/propctrlr/browserview.cxx
index 35d062653d88..fb4c28d827e5 100644
--- a/extensions/source/propctrlr/browserview.cxx
+++ b/extensions/source/propctrlr/browserview.cxx
@@ -29,8 +29,8 @@ namespace pcr
     using namespace ::com::sun::star::uno;
     using namespace ::com::sun::star::lang;
 
-    OPropertyBrowserView::OPropertyBrowserView(css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Builder& rBuilder, bool bInterimBuilder)
-        : m_xPropBox(new OPropertyEditor(rContext, rBuilder, bInterimBuilder))
+    OPropertyBrowserView::OPropertyBrowserView(css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Builder& rBuilder)
+        : m_xPropBox(new OPropertyEditor(rContext, rBuilder))
         , m_nActivePage(0)
     {
         m_xPropBox->SetHelpId(HID_FM_PROPDLG_TABCTR);
diff --git a/extensions/source/propctrlr/browserview.hxx b/extensions/source/propctrlr/browserview.hxx
index c26f57dd1edf..22f897114687 100644
--- a/extensions/source/propctrlr/browserview.hxx
+++ b/extensions/source/propctrlr/browserview.hxx
@@ -35,7 +35,7 @@ namespace pcr
         Link<LinkParamNone*,void>   m_aPageActivationHandler;
 
     public:
-        explicit OPropertyBrowserView(css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Builder& rBuilder, bool bInterimBuilder);
+        explicit OPropertyBrowserView(css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Builder& rBuilder);
         ~OPropertyBrowserView();
 
         OPropertyEditor&    getPropertyBox() { return *m_xPropBox; }
diff --git a/extensions/source/propctrlr/handlerhelper.cxx b/extensions/source/propctrlr/handlerhelper.cxx
index 0f2981971351..18a575d6dbad 100644
--- a/extensions/source/propctrlr/handlerhelper.cxx
+++ b/extensions/source/propctrlr/handlerhelper.cxx
@@ -296,23 +296,14 @@ namespace pcr
 
     std::unique_ptr<weld::Builder> PropertyHandlerHelper::makeBuilder(const OUString& rUIFile, const Reference<XComponentContext>& rContext)
     {
-        bool bInterimBuilder(true);
-        Any aReturn = rContext->getValueByName("InterimBuilder");
-        aReturn >>= bInterimBuilder;
-
         Reference<XWindow> xWindow(rContext->getValueByName("BuilderParent"), UNO_QUERY_THROW);
         weld::TransportAsXWindow& rTunnel = dynamic_cast<weld::TransportAsXWindow&>(*xWindow);
-
-        // bInterimBuilder for the hosted in sidebar in basic IDE case
-        if (!bInterimBuilder)
-            return std::unique_ptr<weld::Builder>(Application::CreateBuilder(rTunnel.getWidget(), rUIFile));
-        return std::unique_ptr<weld::Builder>(Application::CreateInterimBuilder(rTunnel.getWidget(), rUIFile));
+        return std::unique_ptr<weld::Builder>(Application::CreateBuilder(rTunnel.getWidget(), rUIFile));
     }
 
-    void PropertyHandlerHelper::setBuilderParent(css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Widget* pParent, bool bInterimBuilder)
+    void PropertyHandlerHelper::setBuilderParent(css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Widget* pParent)
     {
         Reference<css::container::XNameContainer> xName(rContext, UNO_QUERY_THROW);
-        xName->insertByName("InterimBuilder", makeAny(bInterimBuilder));
         Reference<XWindow> xWindow(new weld::TransportAsXWindow(pParent));
         xName->insertByName("BuilderParent", makeAny(xWindow));
     }
@@ -320,7 +311,6 @@ namespace pcr
     void PropertyHandlerHelper::clearBuilderParent(css::uno::Reference<css::uno::XComponentContext>& rContext)
     {
         Reference<css::container::XNameContainer> xName(rContext, UNO_QUERY_THROW);
-        xName->removeByName("InterimBuilder");
         xName->removeByName("BuilderParent");
     }
 
diff --git a/extensions/source/propctrlr/handlerhelper.hxx b/extensions/source/propctrlr/handlerhelper.hxx
index c170538f52a1..bf2aec5baf9c 100644
--- a/extensions/source/propctrlr/handlerhelper.hxx
+++ b/extensions/source/propctrlr/handlerhelper.hxx
@@ -215,7 +215,7 @@ namespace pcr
 
         static std::unique_ptr<weld::Builder> makeBuilder(const OUString& rUIFile, const css::uno::Reference<css::uno::XComponentContext>& rContext);
 
-        static void setBuilderParent(css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Widget* pParent, bool bInterim);
+        static void setBuilderParent(css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Widget* pParent);
 
         static void clearBuilderParent(css::uno::Reference<css::uno::XComponentContext>& rContext);
 
diff --git a/extensions/source/propctrlr/propcontroller.cxx b/extensions/source/propctrlr/propcontroller.cxx
index 885e7efa8574..88b38e22c554 100644
--- a/extensions/source/propctrlr/propcontroller.cxx
+++ b/extensions/source/propctrlr/propcontroller.cxx
@@ -90,7 +90,6 @@ namespace pcr
             ,m_bSuspendingPropertyHandlers( false )
             ,m_bConstructed( false )
             ,m_bBindingIntrospectee( false )
-            ,m_bInterimBuilder( false )
     {
     }
 
@@ -360,7 +359,6 @@ namespace pcr
         if (weld::TransportAsXWindow* pTunnel = dynamic_cast<weld::TransportAsXWindow*>(xContainerWindow.get()))
         {
             xBuilder.reset(Application::CreateBuilder(pTunnel->getWidget(), sUIFile));
-            m_bInterimBuilder = false;
         }
         else
         {
@@ -369,7 +367,6 @@ namespace pcr
             if (!pParentWin)
                 throw RuntimeException("The frame is invalid. Unable to extract the container window.",*this);
             xBuilder.reset(Application::CreateInterimBuilder(pParentWin, sUIFile));
-            m_bInterimBuilder = true;
         }
 
         Construct(xContainerWindow, std::move(xBuilder));
@@ -658,7 +655,7 @@ namespace pcr
 
         m_xBuilder = std::move(xBuilder);
 
-        m_xPropView.reset(new OPropertyBrowserView(m_xContext, *m_xBuilder, m_bInterimBuilder));
+        m_xPropView.reset(new OPropertyBrowserView(m_xContext, *m_xBuilder));
         m_xPropView->setPageActivationHandler(LINK(this, OPropertyBrowserController, OnPageActivation));
 
         // add as dispose listener for our view. The view is disposed by the frame we're plugged into,
diff --git a/extensions/source/propctrlr/propcontroller.hxx b/extensions/source/propctrlr/propcontroller.hxx
index ee35d796ecca..7cfeba92030e 100644
--- a/extensions/source/propctrlr/propcontroller.hxx
+++ b/extensions/source/propctrlr/propcontroller.hxx
@@ -134,7 +134,6 @@ namespace pcr
         bool        m_bSuspendingPropertyHandlers;
         bool        m_bConstructed;
         bool        m_bBindingIntrospectee;
-        bool        m_bInterimBuilder;
 
     protected:
         DECLARE_XINTERFACE()
diff --git a/extensions/source/propctrlr/propertyeditor.cxx b/extensions/source/propctrlr/propertyeditor.cxx
index 41a7be1d3547..e102a4de21a8 100644
--- a/extensions/source/propctrlr/propertyeditor.cxx
+++ b/extensions/source/propctrlr/propertyeditor.cxx
@@ -31,7 +31,7 @@ namespace pcr
     using ::com::sun::star::inspection::XPropertyControl;
     using ::com::sun::star::uno::Reference;
 
-    OPropertyEditor::OPropertyEditor(css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Builder& rBuilder, bool bInterimBuilder)
+    OPropertyEditor::OPropertyEditor(css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Builder& rBuilder)
         : m_xContainer(rBuilder.weld_container("box"))
         , m_xTabControl(rBuilder.weld_notebook("tabcontrol"))
         , m_xControlHoldingParent(rBuilder.weld_container("controlparent")) // controls initially have this parent before they are moved
@@ -40,11 +40,10 @@ namespace pcr
         , m_pObserver(nullptr)
         , m_nNextId(1)
         , m_bHasHelpSection(false)
-        , m_bInterimBuilder(bInterimBuilder)
         , m_nMinHelpLines(0)
         , m_nMaxHelpLines(0)
     {
-        PropertyHandlerHelper::setBuilderParent(rContext, m_xControlHoldingParent.get(), bInterimBuilder);
+        PropertyHandlerHelper::setBuilderParent(rContext, m_xControlHoldingParent.get());
 
         m_xTabControl->connect_leave_page(LINK(this, OPropertyEditor, OnPageDeactivate));
         m_xTabControl->connect_enter_page(LINK(this, OPropertyEditor, OnPageActivate));
@@ -127,7 +126,7 @@ namespace pcr
         m_xTabControl->append_page(sIdent, rText);
 
         // create a new page
-        auto xPage = std::make_unique<OBrowserPage>(m_xTabControl->get_page(sIdent), m_xControlHoldingParent.get(), m_bInterimBuilder);
+        auto xPage = std::make_unique<OBrowserPage>(m_xTabControl->get_page(sIdent), m_xControlHoldingParent.get());
         xPage->SetPageTitle(rText);
         // some knittings
         xPage->getListBox().SetListener(m_pListener);
diff --git a/extensions/source/propctrlr/propertyeditor.hxx b/extensions/source/propctrlr/propertyeditor.hxx
index d04ab25fc9c0..f0e1b994e23d 100644
--- a/extensions/source/propctrlr/propertyeditor.hxx
+++ b/extensions/source/propctrlr/propertyeditor.hxx
@@ -59,7 +59,6 @@ namespace pcr
         sal_uInt16                  m_nNextId;
         Link<LinkParamNone*,void>   m_aPageActivationHandler;
         bool                        m_bHasHelpSection;
-        bool                        m_bInterimBuilder;
         sal_Int32                   m_nMinHelpLines;
         sal_Int32                   m_nMaxHelpLines;
 
@@ -68,7 +67,7 @@ namespace pcr
         std::map<sal_uInt16, PropertyPage> m_aHiddenPages;
 
     public:
-        explicit OPropertyEditor(css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Builder& rBuilder, bool bInterimBuilder);
+        explicit OPropertyEditor(css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Builder& rBuilder);
         ~OPropertyEditor();
 
         void                        SetLineListener( IPropertyLineListener* );
diff --git a/include/svx/sidebar/PanelLayout.hxx b/include/svx/sidebar/PanelLayout.hxx
index 6439ed51afdb..01cb0ff4a447 100644
--- a/include/svx/sidebar/PanelLayout.hxx
+++ b/include/svx/sidebar/PanelLayout.hxx
@@ -14,6 +14,7 @@
 
 #include <vcl/builder.hxx>
 #include <vcl/ctrl.hxx>
+#include <vcl/layout.hxx>
 #include <vcl/timer.hxx>
 #include <vcl/idle.hxx>
 #include <vcl/weld.hxx>
@@ -25,6 +26,7 @@ class SVX_DLLPUBLIC PanelLayout : public Control, public VclBuilderContainer
 {
 protected:
     std::unique_ptr<weld::Builder> m_xBuilder;
+    VclPtr<VclVBox> m_xVclContentArea;
     std::unique_ptr<weld::Container> m_xContainer;
 
 private:
diff --git a/include/vcl/svapp.hxx b/include/vcl/svapp.hxx
index b36c22ed9de9..8b79031342e7 100644
--- a/include/vcl/svapp.hxx
+++ b/include/vcl/svapp.hxx
@@ -1341,8 +1341,7 @@ public:
     static void setDeInitHook(Link<LinkParamNone*,void> const & hook);
 
     static weld::Builder* CreateBuilder(weld::Widget* pParent, const OUString &rUIFile);
-    static weld::Builder* CreateInterimBuilder(vcl::Window* pParent, const OUString &rUIFile); //for the duration of same SfxTabPages in mixed parent types
-    static weld::Builder* CreateInterimBuilder(weld::Widget* pParent, const OUString &rUIFile); //for the duration of same SfxTabPages in mixed parent types
+    static weld::Builder* CreateInterimBuilder(vcl::Window* pParent, const OUString &rUIFile); //for the duration of vcl parent windows
 
     static weld::MessageDialog* CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType,
                                                     VclButtonsType eButtonType, const OUString& rPrimaryMessage);
diff --git a/include/vcl/sysdata.hxx b/include/vcl/sysdata.hxx
index 393116d98c70..41277c5b9587 100644
--- a/include/vcl/sysdata.hxx
+++ b/include/vcl/sysdata.hxx
@@ -181,6 +181,7 @@ struct SystemWindowData
     // Nothing
 #elif defined( UNX )
     void*           pVisual;        // the visual to be used
+    bool            bClipUsingNativeWidget; // default is false, true will attempt to clip the childwindow with a native widget
 #endif
 };
 
diff --git a/svx/source/sidebar/PanelLayout.cxx b/svx/source/sidebar/PanelLayout.cxx
index 105bb1c1d6da..e82c03fdc513 100644
--- a/svx/source/sidebar/PanelLayout.cxx
+++ b/svx/source/sidebar/PanelLayout.cxx
@@ -30,11 +30,18 @@ PanelLayout::PanelLayout(vcl::Window* pParent, const OString& rID, const OUStrin
 
     // VclBuilder will trigger resize and start Idle
     if (!bInterimBuilder)
+    {
         m_pUIBuilder.reset(new VclBuilder(this, getUIRootDir(), rUIXMLDescription, rID, rFrame));
+        if (GetSettings().GetStyleSettings().GetAutoMnemonic())
+           Accelerator::GenerateAutoMnemonicsOnHierarchy(this);
+    }
     else
-        m_xBuilder.reset(Application::CreateInterimBuilder(this, rUIXMLDescription));
-    if (GetSettings().GetStyleSettings().GetAutoMnemonic())
-       Accelerator::GenerateAutoMnemonicsOnHierarchy(this);
+    {
+        m_xVclContentArea = VclPtr<VclVBox>::Create(this);
+        m_xVclContentArea->Show();
+        m_xBuilder.reset(Application::CreateInterimBuilder(m_xVclContentArea, rUIXMLDescription));
+        m_xContainer = m_xBuilder->weld_container(rID);
+    }
 }
 
 PanelLayout::~PanelLayout()
@@ -46,7 +53,9 @@ void PanelLayout::dispose()
 {
     m_bInClose = true;
     m_aPanelLayoutIdle.Stop();
+    m_xContainer.reset();
     m_xBuilder.reset();
+    m_xVclContentArea.disposeAndClear();
     disposeBuilder();
     Control::dispose();
 }
diff --git a/vcl/inc/salinst.hxx b/vcl/inc/salinst.hxx
index d47fb63436d2..621343677078 100644
--- a/vcl/inc/salinst.hxx
+++ b/vcl/inc/salinst.hxx
@@ -164,7 +164,7 @@ public:
     virtual OpenGLContext*  CreateOpenGLContext() = 0;
 
     virtual weld::Builder* CreateBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile);
-    static  weld::Builder* CreateInterimBuilder(vcl::Window* pParent, const OUString& rUIRoot, const OUString& rUIFile);
+    virtual weld::Builder* CreateInterimBuilder(vcl::Window* pParent, const OUString& rUIRoot, const OUString& rUIFile);
     virtual weld::MessageDialog* CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType,
                                                      VclButtonsType eButtonType, const OUString& rPrimaryMessage);
     virtual weld::Window* GetFrameWeld(const css::uno::Reference<css::awt::XWindow>& rWindow);
diff --git a/vcl/inc/salobj.hxx b/vcl/inc/salobj.hxx
index 90ef3ae5e8d2..6e79e49208bb 100644
--- a/vcl/inc/salobj.hxx
+++ b/vcl/inc/salobj.hxx
@@ -48,6 +48,7 @@ public:
     virtual void                    Show( bool bVisible ) = 0;
     virtual void                    Enable( bool /* nEnable */ ) {} // overridden by WinSalObject
     virtual void                    GrabFocus() {}
+    virtual void                    Reparent(SalFrame* /*pFrame*/) {}
 
     virtual void                    SetForwardKey( bool /* bEnable */ ) {}
 
diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index 0955a1d92dc9..033ee93efe42 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -162,6 +162,8 @@ class GtkSalFrame final : public SalFrame
     };
     friend struct IMHandler;
 
+    friend class GtkSalObjectWidgetClip;
+
     SalX11Screen                    m_nXScreen;
     GtkWidget*                      m_pWindow;
     GtkHeaderBar*                   m_pHeaderBar;
diff --git a/vcl/inc/unx/gtk/gtkinst.hxx b/vcl/inc/unx/gtk/gtkinst.hxx
index 1e0f86cf2cf2..d1d624b9e27e 100644
--- a/vcl/inc/unx/gtk/gtkinst.hxx
+++ b/vcl/inc/unx/gtk/gtkinst.hxx
@@ -236,6 +236,7 @@ public:
     virtual css::uno::Reference< css::uno::XInterface > CreateDropTarget() override;
     virtual OpenGLContext* CreateOpenGLContext() override;
     virtual weld::Builder* CreateBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile) override;
+    virtual weld::Builder* CreateInterimBuilder(vcl::Window* pParent, const OUString& rUIRoot, const OUString& rUIFile) override;
     virtual weld::MessageDialog* CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage) override;
     virtual weld::Window* GetFrameWeld(const css::uno::Reference<css::awt::XWindow>& rWindow) override;
 
diff --git a/vcl/inc/unx/gtk/gtkobject.hxx b/vcl/inc/unx/gtk/gtkobject.hxx
index 7ff9e499815b..d1a5226cd9cc 100644
--- a/vcl/inc/unx/gtk/gtkobject.hxx
+++ b/vcl/inc/unx/gtk/gtkobject.hxx
@@ -25,37 +25,83 @@
 #include <salobj.hxx>
 #include <unx/gtk/gtkframe.hxx>
 
-class GtkSalObject final : public SalObject
+class GtkSalObjectBase : public SalObject
 {
-    SystemEnvData     m_aSystemData;
+protected:
+    SystemEnvData       m_aSystemData;
     GtkWidget*          m_pSocket;
     GtkSalFrame*        m_pParent;
     cairo_region_t*     m_pRegion;
 
+    void Init();
+
+public:
+    GtkSalObjectBase(GtkSalFrame* pParent);
+    virtual ~GtkSalObjectBase() override;
+
+    virtual void                    BeginSetClipRegion( sal_uInt32 nRects ) override;
+    virtual void                    UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) override;
+
+    virtual void                    SetForwardKey( bool bEnable ) override;
+
+    virtual const SystemEnvData*    GetSystemData() const override;
+
+    virtual Size                    GetOptimalSize() const override;
+
+private:
     // signals
     static gboolean     signalButton( GtkWidget*, GdkEventButton*, gpointer );
     static gboolean     signalFocus( GtkWidget*, GdkEventFocus*, gpointer );
+};
+
+// this attempts to clip the hosted native window using gdk_window_shape_combine_region
+class GtkSalObject final : public GtkSalObjectBase
+{
+    // signals
     static void         signalDestroy( GtkWidget*, gpointer );
+
 public:
-    GtkSalObject( GtkSalFrame* pParent, bool bShow );
+    GtkSalObject(GtkSalFrame* pParent, bool bShow);
     virtual ~GtkSalObject() override;
 
     // override all pure virtual methods
     virtual void                    ResetClipRegion() override;
-    virtual void                    BeginSetClipRegion( sal_uInt32 nRects ) override;
-    virtual void                    UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) override;
     virtual void                    EndSetClipRegion() override;
 
     virtual void                    SetPosSize( long nX, long nY, long nWidth, long nHeight ) override;
     virtual void                    Show( bool bVisible ) override;
+    virtual void                    Reparent(SalFrame* pFrame) override;
+};
 
-    virtual void                    SetForwardKey( bool bEnable ) override;
+// this attempts to clip the hosted native GtkWidget by using a GtkScrolledWindow as a viewport
+// only a rectangular area is going to work
+class GtkSalObjectWidgetClip final : public GtkSalObjectBase
+{
+    tools::Rectangle m_aRect;
+    tools::Rectangle m_aClipRect;
+    GtkWidget* m_pScrolledWindow;
 
-    virtual const SystemEnvData*    GetSystemData() const override;
+    // signals
+    static gboolean     signalScroll( GtkWidget*, GdkEvent*, gpointer );
+    static void         signalDestroy( GtkWidget*, gpointer );
 
-    virtual Size                    GetOptimalSize() const override;
+    bool signal_scroll(GtkWidget* pScrolledWindow, GdkEvent* pEvent);
+
+    void ApplyClipRegion();
+public:
+    GtkSalObjectWidgetClip(GtkSalFrame* pParent, bool bShow);
+    virtual ~GtkSalObjectWidgetClip() override;
+
+    // override all pure virtual methods
+    virtual void                    ResetClipRegion() override;
+    virtual void                    EndSetClipRegion() override;
+
+    virtual void                    SetPosSize( long nX, long nY, long nWidth, long nHeight ) override;
+    virtual void                    Show( bool bVisible ) override;
+    virtual void                    Reparent(SalFrame* pFrame) override;
 };
 
+
 #endif // INCLUDED_VCL_INC_UNX_GTK_GTKOBJECT_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 1d49f779e695..7e56847ae509 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -6611,13 +6611,6 @@ weld::Builder* SalInstance::CreateInterimBuilder(vcl::Window* pParent, const OUS
     return new SalInstanceBuilder(pParent, rUIRoot, rUIFile);
 }
 
-weld::Builder* Application::CreateInterimBuilder(weld::Widget* pParent, const OUString &rUIFile)
-{
-    SalInstanceWidget* pParentInstance = dynamic_cast<SalInstanceWidget*>(pParent);
-    vcl::Window* pParentWidget = pParentInstance ? pParentInstance->getWidget() : nullptr;
-    return Application::CreateInterimBuilder(pParentWidget, rUIFile);
-}
-
 void SalInstanceWindow::help()
 {
     //show help for widget with keyboard focus
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index b47ad027188f..91e30d1baf66 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -154,7 +154,7 @@ weld::Builder* Application::CreateBuilder(weld::Widget* pParent, const OUString
 
 weld::Builder* Application::CreateInterimBuilder(vcl::Window* pParent, const OUString &rUIFile)
 {
-    return SalInstance::CreateInterimBuilder(pParent, VclBuilderContainer::getUIRootDir(), rUIFile);
+    return ImplGetSVData()->mpDefInst->CreateInterimBuilder(pParent, VclBuilderContainer::getUIRootDir(), rUIFile);
 }
 
 weld::MessageDialog* Application::CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType,
diff --git a/vcl/source/window/stacking.cxx b/vcl/source/window/stacking.cxx
index 718ce76dea66..08b6cbaa987e 100644
--- a/vcl/source/window/stacking.cxx
+++ b/vcl/source/window/stacking.cxx
@@ -23,6 +23,7 @@
 #include <sal/log.hxx>
 
 #include <salframe.hxx>
+#include <salobj.hxx>
 #include <svdata.hxx>
 #include <window.h>
 #include <brdwin.hxx>
@@ -63,8 +64,13 @@ void Window::ImplInsertWindow( vcl::Window* pParent )
     {
         // search frame window and set window frame data
         vcl::Window* pFrameParent = pParent->mpWindowImpl->mpFrameWindow;
-        mpWindowImpl->mpFrameData     = pFrameParent->mpWindowImpl->mpFrameData;
-        mpWindowImpl->mpFrame         = pFrameParent->mpWindowImpl->mpFrame;
+        mpWindowImpl->mpFrameData = pFrameParent->mpWindowImpl->mpFrameData;
+        if (mpWindowImpl->mpFrame != pFrameParent->mpWindowImpl->mpFrame)
+        {
+            mpWindowImpl->mpFrame = pFrameParent->mpWindowImpl->mpFrame;
+            if (mpWindowImpl->mpSysObj)
+                mpWindowImpl->mpSysObj->Reparent(mpWindowImpl->mpFrame);
+        }
         mpWindowImpl->mpFrameWindow   = pFrameParent;
         mpWindowImpl->mbFrame         = false;
 
@@ -751,7 +757,12 @@ void Window::ImplUpdateWindowPtr( vcl::Window* pWindow )
     }
 
     mpWindowImpl->mpFrameData     = pWindow->mpWindowImpl->mpFrameData;
-    mpWindowImpl->mpFrame         = pWindow->mpWindowImpl->mpFrame;
+    if (mpWindowImpl->mpFrame != pWindow->mpWindowImpl->mpFrame)
+    {
+        mpWindowImpl->mpFrame = pWindow->mpWindowImpl->mpFrame;
+        if (mpWindowImpl->mpSysObj)
+            mpWindowImpl->mpSysObj->Reparent(mpWindowImpl->mpFrame);
+    }
     mpWindowImpl->mpFrameWindow   = pWindow->mpWindowImpl->mpFrameWindow;
     if ( pWindow->ImplIsOverlapWindow() )
         mpWindowImpl->mpOverlapWindow = pWindow;
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index d4842bea9ea6..0df44590ced6 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -241,11 +241,13 @@ SalFrame* GtkInstance::CreateChildFrame( SystemParentData* pParentData, SalFrame
     return new GtkSalFrame( pParentData );
 }
 
-SalObject* GtkInstance::CreateObject( SalFrame* pParent, SystemWindowData* /*pWindowData*/, bool bShow )
+SalObject* GtkInstance::CreateObject( SalFrame* pParent, SystemWindowData* pWindowData, bool bShow )
 {
     EnsureInit();
     //FIXME: Missing CreateObject functionality ...
-    return new GtkSalObject( static_cast<GtkSalFrame*>(pParent), bShow );
+    if (pWindowData && pWindowData->bClipUsingNativeWidget)
+        return new GtkSalObjectWidgetClip(static_cast<GtkSalFrame*>(pParent), bShow);
+    return new GtkSalObject(static_cast<GtkSalFrame*>(pParent), bShow);
 }
 
 extern "C"
@@ -13277,6 +13279,27 @@ weld::Builder* GtkInstance::CreateBuilder(weld::Widget* pParent, const OUString&
     return new GtkInstanceBuilder(pBuilderParent, rUIRoot, rUIFile);
 }
 
+weld::Builder* GtkInstance::CreateInterimBuilder(vcl::Window* pParent, const OUString& rUIRoot, const OUString& rUIFile)
+{
+    // Create a foreign window which we know is a GtkGrid and make the native widgets a child of that, so we can
+    // support GtkWidgets within a vcl::Window
+    SystemWindowData winData = {};
+    winData.bClipUsingNativeWidget = true;
+    auto xEmbedWindow = VclPtr<SystemChildWindow>::Create(pParent, 0, &winData, true);
+    xEmbedWindow->Show();
+    xEmbedWindow->set_expand(true);
+
+    const SystemEnvData* pEnvData = xEmbedWindow->GetSystemData();
+    if (!pEnvData)
+        return nullptr;
+
+    GtkWidget *pWindow = static_cast<GtkWidget*>(pEnvData->pWidget);
+    gtk_widget_show_all(pWindow);
+
+    // build the widget tree as a child of the GtkEventBox GtkGrid parent
+    return new GtkInstanceBuilder(pWindow, rUIRoot, rUIFile);
+}
+
 weld::MessageDialog* GtkInstance::CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType, VclButtonsType eButtonsType, const OUString &rPrimaryMessage)
 {
     GtkInstanceWidget* pParentInstance = dynamic_cast<GtkInstanceWidget*>(pParent);
diff --git a/vcl/unx/gtk3/gtk3gtkobject.cxx b/vcl/unx/gtk3/gtk3gtkobject.cxx
index 3079fdbe03a4..93db53a159ec 100644
--- a/vcl/unx/gtk3/gtk3gtkobject.cxx
+++ b/vcl/unx/gtk3/gtk3gtkobject.cxx
@@ -28,12 +28,19 @@
 #include <unx/gtk/gtkframe.hxx>
 #include <unx/gtk/gtkdata.hxx>
 
-GtkSalObject::GtkSalObject( GtkSalFrame* pParent, bool bShow )
-        : m_pSocket(nullptr)
-        , m_pParent(pParent)
-        , m_pRegion(nullptr)
+GtkSalObjectBase::GtkSalObjectBase(GtkSalFrame* pParent)
+    : m_pSocket(nullptr)
+    , m_pParent(pParent)
+    , m_pRegion(nullptr)
 {
-    if( !pParent )
+    if (!m_pParent)
+        return;
+}
+
+GtkSalObject::GtkSalObject(GtkSalFrame* pParent, bool bShow)
+    : GtkSalObjectBase(pParent)
+{
+    if (!m_pParent)
         return;
 
     // our plug window
@@ -43,17 +50,28 @@ GtkSalObject::GtkSalObject( GtkSalFrame* pParent, bool bShow )
     gtk_fixed_put( pParent->getFixedContainer(),
                    m_pSocket,
                    0, 0 );
+
+    Init();
+
+    g_signal_connect( G_OBJECT(m_pSocket), "destroy", G_CALLBACK(signalDestroy), this );
+
+    // #i59255# necessary due to sync effects with java child windows
+    pParent->Flush();
+}
+
+void GtkSalObjectBase::Init()
+{
     // realize so we can get a window id
     gtk_widget_realize( m_pSocket );
 
     // system data
-    m_aSystemData.aWindow       = pParent->GetNativeWindowHandle(m_pSocket);
+    m_aSystemData.aWindow       = m_pParent->GetNativeWindowHandle(m_pSocket);
     m_aSystemData.aShellWindow  = reinterpret_cast<sal_IntPtr>(this);
     m_aSystemData.pSalFrame     = nullptr;
     m_aSystemData.pWidget       = m_pSocket;
-    m_aSystemData.nScreen       = pParent->getXScreenNumber().getXScreen();
+    m_aSystemData.nScreen       = m_pParent->getXScreenNumber().getXScreen();
     m_aSystemData.toolkit       = SystemEnvData::Toolkit::Gtk3;
-    GdkScreen* pScreen = gtk_window_get_screen(GTK_WINDOW(pParent->getWindow()));
+    GdkScreen* pScreen = gtk_window_get_screen(GTK_WINDOW(m_pParent->getWindow()));
     GdkVisual* pVisual = gdk_screen_get_system_visual(pScreen);
 
 #if defined(GDK_WINDOWING_X11)
@@ -77,19 +95,18 @@ GtkSalObject::GtkSalObject( GtkSalFrame* pParent, bool bShow )
     g_signal_connect( G_OBJECT(m_pSocket), "button-release-event", G_CALLBACK(signalButton), this );
     g_signal_connect( G_OBJECT(m_pSocket), "focus-in-event", G_CALLBACK(signalFocus), this );
     g_signal_connect( G_OBJECT(m_pSocket), "focus-out-event", G_CALLBACK(signalFocus), this );
-    g_signal_connect( G_OBJECT(m_pSocket), "destroy", G_CALLBACK(signalDestroy), this );
-
-    // #i59255# necessary due to sync effects with java child windows
-    pParent->Flush();
-
 }
 
-GtkSalObject::~GtkSalObject()
+GtkSalObjectBase::~GtkSalObjectBase()
 {
     if( m_pRegion )
     {
         cairo_region_destroy( m_pRegion );
     }
+}
+
+GtkSalObject::~GtkSalObject()
+{
     if( m_pSocket )
     {
         // remove socket from parent frame's fixed container
@@ -110,14 +127,14 @@ void GtkSalObject::ResetClipRegion()
         gdk_window_shape_combine_region( gtk_widget_get_window(m_pSocket), nullptr, 0, 0 );
 }
 
-void GtkSalObject::BeginSetClipRegion( sal_uInt32 )
+void GtkSalObjectBase::BeginSetClipRegion( sal_uInt32 )
 {
-    if( m_pRegion )
-        cairo_region_destroy( m_pRegion );
+    if (m_pRegion)
+        cairo_region_destroy(m_pRegion);
     m_pRegion = cairo_region_create();
 }
 
-void GtkSalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
+void GtkSalObjectBase::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
 {
     GdkRectangle aRect;
     aRect.x         = nX;
@@ -134,9 +151,9 @@ void GtkSalObject::EndSetClipRegion()
         gdk_window_shape_combine_region( gtk_widget_get_window(m_pSocket), m_pRegion, 0, 0 );
 }
 
-void GtkSalObject::SetPosSize( long nX, long nY, long nWidth, long nHeight )
+void GtkSalObject::SetPosSize(long nX, long nY, long nWidth, long nHeight)
 {
-    if( m_pSocket )
+    if (m_pSocket)
     {
         GtkFixed* pContainer = GTK_FIXED(gtk_widget_get_parent(m_pSocket));
         gtk_fixed_move( pContainer, m_pSocket, nX, nY );
@@ -145,18 +162,43 @@ void GtkSalObject::SetPosSize( long nX, long nY, long nWidth, long nHeight )
     }
 }
 
+void GtkSalObject::Reparent(SalFrame* pFrame)
+{
+    GtkSalFrame* pNewParent = static_cast<GtkSalFrame*>(pFrame);
+    if (m_pSocket)
+    {
+        GtkFixed* pContainer = GTK_FIXED(gtk_widget_get_parent(m_pSocket));
+
+        gint nX(0), nY(0);
+        gtk_container_child_get(GTK_CONTAINER(pContainer), m_pSocket,
+                "x", &nX,
+                "y", &nY,
+                nullptr);
+
+        g_object_ref(m_pSocket);
+        gtk_container_remove(GTK_CONTAINER(pContainer), m_pSocket);
+
+        gtk_fixed_put(pNewParent->getFixedContainer(),
+                      m_pSocket,
+                      nX, nY);
+
+        g_object_unref(m_pSocket);
+    }
+    m_pParent = pNewParent;
+}
+
 void GtkSalObject::Show( bool bVisible )
 {
     if( m_pSocket )
     {
         if( bVisible )
-            gtk_widget_show( m_pSocket );
+            gtk_widget_show(m_pSocket);
         else
-            gtk_widget_hide( m_pSocket );
+            gtk_widget_hide(m_pSocket);
     }
 }
 
-Size GtkSalObject::GetOptimalSize() const
+Size GtkSalObjectBase::GetOptimalSize() const
 {
     if (m_pSocket)
     {
@@ -172,14 +214,14 @@ Size GtkSalObject::GetOptimalSize() const
     return Size();
 }
 
-const SystemEnvData* GtkSalObject::GetSystemData() const
+const SystemEnvData* GtkSalObjectBase::GetSystemData() const
 {
     return &m_aSystemData;
 }
 
-gboolean GtkSalObject::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointer object )
+gboolean GtkSalObjectBase::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointer object )
 {
-    GtkSalObject* pThis = static_cast<GtkSalObject*>(object);
+    GtkSalObjectBase* pThis = static_cast<GtkSalObject*>(object);
 
     if( pEvent->type == GDK_BUTTON_PRESS )
     {
@@ -189,9 +231,9 @@ gboolean GtkSalObject::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointe
     return FALSE;
 }
 
-gboolean GtkSalObject::signalFocus( GtkWidget*, GdkEventFocus* pEvent, gpointer object )
+gboolean GtkSalObjectBase::signalFocus( GtkWidget*, GdkEventFocus* pEvent, gpointer object )
 {
-    GtkSalObject* pThis = static_cast<GtkSalObject*>(object);
+    GtkSalObjectBase* pThis = static_cast<GtkSalObject*>(object);
 
     pThis->CallCallback( pEvent->in ? SalObjEvent::GetFocus : SalObjEvent::LoseFocus );
 
@@ -207,7 +249,7 @@ void GtkSalObject::signalDestroy( GtkWidget* pObj, gpointer object )
     }
 }
 
-void GtkSalObject::SetForwardKey( bool bEnable )
+void GtkSalObjectBase::SetForwardKey( bool bEnable )
 {
     if( bEnable )
         gtk_widget_add_events( GTK_WIDGET( m_pSocket ), GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE );
@@ -215,4 +257,186 @@ void GtkSalObject::SetForwardKey( bool bEnable )
         gtk_widget_set_events( GTK_WIDGET( m_pSocket ), ~(GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE) & gtk_widget_get_events( GTK_WIDGET( m_pSocket ) ) );
 }
 
+GtkSalObjectWidgetClip::GtkSalObjectWidgetClip(GtkSalFrame* pParent, bool bShow)
+    : GtkSalObjectBase(pParent)
+    , m_pScrolledWindow(nullptr)
+{
+    if( !pParent )
+        return;
+
+    m_pScrolledWindow = gtk_scrolled_window_new(nullptr, nullptr);
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(m_pScrolledWindow),
+                                   GTK_POLICY_EXTERNAL, GTK_POLICY_EXTERNAL);
+    g_signal_connect(m_pScrolledWindow, "scroll-event", G_CALLBACK(signalScroll), this);
+
+    // insert into container
+    gtk_fixed_put( pParent->getFixedContainer(),
+                   m_pScrolledWindow,
+                   0, 0 );
+
+    // deliberately without adjustments to avoid gtk's auto adjustment on changing focus
+    GtkWidget* pViewPort = gtk_viewport_new(nullptr, nullptr);
+
+    // force in a fake background of a suitable color
+    GtkStyleContext *pWidgetContext = gtk_widget_get_style_context(pViewPort);
+    GtkCssProvider* pBgCssProvider = gtk_css_provider_new();
+    OUString sColor = Application::GetSettings().GetStyleSettings().GetDialogColor().AsRGBHexString();
+    OUString aBuffer = "* { background-color: #" + sColor + "; }";
+    OString aResult = OUStringToOString(aBuffer, RTL_TEXTENCODING_UTF8);
+    gtk_css_provider_load_from_data(pBgCssProvider, aResult.getStr(), aResult.getLength(), nullptr);
+    gtk_style_context_add_provider(pWidgetContext, GTK_STYLE_PROVIDER(pBgCssProvider),
+                                   GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+
+    gtk_container_add(GTK_CONTAINER(m_pScrolledWindow), pViewPort);
+    gtk_widget_show(pViewPort);
+
+    // our plug window
+    m_pSocket = gtk_grid_new();
+    gtk_container_add(GTK_CONTAINER(pViewPort), m_pSocket);
+    gtk_widget_show(m_pSocket);
+
+    Show(bShow);
+
+    Init();
+
+    g_signal_connect( G_OBJECT(m_pSocket), "destroy", G_CALLBACK(signalDestroy), this );
+}
+
+GtkSalObjectWidgetClip::~GtkSalObjectWidgetClip()
+{
+    if( m_pSocket )
+    {
+        // remove socket from parent frame's fixed container
+        gtk_container_remove( GTK_CONTAINER(gtk_widget_get_parent(m_pScrolledWindow)),
+                              m_pScrolledWindow );
+        // get rid of the socket
+        // actually the gtk_container_remove should let the ref count
+        // of the socket sink to 0 and destroy it (see signalDestroy)
+        // this is just a sanity check
+        if( m_pScrolledWindow )
+            gtk_widget_destroy( m_pScrolledWindow );
+    }
+}
+
+void GtkSalObjectWidgetClip::ResetClipRegion()
+{
+    m_aClipRect = tools::Rectangle();
+    ApplyClipRegion();
+}
+
+void GtkSalObjectWidgetClip::EndSetClipRegion()
+{
+    int nRects = cairo_region_num_rectangles(m_pRegion);
+    assert(nRects == 0 || nRects == 1);
+    if (nRects == 0)
+        m_aClipRect = tools::Rectangle();
+    else
+    {
+        cairo_rectangle_int_t rectangle;
+        cairo_region_get_rectangle(m_pRegion, 0, &rectangle);
+        m_aClipRect = tools::Rectangle(Point(rectangle.x, rectangle.y), Size(rectangle.width, rectangle.height));
+    }
+    ApplyClipRegion();
+}
+
+void GtkSalObjectWidgetClip::ApplyClipRegion()
+{
+    if( m_pSocket )
+    {
+        GtkFixed* pContainer = GTK_FIXED(gtk_widget_get_parent(m_pScrolledWindow));
+        gtk_fixed_move(pContainer, m_pScrolledWindow, m_aRect.Left() + m_aClipRect.Left(), m_aRect.Top() + m_aClipRect.Top());
+        if (m_aClipRect.IsEmpty())
+            gtk_widget_set_size_request(m_pScrolledWindow, m_aRect.GetWidth(), m_aRect.GetHeight());
+        else
+            gtk_widget_set_size_request(m_pScrolledWindow, m_aClipRect.GetWidth(), m_aClipRect.GetHeight());
+        gtk_adjustment_set_value(gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(m_pScrolledWindow)), m_aClipRect.Left());
+        gtk_adjustment_set_value(gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(m_pScrolledWindow)), m_aClipRect.Top());
+    }
+}
+
+void GtkSalObjectWidgetClip::SetPosSize(long nX, long nY, long nWidth, long nHeight)
+{
+    m_aRect = tools::Rectangle(Point(nX, nY), Size(nWidth, nHeight));
+    if (m_pSocket)
+    {
+        GtkFixed* pContainer = GTK_FIXED(gtk_widget_get_parent(m_pScrolledWindow));
+        gtk_widget_set_size_request(m_pSocket, nWidth, nHeight);
+        ApplyClipRegion();
+        m_pParent->nopaint_container_resize_children(GTK_CONTAINER(pContainer));
+    }
+}
+
+void GtkSalObjectWidgetClip::Reparent(SalFrame* pFrame)
+{
+    GtkSalFrame* pNewParent = static_cast<GtkSalFrame*>(pFrame);
+    if (m_pSocket)
+    {
+        GtkFixed* pContainer = GTK_FIXED(gtk_widget_get_parent(m_pScrolledWindow));
+
+        gint nX(0), nY(0);
+        gtk_container_child_get(GTK_CONTAINER(pContainer), m_pScrolledWindow,
+                "x", &nX,
+                "y", &nY,
+                nullptr);
+
+        g_object_ref(m_pScrolledWindow);
+        gtk_container_remove(GTK_CONTAINER(pContainer), m_pScrolledWindow);
+
+        gtk_fixed_put(pNewParent->getFixedContainer(),
+                      m_pScrolledWindow,
+                      nX, nY);
+
+        g_object_unref(m_pScrolledWindow);
+    }
+    m_pParent = pNewParent;
+}
+
+void GtkSalObjectWidgetClip::Show( bool bVisible )
+{
+    if( m_pSocket )
+    {
+        if( bVisible )
+            gtk_widget_show(m_pScrolledWindow);
+        else
+            gtk_widget_hide(m_pScrolledWindow);
+    }
+}
+
+void GtkSalObjectWidgetClip::signalDestroy( GtkWidget* pObj, gpointer object )
+{
+    GtkSalObjectWidgetClip* pThis = static_cast<GtkSalObjectWidgetClip*>(object);
+    if( pObj == pThis->m_pSocket )
+    {
+        pThis->m_pSocket = nullptr;
+        pThis->m_pScrolledWindow = nullptr;
+    }
+}
+
+gboolean GtkSalObjectWidgetClip::signalScroll(GtkWidget* pScrolledWindow, GdkEvent* pEvent, gpointer object)
+{
+    GtkSalObjectWidgetClip* pThis = static_cast<GtkSalObjectWidgetClip*>(object);
+    return pThis->signal_scroll(pScrolledWindow, pEvent);
+}
+
+// forward the wheel scroll events onto the main window instead
+bool GtkSalObjectWidgetClip::signal_scroll(GtkWidget*, GdkEvent* pEvent)
+{
+    GtkWidget* pEventWidget = gtk_get_event_widget(pEvent);
+
+    GtkWidget* pMouseEventWidget = m_pParent->getMouseEventWidget();
+
+    gint dest_x, dest_y;
+    gtk_widget_translate_coordinates(pEventWidget,
+                                     pMouseEventWidget,
+                                     pEvent->scroll.x,
+                                     pEvent->scroll.y,
+                                     &dest_x,
+                                     &dest_y);
+    pEvent->scroll.x = dest_x;
+    pEvent->scroll.y = dest_y;
+
+    GtkSalFrame::signalScroll(pMouseEventWidget, pEvent, m_pParent);
+    return true;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list