[Libreoffice-commits] core.git: Branch 'feature/wasm' - 52 commits - android/default-document basctl/Library_basctl.mk bin/run chart2/inc chart2/Library_chartcontroller.mk chart2/source comphelper/source compilerplugins/clang config_host/config_clang.h.in config_host/config_global.h.in config_host/config_wasm_strip.h.in config_host.mk.in configure.ac connectivity/source cppuhelper/source cui/inc cui/Library_cui.mk cui/source cui/UIConfig_cui.mk desktop/inc desktop/Module_desktop.mk desktop/scripts desktop/source dictionaries drawinglayer/Library_drawinglayer.mk editeng/Library_editeng.mk editeng/source extensions/Module_extensions.mk extensions/source external/fontconfig external/hunspell external/hyphen external/icu external/mythes extras/Module_extras.mk filter/source framework/Library_fwk.mk framework/source framework/util helpcontent2 i18npool/source include/formula include/sfx2 include/svx include/toolkit include/vcl lingucomponent/Library_guesslang.mk lingucomponent/Module_lingucomponent.mk lotuswordpro/source Makefile.in odk/CppunitTest_odk_checkapi.mk offapi/com offapi/UnoApi_offapi.mk officecfg/registry oox/Library_oox.mk oox/source package/source postprocess/Module_postprocess.mk RepositoryExternal.mk Repository.mk RepositoryModule_host.mk sal/cppunittester sal/Library_cppunitmain.mk sal/Module_sal.mk sax/source sc/qa sd/Library_sd.mk sd/source sfx2/Library_sfx.mk sfx2/source sfx2/util shell/Library_syssh.mk shell/source solenv/clang-format solenv/gbuild solenv/gcc-wrappers static/CustomTarget_emscripten_fs_image.mk static/CustomTarget_wasm-qt5-mandelbrot_moc.mk static/emscripten static/Executable_wasm-qt5-mandelbrot.mk static/Module_static.mk static/README.wasm.md static/source svx/Library_svxcore.mk svx/Library_svx.mk svx/source svx/util sw/inc sw/Library_sw.mk sw/qa sw/source sw/uiconfig toolkit/inc toolkit/source ucb/source unotools/Library_utl.mk vcl/headless vcl/inc vcl/Library_vcl.mk vcl/Module_vcl.mk vcl/osx vcl/qa vcl/qt5 vcl/source vcl/unx wasm-qt/Custom Target_wasm-qt5-mandelbrot_moc.mk wasm-qt/Executable_wasm-qt5-mandelbrot.mk wasm-qt/Makefile wasm-qt/Module_wasm-qt.mk wasm-qt/README.md wasm-qt/source writerperfect/Library_wpftwriter.mk writerperfect/Module_writerperfect.mk writerperfect/source xmloff/Library_xof.mk xmloff/Library_xo.mk xmloff/source xmloff/util

Thu, 20 Jan 2022 10:53:03 -0800

Rebased ref, commits from common ancestor:
commit 983ea068f2a30c08964b7cbadcb8fa19a2ba8e4b
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Sun Jan 9 14:49:28 2022 +0100
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Thu Jan 20 19:51:49 2022 +0100

    Add a larger Writer example document
    
    Change-Id: I4bc9a82c7f99563af8da62f889b51d1b583df760

diff --git a/android/default-document/example_larger.odt 
b/android/default-document/example_larger.odt
new file mode 100644
index 000000000000..1b3a1dfb877a
Binary files /dev/null and b/android/default-document/example_larger.odt differ
diff --git a/static/CustomTarget_emscripten_fs_image.mk 
b/static/CustomTarget_emscripten_fs_image.mk
index ad06e8254c89..63e37d139336 100644
--- a/static/CustomTarget_emscripten_fs_image.mk
+++ b/static/CustomTarget_emscripten_fs_image.mk
@@ -1131,6 +1131,7 @@ gb_emscripten_fs_image_files := \
     $(INSTROOT)/$(LIBO_SHARE_RESOURCE_FOLDER)/common/fonts/opens___.ttf \
     $(INSTROOT)/$(LIBO_URE_ETC_FOLDER)/$(call gb_Helper_get_rcfile,uno) \
     $(INSTROOT)/$(LIBO_URE_MISC_FOLDER)/services.rdb \
+    $(SRCDIR)/android/default-document/example_larger.odt \
     $(SRCDIR)/android/default-document/example.odt \
 
 ifneq ($(ENABLE_WASM_STRIP_CHART),TRUE)
diff --git a/static/emscripten/soffice_args.js 
b/static/emscripten/soffice_args.js
index 7ecf7e8988e8..fa5e9dd4164d 100644
--- a/static/emscripten/soffice_args.js
+++ b/static/emscripten/soffice_args.js
@@ -2,5 +2,5 @@ Module['arguments'] = [
     '--norestore',
     '--nologo',
     '--writer',
-    '/android/default-document/example.odt'
+    '/android/default-document/example_larger.odt'
 ];
commit 028986b8840447fa3a9ced8d3f866595854ff4b7
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Wed Nov 17 01:57:33 2021 +0100
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Thu Jan 20 19:51:48 2022 +0100

    WIP: async popup menus
    
    A first patch to get some feedback. Asnyc LO popup menus are still
    buggy, as I'm not sure where to call the PopupMenu::Finish for
    them.
    
    Also the XDialogClosedListener is currently just for convenience
    and might want some separate notifier.
    
    Fun fact, that ImplExecute / ImplPopup is called for submenu, but
    then doesn't execute. And generally the naming of some variables
    is IMHO wrong; I might also prefix Menu members with "m_" for
    easier readability.
    
    Change-Id: Id8b413aa6b4699201e58db0113649c6b224d33b6

diff --git a/include/sfx2/dispatch.hxx b/include/sfx2/dispatch.hxx
index 6e87c89217f4..0f6cbeb55fdc 100644
--- a/include/sfx2/dispatch.hxx
+++ b/include/sfx2/dispatch.hxx
@@ -20,6 +20,7 @@
 #define INCLUDED_SFX2_DISPATCH_HXX
 
 #include <memory>
+#include <functional>
 #include <sal/config.h>
 #include <sfx2/dllapi.h>
 #include <sfx2/toolbarids.hxx>
@@ -42,6 +43,7 @@ class Point;
 struct SfxDispatcher_Impl;
 
 namespace vcl { class Window; }
+namespace com::sun::star::ui::dialogs { struct DialogClosedEvent; }
 
 enum class SfxDispatcherPopFlags
 {
@@ -136,8 +138,14 @@ public:
     SfxViewFrame*       GetFrame() const;
     SfxModule*          GetModule() const;
 
-    void                ExecutePopup( const OUString &rResName, vcl::Window 
*pWin = nullptr, const Point *pPos = nullptr );
-    static void         ExecutePopup( vcl::Window *pWin = nullptr, const Point 
*pPosPixel = nullptr );
+    /**
+     * @param rCloseFunc
+     *     If this is !nullptr, the popup will be just shown / run async and 
rCloseFunc will be called on close.
+     */
+    void ExecutePopup(const OUString &rResName, vcl::Window *pWin = nullptr, 
const Point *pPos = nullptr,
+                      const std::function<void(sal_Int16)>& rCloseFunc = 
nullptr);
+    static void ExecutePopup(vcl::Window *pWin = nullptr, const Point 
*pPosPixel = nullptr,
+                             const std::function<void(sal_Int16)>& rCloseFunc 
= nullptr);
 
     bool                IsAppDispatcher() const;
     bool                IsFlushed() const;
diff --git a/include/toolkit/awt/vclxmenu.hxx b/include/toolkit/awt/vclxmenu.hxx
index 096c370bce82..ffa89e9a8511 100644
--- a/include/toolkit/awt/vclxmenu.hxx
+++ b/include/toolkit/awt/vclxmenu.hxx
@@ -25,10 +25,11 @@
 #include <toolkit/helper/listenermultiplexer.hxx>
 
 #include <com/sun/star/awt/XMenuBar.hpp>
-#include <com/sun/star/awt/XPopupMenu.hpp>
+#include <com/sun/star/awt/XPopupMenuAsync.hpp>
 #include <com/sun/star/lang/XServiceInfo.hpp>
 #include <com/sun/star/lang/XTypeProvider.hpp>
 #include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/ui/dialogs/XDialogClosedListener.hpp>
 
 #include <comphelper/servicehelper.hxx>
 #include <cppuhelper/weak.hxx>
@@ -39,6 +40,7 @@
 
 #include <vector>
 
+struct DialogClosedEvent;
 class Menu;
 class MenuBar;
 class PopupMenu;
@@ -51,10 +53,11 @@ typedef ::std::vector<
 typedef void (*MenuUserDataReleaseFunction)(void*);
 
 class TOOLKIT_DLLPUBLIC VCLXMenu :  public css::awt::XMenuBar,
-                                    public css::awt::XPopupMenu,
+                                    public css::awt::XPopupMenuAsync,
                                     public css::lang::XServiceInfo,
                                     public css::lang::XTypeProvider,
                                     public css::lang::XUnoTunnel,
+                                    public 
css::ui::dialogs::XDialogClosedListener,
                                     public ::cppu::OWeakObject
 {
 private:
@@ -76,7 +79,6 @@ public:
     VCLXMenu( Menu* pMenu );
     virtual ~VCLXMenu() override;
 
-
     Menu*    GetMenu() const { return mpMenu; }
     bool IsPopupMenu() const;
     void setUserValue(sal_uInt16 nItemId, void* nUserValue, 
MenuUserDataReleaseFunction aFunc);
@@ -137,10 +139,20 @@ public:
     virtual void SAL_CALL setItemImage( ::sal_Int16 nItemId, const 
css::uno::Reference< css::graphic::XGraphic >& xGraphic, sal_Bool bScale ) 
override;
     virtual css::uno::Reference< css::graphic::XGraphic > SAL_CALL 
getItemImage( ::sal_Int16 nItemId ) override;
 
+    // css::awt::XPopupMenuAsync
+    virtual sal_Bool SAL_CALL popup(const css::uno::Reference< 
css::awt::XWindowPeer >& Parent, const css::awt::Rectangle& Position,
+                                    ::sal_Int16 Direction, const 
css::uno::Reference<css::ui::dialogs::XDialogClosedListener>& xListener) 
override;
+
     // css::lang::XServiceInfo
     virtual OUString SAL_CALL getImplementationName(  ) override;
     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) 
override;
     virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames(  
) override;
+
+    // css::ui::dialogs::XDialogClosedListener
+    virtual void SAL_CALL dialogClosed(const 
css::ui::dialogs::DialogClosedEvent& aEvent) override;
+
+    // XEventListener (base of XDialogClosedListener)
+    virtual void SAL_CALL disposing(css::lang::EventObject const & Source) 
override;
 };
 
 class UNLESS_MERGELIBS(TOOLKIT_DLLPUBLIC) VCLXMenuBar final : public VCLXMenu
diff --git a/include/vcl/menu.hxx b/include/vcl/menu.hxx
index 87108359dab1..89a9d2a058c8 100644
--- a/include/vcl/menu.hxx
+++ b/include/vcl/menu.hxx
@@ -44,6 +44,7 @@ class Menu;
 class MenuItemList;
 class Image;
 class PopupMenu;
+struct PopupMenuFinishState;
 class KeyEvent;
 class MenuFloatingWindow;
 class SalMenu;
@@ -54,6 +55,7 @@ enum class FloatWinPopupFlags;
 enum class VclEventId;
 
 namespace com::sun::star::awt { class XPopupMenu; }
+namespace com::sun::star::ui::dialogs { class XDialogClosedListener; }
 namespace com::sun::star::accessibility { class XAccessible;  }
 
 namespace vcl
@@ -492,11 +494,16 @@ class VCL_DLLPUBLIC PopupMenu final : public Menu
     friend struct MenuItemData;
 
 private:
+    struct PopupMenuFinishState* m_pState;
+
     SAL_DLLPRIVATE MenuFloatingWindow * ImplGetFloatingWindow() const;
     SAL_DLLPRIVATE bool PrepareRun(const VclPtr<vcl::Window>& pParentWin, 
tools::Rectangle& rRect, FloatWinPopupFlags& nPopupModeFlags, Menu* pSFrom, 
bool& bRealExecute, VclPtr<MenuFloatingWindow>&);
-    SAL_DLLPRIVATE bool Run(const VclPtr<MenuFloatingWindow>&, bool 
bRealExecute, bool bPreSelectFirst, FloatWinPopupFlags nPopupModeFlags, Menu* 
pSFrom, const tools::Rectangle& rRect);
+    SAL_DLLPRIVATE bool Run(const VclPtr<MenuFloatingWindow>&, bool 
bRealExecute, bool bPreSelectFirst, FloatWinPopupFlags nPopupModeFlags, Menu* 
pSFrom, const tools::Rectangle& rRect,
+                            const 
css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* xListener);
     SAL_DLLPRIVATE void FinishRun(const VclPtr<MenuFloatingWindow>&, const 
VclPtr<vcl::Window>& pParentWin, bool bRealExecute, bool bIsNativeMenu);
     SAL_DLLPRIVATE sal_uInt16 ImplExecute(const VclPtr<vcl::Window>& 
pParentWin, const tools::Rectangle& rRect, FloatWinPopupFlags nPopupModeFlags, 
Menu* pSFrom, bool bPreSelectFirst);
+    SAL_DLLPRIVATE bool ImplPopup(const VclPtr<vcl::Window>& pParentWin, const 
tools::Rectangle& rRect, FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, bool 
bPreSelectFirst,
+                                  const 
css::uno::Reference<css::ui::dialogs::XDialogClosedListener>&);
     SAL_DLLPRIVATE void ImplFlushPendingSelect();
     SAL_DLLPRIVATE tools::Long ImplCalcHeight( sal_uInt16 nEntries ) const;
     SAL_DLLPRIVATE sal_uInt16 ImplCalcVisEntries( tools::Long nMaxHeight, 
sal_uInt16 nStartEntry, sal_uInt16* pLastVisible = nullptr ) const;
@@ -519,6 +526,12 @@ public:
     sal_uInt16 Execute( vcl::Window* pWindow, const Point& rPopupPos );
     sal_uInt16 Execute( vcl::Window* pWindow, const tools::Rectangle& rRect, 
PopupMenuFlags nFlags = PopupMenuFlags::NONE );
 
+    bool Popup(vcl::Window* pParentWin, const Point& rPopupPos,
+               const 
css::uno::Reference<css::ui::dialogs::XDialogClosedListener>&);
+    bool Popup(vcl::Window* pParentWin, const tools::Rectangle& rRect,
+               const 
css::uno::Reference<css::ui::dialogs::XDialogClosedListener>&, PopupMenuFlags = 
PopupMenuFlags::NONE);
+    void Finish();
+
     // for the TestTool
     void EndExecute();
     virtual void SelectItem(sal_uInt16 nId) override;
diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk
index 68068ab4a864..280558b2dbd1 100644
--- a/offapi/UnoApi_offapi.mk
+++ b/offapi/UnoApi_offapi.mk
@@ -1859,6 +1859,7 @@ $(eval $(call 
gb_UnoApi_add_idlfiles,offapi,com/sun/star/awt,\
        XPatternField \
        XPointer \
        XPopupMenu \
+       XPopupMenuAsync \
        XPrinter \
        XPrinterPropertySet \
        XPrinterServer \
diff --git a/offapi/com/sun/star/awt/XPopupMenuAsync.idl 
b/offapi/com/sun/star/awt/XPopupMenuAsync.idl
new file mode 100644
index 000000000000..d3f7b317f086
--- /dev/null
+++ b/offapi/com/sun/star/awt/XPopupMenuAsync.idl
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+#ifndef __com_sun_star_awt_XPopupMenuAsync_idl__
+#define __com_sun_star_awt_XPopupMenuAsync_idl__
+
+#include <com/sun/star/awt/XPopupMenu.idl>
+#include <com/sun/star/ui/dialogs/XDialogClosedListener.idl>
+
+module com {  module sun {  module star {  module awt {
+
+/** shows a pop-up menu without blocking.
+ */
+interface XPopupMenuAsync: XPopupMenu
+{
+    /** just shows the popup menu without blocking and calls the
+        XDialogClosedListener when closed,
+
+        @param Parent
+            the parent window.
+
+        @param Position
+            a Rectangle representing the coordinates system
+            where the popup menu should be executed.
+
+        @param Direction
+            the direction in which a popup menu will grow, as specified
+            by one of the PopupMenuDirection constants.
+
+        @param xListener
+            notified, if the popup is closed.
+
+        @return
+            returns true, if the popup has started to run async.
+            May fail, if the native backend doesn't implement async popups.
+    */
+    boolean popup([in] XWindowPeer Parent, [in] Rectangle Position, [in] short 
Direction,
+                  [in] ::com::sun::star::ui::dialogs::XDialogClosedListener 
xListener);
+};
+
+}; }; }; };
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/view/drviews4.cxx b/sd/source/ui/view/drviews4.cxx
index b07279844265..548504af7746 100644
--- a/sd/source/ui/view/drviews4.cxx
+++ b/sd/source/ui/view/drviews4.cxx
@@ -800,7 +800,7 @@ void DrawViewShell::Command(const CommandEvent& rCEvt, 
::sd::Window* pWin)
             bool bShouldDisableEditHyperlink = ShouldDisableEditHyperlink();
 
             if(rCEvt.IsMouseEvent())
-                GetViewFrame()->GetDispatcher()->ExecutePopup( aPopupId );
+                GetViewFrame()->GetDispatcher()->ExecutePopup(aPopupId, 
nullptr, nullptr, [](sal_Int16){});
             else
             {
                 //don't open contextmenu at mouse position if not opened via 
mouse
diff --git a/sfx2/source/control/dispatch.cxx b/sfx2/source/control/dispatch.cxx
index b0eee6eefb22..c182e67723ab 100644
--- a/sfx2/source/control/dispatch.cxx
+++ b/sfx2/source/control/dispatch.cxx
@@ -60,6 +60,7 @@
 #include <svl/eitem.hxx>
 #include <svl/itemiter.hxx>
 #include <svl/itempool.hxx>
+#include <svtools/dialogclosedlistener.hxx>
 #include <toolkit/awt/vclxmenu.hxx>
 #include <toolkit/helper/vclunohelper.hxx>
 #include <tools/debug.hxx>
@@ -137,8 +138,12 @@ struct SfxDispatcher_Impl
     SfxDisableFlags      nDisableFlags;
     bool                 bFlushed;
     std::deque< std::deque<SfxToDo_Impl> > aToDoCopyStack;
+
+    static css::uno::Reference<css::frame::XPopupMenuController>* 
m_pActivePopupController;
 };
 
+css::uno::Reference<css::frame::XPopupMenuController>* 
SfxDispatcher_Impl::m_pActivePopupController = nullptr;
+
 /** This method checks if the stack of the SfxDispatchers is flushed, or if
     push- or pop- commands are pending.
 */
@@ -1685,7 +1690,52 @@ bool SfxDispatcher::FillState_(const SfxSlotServer& 
rSvr, SfxItemSet& rState,
     return false;
 }
 
-void SfxDispatcher::ExecutePopup( vcl::Window *pWin, const Point *pPos )
+namespace {
+
+static void 
lcl_FinishPopupDispatch(css::uno::Reference<css::frame::XPopupMenuController> 
xPopupController)
+{
+    css::uno::Reference<css::lang::XComponent> xComponent(xPopupController, 
css::uno::UNO_QUERY);
+    if (xComponent.is())
+        xComponent->dispose();
+    SfxDispatcher_Impl::m_pActivePopupController = nullptr;
+}
+
+struct SfxDispatcherPopupFinish final
+{
+    css::uno::Reference<css::frame::XPopupMenuController> m_xPopupController;
+    std::function<void(sal_Int16)> m_aCloseFunc;
+    rtl::Reference<::svt::DialogClosedListener> m_xDialogListener;
+    css::uno::Reference<css::awt::XPopupMenu> m_xPopupMenu;
+
+    DECL_LINK(PopupClosedHdl, css::ui::dialogs::DialogClosedEvent*, void);
+
+    
SfxDispatcherPopupFinish(css::uno::Reference<css::frame::XPopupMenuController> 
xPopupController,
+                             const std::function<void(sal_Int16)>& rCloseFunc,
+                             css::uno::Reference<css::awt::XPopupMenu> 
xPopupMenu)
+        : m_xPopupController(xPopupController)
+        , m_aCloseFunc(rCloseFunc)
+        , m_xDialogListener(new ::svt::DialogClosedListener())
+        , m_xPopupMenu(xPopupMenu)
+    {
+        m_xDialogListener->SetDialogClosedLink(LINK(this, 
SfxDispatcherPopupFinish, PopupClosedHdl));
+    }
+};
+
+IMPL_LINK(SfxDispatcherPopupFinish, PopupClosedHdl, 
css::ui::dialogs::DialogClosedEvent*, pEvt, void)
+{
+    assert(m_xPopupController.is());
+    if (!comphelper::LibreOfficeKit::isActive())
+        assert(SfxDispatcher_Impl::m_pActivePopupController == 
&m_xPopupController);
+    if (m_aCloseFunc)
+        m_aCloseFunc(pEvt ? pEvt->DialogResult : 0);
+    lcl_FinishPopupDispatch(m_xPopupController);
+    delete this;
+}
+
+} // anon namespace
+
+void SfxDispatcher::ExecutePopup(vcl::Window *pWin, const Point *pPos,
+    const std::function<void(sal_Int16)>& rCloseFunc)
 {
     SfxDispatcher &rDisp = *SfxGetpApp()->GetDispatcher_Impl();
     sal_uInt16 nShLevel = 0;
@@ -1699,13 +1749,14 @@ void SfxDispatcher::ExecutePopup( vcl::Window *pWin, 
const Point *pPos )
         const OUString& rResName = pSh->GetInterface()->GetPopupMenuName();
         if ( !rResName.isEmpty() )
         {
-            rDisp.ExecutePopup( rResName, pWin, pPos );
+            rDisp.ExecutePopup(rResName, pWin, pPos, rCloseFunc);
             return;
         }
     }
 }
 
-void SfxDispatcher::ExecutePopup( const OUString& rResName, vcl::Window* pWin, 
const Point* pPos )
+void SfxDispatcher::ExecutePopup( const OUString& rResName, vcl::Window* pWin, 
const Point* pPos,
+    const std::function<void(sal_Int16)>& rCloseFunc)
 {
     css::uno::Sequence< css::uno::Any > aArgs{
         css::uno::Any(comphelper::makePropertyValue( "Value", rResName )),
@@ -1714,16 +1765,29 @@ void SfxDispatcher::ExecutePopup( const OUString& 
rResName, vcl::Window* pWin, c
     };
 
     css::uno::Reference< css::uno::XComponentContext > xContext = 
comphelper::getProcessComponentContext();
-    css::uno::Reference< css::frame::XPopupMenuController > xPopupController(
-        xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
-        "com.sun.star.comp.framework.ResourceMenuController", aArgs, xContext 
), css::uno::UNO_QUERY );
+
+    if (!comphelper::LibreOfficeKit::isActive())
+        assert(!xImp->m_pActivePopupController);
+    if (!comphelper::LibreOfficeKit::isActive() && 
xImp->m_pActivePopupController)
+        return;
+
+    css::uno::Reference<css::frame::XPopupMenuController> xPopupController =
+        css::uno::Reference<css::frame::XPopupMenuController>(
+            
xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
+            "com.sun.star.comp.framework.ResourceMenuController", aArgs, 
xContext), css::uno::UNO_QUERY);
+    if (!xPopupController.is())
+        return;
+    SfxDispatcher_Impl::m_pActivePopupController = &xPopupController;
 
     css::uno::Reference< css::awt::XPopupMenu > xPopupMenu( 
xContext->getServiceManager()->createInstanceWithContext(
         "com.sun.star.awt.PopupMenu", xContext ), css::uno::UNO_QUERY );
-
-    if ( !xPopupController.is() || !xPopupMenu.is() )
+    if (!xPopupMenu.is())
+    {
+        lcl_FinishPopupDispatch(xPopupController);
         return;
+    }
 
+    struct SfxDispatcherPopupFinish* pFin = nullptr;
     vcl::Window* pWindow = pWin ? pWin : 
xImp->pFrame->GetFrame().GetWorkWindow_Impl()->GetWindow();
     Point aPos = pPos ? *pPos : pWindow->GetPointerPosPixel();
 
@@ -1751,14 +1815,22 @@ void SfxDispatcher::ExecutePopup( const OUString& 
rResName, vcl::Window* pWin, c
         OUString aMenuURL = "private:resource/popupmenu/" + rResName;
         if (GetFrame()->GetViewShell()->TryContextMenuInterception(xPopupMenu, 
aMenuURL, aEvent))
         {
+            const sal_Int16 nFlags = 
css::awt::PopupMenuDirection::EXECUTE_DOWN;
+            const css::awt::Rectangle aRect(aPos.X(), aPos.Y(), 1, 1);
             css::uno::Reference<css::awt::XWindowPeer> 
xParent(aEvent.SourceWindow, css::uno::UNO_QUERY);
-            xPopupMenu->execute(xParent, css::awt::Rectangle(aPos.X(), 
aPos.Y(), 1, 1), css::awt::PopupMenuDirection::EXECUTE_DOWN);
+            css::uno::Reference<css::awt::XPopupMenuAsync> 
xAsyncPopup(xPopupMenu, css::uno::UNO_QUERY);
+            pFin = new SfxDispatcherPopupFinish(xPopupController, rCloseFunc, 
xPopupMenu);
+            if (!rCloseFunc || !xAsyncPopup.is() || 
!xAsyncPopup->popup(xParent, aRect, nFlags, pFin->m_xDialogListener))
+            {
+                delete pFin;
+                pFin = nullptr;
+                xPopupMenu->execute(xParent, aRect, nFlags);
+            }
         }
     }
 
-    css::uno::Reference< css::lang::XComponent > xComponent( xPopupController, 
css::uno::UNO_QUERY );
-    if ( xComponent.is() )
-        xComponent->dispose();
+    if (!pFin)
+        lcl_FinishPopupDispatch(xPopupController);
 }
 
 /** With this method the SfxDispatcher can be locked and released. A locked
diff --git a/sw/source/uibase/docvw/edtwin.cxx 
b/sw/source/uibase/docvw/edtwin.cxx
index 859c35664fea..f6bf6da313e3 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -5427,7 +5427,7 @@ void SwEditWin::Command( const CommandEvent& rCEvt )
                         }
                     }
                     else if ( !m_rView.ExecSpellPopup( aDocPos ) )
-                        SfxDispatcher::ExecutePopup(this, &aPixPos);
+                        SfxDispatcher::ExecutePopup(this, &aPixPos, 
[](sal_Int16){});
                 }
                 else if (m_pApplyTempl->nUndo < 
rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount())
                 {
diff --git a/toolkit/inc/helper/unowrapper.hxx 
b/toolkit/inc/helper/unowrapper.hxx
index 03a9b525cc18..fdc65988bb62 100644
--- a/toolkit/inc/helper/unowrapper.hxx
+++ b/toolkit/inc/helper/unowrapper.hxx
@@ -56,7 +56,7 @@ public:
     virtual VclPtr<vcl::Window> GetWindow(const 
css::uno::Reference<css::awt::XWindow>& rxWindow) override;
 
     // Menu
-    virtual css::uno::Reference<css::awt::XPopupMenu> CreateMenuInterface( 
PopupMenu* pPopupMenu ) override;
+    virtual css::uno::Reference<css::awt::XPopupMenu> 
CreateMenuInterface(PopupMenu* pPopupMenu) override;
 
     void                WindowDestroyed( vcl::Window* pWindow ) override;
 
diff --git a/toolkit/source/awt/vclxmenu.cxx b/toolkit/source/awt/vclxmenu.cxx
index cbeb1ef7f810..a13ced69163a 100644
--- a/toolkit/source/awt/vclxmenu.cxx
+++ b/toolkit/source/awt/vclxmenu.cxx
@@ -37,6 +37,7 @@
 #include <vcl/window.hxx>
 
 #include <com/sun/star/awt/KeyModifier.hpp>
+#include <com/sun/star/ui/dialogs/DialogClosedEvent.hpp>
 
 VCLXMenu::VCLXMenu()
     : maMenuListeners( *this )
@@ -492,6 +493,33 @@ sal_Int16 VCLXMenu::execute(
                 static_cast<PopupMenuFlags>(nFlags) | 
PopupMenuFlags::NoMouseUpClose );
 }
 
+sal_Bool VCLXMenu::popup(
+    const css::uno::Reference< css::awt::XWindowPeer >& rxWindowPeer,
+    const css::awt::Rectangle& rPos, sal_Int16 nFlags,
+    const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>& 
xListener)
+{
+    SolarMutexGuard aSolarGuard;
+    std::unique_lock aGuard( maMutex );
+
+    if (!mpMenu || !IsPopupMenu())
+        return false;
+
+    return 
static_cast<PopupMenu*>(mpMenu.get())->Popup(VCLUnoHelper::GetWindow(rxWindowPeer),
+                                   VCLRectangle(rPos), xListener.is() ? 
xListener : this,
+                                   static_cast<PopupMenuFlags>(nFlags) | 
PopupMenuFlags::NoMouseUpClose);
+}
+
+void SAL_CALL VCLXMenu::dialogClosed(const 
css::ui::dialogs::DialogClosedEvent&)
+{
+    SolarMutexGuard aSolarGuard;
+    std::unique_lock aGuard( maMutex );
+
+    assert(mpMenu && IsPopupMenu());
+    if (mpMenu && IsPopupMenu())
+        static_cast<PopupMenu*>(mpMenu.get())->Finish();
+}
+
+void SAL_CALL VCLXMenu::disposing(css::lang::EventObject const&) {}
 
 void SAL_CALL VCLXMenu::setCommand(
     sal_Int16 nItemId,
diff --git a/toolkit/source/helper/unowrapper.cxx 
b/toolkit/source/helper/unowrapper.cxx
index 5d5ce94a9b8f..b73ad471f0d1 100644
--- a/toolkit/source/helper/unowrapper.cxx
+++ b/toolkit/source/helper/unowrapper.cxx
@@ -191,7 +191,7 @@ void UnoWrapper::SetWindowInterface( vcl::Window* pWindow, 
const css::uno::Refer
     }
 }
 
-css::uno::Reference<css::awt::XPopupMenu> UnoWrapper::CreateMenuInterface( 
PopupMenu* pPopupMenu )
+css::uno::Reference<css::awt::XPopupMenu> 
UnoWrapper::CreateMenuInterface(PopupMenu* pPopupMenu)
 {
     return new VCLXPopupMenu(pPopupMenu);
 }
diff --git a/vcl/inc/osx/salmenu.h b/vcl/inc/osx/salmenu.h
index 597180cc1ac3..dae1a1035cae 100644
--- a/vcl/inc/osx/salmenu.h
+++ b/vcl/inc/osx/salmenu.h
@@ -67,7 +67,9 @@ public:
     virtual void SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const 
Image& rImage) override;
     virtual void SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, 
const vcl::KeyCode& rKeyCode, const OUString& rKeyName ) override;
     virtual void GetSystemMenuData( SystemMenuData* pData ) override;
-    virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const 
tools::Rectangle& rRect, FloatWinPopupFlags nFlags) override;
+    virtual bool ShowNativePopupMenu(
+        FloatingWindow*, const tools::Rectangle&, FloatWinPopupFlags,
+        const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* = 
nullptr) override;
     virtual bool AddMenuBarButton( const SalMenuButtonItem& ) override;
     virtual void RemoveMenuBarButton( sal_uInt16 nId ) override;
     virtual tools::Rectangle GetMenuBarButtonRectPixel( sal_uInt16 i_nItemId, 
SalFrame* i_pReferenceFrame ) override;
diff --git a/vcl/inc/qt5/QtMenu.hxx b/vcl/inc/qt5/QtMenu.hxx
index 55275ae6e099..738c98e336a3 100644
--- a/vcl/inc/qt5/QtMenu.hxx
+++ b/vcl/inc/qt5/QtMenu.hxx
@@ -38,7 +38,7 @@ class QtFrame;
 class QtMenu : public QObject, public SalMenu
 {
     Q_OBJECT
-private:
+
     std::vector<QtMenuItem*> maItems;
     VclPtr<Menu> mpVCLMenu;
     QtMenu* mpParentSalMenu;
@@ -52,6 +52,9 @@ private:
     QPushButton* mpCloseButton;
     QMetaObject::Connection maCloseButtonConnection;
 
+    css::uno::Reference<css::ui::dialogs::XDialogClosedListener> m_xListener;
+    FloatingWindow* m_pWin;
+
     void DoFullMenuUpdate(Menu* pMenuBar);
     static void NativeItemText(OUString& rItemText);
 
@@ -72,8 +75,9 @@ public:
     virtual void SetFrame(const SalFrame* pFrame) override;
     const QtFrame* GetFrame() const;
     virtual void ShowMenuBar(bool bVisible) override;
-    virtual bool ShowNativePopupMenu(FloatingWindow* pWin, const 
tools::Rectangle& rRect,
-                                     FloatWinPopupFlags nFlags) override;
+    virtual bool ShowNativePopupMenu(
+        FloatingWindow*, const tools::Rectangle&, FloatWinPopupFlags,
+        const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* = 
nullptr) override;
     QtMenu* GetTopLevel();
     virtual void SetItemBits(unsigned nPos, MenuItemBits nBits) override;
     virtual void CheckItem(unsigned nPos, bool bCheck) override;
diff --git a/vcl/inc/salmenu.hxx b/vcl/inc/salmenu.hxx
index c696503549e6..60840a020460 100644
--- a/vcl/inc/salmenu.hxx
+++ b/vcl/inc/salmenu.hxx
@@ -22,6 +22,7 @@
 
 #include <vcl/menu.hxx>
 #include <vcl/image.hxx>
+#include <com/sun/star/ui/dialogs/XDialogClosedListener.hpp>
 
 struct SystemMenuData;
 class FloatingWindow;
@@ -75,7 +76,17 @@ public:
     virtual void SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const 
Image& rImage ) = 0;
     virtual void SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, 
const vcl::KeyCode& rKeyCode, const OUString& rKeyName ) = 0;
     virtual void GetSystemMenuData( SystemMenuData* pData ) = 0;
-    virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const 
tools::Rectangle& rRect, FloatWinPopupFlags nFlags);
+    /**
+     * @param pListener
+     *     if !nullptr, the menu is supposed to be only shown and it'll run 
async.
+     *     Mainly means, when the menu is hidden, it must call the listener's
+     *     dialogClosed. The listener will destroy the SalMenu!
+     *
+     * @return
+     *     true, if the feature is implemented and was successful.
+     */
+    virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const 
tools::Rectangle& rRect, FloatWinPopupFlags nFlags,
+                                     const 
css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* pListener = 
nullptr);
     virtual void ShowCloseButton(bool bShow);
     virtual bool AddMenuBarButton( const SalMenuButtonItem& ); // return false 
