diff options
author | Caolán McNamara <caolanm@redhat.com> | 2019-12-17 17:27:30 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2019-12-19 22:07:19 +0100 |
commit | e3a002c53a544de02e5119c5b0a2fd4f972156a8 (patch) | |
tree | d6bd55210bb93fdc2aae2e398b63c3dddeb38326 | |
parent | e994b3fc3b2c9b7d39a715fc4d9453e06434d457 (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>
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: */ |