reweld SwWordCountFloatDlg

fixing up the bit that failed the last time

Change-Id: I235f8f92cbc0c3e31837e01a9b094580c6f5aecf
Reviewed-on: https://gerrit.libreoffice.org/62786
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/include/sfx2/basedlgs.hxx b/include/sfx2/basedlgs.hxx
index 79092bb..703998b3 100644
--- a/include/sfx2/basedlgs.hxx
+++ b/include/sfx2/basedlgs.hxx
@@ -107,6 +107,41 @@ public:
    DECL_LINK(TimerHdl, Timer *, void);
};

class SFX2_DLLPUBLIC SfxDialogController : public weld::GenericDialogController
{
private:
    DECL_DLLPRIVATE_LINK(InstallLOKNotifierHdl, void*, vcl::ILibreOfficeKitNotifier*);
public:
    SfxDialogController(weld::Widget* pParent, const OUString& rUIFile, const OString& rDialogId);
};

class SfxModelessDialog_Impl;
class SFX2_DLLPUBLIC SfxModelessDialogController : public SfxDialogController
{
    SfxBindings* m_pBindings;
    std::unique_ptr<SfxModelessDialog_Impl> m_xImpl;

    SfxModelessDialogController(SfxModelessDialogController&) = delete;
    void operator =(SfxModelessDialogController&) = delete;

    void Init(SfxBindings *pBindinx, SfxChildWindow *pCW);

    DECL_DLLPRIVATE_LINK(FocusInHdl, weld::Widget&, void);
    DECL_DLLPRIVATE_LINK(FocusOutHdl, weld::Widget&, void);
protected:
    SfxModelessDialogController(SfxBindings*, SfxChildWindow* pChildWin,
        weld::Window* pParent, const OUString& rUIXMLDescription, const OString& rID);
    virtual ~SfxModelessDialogController() override;

public:
    virtual void            FillInfo(SfxChildWinInfo&) const;
    void                    Initialize (SfxChildWinInfo const * pInfo);
    void                    Close();
    void                    DeInit();
    void                    EndDialog();
    SfxBindings&            GetBindings() { return *m_pBindings; }
};

// class SfxFloatingWindow --------------------------------------------------
class SfxFloatingWindow_Impl;
class SFX2_DLLPUBLIC SfxFloatingWindow: public FloatingWindow
@@ -188,14 +223,6 @@ private:
    std::unique_ptr<SingleTabDlgImpl>   pImpl;
};

class SFX2_DLLPUBLIC SfxDialogController : public weld::GenericDialogController
{
private:
    DECL_DLLPRIVATE_LINK(InstallLOKNotifierHdl, void*, vcl::ILibreOfficeKitNotifier*);
public:
    SfxDialogController(weld::Widget* pParent, const OUString& rUIFile, const OString& rDialogId);
};

class SFX2_DLLPUBLIC SfxSingleTabDialogController : public SfxDialogController
{
private:
diff --git a/include/sfx2/childwin.hxx b/include/sfx2/childwin.hxx
index 8c46889..9a12bf8 100644
--- a/include/sfx2/childwin.hxx
+++ b/include/sfx2/childwin.hxx
@@ -143,9 +143,10 @@ public:

class SFX2_DLLPUBLIC SfxChildWindow
{
    VclPtr<vcl::Window>        pParent;        // parent window ( Topwindow )
    sal_uInt16 const           nType;          // ChildWindow-Id
    VclPtr<vcl::Window>        pParent;         // parent window ( Topwindow )
    sal_uInt16 const           nType;           // ChildWindow-Id
    VclPtr<vcl::Window>        pWindow;         // actual contents
    std::shared_ptr<SfxModelessDialogController> xController;     // actual contents
    SfxChildAlignment          eChildAlignment; // Current css::drawing::Alignment
    std::unique_ptr< SfxChildWindow_Impl>       pImpl;            // Implementation data
    std::unique_ptr<SfxChildWindowContext>      pContext;        // With context-sensitive ChildWindows:
@@ -161,6 +162,9 @@ public:
    void                Destroy();
    vcl::Window*        GetWindow() const
                        { return pWindow; }
    void                SetController(std::shared_ptr<SfxModelessDialogController> controller) { xController = controller; }
    void                ClearController() { xController.reset(); }
    std::shared_ptr<SfxModelessDialogController>& GetController() { return xController; }
    vcl::Window*        GetParent() const
                        { return pParent; }
    SfxChildAlignment   GetAlignment() const
diff --git a/include/vcl/dialog.hxx b/include/vcl/dialog.hxx
index c5a3997..b6d7bbd 100644
--- a/include/vcl/dialog.hxx
+++ b/include/vcl/dialog.hxx
@@ -139,7 +139,7 @@ public:
    virtual FactoryFunction GetUITestFactory() const override;

private:
    bool            ImplStartExecuteModal();
    bool            ImplStartExecute();
    static void     ImplEndExecuteModal();
    void            ImplSetModalInputMode(bool bModal);
public:
@@ -174,6 +174,9 @@ public:
    void            GrabFocusToFirstControl();
    virtual void    Resize() override;

    void            Activate() override;


    void            SetInstallLOKNotifierHdl(const Link<void*, vcl::ILibreOfficeKitNotifier*>& rLink);

    void            add_button(PushButton* pButton, int nResponse, bool bTransferOwnership);
@@ -188,8 +191,6 @@ class VCL_DLLPUBLIC ModelessDialog : public Dialog

public:
    explicit        ModelessDialog( vcl::Window* pParent, const OUString& rID, const OUString& rUIXMLDescription, Dialog::InitFlag eFlag = Dialog::InitFlag::Default );

    void            Activate() override;
};

class VCL_DLLPUBLIC ModalDialog : public Dialog
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 7fcd7b8..7ec022e 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -196,8 +196,15 @@ public:
    virtual void set_busy_cursor(bool bBusy) = 0;
    virtual void window_move(int x, int y) = 0;
    virtual void set_modal(bool bModal) = 0;
    virtual bool get_modal() const = 0;
    virtual bool get_extents_relative_to(Window& rRelative, int& x, int& y, int& width, int& height)
        = 0;
    virtual bool get_resizable() const = 0;
    virtual Size get_size() const = 0;
    virtual Point get_position() const = 0;
    virtual bool has_toplevel_focus() const = 0;
    virtual void set_window_state(const OString& rStr) = 0;
    virtual OString get_window_state(WindowStateMask nMask) const = 0;

