[Libreoffice-commits] core.git: include/vcl sfx2/uiconfig vcl/inc vcl/source vcl/unx

Caolán McNamara caolanm at redhat.com
Mon Feb 19 15:54:55 UTC 2018


 include/vcl/builder.hxx        |    9 ++-
 include/vcl/weld.hxx           |    6 +-
 include/vcl/window.hxx         |    2 
 sfx2/uiconfig/ui/helpmanual.ui |    2 
 vcl/inc/window.h               |    1 
 vcl/source/app/salvtables.cxx  |  116 +++++++++++++++++++++++++++++++++--------
 vcl/source/window/builder.cxx  |   62 ++++++++++++++++-----
 vcl/source/window/layout.cxx   |    3 -
 vcl/source/window/window.cxx   |    7 ++
 vcl/unx/gtk3/gtk3gtkinst.cxx   |   13 ----
 10 files changed, 165 insertions(+), 56 deletions(-)

New commits:
commit 837ba68ac04ed52716eef531f034b6a49f576178
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Sat Feb 17 21:21:32 2018 +0000

    weld: hook up help response
    
    and keep the current legacy ownership behaviour when welding the
    legacy backend
    
    Change-Id: I7e1f90f2d235abf0e10062b4be11ba5150bbdbfb
    Reviewed-on: https://gerrit.libreoffice.org/49918
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/include/vcl/builder.hxx b/include/vcl/builder.hxx
index 68d29903b8c0..d9d500051116 100644
--- a/include/vcl/builder.hxx
+++ b/include/vcl/builder.hxx
@@ -34,9 +34,11 @@
 #include <com/sun/star/frame/XFrame.hpp>
 #include <com/sun/star/uno/XComponentContext.hpp>
 
+class Button;
 class ListBox;
 class NumericFormatter;
 class PopupMenu;
+class SalInstanceBuilder;
 class ScrollBar;
 class Slider;
 class DateField;
@@ -59,7 +61,8 @@ public:
             const OUString& sUIRootDir,
             const OUString& sUIFile,
             const OString& sID = OString(),
-            const css::uno::Reference<css::frame::XFrame> &rFrame = css::uno::Reference<css::frame::XFrame>());
+            const css::uno::Reference<css::frame::XFrame> &rFrame = css::uno::Reference<css::frame::XFrame>(),
+            bool bLegacy = true);
     ~VclBuilder();
 
     ///releases references and disposes all children.
@@ -289,6 +292,7 @@ private:
     bool        m_bToplevelHasDeferredInit;
     bool        m_bToplevelHasDeferredProperties;
     bool        m_bToplevelParentFound;
+    bool        m_bLegacy;
     std::unique_ptr<ParserState> m_pParserState;
 
     vcl::Window *get_by_name(const OString& sID);
@@ -309,6 +313,7 @@ private:
     /// XFrame to be able to extract labels and other properties of the UNO commands (like of .uno:Bold).
     css::uno::Reference<css::frame::XFrame> m_xFrame;
 
