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

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Thu Nov 1 21:13:03 UTC 2018


 include/sfx2/basedlgs.hxx                    |   43 ++++-
 include/sfx2/childwin.hxx                    |    8 -
 include/vcl/dialog.hxx                       |    7 
 include/vcl/weld.hxx                         |    6 
 sfx2/source/appl/childwin.cxx                |   73 +++++++--
 sfx2/source/appl/workwin.cxx                 |   85 +++++++++--
 sfx2/source/dialog/basedlgs.cxx              |  126 ++++++++++++++++
 sfx2/source/inc/workwin.hxx                  |   11 +
 sw/inc/swabstdlg.hxx                         |    4 
 sw/inc/viewsh.hxx                            |   14 -
 sw/source/core/view/viewsh.cxx               |   30 ++-
 sw/source/ui/dialog/swdlgfact.cxx            |   19 +-
 sw/source/ui/dialog/swdlgfact.hxx            |   17 +-
 sw/source/ui/dialog/wordcountdialog.cxx      |  114 +++++----------
 sw/source/uibase/dialog/wordcountwrapper.cxx |   10 -
 sw/source/uibase/inc/wordcountdialog.hxx     |   41 ++---
 sw/source/uibase/uiview/viewport.cxx         |    4 
 sw/uiconfig/swriter/ui/wordcount.ui          |    8 -
 vcl/inc/qt5/Qt5Frame.hxx                     |    1 
 vcl/inc/salframe.hxx                         |    5 
 vcl/inc/unx/gtk/gtkframe.hxx                 |    1 
 vcl/inc/window.h                             |    4 
 vcl/qt5/Qt5Frame.cxx                         |    7 
 vcl/source/app/salvtables.cxx                |   43 +++++
 vcl/source/window/builder.cxx                |   14 +
 vcl/source/window/dialog.cxx                 |  203 +++++++++++++++------------
 vcl/source/window/syswin.cxx                 |    4 
 vcl/unx/gtk3/gtk3gtkframe.cxx                |    7 
 vcl/unx/gtk3/gtk3gtkinst.cxx                 |  101 ++++++++++++-
 29 files changed, 725 insertions(+), 285 deletions(-)

New commits:
commit 26c375671aa362b2f59d84645784938677ae1719
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Thu Oct 4 12:41:22 2018 +0100
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Thu Nov 1 22:12:33 2018 +0100

    weld SwWordCountFloatDlg
    
    enable modeless dialogs to emit a response so runAsync can be used with
    them and get something called when the dialog is dismissed
    
    Change-Id: Ie9603bcc063cefabbae635949671baf06620785d
    Reviewed-on: https://gerrit.libreoffice.org/61383
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/include/sfx2/basedlgs.hxx b/include/sfx2/basedlgs.hxx
index d4279599fe4b..1c3e2b37caa6 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 8c46889e533f..9a12bf896071 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 c5a3997566ff..b6d7bbdb110e 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 7fcd7b884a52..fdb0cba3379e 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -196,8 +196,14 @@ 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 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 aa8018eb0ed4..e2bbc3ee9e7f 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
@@ -646,7 +673,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 363b3005d1f9..69e29d2e6d83 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 f4a07696af43..8fcb0cb1137f 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 7b37d065afa4..38c41653dfdb 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 642218f530d8..99d55a84dfb5 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 db92346bc587..fe904ffcd36e 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 23ef8f436318..4f38a4d4041e 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 c30b671d3b29..b634d18970d2 100644
--- a/sw/source/ui/dialog/swdlgfact.cxx
+++ b/sw/source/ui/dialog/swdlgfact.cxx
@@ -87,7 +87,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);
 
@@ -695,19 +699,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()
@@ -1109,11 +1113,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 103b04b35a02..14b802ef7e2d 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 cc350e6fb9c8..b24767823963 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);
-
-    if (m_pStandardizedPagesLabelFT->IsVisible())
+    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_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 090410509a0d..2a205fb3bf12 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 ea95266a5cac..e63ef3c07c6b 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 e52c3c778940..331309ef025a 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 86595e5125cf..6da9a2c96b8e 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 9d7b15792731..f3fd1f19b0ec 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 e2662d415fc2..b27b46d828c8 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 7b2e78a5414e..a77c7c61686b 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 21448efd9496..452a88e6f9f5 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 17fb684e3c0e..f7e6a571458c 100644
--- a/vcl/qt5/Qt5Frame.cxx
+++ b/vcl/qt5/Qt5Frame.cxx
@@ -474,6 +474,13 @@ void Qt5Frame::SetModal(bool bModal)
     }
 }
 
+bool Qt5Frame::GetModal() const
+{
+    if (isWindow())
+        return windowHandle()->getModality() == Qt::WindowModal;
+    return false;
+}
+
 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 485b404ac200..d3bbd9385470 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,35 @@ 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 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 85ed792d5f39..480c2f7b6c47 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 53ebce93689b..11a92bb9a8f4 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 734e1d0b946f..72f2eb5bf46d 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 048f15c19207..bb1cbf48b569 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 09594386fa1d..2d624e2d6197 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,87 @@ 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 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 +2320,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 +2359,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)


More information about the Libreoffice-commits mailing list