    virtual css::uno::Reference<css::awt::XWindow> GetXWindow() = 0;

diff --git a/sfx2/source/appl/childwin.cxx b/sfx2/source/appl/childwin.cxx
index aa8018e..65f0634 100644
--- a/sfx2/source/appl/childwin.cxx
+++ b/sfx2/source/appl/childwin.cxx
@@ -194,7 +194,10 @@ SfxChildWindow::~SfxChildWindow()
{
    pContext.reset();
    ClearWorkwin();
    pWindow.disposeAndClear();
    if (xController)
        xController->DeInit();
    else
        pWindow.disposeAndClear();
}


@@ -270,7 +273,7 @@ SfxChildWindow* SfxChildWindow::CreateChildWindow( sal_uInt16 nId,

    DBG_ASSERT(pFact && (pChild || !rInfo.bVisible), "ChildWindow-Typ not registered!");

    if ( pChild && !pChild->pWindow )
    if (pChild && (!pChild->pWindow && !pChild->xController))
    {
        DELETEZ(pChild);
        SAL_INFO("sfx.appl", "ChildWindow has no Window!");
@@ -319,26 +322,38 @@ void SfxChildWindow::SetAlignment(SfxChildAlignment eAlign)

SfxChildWinInfo SfxChildWindow::GetInfo() const
{

    SfxChildWinInfo aInfo(pImpl->pFact->aInfo);
    aInfo.aPos  = pWindow->GetPosPixel();
    aInfo.aSize = pWindow->GetSizePixel();
    if ( pWindow->IsSystemWindow() )
    if (xController)
    {
        weld::Dialog* pDialog = xController->getDialog();
        aInfo.aPos  = pDialog->get_position();
        aInfo.aSize = pDialog->get_size();
        WindowStateMask nMask = WindowStateMask::Pos | WindowStateMask::State;
        if ( pWindow->GetStyle() & WB_SIZEABLE )
            nMask |= ( WindowStateMask::Width | WindowStateMask::Height );
        aInfo.aWinState = static_cast<SystemWindow*>(pWindow.get())->GetWindowState( nMask );
        if (pDialog->get_resizable())
            nMask |= (WindowStateMask::Width | WindowStateMask::Height);
        aInfo.aWinState = pDialog->get_window_state(nMask);
    }
    else if (DockingWindow* pDockingWindow = dynamic_cast<DockingWindow*>(pWindow.get()))
    else if (pWindow)
    {
        if (pDockingWindow->GetFloatingWindow())
            aInfo.aWinState = pDockingWindow->GetFloatingWindow()->GetWindowState();
        else if (SfxDockingWindow* pSfxDockingWindow = dynamic_cast<SfxDockingWindow*>(pDockingWindow))
        aInfo.aPos  = pWindow->GetPosPixel();
        aInfo.aSize = pWindow->GetSizePixel();
        if ( pWindow->IsSystemWindow() )
        {
            SfxChildWinInfo aTmpInfo;
            pSfxDockingWindow->FillInfo( aTmpInfo );
            aInfo.aExtraString = aTmpInfo.aExtraString;
            WindowStateMask nMask = WindowStateMask::Pos | WindowStateMask::State;
            if ( pWindow->GetStyle() & WB_SIZEABLE )
                nMask |= ( WindowStateMask::Width | WindowStateMask::Height );
            aInfo.aWinState = static_cast<SystemWindow*>(pWindow.get())->GetWindowState( nMask );
        }
        else if (DockingWindow* pDockingWindow = dynamic_cast<DockingWindow*>(pWindow.get()))
        {
            if (pDockingWindow->GetFloatingWindow())
                aInfo.aWinState = pDockingWindow->GetFloatingWindow()->GetWindowState();
            else if (SfxDockingWindow* pSfxDockingWindow = dynamic_cast<SfxDockingWindow*>(pDockingWindow))
            {
                SfxChildWinInfo aTmpInfo;
                pSfxDockingWindow->FillInfo( aTmpInfo );
                aInfo.aExtraString = aTmpInfo.aExtraString;
            }
        }
    }

@@ -608,12 +623,24 @@ void SfxChildWindow::SetVisible_Impl( bool bVis )

void SfxChildWindow::Hide()
{
    pWindow->Hide();
    if (xController)
        xController->EndDialog();
    else
        pWindow->Hide();
}

void SfxChildWindow::Show( ShowFlags nFlags )
{
    pWindow->Show(true, nFlags);
    if (xController)
    {
        if (!xController->getDialog()->get_visible())
        {
            weld::DialogController::runAsync(xController,
                [=](sal_Int32 /*nResult*/){ xController->Close(); });
        }
    }
    else
        pWindow->Show(true, nFlags);
}

vcl::Window* SfxChildWindow::GetContextWindow( SfxModule const *pModule ) const
@@ -624,8 +651,14 @@ vcl::Window* SfxChildWindow::GetContextWindow( SfxModule const *pModule ) const
void SfxChildWindow::SetWorkWindow_Impl( SfxWorkWindow* pWin )
{
    pImpl->pWorkWin = pWin;
    if ( pWin && pWindow->HasChildPathFocus() )
        pImpl->pWorkWin->SetActiveChild_Impl( pWindow );
    if (pWin)
    {
        if ( (xController && xController->getDialog()->has_toplevel_focus()) ||
             (pWindow && pWindow->HasChildPathFocus()) )
        {
            pImpl->pWorkWin->SetActiveChild_Impl( pWindow );
        }
    }
}

void SfxChildWindow::Activate_Impl()
@@ -646,7 +679,15 @@ bool SfxChildWindow::QueryClose()
    }

    if ( bAllow )
        bAllow = !GetWindow()->IsInModalMode();
    {
        if (GetController())
        {
            weld::Dialog* pDialog = GetController()->getDialog();
            bAllow = !pDialog->get_visible() || !pDialog->get_modal();
        }
        else if (GetWindow())
            bAllow = !GetWindow()->IsInModalMode();
    }

    return bAllow;
}
diff --git a/sfx2/source/appl/workwin.cxx b/sfx2/source/appl/workwin.cxx
index 363b300..69e29d2 100644
--- a/sfx2/source/appl/workwin.cxx
+++ b/sfx2/source/appl/workwin.cxx
@@ -864,7 +864,6 @@ bool SfxWorkWindow::PrepareClose_Impl()
    return true;
}


SfxChild_Impl* SfxWorkWindow::RegisterChild_Impl( vcl::Window& rWindow,
                    SfxChildAlignment eAlign )
{
@@ -885,6 +884,19 @@ SfxChild_Impl* SfxWorkWindow::RegisterChild_Impl( vcl::Window& rWindow,
    return aChildren.back();
}

SfxChild_Impl* SfxWorkWindow::RegisterChild_Impl(std::shared_ptr<SfxModelessDialogController>& rController,
                    SfxChildAlignment eAlign )
{
    DBG_ASSERT( aChildren.size() < 255, "too many children" );
    DBG_ASSERT( SfxChildAlignValid(eAlign), "invalid align" );

    SfxChild_Impl *pChild = new SfxChild_Impl(rController, eAlign);

    aChildren.push_back(pChild);
    bSorted = false;
    nChildren++;
    return aChildren.back();
}

void SfxWorkWindow::ReleaseChild_Impl( vcl::Window& rWindow )
{
@@ -910,6 +922,29 @@ void SfxWorkWindow::ReleaseChild_Impl( vcl::Window& rWindow )
    }
}

void SfxWorkWindow::ReleaseChild_Impl(SfxModelessDialogController& rController)
{

    SfxChild_Impl *pChild = nullptr;
    decltype(aChildren)::size_type nPos;
    for ( nPos = 0; nPos < aChildren.size(); ++nPos )
    {
        pChild = aChildren[nPos];
        if (pChild && pChild->xController.get() == &rController)
            break;
    }

    if ( nPos < aChildren.size() )
    {
        bSorted = false;
        nChildren--;
        aChildren.erase(aChildren.begin() + nPos);
        delete pChild;
    }
    else {
        OSL_FAIL( "releasing unregistered child" );
    }
}

SfxChild_Impl* SfxWorkWindow::FindChild_Impl( const vcl::Window& rWindow ) const
{
@@ -933,8 +968,10 @@ void SfxWorkWindow::ShowChildren_Impl()

    for (SfxChild_Impl* pCli : aChildren)
    {
        if (!pCli)
            continue;
        SfxChildWin_Impl* pCW = nullptr;
        if ( pCli && pCli->pWin )
        if (pCli->pWin || pCli->xController)
        {
            // We have to find the SfxChildWin_Impl to retrieve the
            // SFX_CHILDWIN flags that can influence visibility.
@@ -961,12 +998,27 @@ void SfxWorkWindow::ShowChildren_Impl()
            if ( SfxChildVisibility::VISIBLE == (pCli->nVisible & SfxChildVisibility::VISIBLE) && bVisible )
            {
                ShowFlags nFlags = pCli->bSetFocus ? ShowFlags::NONE : ShowFlags::NoFocusChange | ShowFlags::NoActivate;
                pCli->pWin->Show(true, nFlags);
                if (pCli->xController)
                {
                    if (!pCli->xController->getDialog()->get_visible())
                    {
                        weld::DialogController::runAsync(pCli->xController,
                            [=](sal_Int32 /*nResult*/){ pCli->xController->Close(); });
                    }
                }
                else
                    pCli->pWin->Show(true, nFlags);
                pCli->bSetFocus = false;
            }
            else
            {
                pCli->pWin->Hide();
                if (pCli->xController)
                {
                    if (pCli->xController->getDialog()->get_visible())
                        pCli->xController->response(RET_CLOSE);
                }
                else
                    pCli->pWin->Hide();
            }
        }
    }
@@ -978,12 +1030,15 @@ void SfxWorkWindow::HideChildren_Impl()
    for ( sal_uInt16 nPos = aChildren.size(); nPos > 0; --nPos )
    {
        SfxChild_Impl *pChild = aChildren[nPos-1];
        if (pChild && pChild->pWin)
        if (!pChild)
            continue;
        if (pChild->xController)
            pChild->xController->response(RET_CLOSE);
        else if (pChild->pWin)
            pChild->pWin->Hide();
    }
}


void SfxWorkWindow::ResetObjectBars_Impl()
{
    for ( auto & n: aObjBarList )
@@ -1324,7 +1379,10 @@ void SfxWorkWindow::CreateChildWin_Impl( SfxChildWin_Impl *pCW, bool bSetFocus )
        {
            // The window is not docked or docked outside of one split windows
            // and must therefore be registered explicitly as a Child
            pCW->pCli = RegisterChild_Impl(*(pChildWin->GetWindow()), pChildWin->GetAlignment());
            if (pChildWin->GetController())
                pCW->pCli = RegisterChild_Impl(pChildWin->GetController(), pChildWin->GetAlignment());
            else
                pCW->pCli = RegisterChild_Impl(*(pChildWin->GetWindow()), pChildWin->GetAlignment());
            pCW->pCli->nVisible = SfxChildVisibility::VISIBLE;
            if ( pChildWin->GetAlignment() != SfxChildAlignment::NOALIGNMENT && bIsFullScreen )
                pCW->pCli->nVisible ^= SfxChildVisibility::ACTIVE;
@@ -1363,7 +1421,10 @@ void SfxWorkWindow::RemoveChildWin_Impl( SfxChildWin_Impl *pCW )
        // Child window is a direct child window and must therefore unregister
        // itself from the  WorkWindow
        pCW->pCli = nullptr;
        ReleaseChild_Impl(*pChildWin->GetWindow());
        if (pChildWin->GetController())
            ReleaseChild_Impl(*pChildWin->GetController());
        else
            ReleaseChild_Impl(*pChildWin->GetWindow());
    }
    else
    {
@@ -2382,8 +2443,12 @@ void SfxWorkWindow::DataChanged_Impl()
    for (n=0; n<nCount; n++)
    {
        SfxChildWin_Impl*pCW = aChildWins[n].get();
        if ( pCW && pCW->pWin )
            pCW->pWin->GetWindow()->UpdateSettings( Application::GetSettings() );
        if (pCW && pCW->pWin)
        {
            // TODO does this really have any meaning ?
            if (pCW->pWin->GetWindow())
                pCW->pWin->GetWindow()->UpdateSettings(Application::GetSettings());
        }
    }

    ArrangeChildren_Impl();
diff --git a/sfx2/source/dialog/basedlgs.cxx b/sfx2/source/dialog/basedlgs.cxx
index f4a0769..8fcb0cb 100644
--- a/sfx2/source/dialog/basedlgs.cxx
+++ b/sfx2/source/dialog/basedlgs.cxx
@@ -56,6 +56,7 @@ public:
    OString aWinState;
    SfxChildWindow* pMgr;
    bool            bConstructed;
    bool            bClosing;
    void            Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;

    Idle            aMoveIdle;
@@ -284,6 +285,7 @@ void SfxModelessDialog::Init(SfxBindings *pBindinx, SfxChildWindow *pCW)
    pImpl.reset(new SfxModelessDialog_Impl);
    pImpl->pMgr = pCW;
    pImpl->bConstructed = false;
    pImpl->bClosing = false;
    if ( pBindinx )
        pImpl->StartListening( *pBindinx );
    pImpl->aMoveIdle.SetPriority(TaskPriority::RESIZE);
@@ -382,6 +384,129 @@ void SfxModelessDialog::FillInfo(SfxChildWinInfo& rInfo) const
        rInfo.nFlags |= SfxChildWindowFlags::ZOOMIN;
}

void SfxModelessDialogController::Initialize(SfxChildWinInfo const *pInfo)

/*  [Description]

    Initialization of the class SfxModelessDialog via a SfxChildWinInfo.
    The initialization is done only in a 2nd step after the constructor, this
    constructor should be called from the derived class or from the
    SfxChildWindows.
*/

{
    if (!pInfo)
        return;
    m_xImpl->aWinState = pInfo->aWinState;
    if (m_xImpl->aWinState.isEmpty())
        return;
    m_xDialog->set_window_state(m_xImpl->aWinState);
}

SfxModelessDialogController::SfxModelessDialogController(SfxBindings* pBindinx,
    SfxChildWindow *pCW, weld::Window *pParent, const OUString& rUIXMLDescription,
    const OString& rID)
    : SfxDialogController(pParent, rUIXMLDescription, rID)
{
    Init(pBindinx, pCW);
    m_xDialog->connect_focus_in(LINK(this, SfxModelessDialogController, FocusInHdl));
    m_xDialog->connect_focus_out(LINK(this, SfxModelessDialogController, FocusOutHdl));
}

void SfxModelessDialogController::Init(SfxBindings *pBindinx, SfxChildWindow *pCW)
{
    m_pBindings = pBindinx;
    m_xImpl.reset(new SfxModelessDialog_Impl);
    m_xImpl->pMgr = pCW;
    m_xImpl->bConstructed = true;
    m_xImpl->bClosing = false;
    if (pBindinx)
        m_xImpl->StartListening( *pBindinx );
}

void SfxModelessDialogController::DeInit()
{
    if (m_xImpl->pMgr)
    {
        WindowStateMask nMask = WindowStateMask::Pos | WindowStateMask::State;
        if (m_xDialog->get_resizable())
            nMask |= ( WindowStateMask::Width | WindowStateMask::Height );
        m_xImpl->aWinState = m_xDialog->get_window_state(nMask);
        GetBindings().GetWorkWindow_Impl()->ConfigChild_Impl( SfxChildIdentifier::DOCKINGWINDOW, SfxDockingConfig::ALIGNDOCKINGWINDOW, m_xImpl->pMgr->GetType() );
    }

    m_xImpl->pMgr = nullptr;
}

/*  [Description]

    If a ModelessDialog is enabled its ViewFrame will be activated.
    This is necessary by PluginInFrames.
*/
IMPL_LINK_NOARG(SfxModelessDialogController, FocusInHdl, weld::Widget&, void)
{
    if (!m_xImpl)
        return;
    m_pBindings->SetActiveFrame(m_xImpl->pMgr->GetFrame());
    m_xImpl->pMgr->Activate_Impl();
}

IMPL_LINK_NOARG(SfxModelessDialogController, FocusOutHdl, weld::Widget&, void)
{
    if (!m_xImpl)
        return;
    m_pBindings->SetActiveFrame(css::uno::Reference< css::frame::XFrame>());
}

SfxModelessDialogController::~SfxModelessDialogController()
{
    if (!m_xImpl->pMgr)
        return;
    auto xFrame = m_xImpl->pMgr->GetFrame();
    if (!xFrame)
        return;
    if (xFrame == m_pBindings->GetActiveFrame())
        m_pBindings->SetActiveFrame(nullptr);
}

void SfxModelessDialogController::EndDialog()
{
    if (!m_xDialog->get_visible())
        return;
    m_xImpl->bClosing = true;
    response(RET_CLOSE);
    m_xImpl->bClosing = false;
}

/*  [Description]

    The window is closed when the ChildWindow is destroyed by running the
    ChildWindow-slots.
*/
void SfxModelessDialogController::Close()
{
    if (m_xImpl->bClosing)
        return;
    // Execute with Parameters, since Toggle is ignored by some ChildWindows.
    SfxBoolItem aValue(m_xImpl->pMgr->GetType(), false);
    m_pBindings->GetDispatcher_Impl()->ExecuteList(
        m_xImpl->pMgr->GetType(),
        SfxCallMode::RECORD|SfxCallMode::SYNCHRON, { &aValue } );
}

/*  [Description]

    Fills a SfxChildWinInfo with specific data from SfxModelessDialog,
    so that it can be written in the INI file. It is assumed that rinfo
    receives all other possible relevant data in the ChildWindow class.
    ModelessDialogs have no specific information, so that the base
    implementation does nothing and therefore must not be called.
*/
void SfxModelessDialogController::FillInfo(SfxChildWinInfo& rInfo) const
{
    rInfo.aSize = m_xDialog->get_size();
}

bool SfxFloatingWindow::EventNotify( NotifyEvent& rEvt )

/*  [Description]
@@ -756,7 +881,6 @@ void SfxSingleTabDialogController::SetTabPage(SfxTabPage* pTabPage)
        aUserItem >>= sUserData;
        m_xSfxPage->SetUserData(sUserData);
        m_xSfxPage->Reset(GetInputItemSet());
//TODO        m_xSfxPage->Show();

        m_xHelpBtn->show(Help::IsContextHelpEnabled());

diff --git a/sfx2/source/inc/workwin.hxx b/sfx2/source/inc/workwin.hxx
index 7b37d06..38c4165 100644
--- a/sfx2/source/inc/workwin.hxx
+++ b/sfx2/source/inc/workwin.hxx
@@ -84,6 +84,7 @@ namespace o3tl
struct SfxChild_Impl
{
    VclPtr<vcl::Window>             pWin;
    std::shared_ptr<SfxModelessDialogController> xController;
    Size                            aSize;
    SfxChildAlignment               eAlign;
    SfxChildVisibility              nVisible;
@@ -97,6 +98,14 @@ struct SfxChild_Impl
    {
        nVisible = bIsVisible ? SfxChildVisibility::VISIBLE : SfxChildVisibility::NOT_VISIBLE;
    }

    SfxChild_Impl(std::shared_ptr<SfxModelessDialogController>& rChild,
                  SfxChildAlignment eAlignment):
        pWin(nullptr), xController(rChild), eAlign(eAlignment), bResize(false),
        bSetFocus( false )
    {
        nVisible = xController->getDialog()->get_visible() ? SfxChildVisibility::VISIBLE : SfxChildVisibility::NOT_VISIBLE;
    }
};

struct SfxChildWin_Impl
@@ -239,7 +248,9 @@ public:
    // Methods for all Child windows
    void                    DataChanged_Impl();
    void                    ReleaseChild_Impl( vcl::Window& rWindow );
    void                    ReleaseChild_Impl(SfxModelessDialogController&);
    SfxChild_Impl*          RegisterChild_Impl( vcl::Window& rWindow, SfxChildAlignment eAlign );
    SfxChild_Impl*          RegisterChild_Impl(std::shared_ptr<SfxModelessDialogController>& rController, SfxChildAlignment eAlign);
    void                    ShowChildren_Impl();
    void                    HideChildren_Impl();
    bool                    PrepareClose_Impl();
diff --git a/sw/inc/swabstdlg.hxx b/sw/inc/swabstdlg.hxx
index 642218f..99d55a8 100644
--- a/sw/inc/swabstdlg.hxx
+++ b/sw/inc/swabstdlg.hxx
@@ -200,7 +200,7 @@ protected:
public:
    virtual void        UpdateCounts() = 0;
    virtual void        SetCounts(const SwDocStat &rCurrCnt, const SwDocStat &rDocStat) = 0;
    virtual vcl::Window *    GetWindow() = 0; //this method is added for return a Window type pointer
    virtual std::shared_ptr<SfxModelessDialogController> GetController() = 0;
};

class AbstractSwInsertAbstractDlg : public VclAbstractDialog
@@ -364,7 +364,7 @@ public:
    virtual VclPtr<SfxAbstractDialog> CreateSwBackgroundDialog(weld::Window* pParent, const SfxItemSet& rSet) = 0;

    virtual VclPtr<AbstractSwWordCountFloatDlg> CreateSwWordCountDialog(SfxBindings* pBindings,
        SfxChildWindow* pChild, vcl::Window *pParent, SfxChildWinInfo* pInfo) = 0;
        SfxChildWindow* pChild, weld::Window *pParent, SfxChildWinInfo* pInfo) = 0;

    virtual VclPtr<AbstractSwInsertAbstractDlg> CreateSwInsertAbstractDlg() = 0;
    virtual VclPtr<SfxAbstractDialog> CreateSwAddressAbstractDlg(vcl::Window* pParent, const SfxItemSet& rSet) = 0;
diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx
index db92346..fe904ff 100644
--- a/sw/inc/viewsh.hxx
+++ b/sw/inc/viewsh.hxx
@@ -170,7 +170,7 @@ class SW_DLLPUBLIC SwViewShell : public sw::Ring<SwViewShell>
protected:
    static ShellResource*      mpShellRes;      ///< Resources for the Shell.
    static vcl::DeleteOnDeinit< VclPtr<vcl::Window> > mpCareWindow;    ///< Avoid this window.
    static vcl::DeleteOnDeinit< std::shared_ptr<weld::Dialog> > mpCareDialog;    ///< Avoid this window.
    static vcl::DeleteOnDeinit< std::shared_ptr<weld::Window> > mpCareDialog;    ///< Avoid this window.

    SwRect                  maVisArea;       ///< The modern version of VisArea.
    rtl::Reference<SwDoc>   mxDoc;          ///< The document; never 0.
@@ -432,12 +432,12 @@ public:
    static ShellResource* GetShellRes();

    static void           SetCareWin( vcl::Window* pNew );
    static vcl::Window*   GetCareWin(SwViewShell const & rVSh)
                          { return (*mpCareWindow.get()) ? mpCareWindow.get()->get() : CareChildWin(rVSh); }
    static vcl::Window*   CareChildWin(SwViewShell const & rVSh);
    static void           SetCareDialog(const std::shared_ptr<weld::Dialog>& rNew);
    static weld::Dialog*  GetCareDialog()
                          { return (*mpCareDialog.get()) ? mpCareDialog.get()->get() : nullptr; }
    static vcl::Window*   GetCareWin()
                          { return (*mpCareWindow.get()) ? mpCareWindow.get()->get() : nullptr; }
    static weld::Window*   CareChildWin(SwViewShell const & rVSh);
    static void           SetCareDialog(const std::shared_ptr<weld::Window>& rNew);
    static weld::Window*  GetCareDialog(SwViewShell const & rVSh)
                          { return (*mpCareDialog.get()) ? mpCareDialog.get()->get() : CareChildWin(rVSh); }

    SfxViewShell   *GetSfxViewShell() const { return mpSfxViewShell; }
    void           SetSfxViewShell(SfxViewShell *pNew) { mpSfxViewShell = pNew; }
diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index 23ef8f43..4f38a4d 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -93,7 +93,7 @@
bool SwViewShell::mbLstAct = false;
ShellResource *SwViewShell::mpShellRes = nullptr;
vcl::DeleteOnDeinit< VclPtr<vcl::Window> > SwViewShell::mpCareWindow(new VclPtr<vcl::Window>);
vcl::DeleteOnDeinit<std::shared_ptr<weld::Dialog>> SwViewShell::mpCareDialog(new std::shared_ptr<weld::Dialog>);
vcl::DeleteOnDeinit<std::shared_ptr<weld::Window>> SwViewShell::mpCareDialog(new std::shared_ptr<weld::Window>);

static bool bInSizeNotify = false;

@@ -581,7 +581,7 @@ const SwRect& SwViewShell::VisArea() const

void SwViewShell::MakeVisible( const SwRect &rRect )
{
    if ( !VisArea().IsInside( rRect ) || IsScrollMDI( this, rRect ) || GetCareWin(*this) || GetCareDialog() )
    if ( !VisArea().IsInside( rRect ) || IsScrollMDI( this, rRect ) || GetCareWin() || GetCareDialog(*this) )
    {
        if ( !IsViewLocked() )
        {
@@ -609,19 +609,23 @@ void SwViewShell::MakeVisible( const SwRect &rRect )
    }
}

vcl::Window* SwViewShell::CareChildWin(SwViewShell const & rVSh)
weld::Window* SwViewShell::CareChildWin(SwViewShell const & rVSh)
{
    if(rVSh.mpSfxViewShell)
    {
    if (!rVSh.mpSfxViewShell)
        return nullptr;
#if HAVE_FEATURE_DESKTOP
        const sal_uInt16 nId = SvxSearchDialogWrapper::GetChildWindowId();
        SfxViewFrame* pVFrame = rVSh.mpSfxViewShell->GetViewFrame();
        const SfxChildWindow* pChWin = pVFrame->GetChildWindow( nId );
        vcl::Window *pWin = pChWin ? pChWin->GetWindow() : nullptr;
        if ( pWin && pWin->IsVisible() )
            return pWin;
    const sal_uInt16 nId = SvxSearchDialogWrapper::GetChildWindowId();
    SfxViewFrame* pVFrame = rVSh.mpSfxViewShell->GetViewFrame();
    SfxChildWindow* pChWin = pVFrame->GetChildWindow( nId );
    if (!pChWin)
        return nullptr;
    weld::DialogController* pController = pChWin->GetController().get();
    if (!pController)
        return nullptr;
    weld::Window* pWin = pController->getDialog();
    if (pWin && pWin->get_visible())
        return pWin;
#endif
    }
    return nullptr;
}

@@ -2503,7 +2507,7 @@ void SwViewShell::SetCareWin( vcl::Window* pNew )
    (*mpCareWindow.get()) = pNew;
}

void SwViewShell::SetCareDialog(const std::shared_ptr<weld::Dialog>& rNew)
void SwViewShell::SetCareDialog(const std::shared_ptr<weld::Window>& rNew)
{
    (*mpCareDialog.get()) = rNew;
}
diff --git a/sw/source/ui/dialog/swdlgfact.cxx b/sw/source/ui/dialog/swdlgfact.cxx
index 6badd01..84a3b54 100644
--- a/sw/source/ui/dialog/swdlgfact.cxx
+++ b/sw/source/ui/dialog/swdlgfact.cxx
@@ -89,7 +89,11 @@ using namespace ::com::sun::star;
using namespace css::frame;
using namespace css::uno;

IMPL_ABSTDLG_BASE(AbstractSwWordCountFloatDlg_Impl);
short AbstractSwWordCountFloatDlg_Impl::Execute()
{
    return m_xDlg->run();
}

IMPL_ABSTDLG_BASE(AbstractSwInsertAbstractDlg_Impl);
IMPL_ABSTDLG_BASE(SwAbstractSfxDialog_Impl);

@@ -704,19 +708,19 @@ vcl::Window* AbstractAuthMarkFloatDlg_Impl::GetWindow()
    return static_cast<vcl::Window*>(pDlg);
}

vcl::Window* AbstractSwWordCountFloatDlg_Impl::GetWindow()
std::shared_ptr<SfxModelessDialogController> AbstractSwWordCountFloatDlg_Impl::GetController()
{
    return static_cast<vcl::Window*>(pDlg);
    return m_xDlg;
}

void AbstractSwWordCountFloatDlg_Impl::UpdateCounts()
{
    pDlg->UpdateCounts();
    m_xDlg->UpdateCounts();
}

void AbstractSwWordCountFloatDlg_Impl::SetCounts(const SwDocStat &rCurrCnt, const SwDocStat &rDocStat)
{
    pDlg->SetCounts(rCurrCnt, rDocStat);
    m_xDlg->SetCounts(rCurrCnt, rDocStat);
}

AbstractMailMergeWizard_Impl::~AbstractMailMergeWizard_Impl()
@@ -1131,11 +1135,10 @@ VclPtr<AbstractMarkFloatDlg> SwAbstractDialogFactory_Impl::CreateAuthMarkFloatDl
VclPtr<AbstractSwWordCountFloatDlg> SwAbstractDialogFactory_Impl::CreateSwWordCountDialog(
                                                                              SfxBindings* pBindings,
                                                                              SfxChildWindow* pChild,
                                                                              vcl::Window *pParent,
                                                                              weld::Window *pParent,
                                                                              SfxChildWinInfo* pInfo)
{
    VclPtr<SwWordCountFloatDlg> pDlg = VclPtr<SwWordCountFloatDlg>::Create( pBindings, pChild, pParent, pInfo );
    return VclPtr<AbstractSwWordCountFloatDlg_Impl>::Create( pDlg );
    return VclPtr<AbstractSwWordCountFloatDlg_Impl>::Create(o3tl::make_unique<SwWordCountFloatDlg>(pBindings, pChild, pParent, pInfo));
}

VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateIndexMarkModalDlg(
diff --git a/sw/source/ui/dialog/swdlgfact.hxx b/sw/source/ui/dialog/swdlgfact.hxx
index 103b04b..14b802e 100644
--- a/sw/source/ui/dialog/swdlgfact.hxx
+++ b/sw/source/ui/dialog/swdlgfact.hxx
@@ -74,10 +74,17 @@ bool Class::StartExecuteAsync(VclAbstractDialog::AsyncContext &rCtx) \
class SwWordCountFloatDlg;
class AbstractSwWordCountFloatDlg_Impl : public AbstractSwWordCountFloatDlg
{
    DECL_ABSTDLG_BASE(AbstractSwWordCountFloatDlg_Impl,SwWordCountFloatDlg)
    virtual void                UpdateCounts() override;
    virtual void                SetCounts(const SwDocStat &rCurrCnt, const SwDocStat &rDocStat) override;
    virtual vcl::Window *            GetWindow() override; //this method is added for return a Window type pointer
protected:
    std::shared_ptr<SwWordCountFloatDlg> m_xDlg;
public:
    explicit AbstractSwWordCountFloatDlg_Impl(std::unique_ptr<SwWordCountFloatDlg> p)
        : m_xDlg(std::move(p))
    {
    }
    virtual short Execute() override;
    virtual void  UpdateCounts() override;
    virtual void  SetCounts(const SwDocStat &rCurrCnt, const SwDocStat &rDocStat) override;
    virtual std::shared_ptr<SfxModelessDialogController> GetController() override;
};

class AbstractSwInsertAbstractDlg_Impl : public AbstractSwInsertAbstractDlg
@@ -596,7 +603,7 @@ public:
    virtual VclPtr<SfxAbstractDialog> CreateSwDropCapsDialog(weld::Window* pParent, const SfxItemSet& rSet) override;
    virtual VclPtr<SfxAbstractDialog> CreateSwBackgroundDialog(weld::Window* pParent, const SfxItemSet& rSet) override;
    virtual VclPtr<AbstractSwWordCountFloatDlg> CreateSwWordCountDialog(SfxBindings* pBindings,
        SfxChildWindow* pChild, vcl::Window *pParent, SfxChildWinInfo* pInfo) override;
        SfxChildWindow* pChild, weld::Window *pParent, SfxChildWinInfo* pInfo) override;
    virtual VclPtr<AbstractSwInsertAbstractDlg> CreateSwInsertAbstractDlg() override;
    virtual VclPtr<SfxAbstractDialog> CreateSwAddressAbstractDlg(vcl::Window* pParent, const SfxItemSet& rSet) override;
    virtual VclPtr<AbstractSwAsciiFilterDlg>  CreateSwAsciiFilterDlg(weld::Window* pParent, SwDocShell& rDocSh,
diff --git a/sw/source/ui/dialog/wordcountdialog.cxx b/sw/source/ui/dialog/wordcountdialog.cxx
index cc350e6..b247678 100644
--- a/sw/source/ui/dialog/wordcountdialog.cxx
+++ b/sw/source/ui/dialog/wordcountdialog.cxx
@@ -31,126 +31,92 @@
#include <unotools/localedatawrapper.hxx>
#include <vcl/settings.hxx>

IMPL_STATIC_LINK_NOARG(SwWordCountFloatDlg, CloseHdl, Button*, void)
{
    SfxViewFrame* pVFrame = ::GetActiveView()->GetViewFrame();
    if (pVFrame != nullptr)
    {
        pVFrame->ToggleChildWindow(FN_WORDCOUNT_DIALOG);
    }
}

SwWordCountFloatDlg::~SwWordCountFloatDlg()
{
    disposeOnce();
}

void SwWordCountFloatDlg::dispose()
{
    SwViewShell::SetCareWin( nullptr );
    m_pCurrentWordFT.clear();
    m_pCurrentCharacterFT.clear();
    m_pCurrentCharacterExcludingSpacesFT.clear();
    m_pCurrentCjkcharsFT.clear();
    m_pCurrentStandardizedPagesFT.clear();
    m_pDocWordFT.clear();
    m_pDocCharacterFT.clear();
    m_pDocCharacterExcludingSpacesFT.clear();
    m_pDocCjkcharsFT.clear();
    m_pDocStandardizedPagesFT.clear();
    m_pCjkcharsLabelFT.clear();
    m_pStandardizedPagesLabelFT.clear();
    m_pClosePB.clear();
    SfxModelessDialog::dispose();
}

namespace
{
    void setValue(FixedText *pWidget, sal_uLong nValue, const LocaleDataWrapper& rLocaleData)
    void setValue(weld::Label& rWidget, sal_uLong nValue, const LocaleDataWrapper& rLocaleData)
    {
        pWidget->SetText(rLocaleData.getNum(nValue, 0));
        rWidget.set_label(rLocaleData.getNum(nValue, 0));
    }

    void setDoubleValue(FixedText *pWidget, double fValue)
    void setDoubleValue(weld::Label& rWidget, double fValue)
    {
        OUString sValue(OUString::number(::rtl::math::round(fValue, 1)));
        pWidget->SetText(sValue);
        rWidget.set_label(sValue);
    }
}

void SwWordCountFloatDlg::SetValues(const SwDocStat& rCurrent, const SwDocStat& rDoc)
{
    const LocaleDataWrapper& rLocaleData = GetSettings().GetUILocaleDataWrapper();
    setValue(m_pCurrentWordFT, rCurrent.nWord, rLocaleData);
    setValue(m_pCurrentCharacterFT, rCurrent.nChar, rLocaleData);
    setValue(m_pCurrentCharacterExcludingSpacesFT, rCurrent.nCharExcludingSpaces, rLocaleData);
    setValue(m_pCurrentCjkcharsFT, rCurrent.nAsianWord, rLocaleData);
    setValue(m_pDocWordFT, rDoc.nWord, rLocaleData);
    setValue(m_pDocCharacterFT, rDoc.nChar, rLocaleData);
    setValue(m_pDocCharacterExcludingSpacesFT, rDoc.nCharExcludingSpaces, rLocaleData);
    setValue(m_pDocCjkcharsFT, rDoc.nAsianWord, rLocaleData);
    const LocaleDataWrapper& rLocaleData = Application::GetSettings().GetUILocaleDataWrapper();
    setValue(*m_xCurrentWordFT, rCurrent.nWord, rLocaleData);
    setValue(*m_xCurrentCharacterFT, rCurrent.nChar, rLocaleData);
    setValue(*m_xCurrentCharacterExcludingSpacesFT, rCurrent.nCharExcludingSpaces, rLocaleData);
    setValue(*m_xCurrentCjkcharsFT, rCurrent.nAsianWord, rLocaleData);
    setValue(*m_xDocWordFT, rDoc.nWord, rLocaleData);
    setValue(*m_xDocCharacterFT, rDoc.nChar, rLocaleData);
    setValue(*m_xDocCharacterExcludingSpacesFT, rDoc.nCharExcludingSpaces, rLocaleData);
    setValue(*m_xDocCjkcharsFT, rDoc.nAsianWord, rLocaleData);

    if (m_pStandardizedPagesLabelFT->IsVisible())
    if (m_xStandardizedPagesLabelFT->get_visible())
    {
        sal_Int64 nCharsPerStandardizedPage = officecfg::Office::Writer::WordCount::StandardizedPageSize::get();
        setDoubleValue(m_pCurrentStandardizedPagesFT,
        setDoubleValue(*m_xCurrentStandardizedPagesFT,
            static_cast<double>(rCurrent.nChar) / nCharsPerStandardizedPage);
        setDoubleValue(m_pDocStandardizedPagesFT,
        setDoubleValue(*m_xDocStandardizedPagesFT,
            static_cast<double>(rDoc.nChar) / nCharsPerStandardizedPage);
    }

    bool bShowCJK = (SvtCJKOptions().IsAnyEnabled() || rDoc.nAsianWord);
    bool bToggleCJK = m_pCurrentCjkcharsFT->IsVisible() != bShowCJK;
    bool bToggleCJK = m_xCurrentCjkcharsFT->get_visible() != bShowCJK;
    if (bToggleCJK)
    {
        showCJK(bShowCJK);
        setOptimalLayoutSize(); //force resize of dialog
        m_xDialog->resize_to_request(); //force resize of dialog
    }
}

void SwWordCountFloatDlg::showCJK(bool bShowCJK)
{
    m_pCurrentCjkcharsFT->Show(bShowCJK);
    m_pDocCjkcharsFT->Show(bShowCJK);
    m_pCjkcharsLabelFT->Show(bShowCJK);
    m_xCurrentCjkcharsFT->show(bShowCJK);
    m_xDocCjkcharsFT->show(bShowCJK);
    m_xCjkcharsLabelFT->show(bShowCJK);
}

void SwWordCountFloatDlg::showStandardizedPages(bool bShowStandardizedPages)
{
    m_pCurrentStandardizedPagesFT->Show(bShowStandardizedPages);
    m_pDocStandardizedPagesFT->Show(bShowStandardizedPages);
    m_pStandardizedPagesLabelFT->Show(bShowStandardizedPages);
    m_xCurrentStandardizedPagesFT->show(bShowStandardizedPages);
    m_xDocStandardizedPagesFT->show(bShowStandardizedPages);
    m_xStandardizedPagesLabelFT->show(bShowStandardizedPages);
}

SwWordCountFloatDlg::SwWordCountFloatDlg(SfxBindings* _pBindings,
                                         SfxChildWindow* pChild,
                                         vcl::Window *pParent,
                                         weld::Window *pParent,
                                         SfxChildWinInfo const * pInfo)
    : SfxModelessDialog(_pBindings, pChild, pParent, "WordCountDialog", "modules/swriter/ui/wordcount.ui")
    : SfxModelessDialogController(_pBindings, pChild, pParent, "modules/swriter/ui/wordcount.ui", "WordCountDialog")
    , m_xCurrentWordFT(m_xBuilder->weld_label("selectwords"))
    , m_xCurrentCharacterFT(m_xBuilder->weld_label("selectchars"))
    , m_xCurrentCharacterExcludingSpacesFT(m_xBuilder->weld_label("selectcharsnospaces"))
    , m_xCurrentCjkcharsFT(m_xBuilder->weld_label("selectcjkchars"))
    , m_xCurrentStandardizedPagesFT(m_xBuilder->weld_label("selectstandardizedpages"))
    , m_xDocWordFT(m_xBuilder->weld_label("docwords"))
    , m_xDocCharacterFT(m_xBuilder->weld_label("docchars"))
    , m_xDocCharacterExcludingSpacesFT(m_xBuilder->weld_label("doccharsnospaces"))
    , m_xDocCjkcharsFT(m_xBuilder->weld_label("doccjkchars"))
    , m_xDocStandardizedPagesFT(m_xBuilder->weld_label("docstandardizedpages"))
    , m_xCjkcharsLabelFT(m_xBuilder->weld_label("cjkcharsft"))
    , m_xStandardizedPagesLabelFT(m_xBuilder->weld_label("standardizedpages"))
    , m_xClosePB(m_xBuilder->weld_button("close"))
{
    get(m_pCurrentWordFT, "selectwords");
    get(m_pCurrentCharacterFT, "selectchars");
    get(m_pCurrentCharacterExcludingSpacesFT, "selectcharsnospaces");
    get(m_pCurrentCjkcharsFT, "selectcjkchars");
    get(m_pCurrentStandardizedPagesFT, "selectstandardizedpages");

    get(m_pDocWordFT, "docwords");
    get(m_pDocCharacterFT, "docchars");
    get(m_pDocCharacterExcludingSpacesFT, "doccharsnospaces");
    get(m_pDocCjkcharsFT, "doccjkchars");
    get(m_pDocStandardizedPagesFT, "docstandardizedpages");

    get(m_pCjkcharsLabelFT, "cjkcharsft");
    get(m_pStandardizedPagesLabelFT, "standardizedpages");

    get(m_pClosePB, "close");

    showCJK(SvtCJKOptions().IsAnyEnabled());
    showStandardizedPages(officecfg::Office::Writer::WordCount::ShowStandardizedPageCount::get());

    Initialize(pInfo);

    m_pClosePB->SetClickHdl(LINK(this, SwWordCountFloatDlg, CloseHdl));
}

void SwWordCountFloatDlg::UpdateCounts()
diff --git a/sw/source/uibase/dialog/wordcountwrapper.cxx b/sw/source/uibase/dialog/wordcountwrapper.cxx
index 0904105..2a205fb 100644
--- a/sw/source/uibase/dialog/wordcountwrapper.cxx
+++ b/sw/source/uibase/dialog/wordcountwrapper.cxx
@@ -14,15 +14,15 @@

SFX_IMPL_CHILDWINDOW_WITHID(SwWordCountWrapper, FN_WORDCOUNT_DIALOG)

SwWordCountWrapper::SwWordCountWrapper(   vcl::Window *pParentWindow,
SwWordCountWrapper::SwWordCountWrapper(vcl::Window *pParentWindow,
                            sal_uInt16 nId,
                            SfxBindings* pBindings,
                            SfxChildWinInfo* pInfo ) :
        SfxChildWindow(pParentWindow, nId)
                            SfxChildWinInfo* pInfo )
    : SfxChildWindow(pParentWindow, nId)
{
    SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
    xAbstDlg.reset(pFact->CreateSwWordCountDialog(pBindings, this, pParentWindow, pInfo));
    SetWindow(xAbstDlg->GetWindow());
    xAbstDlg.reset(pFact->CreateSwWordCountDialog(pBindings, this, pParentWindow->GetFrameWeld(), pInfo));
    SetController(xAbstDlg->GetController());
}

SwWordCountWrapper::~SwWordCountWrapper()
diff --git a/sw/source/uibase/inc/wordcountdialog.hxx b/sw/source/uibase/inc/wordcountdialog.hxx
index ea95266..e63ef3c 100644
--- a/sw/source/uibase/inc/wordcountdialog.hxx
+++ b/sw/source/uibase/inc/wordcountdialog.hxx
@@ -25,37 +25,32 @@ struct SwDocStat;
#include <sfx2/childwin.hxx>
#include <swabstdlg.hxx>

class SwWordCountFloatDlg : public SfxModelessDialog
class SwWordCountFloatDlg : public SfxModelessDialogController
{
    void SetValues(const SwDocStat& rCurrent, const SwDocStat& rDoc);
    void showCJK(bool bShowCJK);
    void showStandardizedPages(bool bShowStandardizedPages);

    VclPtr<FixedText> m_pCurrentWordFT;
    VclPtr<FixedText> m_pCurrentCharacterFT;
    VclPtr<FixedText> m_pCurrentCharacterExcludingSpacesFT;
    VclPtr<FixedText> m_pCurrentCjkcharsFT;
    VclPtr<FixedText> m_pCurrentStandardizedPagesFT;
    std::unique_ptr<weld::Label> m_xCurrentWordFT;
    std::unique_ptr<weld::Label> m_xCurrentCharacterFT;
    std::unique_ptr<weld::Label> m_xCurrentCharacterExcludingSpacesFT;
    std::unique_ptr<weld::Label> m_xCurrentCjkcharsFT;
    std::unique_ptr<weld::Label> m_xCurrentStandardizedPagesFT;
    std::unique_ptr<weld::Label> m_xDocWordFT;
    std::unique_ptr<weld::Label> m_xDocCharacterFT;
    std::unique_ptr<weld::Label> m_xDocCharacterExcludingSpacesFT;
    std::unique_ptr<weld::Label> m_xDocCjkcharsFT;
    std::unique_ptr<weld::Label> m_xDocStandardizedPagesFT;
    std::unique_ptr<weld::Label> m_xCjkcharsLabelFT;
    std::unique_ptr<weld::Label> m_xStandardizedPagesLabelFT;
    std::unique_ptr<weld::Button> m_xClosePB;

    VclPtr<FixedText> m_pDocWordFT;
    VclPtr<FixedText> m_pDocCharacterFT;
    VclPtr<FixedText> m_pDocCharacterExcludingSpacesFT;
    VclPtr<FixedText> m_pDocCjkcharsFT;
    VclPtr<FixedText> m_pDocStandardizedPagesFT;

    VclPtr<FixedText> m_pCjkcharsLabelFT;
    VclPtr<FixedText> m_pStandardizedPagesLabelFT;

    VclPtr<CloseButton> m_pClosePB;

    DECL_STATIC_LINK( SwWordCountFloatDlg, CloseHdl, Button*, void );
public:
    SwWordCountFloatDlg(     SfxBindings* pBindings,
                             SfxChildWindow* pChild,
                             vcl::Window *pParent,
                             SfxChildWinInfo const * pInfo);
    SwWordCountFloatDlg(SfxBindings* pBindings,
                        SfxChildWindow* pChild,
                        weld::Window *pParent,
                        SfxChildWinInfo const * pInfo);
    virtual ~SwWordCountFloatDlg() override;
    virtual void dispose() override;
    void    UpdateCounts();

    void    SetCounts(const SwDocStat &rCurrCnt, const SwDocStat &rDocStat);
diff --git a/sw/source/uibase/uiview/viewport.cxx b/sw/source/uibase/uiview/viewport.cxx
index e52c3c7..331309e 100644
--- a/sw/source/uibase/uiview/viewport.cxx
+++ b/sw/source/uibase/uiview/viewport.cxx
@@ -403,8 +403,8 @@ void SwView::Scroll( const tools::Rectangle &rRect, sal_uInt16 nRangeX, sal_uInt
    tools::Rectangle aOldVisArea( m_aVisArea );
    long nDiffY = 0;

    vcl::Window* pCareWn = SwViewShell::GetCareWin(GetWrtShell());
    weld::Dialog* pCareDialog = SwViewShell::GetCareDialog();
    vcl::Window* pCareWn = SwViewShell::GetCareWin();
    weld::Window* pCareDialog = SwViewShell::GetCareDialog(GetWrtShell());
    if (pCareWn || pCareDialog)
    {
        int x, y, width, height;
diff --git a/sw/uiconfig/swriter/ui/wordcount.ui b/sw/uiconfig/swriter/ui/wordcount.ui
index 86595e5..6da9a2c 100644
--- a/sw/uiconfig/swriter/ui/wordcount.ui
+++ b/sw/uiconfig/swriter/ui/wordcount.ui
@@ -1,13 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.2 -->
<!-- Generated with glade 3.22.1 -->
<interface domain="sw">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkDialog" id="WordCountDialog">
    <property name="can_focus">False</property>
    <property name="border_width">6</property>
    <property name="title" translatable="yes" context="wordcount|WordCountDialog">Word Count</property>
    <property name="default_width">0</property>
    <property name="default_height">0</property>
    <property name="destroy_with_parent">True</property>
    <property name="type_hint">dialog</property>
    <child>
      <placeholder/>
    </child>
    <child internal-child="vbox">
      <object class="GtkBox" id="dialog-vbox1">
        <property name="can_focus">False</property>
@@ -319,6 +324,7 @@
      </object>
    </child>
    <action-widgets>
      <action-widget response="-7">close</action-widget>
      <action-widget response="-11">help</action-widget>
    </action-widgets>
  </object>
diff --git a/vcl/inc/qt5/Qt5Frame.hxx b/vcl/inc/qt5/Qt5Frame.hxx
index 5b049fa..766044a 100644
--- a/vcl/inc/qt5/Qt5Frame.hxx
+++ b/vcl/inc/qt5/Qt5Frame.hxx
@@ -147,6 +147,7 @@ public:
    virtual void GetWorkArea(tools::Rectangle& rRect) override;
    virtual SalFrame* GetParent() const override;
    virtual void SetModal(bool bModal) override;
    virtual bool GetModal() const override;
    virtual void SetWindowState(const SalFrameState* pState) override;
    virtual bool GetWindowState(SalFrameState* pState) override;
    virtual void ShowFullScreen(bool bFullScreen, sal_Int32 nDisplay) override;
diff --git a/vcl/inc/salframe.hxx b/vcl/inc/salframe.hxx
index e2662d4..b27b46d 100644
--- a/vcl/inc/salframe.hxx
+++ b/vcl/inc/salframe.hxx
@@ -240,6 +240,11 @@ public:
    {
    }

    virtual bool            GetModal() const
    {
        return false;
    }

    // return true to indicate tooltips are shown natively, false otherwise
    virtual bool            ShowTooltip(const OUString& /*rHelpText*/, const tools::Rectangle& /*rHelpArea*/)
    {
diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index 7b2e78a..a77c7c6 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -537,6 +537,7 @@ public:
#if GTK_CHECK_VERSION(3,0,0)
    virtual void                PositionByToolkit(const tools::Rectangle& rRect, FloatWinPopupFlags nFlags) override;
    virtual void                SetModal(bool bModal) override;
    virtual bool                GetModal() const override;
    void                        HideTooltip();
    virtual bool                ShowTooltip(const OUString& rHelpText, const tools::Rectangle& rHelpArea) override;
    virtual void*               ShowPopover(const OUString& rHelpText, vcl::Window* pParent, const tools::Rectangle& rHelpArea, QuickHelpFlags nFlags) override;
diff --git a/vcl/inc/window.h b/vcl/inc/window.h
index 21448ef..452a88e6 100644
--- a/vcl/inc/window.h
+++ b/vcl/inc/window.h
@@ -40,6 +40,7 @@ class VirtualDevice;
class PhysicalFontCollection;
class ImplFontCache;
class VCLXWindow;
class WindowStateData;
class SalFrame;
class SalObject;
enum class MouseEventModifiers;
@@ -414,6 +415,9 @@ bool ImplHandleMouseEvent( const VclPtr<vcl::Window>& xWindow, MouseNotifyEvent 
                           sal_uInt16 nCode, MouseEventModifiers nMode );
void ImplHandleResize( vcl::Window* pWindow, long nNewWidth, long nNewHeight );

VCL_DLLPUBLIC void ImplWindowStateFromStr(WindowStateData& rData, const OString& rStr);
VCL_DLLPUBLIC OString ImplWindowStateToStr(const WindowStateData& rData);

#endif // INCLUDED_VCL_INC_WINDOW_H

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/Qt5Frame.cxx b/vcl/qt5/Qt5Frame.cxx
index 2628b05..b5680b6 100644
--- a/vcl/qt5/Qt5Frame.cxx
+++ b/vcl/qt5/Qt5Frame.cxx
@@ -474,6 +474,8 @@ void Qt5Frame::SetModal(bool bModal)
    }
}