if not implemented or failure
     virtual void RemoveMenuBarButton( sal_uInt16 nId );
diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
index 85c0f5d3d893..5d5a487df8f1 100644
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
@@ -132,7 +132,8 @@ public:
 #endif
     void ReturnFocus();
 
-    virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const 
tools::Rectangle& rRect, FloatWinPopupFlags nFlags) override;
+    virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const 
tools::Rectangle& rRect, FloatWinPopupFlags nFlags,
+                                     const 
css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* = nullptr) 
override;
     virtual void ShowCloseButton(bool bShow) override;
     virtual bool AddMenuBarButton( const SalMenuButtonItem& rNewItem ) 
override;
     virtual void RemoveMenuBarButton( sal_uInt16 nId ) override;
diff --git a/vcl/osx/salmenu.cxx b/vcl/osx/salmenu.cxx
index 3164ba873bae..0a91ab88cc36 100644
--- a/vcl/osx/salmenu.cxx
+++ b/vcl/osx/salmenu.cxx
@@ -281,8 +281,13 @@ AquaSalMenu::~AquaSalMenu()
     }
 }
 
-bool AquaSalMenu::ShowNativePopupMenu(FloatingWindow * pWin, const 
tools::Rectangle& rRect, FloatWinPopupFlags nFlags)
+bool AquaSalMenu::ShowNativePopupMenu(
+    FloatingWindow* pWin, const tools::Rectangle& rRect, FloatWinPopupFlags 
nFlags,
+    const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* 
pListener)
 {
+    if (pListener)
+        return false;
+
     // set offsets for positioning
     const float offset = 9.0;
 
diff --git a/vcl/qt5/QtMenu.cxx b/vcl/qt5/QtMenu.cxx
index d9279fb9389a..b2d050291084 100644
--- a/vcl/qt5/QtMenu.cxx
+++ b/vcl/qt5/QtMenu.cxx
@@ -93,6 +93,16 @@ void QtMenu::InsertMenuItem(QtMenuItem* pSalMenuItem, 
unsigned nPos)
             // no QMenu set, instantiate own one
             mpOwnedQMenu.reset(new QMenu);
             mpQMenu = mpOwnedQMenu.get();
+
+            connect(mpQMenu, &QMenu::aboutToHide, this, [this] {
+                if (m_pWin && m_xListener.is())
+                {
+                    QMenu* pMenu = mpOwnedQMenu.release();
+                    css::ui::dialogs::DialogClosedEvent 
aEvent(m_pWin->GetComponentInterface(), 0);
+                    m_xListener->dialogClosed(aEvent);
+                    pMenu->deleteLater();
+                }
+            });
         }
 
         if (pSalMenuItem->mpSubMenu)
@@ -672,15 +682,27 @@ void QtMenu::ShowCloseButton(bool bShow)
         pButton->hide();
 }
 
-bool QtMenu::ShowNativePopupMenu(FloatingWindow*, const tools::Rectangle&,
-                                 FloatWinPopupFlags nFlags)
+bool QtMenu::ShowNativePopupMenu(
+    FloatingWindow* pWin, const tools::Rectangle&, FloatWinPopupFlags nFlags,
+    const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* 
pListener)
 {
     assert(mpQMenu);
     DoFullMenuUpdate(mpVCLMenu);
     mpQMenu->setTearOffEnabled(bool(nFlags & 
FloatWinPopupFlags::AllowTearOff));
 
     const QPoint aPos = QCursor::pos();
-    mpQMenu->exec(aPos);
+    if (pListener)
+    {
+        m_xListener = *pListener;
+        m_pWin = pWin;
+        mpQMenu->popup(aPos);
+    }
+    else
+    {
+        m_xListener = nullptr;
+        m_pWin = nullptr;
+        mpQMenu->exec(aPos);
+    }
 
     return true;
 }
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index e19d055b8253..2362838a1396 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -176,7 +176,9 @@ SalObject::~SalObject() {}
 
 SalMenu::~SalMenu() {}
 
-bool SalMenu::ShowNativePopupMenu(FloatingWindow*, const tools::Rectangle&, 
FloatWinPopupFlags)
+bool SalMenu::ShowNativePopupMenu(
+    FloatingWindow*, const tools::Rectangle&, FloatWinPopupFlags,
+    const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>*)
 {
     return false;
 }
diff --git a/vcl/source/control/managedmenubutton.cxx 
b/vcl/source/control/managedmenubutton.cxx
index 880730721ce2..f671cdd9c695 100644
--- a/vcl/source/control/managedmenubutton.cxx
+++ b/vcl/source/control/managedmenubutton.cxx
@@ -13,6 +13,7 @@
 #include <managedmenubutton.hxx>
 #include <vcl/menu.hxx>
 
+#include <com/sun/star/awt/XPopupMenuAsync.hpp>
 #include <com/sun/star/frame/ModuleManager.hpp>
 #include <com/sun/star/frame/theDesktop.hpp>
 #include <com/sun/star/frame/thePopupMenuControllerFactory.hpp>
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index 2fd136429061..f7055dbf92f4 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -2657,6 +2657,7 @@ MenuFloatingWindow * PopupMenu::ImplGetFloatingWindow() 
const {
 }
 
 PopupMenu::PopupMenu()
+    : m_pState(nullptr)
 {
     mpSalMenu = ImplGetSVData()->mpDefInst->CreateMenu(false, this);
 }
@@ -2669,6 +2670,7 @@ PopupMenu::PopupMenu( const PopupMenu& rMenu )
 
 PopupMenu::~PopupMenu()
 {
+    assert(!m_pState);
     disposeOnce();
 }
 
@@ -2766,6 +2768,36 @@ sal_uInt16 PopupMenu::Execute( vcl::Window* pExecWindow, 
const tools::Rectangle&
     return ImplExecute( pExecWindow, rRect, lcl_TranslateFlags(nFlags), 
nullptr, false );
 }
 
+struct PopupMenuFinishState final
+{
+    VclPtr<PopupMenu> pSelf;
+    VclPtr<vcl::Window> pParentWin;
+    VclPtr<MenuFloatingWindow> pWin;
+    bool bRealExecute;
+    bool bIsNativeMenu;
+
+    void clean()
+    {
+        pWin = nullptr;
+        pParentWin = nullptr;
+        pSelf = nullptr;
+    }
+};
+
+bool PopupMenu::Popup(vcl::Window* pExecWindow, const Point& rPopupPos,
+                            const 
css::uno::Reference<css::ui::dialogs::XDialogClosedListener>& listener)
+{
+    return Popup(pExecWindow, tools::Rectangle(rPopupPos, rPopupPos), 
listener, PopupMenuFlags::ExecuteDown);
+}
+
+bool PopupMenu::Popup(vcl::Window* pExecWindow, const tools::Rectangle& rRect,
+                      const 
css::uno::Reference<css::ui::dialogs::XDialogClosedListener>& listener, 
PopupMenuFlags nFlags)
+{
+    assert(!m_pState);
+    ENSURE_OR_RETURN(pExecWindow, "PopupMenu::Popup: need a non-NULL window!", 
false);
+    return ImplPopup(pExecWindow, rRect, lcl_TranslateFlags(nFlags), nullptr, 
false, listener);
+}
+
 void PopupMenu::ImplFlushPendingSelect()
 {
     // is there still Select?
@@ -2917,7 +2949,7 @@ bool PopupMenu::PrepareRun(const VclPtr<vcl::Window>& 
pParentWin, tools::Rectang
     if (pStartedFrom && pStartedFrom->IsMenuBar())
         nMaxHeight -= pParentWin->GetSizePixel().Height();
     sal_Int32 nLeft, nTop, nRight, nBottom;
-    pWindow->GetBorder( nLeft, nTop, nRight, nBottom );
+    pWindow->GetBorder(nLeft, nTop, nRight, nBottom);
     nMaxHeight -= nTop+nBottom;
     if ( aSz.Height() > nMaxHeight )
     {
@@ -2933,10 +2965,11 @@ bool PopupMenu::PrepareRun(const VclPtr<vcl::Window>& 
pParentWin, tools::Rectang
 }
 
 bool PopupMenu::Run(const VclPtr<MenuFloatingWindow>& pWin, const bool 
bRealExecute, const bool bPreSelectFirst,
-                    const FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, 
const tools::Rectangle& rRect)
+                    const FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, 
const tools::Rectangle& rRect,
+                    const 
css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* xListener)
 {
     SalMenu* pMenu = ImplGetSalMenu();
-    if (pMenu && bRealExecute && pMenu->ShowNativePopupMenu(pWin, rRect, 
nPopupModeFlags))
+    if (pMenu && bRealExecute && pMenu->ShowNativePopupMenu(pWin, rRect, 
nPopupModeFlags, xListener))
         return true;
 
     pWin->StartPopupMode(rRect, nPopupModeFlags);
@@ -2972,7 +3005,12 @@ bool PopupMenu::Run(const VclPtr<MenuFloatingWindow>& 
pWin, const bool bRealExec
     }
 
     if (bRealExecute)
-        pWin->Execute();
+    {
+        if (!xListener)
+            pWin->Execute();
+        else
+            pWin->Popup(*xListener);
+    }
 
     return false;
 }
@@ -3017,11 +3055,42 @@ sal_uInt16 PopupMenu::ImplExecute(const 
VclPtr<vcl::Window>& pParentWin, const t
     VclPtr<MenuFloatingWindow> pWin;
     if (!PrepareRun(pParentWin, aRect, nPopupModeFlags, pSFrom, bRealExecute, 
pWin))
         return 0;
-    const bool bNative = Run(pWin, bRealExecute, bPreSelectFirst, 
nPopupModeFlags, pSFrom, aRect);
+    const bool bNative = Run(pWin, bRealExecute, bPreSelectFirst, 
nPopupModeFlags, pSFrom, aRect, nullptr);
     FinishRun(pWin, pParentWin, bRealExecute, bNative);
     return nSelectedId;
 }
 
+bool PopupMenu::ImplPopup(const VclPtr<vcl::Window>& pParentWin, const 
tools::Rectangle& rRect,
+                          FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, 
bool bPreSelectFirst,
+                          const 
css::uno::Reference<css::ui::dialogs::XDialogClosedListener>& xListener)
+{
+    // tdf#126054 hold this until after function completes
+    VclPtr<PopupMenu> xThis(this);
+    bool bRealExecute = false;
+    tools::Rectangle aRect(rRect);
+    VclPtr<MenuFloatingWindow> pWin;
+    if (!PrepareRun(pParentWin, aRect, nPopupModeFlags, pSFrom, bRealExecute, 
pWin))
+        return false;
+    assert(!m_pState);
+    m_pState = new PopupMenuFinishState;
+    m_pState->bIsNativeMenu = Run(pWin, bRealExecute, bPreSelectFirst, 
nPopupModeFlags, pSFrom, aRect, &xListener);
+    m_pState->pWin = pWin;
+    m_pState->pParentWin = pParentWin;
+    m_pState->bRealExecute = bRealExecute;
+    m_pState->pSelf = xThis;
+    return true;
+}
+
+void PopupMenu::Finish()
+{
+    if (!m_pState)
+        return;
+    FinishRun(m_pState->pWin, m_pState->pParentWin, m_pState->bRealExecute, 
m_pState->bIsNativeMenu);
+    m_pState->clean();
+    delete m_pState;
+    m_pState = nullptr;
+}
+
 sal_uInt16 PopupMenu::ImplCalcVisEntries( tools::Long nMaxHeight, sal_uInt16 
nStartEntry, sal_uInt16* pLastVisible ) const
 {
     nMaxHeight -= 2 * ImplGetFloatingWindow()->GetScrollerHeight();
diff --git a/vcl/source/window/menufloatingwindow.cxx 
b/vcl/source/window/menufloatingwindow.cxx
index cfd6a6ae190e..075fb97f5632 100644
--- a/vcl/source/window/menufloatingwindow.cxx
+++ b/vcl/source/window/menufloatingwindow.cxx
@@ -308,8 +308,15 @@ IMPL_LINK_NOARG(MenuFloatingWindow, PopupEnd, 
FloatingWindow*, void)
             pMenu->pStartedFrom->ClosePopup(pMenu);
     }
 
-    if ( pM )
+    if (pM)
+    {
         pM->pStartedFrom = nullptr;
+        if (m_xListener.is())
+        {
+            css::ui::dialogs::DialogClosedEvent 
aEvent(GetComponentInterface(), pM->GetCurItemId());
+            m_xListener->dialogClosed(aEvent);
+        }
+    }
 }
 
 IMPL_LINK_NOARG(MenuFloatingWindow, AutoScroll, Timer *, void)
@@ -443,21 +450,31 @@ void MenuFloatingWindow::End()
         Window::EndSaveFocus(xFocusId);
     }
 
