summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2019-12-17 17:27:30 +0000
committerCaolán McNamara <caolanm@redhat.com>2019-12-19 22:07:19 +0100
commite3a002c53a544de02e5119c5b0a2fd4f972156a8 (patch)
treed6bd55210bb93fdc2aae2e398b63c3dddeb38326
parente994b3fc3b2c9b7d39a715fc4d9453e06434d457 (diff)
get native gtk widgets in sidebars working
Change-Id: If65aef1249f54a87d7854c3fa2db4319a24a5a05 Reviewed-on: https://gerrit.libreoffice.org/85326 Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--extensions/source/propctrlr/browserline.cxx6
-rw-r--r--extensions/source/propctrlr/browserline.hxx2
-rw-r--r--extensions/source/propctrlr/browserlistbox.cxx6
-rw-r--r--extensions/source/propctrlr/browserlistbox.hxx3
-rw-r--r--extensions/source/propctrlr/browserpage.cxx8
-rw-r--r--extensions/source/propctrlr/browserpage.hxx4
-rw-r--r--extensions/source/propctrlr/browserview.cxx4
-rw-r--r--extensions/source/propctrlr/browserview.hxx2
-rw-r--r--extensions/source/propctrlr/handlerhelper.cxx14
-rw-r--r--extensions/source/propctrlr/handlerhelper.hxx2
-rw-r--r--extensions/source/propctrlr/propcontroller.cxx5
-rw-r--r--extensions/source/propctrlr/propcontroller.hxx1
-rw-r--r--extensions/source/propctrlr/propertyeditor.cxx7
-rw-r--r--extensions/source/propctrlr/propertyeditor.hxx3
-rw-r--r--include/svx/sidebar/PanelLayout.hxx2
-rw-r--r--include/vcl/svapp.hxx3
-rw-r--r--include/vcl/sysdata.hxx1
-rw-r--r--svx/source/sidebar/PanelLayout.cxx15
-rw-r--r--vcl/inc/salinst.hxx2
-rw-r--r--vcl/inc/salobj.hxx1
-rw-r--r--vcl/inc/unx/gtk/gtkframe.hxx2
-rw-r--r--vcl/inc/unx/gtk/gtkinst.hxx1
-rw-r--r--vcl/inc/unx/gtk/gtkobject.hxx62
-rw-r--r--vcl/source/app/salvtables.cxx7
-rw-r--r--vcl/source/window/builder.cxx2
-rw-r--r--vcl/source/window/stacking.cxx17
-rw-r--r--vcl/unx/gtk3/gtk3gtkinst.cxx27
-rw-r--r--vcl/unx/gtk3/gtk3gtkobject.cxx282
28 files changed, 390 insertions, 101 deletions
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: */