bool Qt5Frame::GetModal() const { return isWindow() && windowHandle()->isModal(); }

void Qt5Frame::SetWindowState(const SalFrameState* pState)
{
    if (!isWindow() || !pState || isChild(true, false))
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 485b404a..a3b4be4 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -730,11 +730,15 @@ public:
    virtual void set_modal(bool bModal) override
    {
        if (::Dialog* pDialog = dynamic_cast<::Dialog*>(m_xWindow.get()))
        {
            pDialog->SetModalInputMode(bModal);
            return;
        }
        m_xWindow->ImplGetFrame()->SetModal(bModal);
            return pDialog->SetModalInputMode(bModal);
        return m_xWindow->ImplGetFrame()->SetModal(bModal);
    }

    virtual bool get_modal() const override
    {
        if (const ::Dialog* pDialog = dynamic_cast<const ::Dialog*>(m_xWindow.get()))
            return pDialog->IsModalInputMode();
        return m_xWindow->ImplGetFrame()->GetModal();
    }

    virtual void window_move(int x, int y) override
@@ -757,6 +761,40 @@ public:
        return true;
    }

    virtual Size get_size() const override
    {
        return m_xWindow->GetSizePixel();
    }

    virtual Point get_position() const override
    {
        return m_xWindow->GetPosPixel();
    }

    virtual bool get_resizable() const override
    {
        return m_xWindow->GetStyle() & WB_SIZEABLE;
    }

    virtual bool has_toplevel_focus() const override
    {
        return m_xWindow->HasChildPathFocus();
    }

    virtual void set_window_state(const OString& rStr) override
    {
        SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
        assert(pSysWin);
        pSysWin->SetWindowState(rStr);
    }

    virtual OString get_window_state(WindowStateMask nMask) const override
    {
        SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
        assert(pSysWin);
        return pSysWin->GetWindowState(nMask);
    }

    virtual SystemEnvData get_system_data() const override
    {
        return *m_xWindow->GetSystemData();
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index 85ed792..480c2f7 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -831,6 +831,18 @@ namespace
        return bResizable;
    }

    bool extractModal(VclBuilder::stringmap &rMap)
    {
        bool bModal = false;
        VclBuilder::stringmap::iterator aFind = rMap.find(OString("modal"));
        if (aFind != rMap.end())
        {
            bModal = toBool(aFind->second);
            rMap.erase(aFind);
        }
        return bModal;
    }

    bool extractDecorated(VclBuilder::stringmap &rMap)
    {
        bool bDecorated = true;
@@ -1521,6 +1533,8 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OString &
        if (extractResizable(rMap))
            nBits |= WB_SIZEABLE;
        xWindow = VclPtr<Dialog>::Create(pParent, nBits, !pParent ? Dialog::InitFlag::NoParent : Dialog::InitFlag::Default);
        if (!m_bLegacy && !extractModal(rMap))
            xWindow->SetType(WindowType::MODELESSDIALOG);
    }
    else if (name == "GtkMessageDialog")
    {
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index 53ebce9..11a92bb 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -819,7 +819,7 @@ bool Dialog::Close()
        return bRet;
    }

    if ( IsInExecute() )
    if (IsInExecute() || mpDialogImpl->maEndCtx.isSet())
    {
        EndDialog();
        mbInClose = false;
@@ -832,11 +832,11 @@ bool Dialog::Close()
    }
}