+    Finish();
+
     bInExecute = false;
 }
 
-void MenuFloatingWindow::Execute()
+void MenuFloatingWindow::Popup(const 
css::uno::Reference<css::ui::dialogs::XDialogClosedListener>& xListener)
 {
     ImplSVData* pSVData = ImplGetSVData();
-
     pSVData->maAppData.mpActivePopupMenu = 
static_cast<PopupMenu*>(pMenu.get());
-
+    m_xListener = xListener;
     Start();
+}
 
+void MenuFloatingWindow::Finish()
+{
+    ImplSVData* pSVData = ImplGetSVData();
+    pSVData->maAppData.mpActivePopupMenu = nullptr;
+}
+
+void MenuFloatingWindow::Execute()
+{
+    Popup();
     while (bInExecute && !Application::IsQuit())
         Application::Yield();
-
-    pSVData->maAppData.mpActivePopupMenu = nullptr;
+    Finish();
 }
 
 void MenuFloatingWindow::StopExecute()
@@ -474,6 +491,7 @@ void MenuFloatingWindow::StopExecute()
     // notify parent, needed for accessibility
     if( pMenu && pMenu->pStartedFrom )
         pMenu->pStartedFrom->ImplCallEventListeners( 
VclEventId::MenuSubmenuDeactivate, nPosInParent );
+    Finish();
 }
 
 void MenuFloatingWindow::KillActivePopup( PopupMenu* pThisOnly )
@@ -502,6 +520,7 @@ void MenuFloatingWindow::KillActivePopup( PopupMenu* 
pThisOnly )
 
         PaintImmediately();
     }
+    pPopup->Finish();
 }
 
 void MenuFloatingWindow::EndExecute()
diff --git a/vcl/source/window/menufloatingwindow.hxx 
b/vcl/source/window/menufloatingwindow.hxx
index f26fb50373ca..b6c8b54738ce 100644
--- a/vcl/source/window/menufloatingwindow.hxx
+++ b/vcl/source/window/menufloatingwindow.hxx
@@ -46,6 +46,7 @@ private:
     sal_uInt16 nScrollerHeight;
     sal_uInt16 nFirstEntry;
     sal_uInt16 nPosInParent;
+    css::uno::Reference<css::ui::dialogs::XDialogClosedListener> m_xListener;
 
     bool bInExecute : 1;
     bool bScrollMenu : 1;
@@ -67,6 +68,7 @@ private:
 
     void Start();
     void End();
+    static void Finish();
 
 protected:
     vcl::Region ImplCalcClipRegion() const;
@@ -107,6 +109,8 @@ public:
     bool IsScrollMenu() const        { return bScrollMenu; }
     sal_uInt16 GetScrollerHeight() const   { return nScrollerHeight; }
 
+    void Popup(const 
css::uno::Reference<css::ui::dialogs::XDialogClosedListener>& xListener = 
nullptr);
+
     void Execute();
     void StopExecute();
     void EndExecute();
diff --git a/vcl/unx/gtk3/gtksalmenu.cxx b/vcl/unx/gtk3/gtksalmenu.cxx
index ac71e3390d87..0ccda0b66fb8 100644
--- a/vcl/unx/gtk3/gtksalmenu.cxx
+++ b/vcl/unx/gtk3/gtksalmenu.cxx
@@ -422,9 +422,13 @@ static void MenuClosed(GtkPopover* pWidget, GMainLoop* 
pLoop)
     g_main_loop_quit(pLoop);
 }
 