+    DECL_LINK(ResponseHdl, ::Button*, void);
 private:
     VclPtr<vcl::Window> insertObject(vcl::Window *pParent,
                     const OString &rClass, const OString &rID,
@@ -478,6 +483,8 @@ public:
 
 protected:
     std::unique_ptr<VclBuilder> m_pUIBuilder;
+
+    friend class ::SalInstanceBuilder;
 };
 
 /*
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 6d438633277c..e7cd5e7a4c79 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -461,9 +461,9 @@ public:
             m_sHelpRoot = m_sHelpRoot.copy(0, nIdx);
         m_sHelpRoot = m_sHelpRoot + OString('/');
     }
-    virtual MessageDialog* weld_message_dialog(const OString& id, bool bTakeOwnership = false) = 0;
-    virtual Dialog* weld_dialog(const OString& id, bool bTakeOwnership = false) = 0;
-    virtual Window* weld_window(const OString& id, bool bTakeOwnership = false) = 0;
+    virtual MessageDialog* weld_message_dialog(const OString& id, bool bTakeOwnership = true) = 0;
+    virtual Dialog* weld_dialog(const OString& id, bool bTakeOwnership = true) = 0;
+    virtual Window* weld_window(const OString& id, bool bTakeOwnership = true) = 0;
     virtual Widget* weld_widget(const OString& id, bool bTakeOwnership = false) = 0;
     virtual Container* weld_container(const OString& id, bool bTakeOwnership = false) = 0;
     virtual Button* weld_button(const OString& id, bool bTakeOwnership = false) = 0;
diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx
index 4c286ba861c7..9acf3450a391 100644
--- a/include/vcl/window.hxx
+++ b/include/vcl/window.hxx
@@ -1581,6 +1581,8 @@ public:
     virtual FactoryFunction GetUITestFactory() const;
 
     virtual bool IsChart() const { return false; }
+
+    void SetHelpHdl(const Link<vcl::Window&, bool>& rLink);
 };
 
 }
diff --git a/sfx2/uiconfig/ui/helpmanual.ui b/sfx2/uiconfig/ui/helpmanual.ui
index 08bfd238bd23..4104d13ce9bb 100644
--- a/sfx2/uiconfig/ui/helpmanual.ui
+++ b/sfx2/uiconfig/ui/helpmanual.ui
@@ -58,7 +58,7 @@
       </object>
     </child>
     <action-widgets>
-      <action-widget response="1">website</action-widget>
+      <action-widget response="-5">website</action-widget>
       <action-widget response="-6">cancel</action-widget>
     </action-widgets>
   </object>
diff --git a/vcl/inc/window.h b/vcl/inc/window.h
index 5c942db6c1e0..a0f158f8d559 100644
--- a/vcl/inc/window.h
+++ b/vcl/inc/window.h
@@ -237,6 +237,7 @@ public:
     std::vector<Link<VclWindowEvent&,void>> maChildEventListeners;
     int mnChildEventListenersIteratingCount;
     std::set<Link<VclWindowEvent&,void>> maChildEventListenersDeleted;
+    Link<vcl::Window&, bool> maHelpRequestHdl;
 
     // The canvas interface for this VCL window. Is persistent after the first GetCanvas() call
     css::uno::WeakReference< css::rendering::XCanvas >    mxCanvas;
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 12ce25351a46..d2bef1fe030a 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -27,6 +27,7 @@
 #include <salbmp.hxx>
 #include <salobj.hxx>
 #include <salmenu.hxx>
+#include <svdata.hxx>
 #include <vcl/builder.hxx>
 #include <vcl/combobox.hxx>
 #include <vcl/lstbox.hxx>
@@ -296,11 +297,28 @@ class SalInstanceWindow : public SalInstanceContainer, public virtual weld::Wind
 private:
     VclPtr<SystemWindow> m_xWindow;
 
+    DECL_LINK(HelpHdl, vcl::Window&, bool);
+
+    void override_child_help(vcl::Window* pParent)
+    {
+        for (vcl::Window *pChild = pParent->GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
+            override_child_help(pChild);
+        pParent->SetHelpHdl(LINK(this, SalInstanceWindow, HelpHdl));
+    }
+
+    void clear_child_help(vcl::Window* pParent)
+    {
+        for (vcl::Window *pChild = pParent->GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
+            clear_child_help(pChild);
+        pParent->SetHelpHdl(Link<vcl::Window&,bool>());
+    }
+
 public:
     SalInstanceWindow(SystemWindow* pWindow, bool bTakeOwnership)
         : SalInstanceContainer(pWindow, bTakeOwnership)
         , m_xWindow(pWindow)
     {
+        override_child_help(m_xWindow);
     }
 
     virtual void set_title(const OUString& rTitle) override
@@ -312,8 +330,41 @@ public:
     {
         return m_xWindow->GetText();
     }
+
+    bool help()
+    {
+        //show help for widget with keyboard focus
+        vcl::Window* pWidget = ImplGetSVData()->maWinData.mpFocusWin;
+        if (!pWidget)
+            pWidget = m_xWindow;
+        OString sHelpId = pWidget->GetHelpId();
+        while (sHelpId.isEmpty())
+        {
+            pWidget = pWidget->GetParent();
+            if (!pWidget)
+                break;
+            sHelpId = pWidget->GetHelpId();
+        }
+        std::unique_ptr<weld::Widget> xTemp(pWidget != m_xWindow ? new SalInstanceWidget(pWidget, false) : nullptr);
+        weld::Widget* pSource = xTemp ? xTemp.get() : this;
+        bool bRunNormalHelpRequest = !m_aHelpRequestHdl.IsSet() || m_aHelpRequestHdl.Call(*pSource);
+        Help* pHelp = bRunNormalHelpRequest ? Application::GetHelp() : nullptr;
+        if (pHelp)
+            pHelp->Start(OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), pSource);
+        return false;
+    }
+
+    virtual ~SalInstanceWindow() override
+    {
+        clear_child_help(m_xWindow);
+    }
 };
 
+IMPL_LINK_NOARG(SalInstanceWindow, HelpHdl, vcl::Window&, bool)
+{
+    return help();
+}
+
 class SalInstanceDialog : public SalInstanceWindow, public virtual weld::Dialog
 {
 private:
@@ -328,7 +379,6 @@ public:
 
     virtual int run() override
     {
-        m_xDialog->Show();
         return m_xDialog->Execute();
     }
 
@@ -1104,89 +1154,104 @@ public:
 class SalInstanceBuilder : public weld::Builder
 {
 private:
-    VclBuilder m_aBuilder;
+    std::unique_ptr<VclBuilder> m_xBuilder;
+    VclPtr<vcl::Window> m_aOwnedToplevel;
 public:
     SalInstanceBuilder(vcl::Window* pParent, const OUString& rUIRoot, const OUString& rUIFile)
         : weld::Builder(rUIFile)
-        , m_aBuilder(pParent, rUIRoot, rUIFile)
+        , m_xBuilder(new VclBuilder(pParent, rUIRoot, rUIFile, OString(), css::uno::Reference<css::frame::XFrame>(), false))
     {
     }
 
     virtual weld::MessageDialog* weld_message_dialog(const OString &id, bool bTakeOwnership) override
     {
-        MessageDialog* pMessageDialog = m_aBuilder.get<MessageDialog>(id);
-        return pMessageDialog ? new SalInstanceMessageDialog(pMessageDialog, bTakeOwnership) : nullptr;
+        MessageDialog* pMessageDialog = m_xBuilder->get<MessageDialog>(id);
+        weld::MessageDialog* pRet = pMessageDialog ? new SalInstanceMessageDialog(pMessageDialog, false) : nullptr;
+        if (bTakeOwnership && pMessageDialog)
+        {
+            assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
+            m_aOwnedToplevel.set(pMessageDialog);
+            m_xBuilder->drop_ownership(pMessageDialog);
+        }
+        return pRet;
     }
 
     virtual weld::Dialog* weld_dialog(const OString &id, bool bTakeOwnership) override
     {
-        Dialog* pDialog = m_aBuilder.get<Dialog>(id);
-        return pDialog ? new SalInstanceDialog(pDialog, bTakeOwnership) : nullptr;
+        Dialog* pDialog = m_xBuilder->get<Dialog>(id);
+        weld::Dialog* pRet = pDialog ? new SalInstanceDialog(pDialog, false) : nullptr;
+        if (bTakeOwnership && pDialog)
+        {
+            assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
+            m_aOwnedToplevel.set(pDialog);
+            m_xBuilder->drop_ownership(pDialog);
+        }
+        return pRet;
     }
 
     virtual weld::Window* weld_window(const OString &id, bool bTakeOwnership) override
     {
-        SystemWindow* pWindow = m_aBuilder.get<SystemWindow>(id);
+        SystemWindow* pWindow = m_xBuilder->get<SystemWindow>(id);
         return pWindow ? new SalInstanceWindow(pWindow, bTakeOwnership) : nullptr;
     }
 
     virtual weld::Widget* weld_widget(const OString &id, bool bTakeOwnership) override
     {
-        vcl::Window* pWidget = m_aBuilder.get<vcl::Window>(id);
+        vcl::Window* pWidget = m_xBuilder->get<vcl::Window>(id);
         return pWidget ? new SalInstanceWidget(pWidget, bTakeOwnership) : nullptr;
     }
 
     virtual weld::Container* weld_container(const OString &id, bool bTakeOwnership) override
     {
-        vcl::Window* pContainer = m_aBuilder.get<vcl::Window>(id);
+        vcl::Window* pContainer = m_xBuilder->get<vcl::Window>(id);
         return pContainer ? new SalInstanceContainer(pContainer, bTakeOwnership) : nullptr;
     }
 
     virtual weld::Frame* weld_frame(const OString &id, bool bTakeOwnership) override
     {
-        VclFrame* pFrame = m_aBuilder.get<VclFrame>(id);
+        VclFrame* pFrame = m_xBuilder->get<VclFrame>(id);
         return pFrame ? new SalInstanceFrame(pFrame, bTakeOwnership) : nullptr;
     }
 
     virtual weld::Notebook* weld_notebook(const OString &id, bool bTakeOwnership) override
     {
-        TabControl* pNotebook = m_aBuilder.get<TabControl>(id);
+        TabControl* pNotebook = m_xBuilder->get<TabControl>(id);
         return pNotebook ? new SalInstanceNotebook(pNotebook, bTakeOwnership) : nullptr;
     }
 
     virtual weld::Button* weld_button(const OString &id, bool bTakeOwnership) override
     {
-        Button* pButton = m_aBuilder.get<Button>(id);
+        Button* pButton = m_xBuilder->get<Button>(id);
         return pButton ? new SalInstanceButton(pButton, bTakeOwnership) : nullptr;
     }
 
     virtual weld::RadioButton* weld_radio_button(const OString &id, bool bTakeOwnership) override
     {
-        RadioButton* pRadioButton = m_aBuilder.get<RadioButton>(id);
+        RadioButton* pRadioButton = m_xBuilder->get<RadioButton>(id);
         return pRadioButton ? new SalInstanceRadioButton(pRadioButton, bTakeOwnership) : nullptr;
     }
 
     virtual weld::CheckButton* weld_check_button(const OString &id, bool bTakeOwnership) override
     {
-        CheckBox* pCheckButton = m_aBuilder.get<CheckBox>(id);
+        CheckBox* pCheckButton = m_xBuilder->get<CheckBox>(id);
         return pCheckButton ? new SalInstanceCheckButton(pCheckButton, bTakeOwnership) : nullptr;
     }
 
     virtual weld::Entry* weld_entry(const OString &id, bool bTakeOwnership) override
     {
-        Edit* pEntry = m_aBuilder.get<Edit>(id);
+        Edit* pEntry = m_xBuilder->get<Edit>(id);
         return pEntry ? new SalInstanceEntry(pEntry, bTakeOwnership) : nullptr;
     }
 
     virtual weld::SpinButton* weld_spin_button(const OString &id, bool bTakeOwnership) override
     {
-        NumericField* pSpinButton = m_aBuilder.get<NumericField>(id);
+        NumericField* pSpinButton = m_xBuilder->get<NumericField>(id);
         return pSpinButton ? new SalInstanceSpinButton(pSpinButton, bTakeOwnership) : nullptr;
     }
 
     virtual weld::ComboBoxText* weld_combo_box_text(const OString &id, bool bTakeOwnership) override
     {
-        vcl::Window* pComboBoxText = m_aBuilder.get<vcl::Window>(id);
+        vcl::Window* pComboBoxText = m_xBuilder->get<vcl::Window>(id);
         ComboBox* pComboBox = dynamic_cast<ComboBox*>(pComboBoxText);
         if (pComboBox)
             return new SalInstanceComboBoxText<ComboBox>(pComboBox, bTakeOwnership);
@@ -1196,27 +1261,34 @@ public:
 
     virtual weld::TreeView* weld_tree_view(const OString &id, bool bTakeOwnership) override
     {
-        ListBox* pTreeView = m_aBuilder.get<ListBox>(id);
+        ListBox* pTreeView = m_xBuilder->get<ListBox>(id);
         return pTreeView ? new SalInstanceTreeView(pTreeView, bTakeOwnership) : nullptr;
     }
 
     virtual weld::Label* weld_label(const OString &id, bool bTakeOwnership) override
     {
-        FixedText* pLabel = m_aBuilder.get<FixedText>(id);
+        FixedText* pLabel = m_xBuilder->get<FixedText>(id);
         return pLabel ? new SalInstanceLabel(pLabel, bTakeOwnership) : nullptr;
     }
 
     virtual weld::TextView* weld_text_view(const OString &id, bool bTakeOwnership) override
     {
-        VclMultiLineEdit* pTextView = m_aBuilder.get<VclMultiLineEdit>(id);
+        VclMultiLineEdit* pTextView = m_xBuilder->get<VclMultiLineEdit>(id);
         return pTextView ? new SalInstanceTextView(pTextView, bTakeOwnership) : nullptr;
     }
 
     virtual weld::DrawingArea* weld_drawing_area(const OString &id, bool bTakeOwnership) override
     {
-        VclDrawingArea* pDrawingArea = m_aBuilder.get<VclDrawingArea>(id);
+        VclDrawingArea* pDrawingArea = m_xBuilder->get<VclDrawingArea>(id);
         return pDrawingArea ? new SalInstanceDrawingArea(pDrawingArea, bTakeOwnership) : nullptr;
     }
+
+    virtual ~SalInstanceBuilder() override
+    {
+        if (VclBuilderContainer* pOwnedToplevel = dynamic_cast<VclBuilderContainer*>(m_aOwnedToplevel.get()))
+            pOwnedToplevel->m_pUIBuilder = std::move(m_xBuilder);
+        m_aOwnedToplevel.disposeAndClear();
+    }
 };
 
 weld::Builder* SalInstance::CreateBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile)
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index cd7ffe99d051..c6d345434bc6 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -232,12 +232,14 @@ namespace weld
     }
 }
 
-VclBuilder::VclBuilder(vcl::Window *pParent, const OUString& sUIDir, const OUString& sUIFile, const OString& sID, const css::uno::Reference<css::frame::XFrame>& rFrame)
+VclBuilder::VclBuilder(vcl::Window *pParent, const OUString& sUIDir, const OUString& sUIFile, const OString& sID,
+                       const css::uno::Reference<css::frame::XFrame>& rFrame, bool bLegacy)
     : m_sID(sID)
     , m_sHelpRoot(OUStringToOString(sUIFile, RTL_TEXTENCODING_UTF8))
     , m_pStringReplace(Translate::GetReadStringHook())
     , m_pParent(pParent)
     , m_bToplevelParentFound(false)
+    , m_bLegacy(bLegacy)
     , m_pParserState(new ParserState)
     , m_xFrame(rFrame)
 {
@@ -869,7 +871,7 @@ namespace
         pButton->SetCommandHandler(aCommand);
     }
 
-    VclPtr<Button> extractStockAndBuildPushButton(vcl::Window *pParent, VclBuilder::stringmap &rMap)
+    VclPtr<Button> extractStockAndBuildPushButton(vcl::Window *pParent, VclBuilder::stringmap &rMap, bool bLegacy)
     {
         WinBits nBits = WB_CLIPCHILDREN|WB_CENTER|WB_VCENTER;
 
@@ -880,15 +882,18 @@ namespace
         if (extractStock(rMap))
         {
             OUString sType = extractLabel(rMap);
-            if (sType == "gtk-ok")
-                xWindow = VclPtr<OKButton>::Create(pParent, nBits);
-            else if (sType == "gtk-cancel")
-                xWindow = VclPtr<CancelButton>::Create(pParent, nBits);
-            else if (sType == "gtk-close")
-                xWindow = VclPtr<CloseButton>::Create(pParent, nBits);
-            else if (sType == "gtk-help")
-                xWindow = VclPtr<HelpButton>::Create(pParent, nBits);
-            else
+            if (bLegacy)
+            {
+                if (sType == "gtk-ok")
+                    xWindow = VclPtr<OKButton>::Create(pParent, nBits);
+                else if (sType == "gtk-cancel")
+                    xWindow = VclPtr<CancelButton>::Create(pParent, nBits);
+                else if (sType == "gtk-close")
+                    xWindow = VclPtr<CloseButton>::Create(pParent, nBits);
+                else if (sType == "gtk-help")
+                    xWindow = VclPtr<HelpButton>::Create(pParent, nBits);
+            }
+            if (!xWindow)
             {
                 xWindow = VclPtr<PushButton>::Create(pParent, nBits);
                 xWindow->SetText(getStockText(sType));
@@ -1305,7 +1310,7 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OString &
     }
     else if (name == "GtkMessageDialog")
     {
-        WinBits nBits = WB_CLIPCHILDREN|WB_MOVEABLE|WB_3DLOOK|WB_CLOSEABLE;
+        WinBits nBits = WB_MOVEABLE|WB_3DLOOK|WB_CLOSEABLE;
         if (extractResizable(rMap))
             nBits |= WB_SIZEABLE;
         xWindow = VclPtr<MessageDialog>::Create(pParent, nBits);
@@ -1357,7 +1362,7 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OString &
         VclPtr<Button> xButton;
         OUString sMenu = BuilderUtils::extractCustomProperty(rMap);
         if (sMenu.isEmpty())
-            xButton = extractStockAndBuildPushButton(pParent, rMap);
+            xButton = extractStockAndBuildPushButton(pParent, rMap, m_bLegacy);
         else
         {
             xButton = extractStockAndBuildMenuButton(pParent, rMap);
@@ -3386,6 +3391,23 @@ short VclBuilder::get_response(const vcl::Window *pWindow) const
     return RET_CANCEL;
 }
 
+IMPL_LINK(VclBuilder, ResponseHdl, ::Button*, pButton, void)
+{
+    short nResponse = get_response(pButton);
+    Dialog* pDialog = pButton->GetParentDialog();
+    assert(pDialog && "who puts a response without a dialog");
+    if (nResponse == RET_HELP)
+    {
+        vcl::Window* pFocusWin = Application::GetFocusWindow();
+        if (!pFocusWin)
+            pFocusWin = pButton;
+        HelpEvent aEvt(pFocusWin->GetPointerPosPixel(), HelpEventMode::CONTEXT);
+        pFocusWin->RequestHelp(aEvt);
+    }
+    else
+        pDialog->EndDialog(nResponse);
+}
+
 void VclBuilder::set_response(const OString& sID, short nResponse)
 {
     switch (nResponse)
@@ -3412,17 +3434,27 @@ void VclBuilder::set_response(const OString& sID, short nResponse)
 
     assert(nResponse >= 0);
 
+    bool bFound = false;
+
     for (auto & child : m_aChildren)
     {
         if (child.m_sID == sID)
         {
             child.m_nResponseId = nResponse;
-            return;
+            bFound = true;
+            break;
         }
     }
 
+    if (!m_bLegacy)
+    {
+        PushButton* pPushButton = get<PushButton>(sID);
+        assert(pPushButton);
+        pPushButton->SetClickHdl(LINK(this, VclBuilder, ResponseHdl));
+    }
+
     //how did we not find sID ?
-    assert(false);
+    assert(bFound); (void)bFound;
 }
 
 void VclBuilder::delete_by_name(const OString& sID)
diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx
index 83f9616f5933..b36923871d10 100644
--- a/vcl/source/window/layout.cxx
+++ b/vcl/source/window/layout.cxx
@@ -2252,7 +2252,8 @@ void MessageDialog::setButtonHandlers(VclButtonBox const *pButtonBox)
             case WindowType::PUSHBUTTON:
             {
                 PushButton* pButton = static_cast<PushButton*>(pChild);
-                pButton->SetClickHdl(LINK(this, MessageDialog, ButtonHdl));
+                if (!pButton->GetClickHdl().IsSet())
+                    pButton->SetClickHdl(LINK(this, MessageDialog, ButtonHdl));
                 break;
             }
             //insist that the response ids match the default actions for those
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 111194255057..0945f881e7e9 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -1851,6 +1851,11 @@ void Window::LoseFocus()
     CompatNotify( aNEvt );
 }
 
+void Window::SetHelpHdl(const Link<vcl::Window&, bool>& rLink)
+{
+    mpWindowImpl->maHelpRequestHdl = rLink;
+}
+
 void Window::RequestHelp( const HelpEvent& rHEvt )
 {
     // if Balloon-Help is requested, show the balloon
@@ -1889,7 +1894,7 @@ void Window::RequestHelp( const HelpEvent& rHEvt )
             Help::ShowQuickHelp( this, aRect, rStr, aHelpText, QuickHelpFlags::CtrlText );
         }
     }
-    else
+    else if (!mpWindowImpl->maHelpRequestHdl.IsSet() || mpWindowImpl->maHelpRequestHdl.Call(*this))
     {
         OUString aStrHelpId( OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8 ) );
         if ( aStrHelpId.isEmpty() && ImplGetParent() )
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 0acaed180b20..5777a4d4d838 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -2416,14 +2416,6 @@ namespace
             }
         }
     }
-
-    void destroy_toplevels(gpointer data, gpointer /*user_data*/)
-    {
-        GObject* pObject = static_cast<GObject*>(data);
-        if (!GTK_IS_WINDOW(pObject))
-            return;
-        gtk_widget_destroy(GTK_WIDGET(pObject));
-    }
 }
 
 class GtkInstanceBuilder : public weld::Builder
@@ -2456,7 +2448,6 @@ public:
 
     virtual ~GtkInstanceBuilder() override
     {
-        g_slist_foreach(m_pObjectList, destroy_toplevels, nullptr);
         g_slist_free(m_pObjectList);
         g_object_unref(m_pBuilder);
     }
@@ -2638,9 +2629,7 @@ void GtkInstanceWindow::help()
     }
     std::unique_ptr<weld::Widget> xTemp(pWidget != m_pWidget ? new GtkInstanceWidget(pWidget, false) : nullptr);
     weld::Widget* pSource = xTemp ? xTemp.get() : this;
-    bool bRunNormalHelpRequest = true;
-    if (m_aHelpRequestHdl.IsSet())
-        bRunNormalHelpRequest = m_aHelpRequestHdl.Call(*pSource);
+    bool bRunNormalHelpRequest = !m_aHelpRequestHdl.IsSet() || m_aHelpRequestHdl.Call(*pSource);
     Help* pHelp = bRunNormalHelpRequest ? Application::GetHelp() : nullptr;
     if (pHelp)
         pHelp->Start(OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), pSource);


More information about the Libreoffice-commits mailing list