tdf#141708 wait until float is activated to grab focus

otherwise the grab occurs in the navigator ctor which happens during
impress startup and will generate focus events which leads to impress
getting activated during its startup triggering the creation of the
navigator which is already being created resulting in multiple
navigators created during startup

Change-Id: Ic0a868437845fda9edf9eb0d761227d4c27992d5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114235
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/sd/source/ui/dlg/NavigatorChildWindow.cxx b/sd/source/ui/dlg/NavigatorChildWindow.cxx
index ba5d6a6..a6eee97 100644
--- a/sd/source/ui/dlg/NavigatorChildWindow.cxx
+++ b/sd/source/ui/dlg/NavigatorChildWindow.cxx
@@ -43,6 +43,7 @@ static void RequestNavigatorUpdate (SfxBindings const * pBindings)
SdNavigatorFloat::SdNavigatorFloat(SfxBindings* _pBindings, SfxChildWindow* _pMgr, vcl::Window* _pParent)
    : SfxNavigator(_pBindings, _pMgr, _pParent)
    , m_xNavWin(std::make_unique<SdNavigatorWin>(m_xContainer.get(), _pBindings, this))
    , m_bSetInitialFocusOnActivate(true)
{
    m_xNavWin->SetUpdateRequestFunctor(
        [_pBindings] () { return RequestNavigatorUpdate(_pBindings); });
@@ -50,6 +51,18 @@ SdNavigatorFloat::SdNavigatorFloat(SfxBindings* _pBindings, SfxChildWindow* _pMg
    SetMinOutputSizePixel(GetOptimalSize());
}

void SdNavigatorFloat::Activate()
{
    SfxNavigator::Activate();
    // tdf#141708 defer grabbing focus to preferred widget until the float is
    // first activated
    if (m_bSetInitialFocusOnActivate)
    {
        m_xNavWin->FirstFocus();
        m_bSetInitialFocusOnActivate = false;
    }
}

void SdNavigatorFloat::InitTreeLB(const SdDrawDocument* pDoc)
{
    m_xNavWin->InitTreeLB(pDoc);
diff --git a/sd/source/ui/dlg/navigatr.cxx b/sd/source/ui/dlg/navigatr.cxx
index c8d23c0..d9f7c50 100644
--- a/sd/source/ui/dlg/navigatr.cxx
+++ b/sd/source/ui/dlg/navigatr.cxx
@@ -77,9 +77,6 @@ SdNavigatorWin::SdNavigatorWin(weld::Widget* pParent, SfxBindings* pInBindings, 
    mxToolbox->set_item_menu("shapes", mxShapeMenu.get());
    mxShapeMenu->connect_activate(LINK(this, SdNavigatorWin, ShapeFilterCallback));

    // set focus to listbox, otherwise it is in the toolbox which is only useful
    // for keyboard navigation
    mxTlbObjects->grab_focus();
    mxTlbObjects->SetSdNavigator(this);

    // DragTypeListBox
@@ -93,6 +90,13 @@ SdNavigatorWin::SdNavigatorWin(weld::Widget* pParent, SfxBindings* pInBindings, 
    mxLbDocs->connect_key_press(LINK(this, SdNavigatorWin, KeyInputHdl));
}

void SdNavigatorWin::FirstFocus()
{
    // set focus to listbox, otherwise it is in the toolbox which is only useful
    // for keyboard navigation
    mxTlbObjects->grab_focus();
}

weld::Window* SdNavigatorWin::GetFrameWeld() const
{
    if (mxNavigatorDlg)
diff --git a/sd/source/ui/inc/navigatr.hxx b/sd/source/ui/inc/navigatr.hxx
index 4c85228..218b594 100644
--- a/sd/source/ui/inc/navigatr.hxx
+++ b/sd/source/ui/inc/navigatr.hxx
@@ -83,10 +83,13 @@ class SdNavigatorFloat : public SfxNavigator
{
private:
    std::unique_ptr<SdNavigatorWin> m_xNavWin;
    bool m_bSetInitialFocusOnActivate;

public:
    SdNavigatorFloat(SfxBindings* _pBindings, SfxChildWindow* pMgr, vcl::Window* pParent);
    void InitTreeLB(const SdDrawDocument* pDoc);
    void FreshTree(const SdDrawDocument* pDoc);
    virtual void Activate() override;
    virtual void dispose() override;
    virtual ~SdNavigatorFloat() override;
};
@@ -111,6 +114,7 @@ public:

    void                        InitTreeLB( const SdDrawDocument* pDoc );
    void                        RefreshDocumentLB( const OUString* pDocName = nullptr );
    void                        FirstFocus();

    bool                        InsertFile(const OUString& rFileName);