-bool GtkSalMenu::ShowNativePopupMenu(FloatingWindow* pWin, const 
tools::Rectangle& rRect,
-                                     FloatWinPopupFlags nFlags)
+bool GtkSalMenu::ShowNativePopupMenu
+    (FloatingWindow* pWin, const tools::Rectangle& rRect, FloatWinPopupFlags 
nFlags,
+     const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* 
pListener)
 {
+    if (pListener)
+        return false;
+
     VclPtr<vcl::Window> xParent = pWin->ImplGetWindowImpl()->mpRealParent;
     mpFrame = static_cast<GtkSalFrame*>(xParent->ImplGetFrame());
 
commit 7e3b66c48ff80aa9f415e007e580ec520ccc6b8f
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Sat Nov 20 15:06:35 2021 +0100
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Thu Jan 20 19:51:48 2022 +0100

    Refactor PopupMenu::ImplExecute for async support
    
    Splits ImplExecute into PrepareRun, Run and FinishRun.
    
    Change-Id: Ifddb1e968b468c9757eeece0bb19513cc26a9c8d

diff --git a/include/vcl/menu.hxx b/include/vcl/menu.hxx
index a6699a7e71d9..87108359dab1 100644
--- a/include/vcl/menu.hxx
+++ b/include/vcl/menu.hxx
@@ -493,7 +493,10 @@ class VCL_DLLPUBLIC PopupMenu final : public Menu
 
 private:
     SAL_DLLPRIVATE MenuFloatingWindow * ImplGetFloatingWindow() const;
-    SAL_DLLPRIVATE sal_uInt16 ImplExecute( const VclPtr<vcl::Window>& pW, 
const tools::Rectangle& rRect, FloatWinPopupFlags nPopupModeFlags, Menu* 
pSFrom, bool bPreSelectFirst );
+    SAL_DLLPRIVATE bool PrepareRun(const VclPtr<vcl::Window>& pParentWin, 
tools::Rectangle& rRect, FloatWinPopupFlags& nPopupModeFlags, Menu* pSFrom, 
bool& bRealExecute, VclPtr<MenuFloatingWindow>&);
+    SAL_DLLPRIVATE bool Run(const VclPtr<MenuFloatingWindow>&, bool 
bRealExecute, bool bPreSelectFirst, FloatWinPopupFlags nPopupModeFlags, Menu* 
pSFrom, const tools::Rectangle& rRect);
+    SAL_DLLPRIVATE void FinishRun(const VclPtr<MenuFloatingWindow>&, const 
VclPtr<vcl::Window>& pParentWin, bool bRealExecute, bool bIsNativeMenu);
+    SAL_DLLPRIVATE sal_uInt16 ImplExecute(const VclPtr<vcl::Window>& 
pParentWin, const tools::Rectangle& rRect, FloatWinPopupFlags nPopupModeFlags, 
Menu* pSFrom, bool bPreSelectFirst);
     SAL_DLLPRIVATE void ImplFlushPendingSelect();
     SAL_DLLPRIVATE tools::Long ImplCalcHeight( sal_uInt16 nEntries ) const;
     SAL_DLLPRIVATE sal_uInt16 ImplCalcVisEntries( tools::Long nMaxHeight, 
sal_uInt16 nStartEntry, sal_uInt16* pLastVisible = nullptr ) const;
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index 6af85523f8a1..2fd136429061 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -2742,10 +2742,8 @@ sal_uInt16 PopupMenu::Execute( vcl::Window* pExecWindow, 
const Point& rPopupPos
     return Execute( pExecWindow, tools::Rectangle( rPopupPos, rPopupPos ), 
PopupMenuFlags::ExecuteDown );
 }
 
-sal_uInt16 PopupMenu::Execute( vcl::Window* pExecWindow, const 
tools::Rectangle& rRect, PopupMenuFlags nFlags )
+static FloatWinPopupFlags lcl_TranslateFlags(PopupMenuFlags nFlags)
 {
-    ENSURE_OR_RETURN( pExecWindow, "PopupMenu::Execute: need a non-NULL 
window!", 0 );
-
     FloatWinPopupFlags nPopupModeFlags = FloatWinPopupFlags::NONE;
     if ( nFlags & PopupMenuFlags::ExecuteDown )
         nPopupModeFlags = FloatWinPopupFlags::Down;
@@ -2759,7 +2757,13 @@ sal_uInt16 PopupMenu::Execute( vcl::Window* pExecWindow, 
const tools::Rectangle&
     if (nFlags & PopupMenuFlags::NoMouseUpClose )                      // 
allow popup menus to stay open on mouse button up
         nPopupModeFlags |= FloatWinPopupFlags::NoMouseUpClose;    // useful if 
the menu was opened on mousebutton down (eg toolbox configuration)
 
-    return ImplExecute( pExecWindow, rRect, nPopupModeFlags, nullptr, false );
+    return nPopupModeFlags;
+}
+
+sal_uInt16 PopupMenu::Execute( vcl::Window* pExecWindow, const 
tools::Rectangle& rRect, PopupMenuFlags nFlags )
+{
+    ENSURE_OR_RETURN( pExecWindow, "PopupMenu::Execute: need a non-NULL 
window!", 0 );
+    return ImplExecute( pExecWindow, rRect, lcl_TranslateFlags(nFlags), 
nullptr, false );
 }
 
 void PopupMenu::ImplFlushPendingSelect()
@@ -2775,10 +2779,14 @@ void PopupMenu::ImplFlushPendingSelect()
     }
 }
 
-sal_uInt16 PopupMenu::ImplExecute( const VclPtr<vcl::Window>& pW, const 
tools::Rectangle& rRect, FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, bool 
bPreSelectFirst )
+bool PopupMenu::PrepareRun(const VclPtr<vcl::Window>& pParentWin, 
tools::Rectangle& rRect,
+                           FloatWinPopupFlags& nPopupModeFlags, Menu* pSFrom,
+                           bool& bRealExecute, VclPtr<MenuFloatingWindow>& 
pWin)
 {
-    if ( !pSFrom && ( vcl::IsInPopupMenuExecute() || !GetItemCount() ) )
-        return 0;
+    bRealExecute = false;
+    const sal_uInt16 nItemCount = GetItemCount();
+    if (!pSFrom && (vcl::IsInPopupMenuExecute() || !nItemCount))
+        return false;
 
     mpLayoutData.reset();
 
@@ -2790,7 +2798,6 @@ sal_uInt16 PopupMenu::ImplExecute( const 
VclPtr<vcl::Window>& pW, const tools::R
     bCanceled = false;
 
     VclPtr<vcl::Window> xFocusId;
-    bool bRealExecute = false;
     if ( !pStartedFrom )
     {
         pSVData->mpWinData->mbNoDeactivate = true;
@@ -2806,25 +2813,24 @@ sal_uInt16 PopupMenu::ImplExecute( const 
VclPtr<vcl::Window>& pW, const tools::R
     }
 
     SAL_WARN_IF( ImplGetWindow(), "vcl", "Win?!" );
-    tools::Rectangle aRect( rRect );
-    aRect.SetPos( pW->OutputToScreenPixel( aRect.TopLeft() ) );
+    rRect.SetPos(pParentWin->OutputToScreenPixel(rRect.TopLeft()));
 
+    nPopupModeFlags |= FloatWinPopupFlags::NoKeyClose | 
FloatWinPopupFlags::AllMouseButtonClose | FloatWinPopupFlags::GrabFocus;
     if (bRealExecute)
         nPopupModeFlags |= FloatWinPopupFlags::NewLevel;
-    nPopupModeFlags |= FloatWinPopupFlags::NoKeyClose | 
FloatWinPopupFlags::AllMouseButtonClose;
 
     bInCallback = true; // set it here, if Activate overridden
     Activate();
     bInCallback = false;
 
-    if ( pW->isDisposed() )
-        return 0;   // Error
+    if (pParentWin->isDisposed())
+        return false;
 
     if ( bCanceled || bKilled )
-        return 0;
+        return false;
 
-    if ( !GetItemCount() )
-        return 0;
+    if (!nItemCount)
+        return false;
 
     // The flag MenuFlags::HideDisabledEntries is inherited.
     if ( pSFrom )
@@ -2854,10 +2860,10 @@ sal_uInt16 PopupMenu::ImplExecute( const 
VclPtr<vcl::Window>& pW, const tools::R
         ImplCallEventListeners(VclEventId::MenuSubmenuChanged, nPos);
     }
 
-    VclPtrInstance<MenuFloatingWindow> pWin( this, pW, WB_BORDER | 
WB_SYSTEMWINDOW );
+    pWin = VclPtrInstance<MenuFloatingWindow>(this, pParentWin, WB_BORDER | 
WB_SYSTEMWINDOW);
     if (comphelper::LibreOfficeKit::isActive() && get_id() == 
"editviewspellmenu")
     {
-        VclPtr<vcl::Window> xNotifierParent = pW->GetParentWithLOKNotifier();
+        VclPtr<vcl::Window> xNotifierParent = 
pParentWin->GetParentWithLOKNotifier();
         assert(xNotifierParent && xNotifierParent->GetLOKNotifier() && 
"editview menu without LOKNotifier");
         pWin->SetLOKNotifier(xNotifierParent->GetLOKNotifier());
     }
@@ -2876,9 +2882,9 @@ sal_uInt16 PopupMenu::ImplExecute( const 
VclPtr<vcl::Window>& pW, const tools::R
         vcl::Window* pDeskW = pWindow->GetWindow( GetWindowType::RealParent );
         if( ! pDeskW )
             pDeskW = pWindow;
-        Point aDesktopTL( pDeskW->OutputToAbsoluteScreenPixel( aRect.TopLeft() 
) );
+        Point aDesktopTL(pDeskW->OutputToAbsoluteScreenPixel(rRect.TopLeft()));
         aDesktopRect = Application::GetScreenPosSizePixel(
-            Application::GetBestScreen( tools::Rectangle( aDesktopTL, 
aRect.GetSize() ) ));
+            Application::GetBestScreen(tools::Rectangle(aDesktopTL, 
rRect.GetSize())));
     }
 
     tools::Long nMaxHeight = aDesktopRect.GetHeight();
@@ -2893,8 +2899,8 @@ sal_uInt16 PopupMenu::ImplExecute( const 
VclPtr<vcl::Window>& pW, const tools::R
         if ( pRef->GetParent() )
             pRef = pRef->GetParent();
 
-        tools::Rectangle devRect(  pRef->OutputToAbsoluteScreenPixel( 
aRect.TopLeft() ),
-                            pRef->OutputToAbsoluteScreenPixel( 
aRect.BottomRight() ) );
+        tools::Rectangle 
devRect(pRef->OutputToAbsoluteScreenPixel(rRect.TopLeft()),
+                                 
pRef->OutputToAbsoluteScreenPixel(rRect.BottomRight()));
 
         tools::Long nHeightAbove = devRect.Top() - aDesktopRect.Top();
         tools::Long nHeightBelow = aDesktopRect.Bottom() - devRect.Bottom();
@@ -2909,7 +2915,7 @@ sal_uInt16 PopupMenu::ImplExecute( const 
VclPtr<vcl::Window>& pW, const tools::R
     nMaxHeight = std::max(nMaxHeight, tools::Long(768));
 
     if (pStartedFrom && pStartedFrom->IsMenuBar())
-        nMaxHeight -= pW->GetSizePixel().Height();
+        nMaxHeight -= pParentWin->GetSizePixel().Height();
     sal_Int32 nLeft, nTop, nRight, nBottom;
     pWindow->GetBorder( nLeft, nTop, nRight, nBottom );
     nMaxHeight -= nTop+nBottom;
@@ -2921,43 +2927,34 @@ sal_uInt16 PopupMenu::ImplExecute( const 
VclPtr<vcl::Window>& pW, const tools::R
         aSz.setHeight( ImplCalcHeight( nEntries ) );
     }
 
-    // tdf#126054 hold this until after function completes
-    VclPtr<PopupMenu> xThis(this);
-
     pWin->SetFocusId( xFocusId );
     pWin->SetOutputSizePixel( aSz );
-    if ( GetItemCount() )
+    return true;
+}
+
+bool PopupMenu::Run(const VclPtr<MenuFloatingWindow>& pWin, const bool 
bRealExecute, const bool bPreSelectFirst,
+                    const FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, 
const tools::Rectangle& rRect)
+{
+    SalMenu* pMenu = ImplGetSalMenu();
+    if (pMenu && bRealExecute && pMenu->ShowNativePopupMenu(pWin, rRect, 
nPopupModeFlags))
+        return true;
+
+    pWin->StartPopupMode(rRect, nPopupModeFlags);
+    if (pSFrom)
     {
-        SalMenu* pMenu = ImplGetSalMenu();
-        if( pMenu && bRealExecute && pMenu->ShowNativePopupMenu( pWin, aRect, 
nPopupModeFlags | FloatWinPopupFlags::GrabFocus ) )
-        {
-            pWin->StopExecute();
-            pWin->doShutdown();
-            pWindow.disposeAndClear();
-            ImplClosePopupToolBox(pW);
-            ImplFlushPendingSelect();
-            return nSelectedId;
-        }
+        sal_uInt16 aPos;
+        if (pSFrom->IsMenuBar())
+            aPos = static_cast<MenuBarWindow 
*>(pSFrom->pWindow.get())->GetHighlightedItem();
         else
-        {
-            pWin->StartPopupMode( aRect, nPopupModeFlags | 
FloatWinPopupFlags::GrabFocus );
-        }
-        if( pSFrom )
-        {
-            sal_uInt16 aPos;
-            if (pSFrom->IsMenuBar())
-                aPos = static_cast<MenuBarWindow 
*>(pSFrom->pWindow.get())->GetHighlightedItem();
-            else
-                aPos = static_cast<MenuFloatingWindow 
*>(pSFrom->pWindow.get())->GetHighlightedItem();
+            aPos = static_cast<MenuFloatingWindow 
*>(pSFrom->pWindow.get())->GetHighlightedItem();
 
-            pWin->SetPosInParent( aPos );  // store position to be sent in 
SUBMENUDEACTIVATE
-            pSFrom->ImplCallEventListeners( VclEventId::MenuSubmenuActivate, 
aPos );
-        }
+        pWin->SetPosInParent(aPos);  // store position to be sent in 
SUBMENUDEACTIVATE
+        pSFrom->ImplCallEventListeners(VclEventId::MenuSubmenuActivate, aPos);
     }
+
     if ( bPreSelectFirst )
     {
-        size_t nCount = pItemList->size();
-        for ( size_t n = 0; n < nCount; n++ )
+        for (size_t n = 0; n < static_cast<size_t>(GetItemCount()); n++)
         {
             MenuItemData* pData = pItemList->GetDataFromPos( n );
             if (  (  pData->bEnabled
@@ -2968,22 +2965,30 @@ sal_uInt16 PopupMenu::ImplExecute( const 
VclPtr<vcl::Window>& pW, const tools::R
                && ImplIsSelectable( n )
                )
             {
-                pWin->ChangeHighlightItem( n, false );
+                pWin->ChangeHighlightItem(n, false);
                 break;
             }
         }
     }
-    if ( bRealExecute )
-    {
+
+    if (bRealExecute)
         pWin->Execute();
-        if (pWin->isDisposed())
-            return 0;
 
-        xFocusId = pWin->GetFocusId();
+    return false;
+}
+
+void PopupMenu::FinishRun(const VclPtr<MenuFloatingWindow>& pWin, const 
VclPtr<vcl::Window>& pParentWin, const bool bRealExecute, const bool 
bIsNativeMenu)
+{
+    if (!bRealExecute || pWin->isDisposed())
+        return;
+
+    if (!bIsNativeMenu)
+    {
+        VclPtr<vcl::Window> xFocusId = pWin->GetFocusId();
         assert(xFocusId == nullptr && "Focus should already be restored by 
MenuFloatingWindow::End");
         pWin->ImplEndPopupMode(FloatWinPopupEndFlags::NONE, xFocusId);
 
-        if ( nSelectedId )  // then clean up .. ( otherwise done by TH )
+        if (nSelectedId)  // then clean up .. ( otherwise done by TH )
         {
             PopupMenu* pSub = pWin->GetActivePopup();
             while ( pSub )
@@ -2992,13 +2997,29 @@ sal_uInt16 PopupMenu::ImplExecute( const 
VclPtr<vcl::Window>& pW, const tools::R
                 pSub = pSub->ImplGetFloatingWindow()->GetActivePopup();
             }
         }
-        pWin->doShutdown();
-        pWindow.disposeAndClear();
-        ImplClosePopupToolBox(pW);
-        ImplFlushPendingSelect();
     }
+    else
+        pWin->StopExecute();
 
-    return bRealExecute ? nSelectedId : 0;
+    pWin->doShutdown();
+    pWindow.disposeAndClear();
+    ImplClosePopupToolBox(pParentWin);
+    ImplFlushPendingSelect();
+}
+
+sal_uInt16 PopupMenu::ImplExecute(const VclPtr<vcl::Window>& pParentWin, const 
tools::Rectangle& rRect,
+                                  FloatWinPopupFlags nPopupModeFlags, Menu* 
pSFrom, bool bPreSelectFirst)
+{
+    // tdf#126054 hold this until after function completes
+    VclPtr<PopupMenu> xThis(this);
+    bool bRealExecute = false;
+    tools::Rectangle aRect(rRect);
+    VclPtr<MenuFloatingWindow> pWin;
+    if (!PrepareRun(pParentWin, aRect, nPopupModeFlags, pSFrom, bRealExecute, 
pWin))
+        return 0;
+    const bool bNative = Run(pWin, bRealExecute, bPreSelectFirst, 
nPopupModeFlags, pSFrom, aRect);
+    FinishRun(pWin, pParentWin, bRealExecute, bNative);
+    return nSelectedId;
 }
 
 sal_uInt16 PopupMenu::ImplCalcVisEntries( tools::Long nMaxHeight, sal_uInt16 
nStartEntry, sal_uInt16* pLastVisible ) const
commit 49f7265efc8a1459498300b93ec899e572b1edc2
Author:     Thorsten Behrens <thorsten.behr...@allotropia.de>
AuthorDate: Sat Nov 13 23:12:58 2021 +0100
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Thu Jan 20 19:51:48 2022 +0100

    WASM default to notebookbar
    
    ..and use the full, desktop variant..
    
    Change-Id: Ib00aad8cd130b4a3433209c540fe82970c45c98e

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index e6771b6d08f7..ff5e2e12603d 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -6501,7 +6501,11 @@ static void activateNotebookbar(std::u16string_view rApp)
 
     if (aAppNode.isValid())
     {
+#ifdef EMSCRIPTEN
+        aAppNode.setNodeValue("Active", makeAny(OUString("notebookbar.ui")));
+#else
         aAppNode.setNodeValue("Active", 
makeAny(OUString("notebookbar_online.ui")));
+#endif
         aAppNode.commit();
     }
 }
@@ -6540,7 +6544,11 @@ static int lo_initialize(LibreOfficeKit* pThis, const 
char* pAppPath, const char
     static bool bPreInited = false;
     static bool bUnipoll = false;
     static bool bProfileZones = false;
+#ifdef EMSCRIPTEN
+    static bool bNotebookbar = true;
+#else
     static bool bNotebookbar = false;
+#endif
 
     { // cf. string lifetime for preinit
         std::vector<OUString> aOpts;
commit d778aa1d0ecc2127a4968fc4f88e9cbf5a8be451
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Mon Dec 6 09:24:50 2021 +0100
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Thu Jan 20 19:51:48 2022 +0100

    gbuild: build static unit tests
    
    While this generally works, the setup is not very practical. The
    unit tests become all very large, if they use components. The best
    static solution I can imagine is either just somehow linking them
    on demand, or create a single huge liblibreoffice.so, so keeping
    everthing almost static.
    
    Change-Id: If00f9ac3b3f63b915e3b5dcd931d233681a58006

diff --git a/Repository.mk b/Repository.mk
index 5c164d73729d..f0ce0774d756 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -32,7 +32,7 @@ $(eval $(call gb_Helper_register_executables,NONE, \
        cfgex \
        concat-deps \
        cpp \
-       cppunittester \
+    $(call gb_CondCppunitMainLibOrExe,,cppunittester) \
        gbuildtojson \
        $(if $(filter MSC,$(COM)), \
                gcc-wrapper \
@@ -580,6 +580,7 @@ $(eval $(call gb_Helper_register_libraries,PLAINLIBS_NONE, \
        $(if $(filter MSC,$(COM)),cli_cppuhelper) \
        $(if $(filter $(OS),ANDROID),lo-bootstrap) \
        $(if $(filter $(OS),MACOSX),OOoSpotlightImporter) \
+    $(call gb_CondCppunitMainLibOrExe,cppunitmain) \
 ))
 
 $(eval $(call gb_Helper_register_libraries_for_install,PLAINLIBS_URE,ure, \
diff --git a/sal/Library_cppunitmain.mk b/sal/Library_cppunitmain.mk
new file mode 100644
index 000000000000..07f51e0c4821
--- /dev/null
+++ b/sal/Library_cppunitmain.mk
@@ -0,0 +1,42 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,cppunitmain))
+
+$(eval $(call gb_Library_set_include,cppunitmain,\
+    $$(INCLUDE) \
+    -I$(SRCDIR)/sal/inc \
+))
+
+$(eval $(call gb_Library_use_libraries,cppunitmain,\
+    sal \
+    unoexceptionprotector \
+    unobootstrapprotector \
+    vclbootstrapprotector \
+))
+
+$(eval $(call gb_Library_use_externals,cppunitmain,\
+    boost_headers \
+    cppunit \
+))
+
+$(eval $(call gb_Library_add_exception_objects,cppunitmain,\
+    sal/cppunittester/cppunittester \
+))
+
+ifeq ($(COM),MSC)
+
+$(eval $(call gb_Library_add_ldflags,cppunitmain,\
+    /STACK:10000000 \
+))
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/sal/Module_sal.mk b/sal/Module_sal.mk
index e0448a5085bf..6c18d6282977 100644
--- a/sal/Module_sal.mk
+++ b/sal/Module_sal.mk
@@ -10,7 +10,7 @@
 $(eval $(call gb_Module_Module,sal))
 
 $(eval $(call gb_Module_add_targets,sal,\
-       $(if $(CROSS_COMPILING),,$(if $(filter 
TRUE,$(DISABLE_DYNLOADING)),,Executable_cppunittester)) \
+    $(call 
gb_CondCppunitMainLibOrExe,Library_cppunitmain,Executable_cppunittester) \
        $(if $(filter $(OS),ANDROID), \
                Library_lo-bootstrap) \
        Library_sal \
diff --git a/sal/cppunittester/cppunittester.cxx 
b/sal/cppunittester/cppunittester.cxx
index 5b886ea2189d..e1fcf84c255f 100644
--- a/sal/cppunittester/cppunittester.cxx
+++ b/sal/cppunittester/cppunittester.cxx
@@ -230,13 +230,17 @@ class CPPUNIT_API ProtectedFixtureFunctor
 {
 private:
     const std::string &testlib;
+#ifndef DISABLE_DYNLOADING
     const std::string &args;
+#endif
     std::vector<CppUnit::Protector *> &protectors;
     CppUnit::TestResult &result;
 public:
     ProtectedFixtureFunctor(const std::string& testlib_, const std::string 
&args_, std::vector<CppUnit::Protector*> &protectors_, CppUnit::TestResult 
&result_)
         : testlib(testlib_)
+#ifndef DISABLE_DYNLOADING
         , args(args_)
+#endif
         , protectors(protectors_)
         , result(result_)
     {
diff --git a/solenv/gbuild/Conditions.mk b/solenv/gbuild/Conditions.mk
index 0a7b88969557..4cb5688997e9 100644
--- a/solenv/gbuild/Conditions.mk
+++ b/solenv/gbuild/Conditions.mk
@@ -12,6 +12,10 @@
 # just end in two (!) braces, otherwise you may need to use either the $(1)
 # or the $(2) multiple times.
 
+define gb_CondCppunitMainLibOrExe
+$(if $(or $(CROSS_COMPILING),$(DISABLE_DYNLOADING)),$(1),$(2))
+endef
+
 define gb_CondExeLockfile
 $(if $(and $(filter-out ANDROID MACOSX iOS WNT,$(OS))),$(1),$(2))
 endef
diff --git a/solenv/gbuild/CppunitTest.mk b/solenv/gbuild/CppunitTest.mk
index 7fc1cd79c12d..eeba150d0275 100644
--- a/solenv/gbuild/CppunitTest.mk
+++ b/solenv/gbuild/CppunitTest.mk
@@ -21,6 +21,7 @@
 
 gb_CppunitTest_UNITTESTFAILED ?= 
$(GBUILDDIR)/platform/unittest-failed-default.sh
 gb_CppunitTest_PYTHONDEPS ?= $(call gb_Library_get_target,pyuno_wrapper) $(if 
$(SYSTEM_PYTHON),,$(call gb_Package_get_target,python3))
+gb_CppunitTest_KNOWN :=
 
 ifneq ($(strip $(CPPUNITTRACE)),)
 ifneq ($(filter gdb,$(CPPUNITTRACE)),)
@@ -70,8 +71,13 @@ endif
 
 # defined by platform
 #  gb_CppunitTest_get_filename
+ifeq (,$(DISABLE_DYNLOADING))
 gb_CppunitTest_RUNTIMEDEPS := $(call 
gb_Executable_get_runtime_dependencies,cppunittester)
 gb_CppunitTest_CPPTESTCOMMAND := $(call 
gb_Executable_get_target_for_build,cppunittester)
+else
+gb_CppunitTest_RUNTIMEDEPS :=
+gb_CppunitTest_CPPTESTCOMMAND :=
+endif
 
 # i18npool dlopens localedata_* libraries.
 gb_CppunitTest_RUNTIMEDEPS += \
@@ -198,6 +204,11 @@ $(call gb_CppunitTest_get_target,$(1)) : HEADLESS := 
--headless
 $(call gb_CppunitTest_get_target,$(1)) : EXTRA_ENV_VARS :=
 $$(eval $$(call gb_Module_register_target,$(call 
gb_CppunitTest_get_target,$(1)),$(call gb_CppunitTest_get_clean_target,$(1))))
 $(call gb_Helper_make_userfriendly_targets,$(1),CppunitTest)
+ifeq ($(DISABLE_DYNLOADING),TRUE)
+$$(eval $$(call gb_CppunitTest_use_libraries,$(1),cppunitmain))
+$$(eval $$(call gb_CppunitTest_add_defs,$(1),-D__EMSCRIPTEN__))
+endif
+$(if $(filter $(1),$(gb_CppunitTest_KNOWN)),,gb_CppunitTest_KNOWN += $(1))
 
 endef
 
diff --git a/solenv/gbuild/TargetLocations.mk b/solenv/gbuild/TargetLocations.mk
index 32d7eed72ec0..253e01acf5fd 100644
--- a/solenv/gbuild/TargetLocations.mk
+++ b/solenv/gbuild/TargetLocations.mk
@@ -53,6 +53,7 @@ gb_CompilerTest_get_target = $(WORKDIR)/CompilerTest/$(1)
 gb_ComponentTarget_get_target = $(WORKDIR)/ComponentTarget/$(1).component
 gb_ComponentTarget_get_target_for_build = 
$(WORKDIR_FOR_BUILD)/ComponentTarget/$(1).component
 gb_Configuration_get_preparation_target = 
$(WORKDIR)/Configuration/$(1).prepared
+gb_CppunitTest_get_linktargetfile = $(call gb_LinkTarget_get_target,$(call 
gb_CppunitTest_get_linktarget,$1))
 gb_CppunitTest_get_target = $(WORKDIR)/CppunitTest/$(1).test
 gb_CustomPackage_get_target = $(WORKDIR)/CustomPackage/$(1).filelist
 gb_CustomTarget_get_repo_target = $(WORKDIR)/CustomTarget/$(2)_$(1).done
diff --git a/solenv/gbuild/extensions/post_SpeedUpTargets.mk 
b/solenv/gbuild/extensions/post_SpeedUpTargets.mk
index 3db6355ab90d..6fcbe243a01f 100644
--- a/solenv/gbuild/extensions/post_SpeedUpTargets.mk
+++ b/solenv/gbuild/extensions/post_SpeedUpTargets.mk
@@ -52,7 +52,6 @@ endif
 
 endif
 
-
 ifneq (,$(filter build,$(gb_Module_SKIPTARGETS)))
 gb_Module_add_target =
 endif
diff --git a/solenv/gbuild/gbuild.mk b/solenv/gbuild/gbuild.mk
index dcfa05337843..7f7363ebb85c 100644
--- a/solenv/gbuild/gbuild.mk
+++ b/solenv/gbuild/gbuild.mk
@@ -283,6 +283,7 @@ gb_TEST_ENV_VARS += 
SAL_DISABLE_SYNCHRONOUS_PRINTER_DETECTION=1
 ifeq (,$(SAL_USE_VCLPLUGIN))
 gb_TEST_ENV_VARS += SAL_USE_VCLPLUGIN=svp
 endif
+gb_TEST_ENV_VARS += STATIC_UNO_HOME=file://$$I/program
 
 # This is used to detect whether LibreOffice is being built (as opposed to 
building
 # 3rd-party code). Used for tag deprecation for API we want to
diff --git a/solenv/gbuild/platform/unxgcc.mk b/solenv/gbuild/platform/unxgcc.mk
index c70e3ce222bb..9ca593154d38 100644
--- a/solenv/gbuild/platform/unxgcc.mk
+++ b/solenv/gbuild/platform/unxgcc.mk
@@ -313,12 +313,18 @@ endef
 
 gb_CppunitTest_CPPTESTPRECOMMAND := \
     $(call 
gb_Helper_extend_ld_path,$(WORKDIR)/UnpackedTarball/cppunit/src/cppunit/.libs)
-gb_CppunitTest_get_filename = libtest_$(1).so
+ifeq (,$(DISABLE_DYNLOADING))
+gb_CppunitTest_get_filename = libtest_$(1)$(gb_Library_PLAINEXT)
+else
+gb_CppunitTest_get_filename = test_$(1)$(gb_Executable_EXT)
+endif
 gb_CppunitTest_get_ilibfilename = $(gb_CppunitTest_get_filename)
 gb_CppunitTest_malloc_check := -ex 'set environment MALLOC_CHECK_=2; set 
environment MALLOC_PERTURB_=153'
 
 define gb_CppunitTest_CppunitTest_platform
+ifeq (,$(DISABLE_DYNLOADING))
 $(call gb_LinkTarget_get_target,$(2)) : RPATH := $(call 
gb_Library__get_rpath,$(call gb_LinkTarget__get_rpath_for_layer,NONE))
+endif
 
 endef
 
diff --git a/solenv/gbuild/static.mk b/solenv/gbuild/static.mk
index faa9a73db516..1b7f0214900a 100644
--- a/solenv/gbuild/static.mk
+++ b/solenv/gbuild/static.mk
@@ -198,6 +198,8 @@ $(foreach lib,$(gb_Library_KNOWNLIBS), \
     $(eval $(call gb_LinkTarget__fill_all_deps,$(call 
gb_Library_get_linktarget,$(lib)))))
 $(foreach exec,$(gb_Executable_KNOWN), \
     $(eval $(call gb_LinkTarget__expand_executable,$(call 
gb_Executable_get_linktarget,$(exec)))))
+$(foreach cppunit,$(gb_CppunitTest_KNOWN), \
+    $(eval $(call gb_LinkTarget__expand_executable,$(call 
gb_CppunitTest_get_linktarget,$(cppunit)))))
 $(foreach workdir_linktargetname,$(gb_LinkTarget__ALL_TOUCHED), \
     $(eval $(call gb_LinkTarget__remove_touch,$(workdir_linktargetname))))
 
@@ -235,11 +237,14 @@ endef
 endef # gb_LinkTarget__expand_executable_template
 
 ifneq (,$(gb_DEBUG_STATIC))
+$(info $(call gb_LinkTarget__expand_executable_template,CppunitTest))
 $(info $(call gb_LinkTarget__expand_executable_template,Executable))
 endif
+$(eval $(call gb_LinkTarget__expand_executable_template,CppunitTest))
 $(eval $(call gb_LinkTarget__expand_executable_template,Executable))
 
 $(foreach exec,$(gb_Executable_KNOWN),$(eval $(call 
gb_Executable__expand_deps,$(exec))))
+$(foreach cppunit,$(gb_CppunitTest_KNOWN),$(eval $(call 
gb_CppunitTest__expand_deps,$(cppunit))))
 
 endif # gb_PARTIAL_BUILD
 endif # gb_FULLDEPS
commit 0e97584cacec5ef6efb857a5fdf0e6f4ca33382c
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Sat Jan 8 22:53:29 2022 +0100
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Thu Jan 20 19:51:48 2022 +0100

    gbuild: set unorc lookup dir via environment
    
    UNO tries hard to find the path of the executable to look at that
    place for its unorc / uno.ini. All these approaches don't work for
    static binaries, so just override the lookup with the environment
    variable STATIC_UNO_HOME.
    
    Change-Id: I0d80c91e474d9f869475ba752d708b77c99f8a56

diff --git a/Makefile.in b/Makefile.in
index 300469aa0d5e..015fa183fd66 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -7,6 +7,8 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 #
 
+unexport STATIC_UNO_HOME
+
 gb_Top_MODULE_CHECK_TARGETS := slowcheck unitcheck subsequentcheck perfcheck 
uicheck screenshot
 
 .PHONY : check-if-root bootstrap gbuild build build-non-l10n-only 
build-l10n-only check clean clean-build clean-host test-install distclean 
distro-pack-install docs download etags fetch get-submodules id install 
install-gdb-printers install-strip tags debugrun help showmodules translations 
packageinfo internal.clean $(gb_Top_MODULE_CHECK_TARGETS)
diff --git a/bin/run b/bin/run
index 523da3c0e178..f812c2baadbb 100755
--- a/bin/run
+++ b/bin/run
@@ -67,6 +67,8 @@ else
 
 fi
 
+test "${STATIC_UNO_HOME+set}" = set || export 
STATIC_UNO_HOME="file://${dir}/instdir/program"
+
 # echo "setting URE_BOOTSTRAP to: ${URE_BOOTSTRAP}"
 # echo "setting search path to: ${SEARCH_PATH}"
 # echo "execing: ${exedir}/$1"
diff --git a/cppuhelper/source/paths.cxx b/cppuhelper/source/paths.cxx
index d2f37bb549a7..217e2119ad2c 100644
--- a/cppuhelper/source/paths.cxx
+++ b/cppuhelper/source/paths.cxx
@@ -20,12 +20,14 @@
 #include <config_folders.h>
 
 #include <sal/config.h>
+#include <sal/log.hxx>
 
 #include <cassert>
 
 #include <com/sun/star/uno/DeploymentException.hpp>
 #include <osl/file.hxx>
 #include <osl/module.hxx>
+#include <osl/thread.h>
 #include <rtl/ustring.hxx>
 #include <sal/types.h>
 
@@ -64,7 +66,16 @@ OUString cppu::getUnoIniUri() {
 #elif defined(EMSCRIPTEN)
     OUString uri("file:///instdir/program");
 #else
-    OUString uri(get_this_libpath());
+
+    OUString uri;
+#ifdef DISABLE_DYNLOADING
+    static const char* uno_home = getenv("STATIC_UNO_HOME");
+    if (uno_home)
+        uri = OStringToOUString(uno_home, osl_getThreadTextEncoding());
+    else
+#endif
+        uri = get_this_libpath();
+
 #ifdef MACOSX
     // We keep the URE dylibs directly in "Frameworks" (that is, 
LIBO_LIB_FOLDER) and unorc in
     // "Resources/ure/etc" (LIBO_URE_ETC_FOLDER).
@@ -74,7 +85,9 @@ OUString cppu::getUnoIniUri() {
     }
 #endif
 #endif
-    return uri + "/" SAL_CONFIGFILE("uno");
+    uri += "/" SAL_CONFIGFILE("uno");
+    SAL_INFO("cppuhelper", "expected uno config: " << uri);
+    return uri;
 }
 
 bool cppu::nextDirectoryItem(osl::Directory & directory, OUString * url) {
diff --git a/desktop/scripts/soffice.sh b/desktop/scripts/soffice.sh
index 67cc0b89751f..1bfb60682648 100755
--- a/desktop/scripts/soffice.sh
+++ b/desktop/scripts/soffice.sh
@@ -176,6 +176,8 @@ else
     unset LC_ALL
 fi
 
+test "${STATIC_UNO_HOME+set}" = set || export 
STATIC_UNO_HOME="file://${sd_prog}"
+
 # run soffice.bin directly when you want to get the backtrace
 if [ -n "$GDBTRACECHECK" ] ; then
     exec $GDBTRACECHECK "$sd_prog/soffice.bin" "$@"
commit 12a6b57c74aa555ab15de84c58d4698a14881752
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Mon Jan 10 04:50:03 2022 +0100
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Thu Jan 20 19:49:55 2022 +0100

    WASM update README.wasm.md
    
    Change-Id: Ic38a7a0637ab007f12a6046655cb7d36e24fae33
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128655
    Tested-by: Jenkins
    Reviewed-by: Jan-Marek Glogowski <glo...@fbihome.de>

diff --git a/static/README.wasm.md b/static/README.wasm.md
index bfe930ef6775..ccc7a5b8aec7 100644
--- a/static/README.wasm.md
+++ b/static/README.wasm.md
@@ -4,23 +4,20 @@ This module provides support for emscripten cross build
 
 ## Status
 
-    $ make
+The build generates a Writer-only LO build. You should be able to run either
 
-You can run the WASM mandelbrot Qt example, if you copy its HTML
-and the qtloader.js from the Qt's example folder after build with:
-
-    $ emrun --serve_after_close workdir/LinkTarget/Executable/mandelbrot.html
+    $ emrun --serve_after_close instdir/program/qt_soffice.html
+    $ emrun --serve_after_close workdir/LinkTarget/Executable/qt_vcldemo.html
+    $ emrun --serve_after_close 
workdir/LinkTarget/Executable/qt_wasm-qt5-mandelbrot.html
 
 REMINDER: Always start new tabs in the browser, reload might fail / cache!
-
+INFO: latest browser won't work anymore with 0.0.0.0 and need 127.0.0.1.
 
 ## Setup for the LO WASM build (with Qt)
 
-We're using Qt 5.15 with the officially supported emscripten v1.39.8.
-But there are several potential problems with threads and exceptions, so this 
will likely
-change later to a newer emscripten.
-
-Qt WASM is not yet used with LO, just if you're wondering!
+We're using Qt 5.15.2 with Emscripten 2.0.31. There are a bunch of Qt patches
+to fix the most grave bugs. Also newer Emscripten versions have various bugs
+with the FS image support.
 
 - See below under Docker build for another build option
 
@@ -29,8 +26,8 @@ Qt WASM is not yet used with LO, just if you're wondering!
 <https://emscripten.org/docs/getting_started/index.html>
 
     git clone https://github.com/emscripten-core/emsdk.git
-    ./emsdk install 1.39.8
-    ./emsdk activate --embedded 1.39.8
+    ./emsdk install 2.0.31
+    ./emsdk activate --embedded 2.0.31
 
 Example `bashrc` scriptlet:
 
@@ -41,41 +38,54 @@ Example `bashrc` scriptlet:
 
 <https://doc.qt.io/qt-5/wasm.html>
 
-I originally build the Qt 5.15 branch, but probably better to build a tag like 
v5.15.2.
+Most of the information from <https://doc.qt.io/qt-6/wasm.html> is still valid 
for Qt5;
+generally the Qt6 WASM documentation is much better, because it incorporated 
many
+information from the Qt Wiki.
+
+FWIW: Qt 5.15 LTS is not maintained publically and Qt WASM has quite a few 
bugs. Most
+WASM fixes from Qt 6 are needed for Qt 5.15 too. They can mainly be 
cherry-picked from:
+- git log origin/dev src/plugins/platforms/wasm/
+- git log --grep wasm origin/dev
 
-So:
+We will probably offer our own Qt repository clone at some point.
+
+But even the public Qt 5.15 branch is still broken, so better start with the 
v5.15.2 tag.
 
     git clone https://github.com/qt/qt5.git
     cd qt5
     git checkout v5.15.2
-    ./init-repository
-    ./configure -xplatform wasm-emscripten -feature-thread -compile-examples 
-prefix $PWD/qtbase
-    make -j<CORES> module-qtbase module-qtdeclarative
-
+    ./init-repository --module-subset=qtbase
+    ./configure -xplatform wasm-emscripten -feature-thread -prefix 
$PWD/install-5.15.2
+    make -j<CORES> module-qtbase
+
+Optionally you can add the configure flag "-compile-examples". But then you 
also have to
+patch at least mkspecs/wasm-emscripten/qmake.conf with EXIT_RUNTIME=0, 
otherwise they will
+fail to run. In addition, building with examples will break with some of them, 
but at that
+point Qt already works and also most examples.
 Building with examples will break with some of them, but at that point Qt 
already works.
+Or just skip them. Other interesting flags might be "-nomake tests -no-pch 
-ccache".
 
-At some point Qt configure failed for me with:
+Linking takes quite a long time, because emscripten-finalize rewrites the 
whole WASM files
+with some options. This way the LO WASM needs at least 64GB RAM. For faster 
link times add
+"-s WASM_BIGINT=1", change to ASSERTIONS=1 nd use -g3 to prevent rewriting the 
WASM file
+and generating source maps (see emscripten.py, finalize_wasm, and avoid 
modify_wasm = True).
+This is just needed for Qt examples, as LO already uses the correct flags!
 
-"Checking for target architecture... Project ERROR: target architecture 
detection binary not found."
+The install is not really needed, as LO currently just uses qtbase on it's 
own. You can do
 
-What seems to have fixed this was to run "emsdk activate 1.39.8" again.
+    make -j<CORES> install
+or
+    make -j8 -C qtbase/src install_subtargets
 
 Current Qt fails to start the demo webserver: 
<https://bugreports.qt.io/browse/QTCREATORBUG-24072>
 
-Use `emrun --serve_after_close` to run Qt WASM demos
-
-Enabling multi-thread support in Firefox is a bit of work with older versions:
-
-- <https://bugzilla.mozilla.org/show_bug.cgi?id=1477743#c7>
-- <https://wiki.qt.io/Qt_for_WebAssembly#Multithreading_Support>
-- 
<https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer>
-
+Use `emrun --serve_after_close` to run Qt WASM demos.
 
 ### Setup LO
 
-`autogen.sh` is patched to use emconfigure. That basically sets various 
environment vars,
-especially `EMMAKEN_JUST_CONFIGURE`, which will create the correct output file 
names, checked by
-`configure` (`a.out`).
+`autogen.sh` is patched to use emconfigure. That basically sets various
+environment vars, especially `EMMAKEN_JUST_CONFIGURE`, which will create the
+correct output file names, checked by `configure` (`a.out`).
 
 There's a distro config for WASM (work in progress), that gets your
 defaults right (and currently disables a ton of 3rd party stuff which
@@ -93,6 +103,35 @@ Recommended configure setup is thusly:
     `--with-build-platform-configure-options=--enable-ccache`
     `--enable-ccache`
 
+FWIW: it's also possible to build an almost static Linux LibreOffice by just 
using
+--disable-dynloading --enable-customtarget-components. System externals are 
still
+linked dynamically, but everything else is static.
+
+### "Deploying" soffice.wasm
+
+    tar -chf wasm.tar --xform 's/.*program/lo-wasm/' instdir/program/soffice.* 
\
+        instdir/program/qt*
+
+Your HTTP server needs to provide aditional headers:
+* add_header Cross-Origin-Opener-Policy same-origin
+* add_header Cross-Origin-Embedder-Policy require-corp
+
+The default html to use should be qt_soffice.html
+
+### Debugging setup
+
+Since a few months you can use DWARF information embedded by LLVM into the WASM
+to debug WASM in Chrome. You need to enable an experimental feature and install
+an additional extension. The whole setup is described in:
+
+https://developer.chrome.com/blog/wasm-debugging-2020/
+
+This way you don't need source maps (much faster linking!) and can resolve 
local
+WASM variables to C++ names!
+
+Per default, the WASM debug build splits the DWARF information into an 
additional
+WASM file, postfixed '.debug.wasm'.
+
 ### Using Docker to cross-build with emscripten
 
 If you prefer a controlled environment (sadly emsdk install/activate
@@ -109,7 +148,8 @@ Run
 
 in the lode/docker dir to get the container prepared. Run
 
-    PARALLELISM=4 BUILD_OPTIONS= BUILD_TARGET=build docker-compose run --rm -e 
PARALLELISM -e BUILD_TARGET -e BUILD_OPTIONS builder
+    PARALLELISM=4 BUILD_OPTIONS= BUILD_TARGET=build docker-compose run --rm \
+        -e PARALLELISM -e BUILD_TARGET -e BUILD_OPTIONS builder
 
 to perform an actual `srcdir != builddir` build; the container mounts
 checked-out git repo and output dir via `docker-compose.yml` (so make
@@ -152,27 +192,6 @@ WASM dynamic dispatch:
 
 - 
<https://fitzgeraldnick.com/2018/04/26/how-does-dynamic-dispatch-work-in-wasm.html>
 
-
-## Workaround for eventual clang WASM compiler bug
-
-````
-sc/source/core/data/attarray.cxx:378:44: error: call to member function 
'erase' is ambiguous
-                        aNewCondFormatData.erase(nIndex);
-                        ~~~~~~~~~~~~~~~~~~~^~~~~
-include/o3tl/sorted_vector.hxx:86:15: note: candidate function
-    size_type erase( const Value& x )
-              ^
-include/o3tl/sorted_vector.hxx:97:10: note: candidate function
-    void erase( size_t index )
-````
-
-This is currently patched by using `x.erase` (`x.begin() + nIndex`).
-
-There shouldn't be an ambiguity, because of "[WebAssembly] Change size_t to 
`unsigned long`."
-<https://reviews.llvm.org/rGdf07a35912d78781ed6a62a7c032bfef5085a4f5#change-IrS9f6jH6PFq>,
-from "Jul 23 2018" which pre-dates the emscripten tag 1.39.8 from 02/14/2020 
by ~1.5y.
-
-
 ## Tools for problem diagnosis
 
 * `nm -s` should list the symbols in the archive, based on the index generated 
by ranlib.
@@ -185,7 +204,6 @@ This is closed, but not really fixed IMHO:
 
 - <https://github.com/emscripten-core/emscripten/issues/3922>
 
-
 ## Dynamic libraries `/` modules in emscripten
 
 There is a good summary in:
commit 1ad8c5066bdb6ea825ad09d2a6c7f633b974fc69
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Thu Jan 20 16:09:38 2022 +0100
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Thu Jan 20 18:37:08 2022 +0100

    Sorting component implementations needs LC_ALL=C
    
    Change-Id: Ifba53b95fdefed59123a2e682e787119b6c67857
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128689
    Tested-by: Jenkins
    Reviewed-by: Jan-Marek Glogowski <glo...@fbihome.de>

diff --git a/config_host.mk.in b/config_host.mk.in
index 9a0388fa0d35..193406c8fbc9 100644
--- a/config_host.mk.in
+++ b/config_host.mk.in
@@ -685,6 +685,7 @@ export TOUCH=@TOUCH@
 export UCRTSDKDIR=@UCRTSDKDIR@
 export UCRTVERSION=@UCRTVERSION@
 export UCRT_REDISTDIR=@UCRT_REDISTDIR@
+export UNIQ=@UNIQ@
 export UNIX_DLAPI_LIBS=@UNIX_DLAPI_LIBS@
 export USE_HEADLESS_CODE=@USE_HEADLESS_CODE@
 export USE_LD=@USE_LD@
diff --git a/configure.ac b/configure.ac
index 751ad1ebb872..53b2323a2c09 100644
--- a/configure.ac
+++ b/configure.ac
@@ -11415,6 +11415,12 @@ if test -z "$DIFF"; then
 fi
 AC_SUBST([DIFF])
 
+AC_PATH_PROG(UNIQ, uniq)
+if test -z "$UNIQ"; then
+    AC_MSG_ERROR(["uniq" not found in \$PATH, install it])
+fi
+AC_SUBST([UNIQ])
+
 dnl ***************************************
 dnl Checking for patch
 dnl ***************************************
diff --git a/solenv/gbuild/ComponentTarget.mk b/solenv/gbuild/ComponentTarget.mk
index ce0224433661..aed3fd88e889 100644
--- a/solenv/gbuild/ComponentTarget.mk
+++ b/solenv/gbuild/ComponentTarget.mk
@@ -62,18 +62,18 @@ $(call gb_ComponentTarget_get_target,%).optionals : \
            | $(call gb_ComponentTarget_get_target,%).dir \
              $(call gb_ExternalExecutable_get_dependencies,xsltproc)
        $(call gb_ExternalExecutable_get_command,xsltproc) --nonet \
-           $(gb_ComponentTarget_XSLT_DUMP_OPTIONALS) $(COMPONENTSOURCE) 2>&1 | 
sort > $@
+           $(gb_ComponentTarget_XSLT_DUMP_OPTIONALS) $(COMPONENTSOURCE) 2>&1 | 
LC_ALL=C $(SORT) > $@
 
 # %.filtered : list of all optional implementations we don't build
 .PRECIOUS: $(call gb_ComponentTarget_get_target,%).filtered
 $(call gb_ComponentTarget_get_target,%).filtered : $(call 
gb_ComponentTarget_get_target,%).optionals
-       cat $< $(COMPONENTIMPL) | sed -e '/^#/d' -e '/^[        ]*$$/d' | sort 
| uniq -u > $@
+       cat $< $(COMPONENTIMPL) | sed -e '/^#/d' -e '/^[        ]*$$/d' | 
LC_ALL=C $(SORT) | $(UNIQ) -u > $@
 
 # %.allfiltered : contains all possible filtered components, which must match 
%.optionals
 .PRECIOUS: $(call gb_ComponentTarget_get_target,%).allfiltered
 $(call gb_ComponentTarget_get_target,%).allfiltered : $(call 
gb_ComponentTarget_get_target,%).optionals
        $(if $(ALLFILTEREDIMPL), \
-           cat $(ALLFILTEREDIMPL) | sed -e '/^#/d' -e '/^[     ]*$$/d' | sort 
| uniq > $@.tmp, \
+           cat $(ALLFILTEREDIMPL) | sed -e '/^#/d' -e '/^[     ]*$$/d' | 
LC_ALL=C $(SORT) -u > $@.tmp, \
            touch $@.tmp)
        $(DIFF) -u $< $@.tmp
        mv $@.tmp $@
commit 493d3558c6e6dce980cb92434f72c0ad03487aa0
Author:     Andrea Gelmini <andrea.gelm...@gelma.net>
AuthorDate: Thu Jan 20 15:33:13 2022 +0100
Commit:     Julien Nabet <serval2...@yahoo.fr>
CommitDate: Thu Jan 20 17:34:36 2022 +0100

    Fix typo
    
    Thanks a lot to Valter Mura:
    https://listarchives.libreoffice.org/global/l10n/2022/msg00005.html
    
    Change-Id: I37467e1b9ba7cba2553be5df0d8324da8fe6c13b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128303
    Tested-by: Jenkins
    Reviewed-by: Julien Nabet <serval2...@yahoo.fr>

diff --git a/config_host/config_global.h.in b/config_host/config_global.h.in
index 5f24fe8da397..40b804a60f77 100644
--- a/config_host/config_global.h.in
+++ b/config_host/config_global.h.in
@@ -35,7 +35,7 @@ Any change in this header will cause a rebuild of almost 
everything.
    <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87150> "move ctor wrongly 
chosen in return stmt
    (derived vs. base)"; MSVC++ 14.24 started to implement it, see <https://
    developercommunity.visualstudio.com/content/problem/852827/
-   msvc-1424-started-to-chose-move-ctor-in-return-der.html> "MSVC++ 14.24 
started to chose move ctor
+   msvc-1424-started-to-chose-move-ctor-in-return-der.html> "MSVC++ 14.24 
started to choose move ctor
    in return derived vs. base".  At least Clang 9, which does not implement 
it, emits
    -Werror,-Wreturn-std-move when it therefore considers a std::move to be 
missing.  On the other
    hand, at least some versions of GCC would emit -Werror=redundant-move in 
places where such a
diff --git a/extensions/source/propctrlr/formcomponenthandler.hxx 
b/extensions/source/propctrlr/formcomponenthandler.hxx
index 79b83fb927ed..bc7367abbeae 100644
--- a/extensions/source/propctrlr/formcomponenthandler.hxx
+++ b/extensions/source/propctrlr/formcomponenthandler.hxx
@@ -255,7 +255,7 @@ namespace pcr
         */
         bool impl_dialogFilterOrSort_nothrow( bool _bFilter, OUString& 
_out_rSelectedClause, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const;
 
-        /** executes a dialog which allows the user to chose the columns 
linking
+        /** executes a dialog which allows the user to choose the columns 
linking
             a sub to a master form, and sets the respective MasterFields / 
SlaveFields
             properties at the form.
             @precond
diff --git a/include/formula/grammar.hxx b/include/formula/grammar.hxx
index b5b499d5aab4..677087d19934 100644
--- a/include/formula/grammar.hxx
+++ b/include/formula/grammar.hxx
@@ -33,7 +33,7 @@ class FORMULA_DLLPUBLIC FormulaGrammar
 {
 public:
     enum AddressConvention{
-        CONV_UNSPECIFIED = -1,  /* useful when we want method to chose, must 
be first */
+        CONV_UNSPECIFIED = -1,  /* useful when we want method to choose, must 
be first */
 
         /* elements must be sequential and changes should be reflected in 
ScCompiler::pCharTables */
         CONV_OOO     =  0,  /* 'doc'#sheet.A1:sheet2.B2 */
diff --git a/include/svx/svdmodel.hxx b/include/svx/svdmodel.hxx
index 2170f78907ed..62c9be0344e5 100644
--- a/include/svx/svdmodel.hxx
+++ b/include/svx/svdmodel.hxx
@@ -279,7 +279,7 @@ public:
     // If you do use a custom Pool, make sure you inherit from SdrItemPool,
     // if you want to use symbol objects inherited from SdrAttrObj.
     // If, however, you use objects inheriting from SdrObject you are free
-    // to chose a pool of your liking.
+    // to choose a pool of your liking.
     //
     // tdf#118731 a bDisablePropertyFiles of true will disable ability to load
     // XPropertyFiles describing defaults. Useful for UI preview widgets
diff --git a/offapi/com/sun/star/chart2/XChartDocument.idl 
b/offapi/com/sun/star/chart2/XChartDocument.idl
index 0055cbb83fd2..484d4c256a94 100644
--- a/offapi/com/sun/star/chart2/XChartDocument.idl
+++ b/offapi/com/sun/star/chart2/XChartDocument.idl
@@ -42,7 +42,7 @@ interface XChartDocument : ::com::sun::star::frame::XModel
 
         <p>Notes: this is preliminary, we need an API that supports
         more than one diagram. The method name getDiagram exists in
-        the css.chart API, so there is would be no way to chose either
+        the css.chart API, so there is would be no way to choose either
         this or the other method from Basic (it would chose one or the
         other by random).</p>
      */
@@ -52,7 +52,7 @@ interface XChartDocument : ::com::sun::star::frame::XModel
 
         <p>Notes: this is preliminary, we need an API that supports
         more than one diagram. The method name setDiagram exists in
-        the css.chart API, so there is would be no way to chose either
+        the css.chart API, so there is would be no way to choose either
         this or the other method from Basic (it would chose one or the
         other by random).</p>
      */
diff --git a/offapi/com/sun/star/ucb/XFileIdentifierConverter.idl 
b/offapi/com/sun/star/ucb/XFileIdentifierConverter.idl
index 0f210ea1251b..618cfa33bf4d 100644
--- a/offapi/com/sun/star/ucb/XFileIdentifierConverter.idl
+++ b/offapi/com/sun/star/ucb/XFileIdentifierConverter.idl
@@ -33,7 +33,7 @@ published interface XFileIdentifierConverter : 
com::sun::star::uno::XInterface
 {
     /** Get information about the "locality" of a file content provider.
 
-        <p>The returned information can be used to chose the "best" among a
+        <p>The returned information can be used to choose the "best" among a
         number of file content providers implementing this interface.
 
         @param BaseURL
commit a557830dea9c287b11f3e610778acab94d03cdb0
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Tue Jan 18 16:07:47 2022 +0000
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Thu Jan 20 17:11:56 2022 +0100

    centralize these GetTextArray uses
    
    no logic change intended
    
    Change-Id: Ide0a6afc30690d05647acf9bf1a0eccf72a9e60c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128570
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/sw/source/core/inc/fntcache.hxx b/sw/source/core/inc/fntcache.hxx
index 0bdc4757d9b3..4285165a3336 100644
--- a/sw/source/core/inc/fntcache.hxx
+++ b/sw/source/core/inc/fntcache.hxx
@@ -66,13 +66,13 @@ extern SwFntObj *pLastFont;
  */
 struct SwTextGlyphsKey
 {
-    VclPtr<OutputDevice> m_pOutputDevice;
+    VclPtr<const OutputDevice> m_pOutputDevice;
     OUString m_aText;
     sal_Int32 m_nIndex;
     sal_Int32 m_nLength;
     size_t mnHashCode;
 
-    SwTextGlyphsKey(VclPtr<OutputDevice> const& pOutputDevice, const OUString 
& sText, sal_Int32 nIndex, sal_Int32 nLength);
+    SwTextGlyphsKey(const OutputDevice* pOutputDevice, const OUString & sText, 
sal_Int32 nIndex, sal_Int32 nLength);
     bool operator==(SwTextGlyphsKey const & rhs) const;
 };
 struct SwTextGlyphsKeyHash
@@ -113,6 +113,10 @@ class SwFntObj final : public SwCacheObj
     /// Cache of already calculated layout glyphs and text widths.
     SwTextGlyphsMap m_aTextGlyphs;
 
+    void GetTextArray(const OutputDevice& rOutputDevice, const OUString& rStr,
+                      std::vector<sal_Int32>& rDXAry, sal_Int32 nIndex, 
sal_Int32 nLen,
+                      bool bCaching);
+
     static tools::Long s_nPixWidth;
     static MapMode *s_pPixMap;
 
diff --git a/sw/source/core/txtnode/fntcache.cxx 
b/sw/source/core/txtnode/fntcache.cxx
index cb68f6535635..2c5f81a63390 100644
--- a/sw/source/core/txtnode/fntcache.cxx
+++ b/sw/source/core/txtnode/fntcache.cxx
@@ -77,11 +77,11 @@ static vcl::DeleteOnDeinit< VclPtr<OutputDevice> > 
s_pFntObjPixOut {};
  * Defines a substring on a given output device, to be used as an 
std::unordered_map<>
  * key.
  */
-SwTextGlyphsKey::SwTextGlyphsKey(VclPtr<OutputDevice> const& pOutputDevice, 
const OUString & sText, sal_Int32 nIndex, sal_Int32 nLength)
+SwTextGlyphsKey::SwTextGlyphsKey(const OutputDevice* pOutputDevice, const 
OUString & sText, sal_Int32 nIndex, sal_Int32 nLength)
     : m_pOutputDevice(pOutputDevice), m_aText(sText), m_nIndex(nIndex), 
m_nLength(nLength)
 {
     mnHashCode = 0;
-    o3tl::hash_combine(mnHashCode, pOutputDevice.get());
+    o3tl::hash_combine(mnHashCode, pOutputDevice);
     o3tl::hash_combine(mnHashCode, m_nIndex);
     o3tl::hash_combine(mnHashCode, m_nLength);
     if(m_nLength >= 0 && m_nIndex >= 0 && m_nIndex + m_nLength <= 
m_aText.getLength())
@@ -899,6 +899,18 @@ namespace
     }
 }
 
+void SwFntObj::GetTextArray(const OutputDevice& rDevice, const OUString& rStr, 
std::vector<sal_Int32>& rDXAry,
+                            sal_Int32 nIndex, sal_Int32 nLen, bool bCaching)
+{
+    SalLayoutGlyphs* pLayoutCache = nullptr;
+    if (bCaching)
+    {
+        SwTextGlyphsKey aGlyphsKey{&rDevice, rStr, nIndex, nLen};
+        pLayoutCache = GetCachedSalLayoutGlyphs(aGlyphsKey);
+    }
+    rDevice.GetTextArray(rStr, &rDXAry, nIndex, nLen, nullptr, pLayoutCache);
+}
+
 void SwFntObj::DrawText( SwDrawTextInfo &rInf )
 {
     OSL_ENSURE( rInf.GetShell(), "SwFntObj::DrawText without shell" );
@@ -1075,11 +1087,11 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
             std::vector<sal_Int32> aKernArray;
 
             if ( m_pPrinter )
-                m_pPrinter->GetTextArray( rInf.GetText(), &aKernArray,
-                            sal_Int32(rInf.GetIdx()), 
sal_Int32(rInf.GetLen()));
+                GetTextArray(*m_pPrinter, rInf.GetText(), aKernArray,
+                            sal_Int32(rInf.GetIdx()), 
sal_Int32(rInf.GetLen()), false);
             else
-                rInf.GetOut().GetTextArray( rInf.GetText(), &aKernArray,
-                            sal_Int32(rInf.GetIdx()), 
sal_Int32(rInf.GetLen()));
+                GetTextArray(rInf.GetOut(), rInf.GetText(), aKernArray,
+                            sal_Int32(rInf.GetIdx()), 
sal_Int32(rInf.GetLen()), false);
 
             // Change the average width per character to an appropriate grid 
width
             // basically get the ratio of the avg width to the grid unit 
width, then
@@ -1182,11 +1194,11 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
             std::vector<sal_Int32> aKernArray;
 
             if ( m_pPrinter )
-                m_pPrinter->GetTextArray( rInf.GetText(), &aKernArray,
-                    sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()));
+                GetTextArray(*m_pPrinter, rInf.GetText(), aKernArray,
+                    sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()), false);
             else
-                rInf.GetOut().GetTextArray( rInf.GetText(), &aKernArray,
-                    sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()));
+                GetTextArray(rInf.GetOut(), rInf.GetText(), aKernArray,
+                    sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()), false);
             if ( bSwitchH2V )
                 rInf.GetFrame()->SwitchHorizontalToVertical( aTextOriginPos );
             if ( rInf.GetSpace() || rInf.GetKanaComp())
@@ -1322,8 +1334,8 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
         if( rInf.GetSpace() || rInf.GetKanaComp() )
         {
             std::vector<sal_Int32> aKernArray;
-            rInf.GetOut().GetTextArray( rInf.GetText(), &aKernArray,
-                           sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()));
+            GetTextArray(rInf.GetOut(), rInf.GetText(), aKernArray,
+                         sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()), 
false);
 
             if( bStretch )
             {
@@ -1540,10 +1552,8 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
 
         // get screen array
         std::vector<sal_Int32> aScrArray;
-        SwTextGlyphsKey aGlyphsKey{ &rInf.GetOut(), rInf.GetText(), 
sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()) };
-        SalLayoutGlyphs* pGlyphs = GetCachedSalLayoutGlyphs(aGlyphsKey);
-        rInf.GetOut().GetTextArray( rInf.GetText(), &aScrArray,
-                        sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()), 
nullptr, pGlyphs);
+        GetTextArray(rInf.GetOut(), rInf.GetText(), aScrArray,
+                     sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()), true);
 
         // OLE: no printer available
         // OSL_ENSURE( pPrinter, "DrawText needs pPrinter" )
@@ -1555,16 +1565,14 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
                 if( !m_pPrtFont->IsSameInstance( m_pPrinter->GetFont() ) )
                     m_pPrinter->SetFont( *m_pPrtFont );
             }
-            aGlyphsKey = SwTextGlyphsKey{ m_pPrinter, rInf.GetText(), 
sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()) };
-            pGlyphs = GetCachedSalLayoutGlyphs(aGlyphsKey);
-            m_pPrinter->GetTextArray(rInf.GetText(), &aKernArray,
-                    sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()), 
nullptr, pGlyphs);
+            GetTextArray(*m_pPrinter, rInf.GetText(), aKernArray,
+                    sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()), true);
         }
         else
         {
 #ifndef NDEBUG
-            rInf.GetOut().GetTextArray( rInf.GetText(), &aKernArray,
-                    sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()));
+            GetTextArray(rInf.GetOut(), rInf.GetText(), aKernArray,
+                    sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()), false);
             assert(aKernArray == aScrArray);
 #endif
             aKernArray = aScrArray;
@@ -1876,8 +1884,8 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
                 sal_Int32 nTmpIdx = bBullet
                             ? (rInf.GetIdx() ? 1 : 0)
                             : sal_Int32(rInf.GetIdx());
-                aGlyphsKey = SwTextGlyphsKey{ &rInf.GetOut(), *pStr, nTmpIdx, 
nLen };
-                pGlyphs = GetCachedSalLayoutGlyphs(aGlyphsKey);
+                SwTextGlyphsKey aGlyphsKey{ &rInf.GetOut(), *pStr, nTmpIdx, 
nLen };
+                SalLayoutGlyphs* pGlyphs = 
GetCachedSalLayoutGlyphs(aGlyphsKey);
                 rInf.GetOut().DrawTextArray( aTextOriginPos, *pStr, aKernArray,
                                              nTmpIdx , nLen, 
SalLayoutFlags::NONE, pGlyphs );
                 if (bBullet)
@@ -2038,8 +2046,8 @@ Size SwFntObj::GetTextSize( SwDrawTextInfo& rInf )
         if( !GetScrFont()->IsSameInstance( rInf.GetOut().GetFont() ) )
             rInf.GetOut().SetFont( *m_pScrFont );
 
-        m_pPrinter->GetTextArray(rInf.GetText(), &aKernArray,
-                sal_Int32(rInf.GetIdx()), sal_Int32(nLn));
+        GetTextArray(*m_pPrinter, rInf.GetText(), aKernArray,
+                sal_Int32(rInf.GetIdx()), sal_Int32(nLn), false);
         if( bCompress )
             rInf.SetKanaDiff( rInf.GetScriptInfo()->Compress( 
aKernArray.data(),
                 rInf.GetIdx(), nLn, rInf.GetKanaComp(),
@@ -2057,8 +2065,8 @@ Size SwFntObj::GetTextSize( SwDrawTextInfo& rInf )
             if (eGlyphPositioningMode == GlyphPositioningMode::Classic)
             {
                 std::vector<sal_Int32> aScrArray;
-                rInf.GetOut().GetTextArray( rInf.GetText(), &aScrArray,
-                            sal_Int32(rInf.GetIdx()), 
sal_Int32(rInf.GetLen()));
+                GetTextArray(rInf.GetOut(), rInf.GetText(), aScrArray,
+                            sal_Int32(rInf.GetIdx()), 
sal_Int32(rInf.GetLen()), false);
                 tools::Long nScrPos = aScrArray[ 0 ];
                 TextFrameIndex nCnt(rInf.GetText().getLength());
                 if ( nCnt < rInf.GetIdx() )
@@ -2094,8 +2102,8 @@ Size SwFntObj::GetTextSize( SwDrawTextInfo& rInf )
         if( bCompress )
         {
             std::vector<sal_Int32> aKernArray;
-            rInf.GetOut().GetTextArray( rInf.GetText(), &aKernArray,
-                                sal_Int32(rInf.GetIdx()), sal_Int32(nLn));
+            GetTextArray(rInf.GetOut(), rInf.GetText(), aKernArray,
+                         sal_Int32(rInf.GetIdx()), sal_Int32(nLn), false);
             rInf.SetKanaDiff( rInf.GetScriptInfo()->Compress( 
aKernArray.data(),
                 rInf.GetIdx(), nLn, rInf.GetKanaComp(),
                 o3tl::narrowing<sal_uInt16>(m_aFont.GetFontSize().Height()) 
,lcl_IsFullstopCentered( rInf.GetOut() ) ) );
@@ -2137,14 +2145,14 @@ TextFrameIndex 
SwFntObj::GetModelPositionForViewPoint(SwDrawTextInfo &rInf)
     {
         m_pPrinter->SetLayoutMode( rInf.GetOut().GetLayoutMode() );
         m_pPrinter->SetDigitLanguage( rInf.GetOut().GetDigitLanguage() );
-        SwTextGlyphsKey aGlyphsKey{ m_pPrinter, rInf.GetText(), 
sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()) };
-        SalLayoutGlyphs* pGlyphs = GetCachedSalLayoutGlyphs(aGlyphsKey);
-        m_pPrinter->GetTextArray( rInf.GetText(), &aKernArray,
-                sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()), nullptr, 
pGlyphs);
+        GetTextArray(*m_pPrinter, rInf.GetText(), aKernArray,
+                     sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()), true);
     }
     else
-        rInf.GetOut().GetTextArray( rInf.GetText(), &aKernArray,
-                sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()));
+    {
+        GetTextArray(rInf.GetOut(), rInf.GetText(), aKernArray,
+                     sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()), 
false);
+    }
 
     const SwScriptInfo* pSI = rInf.GetScriptInfo();
     if ( rInf.GetFont() && rInf.GetLen() )
commit 96607133f4457b31ddaee5808c04e96243ed99c6
Author:     Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de>
AuthorDate: Thu Jan 20 13:05:39 2022 +0100

... etc. - the rest is truncated

Reply via email to