bool Dialog::ImplStartExecuteModal()
bool Dialog::ImplStartExecute()
{
    setDeferredProperties();

    if ( mbInExecute || mpDialogImpl->maEndCtx.isSet() )
    if (IsInExecute() || mpDialogImpl->maEndCtx.isSet())
    {
#ifdef DBG_UTIL
        SAL_WARN( "vcl", "Dialog::StartExecuteModal() is called in Dialog::StartExecuteModal(): "
@@ -854,68 +854,74 @@ bool Dialog::ImplStartExecuteModal()
            SetLOKNotifier(pViewShell);
    }

    switch ( Application::GetDialogCancelMode() )
    const bool bModal = GetType() != WindowType::MODELESSDIALOG;

    if (bModal)
    {
    case Application::DialogCancelMode::Off:
        break;
    case Application::DialogCancelMode::Silent:
        if (GetLOKNotifier())
        switch ( Application::GetDialogCancelMode() )
        {
            // check if there's already some dialog being ::Execute()d
            const bool bDialogExecuting = std::any_of(pSVData->maWinData.mpExecuteDialogs.begin(),
                                                      pSVData->maWinData.mpExecuteDialogs.end(),
                                                      [](const Dialog* pDialog) {
                                                          return pDialog->IsInSyncExecute();
                                                      });
            if (!(bDialogExecuting && IsInSyncExecute()))
                break;
            else
                SAL_WARN("lok.dialog", "Dialog \"" << ImplGetDialogText(this) << "\" is being synchronously executed over an existing synchronously executing dialog.");
        case Application::DialogCancelMode::Off:
            break;
        case Application::DialogCancelMode::Silent:
            if (bModal && GetLOKNotifier())
            {
                // check if there's already some dialog being ::Execute()d
                const bool bDialogExecuting = std::any_of(pSVData->maWinData.mpExecuteDialogs.begin(),
                                                          pSVData->maWinData.mpExecuteDialogs.end(),
                                                          [](const Dialog* pDialog) {
                                                              return pDialog->IsInSyncExecute();
                                                          });
                if (!(bDialogExecuting && IsInSyncExecute()))
                    break;
                else
                    SAL_WARN("lok.dialog", "Dialog \"" << ImplGetDialogText(this) << "\" is being synchronously executed over an existing synchronously executing dialog.");
            }

            SAL_INFO(
                "vcl",
                "Dialog \"" << ImplGetDialogText(this)
                    << "\"cancelled in silent mode");
            return false;
        default: // default cannot happen
        case Application::DialogCancelMode::Fatal:
            std::abort();
        }

        SAL_INFO(
            "vcl",
            "Dialog \"" << ImplGetDialogText(this)
                << "\"cancelled in silent mode");
        return false;
    default: // default cannot happen
    case Application::DialogCancelMode::Fatal:
        std::abort();
    }

#ifdef DBG_UTIL
    vcl::Window* pParent = GetParent();
    if ( pParent )
    {
        pParent = pParent->ImplGetFirstOverlapWindow();
        SAL_WARN_IF( !pParent->IsReallyVisible(), "vcl",
                    "Dialog::StartExecuteModal() - Parent not visible" );
        SAL_WARN_IF( !pParent->IsInputEnabled(), "vcl",
                    "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" );
        SAL_WARN_IF(  pParent->IsInModalMode(), "vcl",
                    "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" );
        vcl::Window* pParent = GetParent();
        if ( pParent )
        {
            pParent = pParent->ImplGetFirstOverlapWindow();
            SAL_WARN_IF( !pParent->IsReallyVisible(), "vcl",
                        "Dialog::StartExecuteModal() - Parent not visible" );
            SAL_WARN_IF( !pParent->IsInputEnabled(), "vcl",
                        "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" );
            SAL_WARN_IF(  pParent->IsInModalMode(), "vcl",
                        "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" );

    }
        }
#endif

    // link all dialogs which are being executed
    pSVData->maWinData.mpExecuteDialogs.push_back(this);
        // link all dialogs which are being executed
        pSVData->maWinData.mpExecuteDialogs.push_back(this);

    // stop capturing, in order to have control over the dialog
    if ( pSVData->maWinData.mpTrackWin )
        pSVData->maWinData.mpTrackWin->EndTracking( TrackingEventFlags::Cancel );
    if ( pSVData->maWinData.mpCaptureWin )
        pSVData->maWinData.mpCaptureWin->ReleaseMouse();
    EnableInput();
        // stop capturing, in order to have control over the dialog
        if ( pSVData->maWinData.mpTrackWin )
            pSVData->maWinData.mpTrackWin->EndTracking( TrackingEventFlags::Cancel );
        if ( pSVData->maWinData.mpCaptureWin )
            pSVData->maWinData.mpCaptureWin->ReleaseMouse();
        EnableInput();

    if ( GetParent() )
    {
        NotifyEvent aNEvt( MouseNotifyEvent::EXECUTEDIALOG, this );
        GetParent()->CompatNotify( aNEvt );
        if ( GetParent() )
        {
            NotifyEvent aNEvt( MouseNotifyEvent::EXECUTEDIALOG, this );
            GetParent()->CompatNotify( aNEvt );
        }
    }

    mbInExecute = true;
    // no real modality in LibreOfficeKit
    if (!bKitActive)
    if (!bKitActive && bModal)
        SetModalInputMode(true);

    // FIXME: no layouting, workaround some clipping issues
@@ -927,13 +933,17 @@ bool Dialog::ImplStartExecuteModal()
    ShowFlags showFlags = bForceFocusAndToFront ? ShowFlags::ForegroundTask : ShowFlags::NONE;
    Show(true, showFlags);

    pSVData->maAppData.mnModalMode++;
    if (bModal)
        pSVData->maAppData.mnModalMode++;

    css::uno::Reference<css::frame::XGlobalEventBroadcaster> xEventBroadcaster(css::frame::theGlobalEventBroadcaster::get(xContext), css::uno::UNO_QUERY_THROW);
    css::document::DocumentEvent aObject;
    aObject.EventName = "DialogExecute";
    xEventBroadcaster->documentEventOccured(aObject);
    UITestLogger::getInstance().log("ModalDialogExecuted Id:" + get_id());
    if (bModal)
        UITestLogger::getInstance().log("ModalDialogExecuted Id:" + get_id());
    else
        UITestLogger::getInstance().log("ModelessDialogExecuted Id:" + get_id());

    if (bKitActive)
    {
@@ -1015,7 +1025,7 @@ short Dialog::Execute()
            mbInSyncExecute = false;
        });

    if ( !ImplStartExecuteModal() )
    if ( !ImplStartExecute() )
        return 0;

    // Yield util EndDialog is called or dialog gets destroyed
@@ -1054,7 +1064,8 @@ short Dialog::Execute()
// virtual
bool Dialog::StartExecuteAsync( VclAbstractDialog::AsyncContext &rCtx )
{
    if ( !ImplStartExecuteModal() )
    const bool bModal = GetType() != WindowType::MODELESSDIALOG;
    if (!ImplStartExecute())
    {
        rCtx.mxOwner.disposeAndClear();
        rCtx.mxOwnerDialog.reset();
@@ -1062,7 +1073,7 @@ bool Dialog::StartExecuteAsync( VclAbstractDialog::AsyncContext &rCtx )
    }

    mpDialogImpl->maEndCtx = rCtx;
    mpDialogImpl->mbStartedModal = true;
    mpDialogImpl->mbStartedModal = bModal;

    return true;
}
@@ -1081,47 +1092,60 @@ void Dialog::EndDialog( long nResult )
    if ( !mbInExecute )
        return;

    SetModalInputMode(false);
    const bool bModal = GetType() != WindowType::MODELESSDIALOG;

    RemoveFromDlgList();

    // set focus to previous modal dialogue if it is modal for
    // the same frame parent (or NULL)
    ImplSVData* pSVData = ImplGetSVData();
    if (!pSVData->maWinData.mpExecuteDialogs.empty())
    if (bModal)
    {
        VclPtr<Dialog> pPrevious = pSVData->maWinData.mpExecuteDialogs.back();
        SetModalInputMode(false);

        vcl::Window* pFrameParent = ImplGetFrameWindow()->ImplGetParent();
        vcl::Window* pPrevFrameParent = pPrevious->ImplGetFrameWindow()? pPrevious->ImplGetFrameWindow()->ImplGetParent(): nullptr;
        if( ( !pFrameParent && !pPrevFrameParent ) ||
            ( pFrameParent && pPrevFrameParent && pFrameParent->ImplGetFrame() == pPrevFrameParent->ImplGetFrame() )
            )
        RemoveFromDlgList();

        // set focus to previous modal dialogue if it is modal for
        // the same frame parent (or NULL)
        ImplSVData* pSVData = ImplGetSVData();
        if (!pSVData->maWinData.mpExecuteDialogs.empty())
        {
            pPrevious->GrabFocus();
            VclPtr<Dialog> pPrevious = pSVData->maWinData.mpExecuteDialogs.back();

            vcl::Window* pFrameParent = ImplGetFrameWindow()->ImplGetParent();
            vcl::Window* pPrevFrameParent = pPrevious->ImplGetFrameWindow()? pPrevious->ImplGetFrameWindow()->ImplGetParent(): nullptr;
            if( ( !pFrameParent && !pPrevFrameParent ) ||
                ( pFrameParent && pPrevFrameParent && pFrameParent->ImplGetFrame() == pPrevFrameParent->ImplGetFrame() )
                )
            {
                pPrevious->GrabFocus();
            }
        }
    }

    Hide();
    if ( GetParent() )

    if (bModal)
    {
        NotifyEvent aNEvt( MouseNotifyEvent::ENDEXECUTEDIALOG, this );
        GetParent()->CompatNotify( aNEvt );
        if ( GetParent() )
        {
            NotifyEvent aNEvt( MouseNotifyEvent::ENDEXECUTEDIALOG, this );
            GetParent()->CompatNotify( aNEvt );
        }
    }

    mpDialogImpl->mnResult = nResult;

    if ( mpDialogImpl->mbStartedModal )
    {
        ImplEndExecuteModal();
        if (mpDialogImpl->maEndCtx.isSet())
        {
            mpDialogImpl->maEndCtx.maEndDialogFn(nResult);
            mpDialogImpl->maEndCtx.maEndDialogFn = nullptr;
        }

    if (mpDialogImpl->maEndCtx.isSet())
    {
        mpDialogImpl->maEndCtx.maEndDialogFn(nResult);
        mpDialogImpl->maEndCtx.maEndDialogFn = nullptr;
    }

    if ( mpDialogImpl->mbStartedModal )
    {
        mpDialogImpl->mbStartedModal = false;
        mpDialogImpl->mnResult = -1;
    }

    mbInExecute = false;

    // Destroy ourselves (if we have a context with VclPtr owner)
@@ -1474,15 +1498,18 @@ ModalDialog::ModalDialog( vcl::Window* pParent, const OUString& rID, const OUStr
{
}

void ModelessDialog::Activate()
void Dialog::Activate()
{
    css::uno::Reference< css::uno::XComponentContext > xContext(
            comphelper::getProcessComponentContext() );
    css::uno::Reference<css::frame::XGlobalEventBroadcaster> xEventBroadcaster(css::frame::theGlobalEventBroadcaster::get(xContext), css::uno::UNO_QUERY_THROW);
    css::document::DocumentEvent aObject;
    aObject.EventName = "ModelessDialogVisible";
    xEventBroadcaster->documentEventOccured(aObject);
    Dialog::Activate();
    if (GetType() == WindowType::MODELESSDIALOG)
    {
        css::uno::Reference< css::uno::XComponentContext > xContext(
                comphelper::getProcessComponentContext() );
        css::uno::Reference<css::frame::XGlobalEventBroadcaster> xEventBroadcaster(css::frame::theGlobalEventBroadcaster::get(xContext), css::uno::UNO_QUERY_THROW);
        css::document::DocumentEvent aObject;
        aObject.EventName = "ModelessDialogVisible";
        xEventBroadcaster->documentEventOccured(aObject);
    }
    SystemWindow::Activate();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/window/syswin.cxx b/vcl/source/window/syswin.cxx
index 734e1d0..72f2eb5 100644
--- a/vcl/source/window/syswin.cxx
+++ b/vcl/source/window/syswin.cxx
@@ -431,7 +431,7 @@ const Size& SystemWindow::GetMaxOutputSizePixel() const
    return mpImplData->maMaxOutSize;
}

static void ImplWindowStateFromStr(WindowStateData& rData,
void ImplWindowStateFromStr(WindowStateData& rData,
    const OString& rStr)
{
    WindowStateMask nValidMask = WindowStateMask::NONE;
@@ -545,7 +545,7 @@ static void ImplWindowStateFromStr(WindowStateData& rData,
    rData.SetMask( nValidMask );
}

static OString ImplWindowStateToStr(const WindowStateData& rData)
OString ImplWindowStateToStr(const WindowStateData& rData)
{
    const WindowStateMask nValidMask = rData.GetMask();
    if ( nValidMask == WindowStateMask::NONE )
diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx
index 048f15c..bb1cbf4 100644
--- a/vcl/unx/gtk3/gtk3gtkframe.cxx
+++ b/vcl/unx/gtk3/gtk3gtkframe.cxx
@@ -2467,6 +2467,13 @@ void GtkSalFrame::SetModal(bool bModal)
    gtk_window_set_modal(GTK_WINDOW(m_pWindow), bModal);
}

bool GtkSalFrame::GetModal() const
{
    if (!m_pWindow)
        return false;
    return gtk_window_get_modal(GTK_WINDOW(m_pWindow));
}

gboolean GtkSalFrame::signalTooltipQuery(GtkWidget*, gint /*x*/, gint /*y*/,
                                     gboolean /*keyboard_mode*/, GtkTooltip *tooltip,
                                     gpointer frame)
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 0959438..75486ca 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -36,7 +36,9 @@
#include <vcl/ImageTree.hxx>
#include <vcl/quickselectionengine.hxx>
#include <vcl/mnemonic.hxx>
#include <vcl/syswin.hxx>
#include <vcl/weld.hxx>
#include <window.h>

using namespace com::sun::star;
using namespace com::sun::star::uno;
@@ -2057,6 +2059,11 @@ public:
        gtk_window_set_modal(m_pWindow, bModal);
    }

    virtual bool get_modal() const override
    {
        return gtk_window_get_modal(m_pWindow);
    }

    virtual void resize_to_request() override
    {
        gtk_window_resize(m_pWindow, 1, 1);
@@ -2083,6 +2090,92 @@ public:
        return SystemEnvData();
    }

    virtual Size get_size() const override
    {
        int current_width, current_height;
        gtk_window_get_size(m_pWindow, &current_width, &current_height);
        return Size(current_width, current_height);
    }

    virtual Point get_position() const override
    {
        int current_x, current_y;
        gtk_window_get_position(m_pWindow, &current_x, &current_y);
        return Point(current_x, current_y);
    }

    virtual bool get_resizable() const override
    {
        return gtk_window_get_resizable(m_pWindow);
    }

    virtual bool has_toplevel_focus() const override
    {
        return gtk_window_has_toplevel_focus(m_pWindow);
    }

    virtual void set_window_state(const OString& rStr) override
    {
        WindowStateData aData;
        ImplWindowStateFromStr( aData, rStr );

        auto nMask = aData.GetMask();
        auto nState = aData.GetState() & WindowStateState::SystemMask;

        if (nMask & WindowStateMask::Width && nMask & WindowStateMask::Height)
        {
            gtk_window_set_default_size(m_pWindow, aData.GetWidth(), aData.GetHeight());
        }
        if (nMask & WindowStateMask::State)
        {
            if (nState & WindowStateState::Maximized)
                gtk_window_maximize(m_pWindow);
            else
                gtk_window_unmaximize(m_pWindow);
        }
    }

    virtual OString get_window_state(WindowStateMask nMask) const override
    {
        bool bPositioningAllowed = true;
#if defined(GDK_WINDOWING_WAYLAND)
        // drop x/y when under wayland
        GdkDisplay *pDisplay = gtk_widget_get_display(m_pWidget);
        bPositioningAllowed = !GDK_IS_WAYLAND_DISPLAY(pDisplay);
#endif

        WindowStateData aData;
        WindowStateMask nAvailable = WindowStateMask::State |
                                     WindowStateMask::Width | WindowStateMask::Height;
        if (bPositioningAllowed)
            nAvailable |= WindowStateMask::X | WindowStateMask::Y;
        aData.SetMask(nMask & nAvailable);

        if (nMask & WindowStateMask::State)
        {
            WindowStateState nState = WindowStateState::Normal;
            if (gtk_window_is_maximized(m_pWindow))
                nState |= WindowStateState::Maximized;
            aData.SetState(nState);
        }

        if (bPositioningAllowed && (nMask & (WindowStateMask::X | WindowStateMask::Y)))
        {
            auto aPos = get_position();
            aData.SetX(aPos.X());
            aData.SetY(aPos.Y());
        }

        if (nMask & (WindowStateMask::Width | WindowStateMask::Height))
        {
            auto aSize = get_size();
            aData.SetWidth(aSize.Width());
            aData.SetHeight(aSize.Height());
        }

        return ImplWindowStateToStr(aData);
    }

    virtual ~GtkInstanceWindow() override
    {
        if (m_xWindow.is())
@@ -2232,11 +2325,7 @@ public:
        m_xDialogController = rDialogController;
        m_aFunc = func;

        if (!gtk_widget_get_visible(m_pWidget))
        {
            sort_native_button_order(GTK_BOX(gtk_dialog_get_action_area(m_pDialog)));
            gtk_widget_show(m_pWidget);
        }
        show();

        m_nResponseSignalId = g_signal_connect(m_pDialog, "response", G_CALLBACK(signalAsyncResponse), this);

@@ -2275,8 +2364,11 @@ public:

    virtual void show() override
    {
        sort_native_button_order(GTK_BOX(gtk_dialog_get_action_area(m_pDialog)));
        gtk_widget_show(m_pWidget);
        if (!gtk_widget_get_visible(m_pWidget))
        {
            sort_native_button_order(GTK_BOX(gtk_dialog_get_action_area(m_pDialog)));
            gtk_widget_show(m_pWidget);
        }
    }

    static int VclToGtk(int nResponse)