[Libreoffice-commits] core.git: Branch 'feature/wasm' - 1226 commits - accessibility/inc accessibility/source android/default-document android/source animations/source avmedia/source basctl/Library_basctl.mk basctl/sdi basctl/source basctl/uiconfig basegfx/source basic/qa basic/source bin/check-autocorr.py bin/flat-odf-cleanup.py bin/gbuild-to-ide bin/get_config_variables bin/get-forum-attachments.py bin/lo-all-static-libs bin/oss-fuzz-setup.sh bin/run bin/update_pch bridges/Library_cpp_uno.mk bridges/source canvas/source chart2/inc chart2/qa chart2/source codemaker/source comphelper/Library_comphelper.mk comphelper/source compilerplugins/clang compilerplugins/LICENSE.TXT config.guess config_host/config_vclplug.h.in config_host_lang.mk.in config_host.mk.in config.sub configure.ac connectivity/source cppcanvas/qa cppcanvas/source cppuhelper/source cui/inc cui/Library_cui.mk cui/source cui/uiconfig dbaccess/inc dbaccess/source desktop/Executable_soffice_bin.mk desktop/inc desktop/Library_sofficeapp .mk desktop/qa desktop/scripts desktop/source dictionaries distro-configs/LibreOfficeWASM32.conf docmodel/inc docmodel/Library_docmodel.mk docmodel/Makefile docmodel/Module_docmodel.mk docmodel/README.md docmodel/source download.lst drawinglayer/Library_drawinglayer.mk drawinglayer/source editeng/CppunitTest_editeng_core.mk editeng/inc editeng/Library_editeng.mk editeng/source emfio/inc emfio/qa emfio/source extensions/source external/boost external/cairo external/cppunit external/curl external/fontconfig external/gpgmepp external/harfbuzz external/hunspell external/icu external/libtiff external/libwebp external/more_fonts external/nss external/openssl external/poppler external/redland external/zxing extras/CustomTarget_autocorr.mk extras/CustomTarget_gallsystem.mk extras/source filter/source forms/qa forms/source formula/source formula/uiconfig framework/inc framework/source .git-hooks/pre-commit helpcontent2 hwpfilter/source i18nlangtag/source i18npool/source i18nutil/source icon- themes/breeze icon-themes/breeze_dark icon-themes/breeze_dark_svg icon-themes/breeze_svg icon-themes/karasa_jaga icon-themes/karasa_jaga_svg icon-themes/sifr icon-themes/sifr_dark icon-themes/sifr_dark_svg icon-themes/sifr_svg icon-themes/sukapura icon-themes/sukapura_svg include/basegfx include/com include/comphelper include/docmodel include/drawinglayer include/editeng include/filter include/formula include/i18nlangtag include/i18nutil include/IwyuFilter_include.yaml include/LibreOfficeKit include/linguistic include/oox include/osl include/sfx2 include/svl include/svtools include/svx include/test include/toolkit include/unotools include/vbahelper include/vcl include/xmloff instsetoo_native/CustomTarget_install.mk instsetoo_native/CustomTarget_setup.mk ios/UnitTest librelogo/CustomTarget_librelogo.mk librelogo/source libreofficekit/qa libreofficekit/source lingucomponent/source linguistic/source linguistic/workben lotuswordpro/source Makefile.fetch Makefile.gbuild Makefile.in nlpso lver/README.md odk/CustomTarget_allheaders.mk odk/docs odk/examples odk/index.html odk/index_online.html offapi/com offapi/type_reference offapi/UnoApi_offapi.mk officecfg/CustomTarget_registry.mk officecfg/registry onlineupdate/source oovbaapi/ooo oox/CppunitTest_oox_drawingml.mk oox/CppunitTest_oox_shape.mk oox/CppunitTest_oox_tokenmap.mk oox/inc oox/Library_oox.mk oox/Module_oox.mk oox/qa oox/source package/source postprocess/CustomTarget_components.mk postprocess/CustomTarget_images.mk postprocess/CustomTarget_registry.mk pyuno/demo pyuno/qa qadevOOo/tests readlicense_oo/docs readlicense_oo/license README.md reportdesign/source RepositoryExternal.mk Repository.mk RepositoryModule_build.mk RepositoryModule_host.mk sal/cppunittester sal/emscripten sal/Library_cppunitmain.mk sal/Library_lo-bootstrap.mk sal/Library_sal.mk sal/Module_sal.mk sal/osl sal/rtl schema/libreoffice sc/inc sc/IwyuFilter_sc.yaml sc/Module_sc.mk sc/qa scripting/source sc/source sc/uiconfig sc/UITest_hide_cols. mk sd/CppunitTest_sd_uiimpress.mk sd/CppunitTest_sd_uimpress.mk sdext/CppunitTest_sdext_pdfimport.mk sdext/Executable_pdf2xml.mk sdext/Executable_pdfunzip.mk sdext/Library_pdfimport.mk sdext/Library_PresentationMinimizer.mk sdext/qa sdext/source sd/inc sd/Library_sd.mk sd/qa sd/source sd/uiconfig sd/UIConfig_simpress.mk setup_native/source sfx2/inc sfx2/qa sfx2/sdi sfx2/source sfx2/uiconfig slideshow/source solenv/bin solenv/clang-format solenv/CompilerTest_compilerplugins_clang.mk solenv/flatpak-manifest.in solenv/gbuild solenv/gdb solenv/inc solenv/qa solenv/sanitizers solenv/vs soltools/mkdepend starmath/inc starmath/qa starmath/source starmath/util static/CustomTarget_emscripten_fs_image.mk static/emscripten static/README.wasm.md stoc/source svgio/qa svl/source svtools/source svx/CppunitTest_svx_removewhichrange.mk svx/CppunitTest_svx_styles.mk svx/CppunitTest_svx_unit.mk svx/inc svx/Library_svxcore.mk svx/Library_svx.mk svx/qa svx/sdi svx/source svx/uiconfig svx/UIConfig_svx.mk sw/CppunitTest_sw_apitests.mk sw/CppunitTest_sw_core_draw.mk sw/CppunitTest_sw_core_layout.mk sw/CppunitTest_sw_core_theme.mk sw/CppunitTest_sw_filters_test2.mk sw/CppunitTest_sw_globalfilter.mk sw/CppunitTest_sw_macros_test.mk sw/CppunitTest_sw_mailmerge2.mk sw/CppunitTest_sw_odfimport.mk sw/CppunitTest_sw_ooxmlimport2.mk sw/CppunitTest_sw_ooxmlimport.mk sw/CppunitTest_sw_rtfimport.mk sw/CppunitTest_sw_tiledrendering.mk sw/CppunitTest_sw_uibase_dialog.mk sw/CppunitTest_sw_uwriter.mk sw/inc sw/layoutwriter_setup.mk sw/Library_sw.mk sw/Library_swui.mk sw/Module_sw.mk sw/ooxmlexport_setup.mk sw/qa sw/sdi sw/source sw/uiconfig sw/UIConfig_swriter.mk sw/uiwriter_setup.mk sw/ww8export_setup.mk sysui/CustomTarget_share.mk sysui/desktop sysui/Package_osxicons.mk testtools/CustomTarget_bridgetest.mk testtools/CustomTarget_uno_test.mk testtools/source toolkit/inc toolkit/Library_tk.mk toolkit/source tools/source translations ucb/source uitest/impress_tests unotest/source unotools/source vcl /headless vcl/inc vcl/jsdialog vcl/Library_vcl.mk vcl/Library_vclplug_gen.mk vcl/Module_vcl.mk vcl/osx vcl/qa vcl/qt5 vcl/quartz vcl/skia vcl/source vcl/unx vcl/win vcl/workben .vscode/vs-code-template.code-workspace.in wizards/com wizards/CustomTarget_wizards.mk wizards/Package_sfdocuments.mk wizards/source writerfilter/inc writerfilter/Library_writerfilter.mk writerfilter/qa writerfilter/source writerperfect/source xmlhelp/source xmloff/CppunitTest_xmloff_draw.mk xmloff/CppunitTest_xmloff_uxmloff.mk xmloff/inc xmloff/Library_xo.mk xmloff/qa xmloff/source xmlsecurity/CppunitTest_xmlsecurity_signing2.mk xmlsecurity/CppunitTest_xmlsecurity_signing.mk xmlsecurity/Module_xmlsecurity.mk xmlsecurity/qa xmlsecurity/source

Sat, 14 Jan 2023 16:49:11 -0800

Rebased ref, commits from common ancestor:
commit 33c00fcae871a7c1419ca70d4a381c31e85ca944
Author:     Tor Lillqvist <t...@collabora.com>
AuthorDate: Mon Nov 21 14:20:28 2022 +0200
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sun Jan 15 01:19:14 2023 +0100

    Document how tml managed to run the qt_soffice.html thing without emrun

diff --git a/static/README.wasm.md b/static/README.wasm.md
index cbe5f74f6607..d4235a4683b3 100644
--- a/static/README.wasm.md
+++ b/static/README.wasm.md
@@ -10,6 +10,34 @@ The build generates a Writer-only LO build. You should be 
able to run either
     $ emrun --serve_after_close workdir/LinkTarget/Executable/qt_vcldemo.html
     $ emrun --serve_after_close 
workdir/LinkTarget/Executable/qt_wasm-qt5-mandelbrot.html
 
+To run the WASM Qt-LibreOffice, it also works to just use the Chromium
+browser on Linux against a local web server as long as the following
+files (that have ended up after the build in instdir/program) are
+available in a folder through the web server:
+
+  qtloader.js
+  qtlogo.svg
+  qt_soffice.html
+  soffice.data
+  soffice.data.js.metadata
+  soffice.html
+  soffice.html.linkdeps
+  soffice.js
+  soffice.wasm
+  soffice.worker.js
+
+Either the instdir/program folder itself can be available in the web
+server, or you copy those files to some place that is. No emrun or
+container (as perhaps used to build the thing) necessary.
+
+Like this:
+
+  chromium-browser --enable-features=SharedArrayBuffer 
http://localhost/tml/wasm/
+
+Where the above mentioned files have been copied to a folder that
+shows up as tml/wasm on localhost, and qt_soffice.html has been
+renamed to index.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.
 
commit f814cc609f37d94075c32bddea97d7ba5b4fea32
Author:     Balazs Varga <balazs.varga.ext...@allotropia.de>
AuthorDate: Fri Sep 23 10:57:09 2022 +0200
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sun Jan 15 01:19:14 2023 +0100

    WASM pdf conversion through emscripten and qt5
    
    Exporting files to pdf and downloading it from the emscripten
    virtual memory file system to the local file system with qt5 and emscripten.
    
    What is working:
    1. Uploading a file from the local file system to the emscripten memory
       with 'Open file dialoge' and then opening it. In the same time export it 
to pdf.
    2. Load an uploaded document with the LibreOffice Kit command:
     - lodoc = _libreofficekit_hook(0)
     - _doc_postUnoCommand(lodoc, allocateUTF8(".uno:Open"), allocateUTF8(
       "{ \"URL\" : { \"type\":\"string\", 
\"value\":\"file:///android/default-document/{UPLOADED_FILE_NAME}\" }}"), 0)
    3. Export the loaded document to pdf with the ExportDirectlyToPDF UI or 
with the LibreOffice Kit command:
     - lodoc = _libreofficekit_hook(0)
     - _doc_postUnoCommand(lodoc, allocateUTF8(".uno:ExportDirectToPDF"), 
allocateUTF8(""), 0)
    4. alternatively, you can plant a file in the virtual filesystem prior
       to LibreOffice bootstrap, and export headless, via soffice cmdline args
    
    Change-Id: I8f03b0a057155afaa5f1ca0e3e451bb362a99769

diff --git a/include/sfx2/objsh.hxx b/include/sfx2/objsh.hxx
index b64fa61389bf..47a7a2510403 100644
--- a/include/sfx2/objsh.hxx
+++ b/include/sfx2/objsh.hxx
@@ -45,6 +45,13 @@
 #include <functional>
 #include <sfx2/AccessibilityIssue.hxx>
 
+#ifdef EMSCRIPTEN
+#include <emscripten.h>
+#include <emscripten/bind.h>
+#include <emscripten/html5.h>
+#include <emscripten/val.h>
+#endif
+
 namespace weld {class Button; }
 class SbxValue;
 class SbxArray;
@@ -435,6 +442,10 @@ public:
     virtual bool                PrepareClose(bool bUI = true);
     virtual HiddenInformation   GetHiddenInformationState( HiddenInformation 
nStates );
     sal_Int16                   QueryHiddenInformation( HiddenWarningFact 
eFact, weld::Window* pParent );
+    #ifdef EMSCRIPTEN
+    void                        ReadWASMFile(emscripten::val& contentArray, 
sal_Int32 nRead, css::uno::Sequence<sal_Int8>& aContent);
+    void                        WriteWASMFile(emscripten::val& contentArray, 
const OUString& rFileName);
+    #endif
     bool                        IsSecurityOptOpenReadOnly() const;
     void                        SetSecurityOptOpenReadOnly( bool bOpenReadOnly 
);
 
diff --git a/sfx2/source/dialog/filedlghelper.cxx 
b/sfx2/source/dialog/filedlghelper.cxx
index 541d26a9ae29..6643aa8ceff0 100644
--- a/sfx2/source/dialog/filedlghelper.cxx
+++ b/sfx2/source/dialog/filedlghelper.cxx
@@ -1628,7 +1628,12 @@ void FileDialogHelper_Impl::getRealFilter( OUString& 
_rFilter ) const
     _rFilter = getCurrentFilterUIName();
 
     if ( _rFilter.isEmpty() )
-        _rFilter = maCurFilter;
+    {
+        if (isShowFilterExtensionEnabled())
+            _rFilter = getFilterName(maCurFilter);
+        else
+            _rFilter = maCurFilter;
+    }
 
     if ( !_rFilter.isEmpty() && mpMatcher )
     {
diff --git a/sfx2/source/doc/guisaveas.cxx b/sfx2/source/doc/guisaveas.cxx
index dc32d10c103b..66596e59ea03 100644
--- a/sfx2/source/doc/guisaveas.cxx
+++ b/sfx2/source/doc/guisaveas.cxx
@@ -1629,10 +1629,53 @@ bool 
SfxStoringHelper::FinishGUIStoreModel(::comphelper::SequenceAsHashMap::cons
         if ( aDenyListIter != aModelData.GetMediaDescr().end() )
             aDenyListIter->second >>= aDenyList;
 
+        bool bWasmPdfExport = false;
+#ifdef EMSCRIPTEN
+        // Do not create file dialoge for direct pdf export, (just a 
workaround for WASM pdf export now)
+        // because that is still buggy on the Qt side
+        if ( nStoreMode & PDFDIRECTEXPORT_REQUESTED )
+        {
+            // preselect a filter for the storing process
+            ::comphelper::SequenceAsHashMap aFilterPropsHM( aFilterProps );
+
+            // this is a WASM direct pdf export
+            const OUString aFilterUIName = 
aFilterPropsHM.getUnpackedValueOrDefault( "UIName", OUString() );
+            if (aFilterUIName == "PDF - Portable Document Format")
+            {
+                OUString realfiltername;
+                const OUString aDocServiceName{ aModelData.GetDocServiceName() 
};
+                if ( aDocServiceName == "com.sun.star.drawing.DrawingDocument" 
)
+                    realfiltername = "draw_pdf_Export";
+                else if ( aDocServiceName == 
"com.sun.star.presentation.PresentationDocument" )
+                    realfiltername = "impress_pdf_Export";
+                else if ( aDocServiceName == "com.sun.star.text.TextDocument" )
+                    realfiltername = "writer_pdf_Export";
+                else if ( aDocServiceName == 
"com.sun.star.sheet.SpreadsheetDocument" )
+                    realfiltername = "calc_pdf_Export";
+
+                if (realfiltername.endsWith("pdf_Export"))
+                {
+                    const OUString aRecommendedDir 
{aModelData.GetRecommendedDir( aSuggestedDir )};
+                    OUString aAdjustToType = 
aFilterPropsHM.getUnpackedValueOrDefault( "Type", OUString() );
+                    const OUString aRecommendedName 
{aModelData.GetRecommendedName( aSuggestedName, aAdjustToType )};
+                    OUString aTempURL = aRecommendedDir + aRecommendedName;
+                    INetURLObject aURL2(aTempURL);
+                    aModelData.GetMediaDescr()[OUString("URL")] <<= 
aURL2.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+                    aModelData.GetMediaDescr()[sFilterNameString] <<= 
realfiltername;
+                    bWasmPdfExport = true;
+                }
+            }
+        }
+#endif // EMSCRIPTEN
+
         for (;;)
         {
             // in case the dialog is opened a second time the folder should be 
the same as previously navigated to by the user, not what was handed over by 
initial parameters
-            bUseFilterOptions = aModelData.OutputFileDialog( nStoreMode, 
aFilterProps, bSetStandardName, aSuggestedName, bPreselectPassword, 
aSuggestedDir, nDialog, sStandardDir, aDenyList );
+            if (!bWasmPdfExport)
+                bUseFilterOptions = aModelData.OutputFileDialog( nStoreMode, 
aFilterProps, bSetStandardName, aSuggestedName, bPreselectPassword, 
aSuggestedDir, nDialog, sStandardDir, aDenyList );
+            else
+                bUseFilterOptions = true;
+
             if ( nStoreMode == SAVEAS_REQUESTED )
             {
                 // in case of saving check filter for possible alien warning
@@ -1653,7 +1696,7 @@ bool 
SfxStoringHelper::FinishGUIStoreModel(::comphelper::SequenceAsHashMap::cons
                 break;
         }
 
-        bDialogUsed = true;
+        bDialogUsed = !bWasmPdfExport;
         aFileNameIter = aModelData.GetMediaDescr().find( OUString("URL") );
     }
     else
diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx
index 2cc7c3c932f0..cf6ed7269088 100644
--- a/sfx2/source/doc/objstor.cxx
+++ b/sfx2/source/doc/objstor.cxx
@@ -3005,6 +3005,39 @@ bool SfxObjectShell::PreDoSaveAs_Impl(const OUString& 
rFileName, const OUString&
 
         if( bOk )
         {
+#ifdef EMSCRIPTEN
+            if (aFilterName.endsWith("pdf_Export"))
+            {
+                try
+                {
+                    sal_Int32 nRead;
+                    Reference<io::XInputStream> aTempInput = 
pNewFile->GetInputStream();
+                    sal_Int32 nBufferSize = 32767;
+                    Sequence<sal_Int8> aSequence(nBufferSize);
+                    emscripten::val contentArray = emscripten::val::array();
+
+                    do
+                    {
+                        nRead = aTempInput->readBytes(aSequence, nBufferSize);
+                        if (nRead < nBufferSize)
+                        {
+                            Sequence<sal_Int8> 
aTempBuf(aSequence.getConstArray(), nRead);
+                            ReadWASMFile(contentArray, nRead, aTempBuf);
+                        }
+                        else
+                        {
+                            ReadWASMFile(contentArray, nRead, aSequence);
+                        }
+                    } while (nRead == nBufferSize);
+
+                    WriteWASMFile(contentArray, pNewFile->GetName());
+                }
+                catch (const Exception&)
+                {
+                }
+            }
+#endif
+
             if( !bCopyTo )
                 SetModified( false );
         }
@@ -3049,6 +3082,46 @@ bool SfxObjectShell::PreDoSaveAs_Impl(const OUString& 
rFileName, const OUString&
     return bOk;
 }
 
+#ifdef EMSCRIPTEN
+void SfxObjectShell::ReadWASMFile(emscripten::val& contentArray, sal_Int32 
nRead, css::uno::Sequence<sal_Int8>& aContent)
+{
+    emscripten::val fileContentView = 
emscripten::val(emscripten::typed_memory_view(
+        nRead,
+        reinterpret_cast<const char*>(aContent.getConstArray())));
+    emscripten::val fileContentCopy = 
emscripten::val::global("ArrayBuffer").new_(nRead);
+    emscripten::val fileContentCopyView = 
emscripten::val::global("Uint8Array").new_(fileContentCopy);
+    fileContentCopyView.call<void>("set", fileContentView);
+    contentArray.call<void>("push", fileContentCopyView);
+}
+
+
+void SfxObjectShell::WriteWASMFile(emscripten::val& contentArray, const 
OUString& rFileName)
+{
+    INetURLObject aURL(rFileName);
+    OUString aNewname = 
aURL.GetLastName(INetURLObject::DecodeMechanism::WithCharset);
+
+    emscripten::val document = emscripten::val::global("document");
+    emscripten::val window = emscripten::val::global("window");
+
+    emscripten::val type = emscripten::val::object();
+    type.set("type","application/octet-stream");
+    emscripten::val contentBlob = 
emscripten::val::global("Blob").new_(contentArray, type);
+
+    emscripten::val contentUrl = 
window["URL"].call<emscripten::val>("createObjectURL", contentBlob);
+    emscripten::val contentLink = 
document.call<emscripten::val>("createElement", std::string("a"));
+    contentLink.set("href", contentUrl);
+    contentLink.set("download", aNewname.toUtf8().getStr());
+    contentLink.set("style", "display:none");
+
+    emscripten::val body = document["body"];
+    body.call<void>("appendChild", contentLink);
+    contentLink.call<void>("click");
+    body.call<void>("removeChild", contentLink);
+
+    window["URL"].call<emscripten::val>("revokeObjectURL", contentUrl);
+}
+#endif
+
 
 bool SfxObjectShell::LoadFrom( SfxMedium& /*rMedium*/ )
 {
diff --git a/sfx2/source/doc/objxtor.cxx b/sfx2/source/doc/objxtor.cxx
index c7f34aeadc31..0d89c4b9d482 100644
--- a/sfx2/source/doc/objxtor.cxx
+++ b/sfx2/source/doc/objxtor.cxx
@@ -867,6 +867,7 @@ void SfxObjectShell::SetCurrentComponent( const Reference< 
XInterface >& _rxComp
     if ( _rxComponent == xOldCurrentComp )
         // nothing to do
         return;
+    rTheCurrentComponent = _rxComponent;
     // note that "_rxComponent.get() == s_xCurrentComponent.get().get()" is 
/sufficient/, but not
     // /required/ for "_rxComponent == s_xCurrentComponent.get()".
     // In other words, it's still possible that we here do something which is 
not necessary,
@@ -874,7 +875,6 @@ void SfxObjectShell::SetCurrentComponent( const Reference< 
XInterface >& _rxComp
 
 #if HAVE_FEATURE_SCRIPTING
     BasicManager* pAppMgr = SfxApplication::GetBasicManager();
-    rTheCurrentComponent = _rxComponent;
     if ( !pAppMgr )
         return;
 
diff --git a/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk 
b/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk
index 8f8155642852..4e4e171a52ee 100644
--- a/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk
+++ b/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk
@@ -27,7 +27,7 @@ gb_EMSCRIPTEN_LDFLAGS += -s TOTAL_MEMORY=1GB -s 
PTHREAD_POOL_SIZE=4
 # To keep the link time (and memory) down, prevent all rewriting options from 
wasm-emscripten-finalize
 # See emscripten.py, finalize_wasm, modify_wasm = True
 # So we need WASM_BIGINT=1 and ASSERTIONS=1 (2 implies STACK_OVERFLOW_CHECK)
-gb_EMSCRIPTEN_LDFLAGS += --bind -s FORCE_FILESYSTEM=1 -s WASM_BIGINT=1 -s 
ERROR_ON_UNDEFINED_SYMBOLS=1 -s FETCH=1 -s ASSERTIONS=1 -s EXIT_RUNTIME=0 -s 
EXPORTED_RUNTIME_METHODS=["UTF16ToString","stringToUTF16","UTF8ToString","allocateUTF8","printErr","ccall","cwrap"]
+gb_EMSCRIPTEN_LDFLAGS += --bind -s FORCE_FILESYSTEM=1 -s WASM_BIGINT=1 -s 
ERROR_ON_UNDEFINED_SYMBOLS=1 -s FETCH=1 -s ASSERTIONS=1 -s EXIT_RUNTIME=0 -s 
EXPORTED_RUNTIME_METHODS=["UTF16ToString","stringToUTF16","UTF8ToString","allocateUTF8","printErr","ccall","cwrap","FS"]
 gb_EMSCRIPTEN_QTDEFS := -DQT_NO_LINKED_LIST -DQT_NO_JAVA_STYLE_ITERATORS 
-DQT_NO_EXCEPTIONS -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -DQT_NO_DEBUG 
-DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB
 
 gb_Executable_EXT := .html
diff --git a/vcl/inc/qt5/QtFilePicker.hxx b/vcl/inc/qt5/QtFilePicker.hxx
index 58824adbbd48..96c1dd60c8db 100644
--- a/vcl/inc/qt5/QtFilePicker.hxx
+++ b/vcl/inc/qt5/QtFilePicker.hxx
@@ -32,6 +32,22 @@
 #include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
 #include <com/sun/star/uno/XComponentContext.hpp>
 
+#ifdef EMSCRIPTEN
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/frame/XDesktop2.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/propertyvalue.hxx>
+
+#include <unotools/mediadescriptor.hxx>
+
+#include <tools/urlobj.hxx>
+#endif
+
 #include <osl/conditn.hxx>
 #include <osl/mutex.hxx>
 #include <unotools/resmgr.hxx>
@@ -40,6 +56,9 @@
 #include <QtCore/QString>
 #include <QtCore/QStringList>
 #include <QtCore/QHash>
+#ifdef EMSCRIPTEN
+#include <QtWidgets/QtWidgets>
+#endif
 #include <QtWidgets/QFileDialog>
 
 #include <memory>
@@ -173,6 +192,15 @@ private:
 
     void prepareExecute();
 
+#ifdef EMSCRIPTEN
+    void headlessPdfConversionWASM();
+    void exportFileToPDFWASM(const OUString& rfileName);
+    css::uno::Reference<css::lang::XComponent>
+    loadFromDesktop(const OUString& rURL, const OUString& rDocService = 
OUString(),
+                    const css::uno::Sequence<css::beans::PropertyValue>& 
rExtra_args
+                    = css::uno::Sequence<css::beans::PropertyValue>());
+#endif
+
 private Q_SLOTS:
     // emit XFilePickerListener controlStateChanged event
     void filterSelected(const QString&);
diff --git a/vcl/qt5/QtFilePicker.cxx b/vcl/qt5/QtFilePicker.cxx
index 8a13ec67235c..403e46509031 100644
--- a/vcl/qt5/QtFilePicker.cxx
+++ b/vcl/qt5/QtFilePicker.cxx
@@ -67,6 +67,10 @@
 #include <fpicker/strings.hrc>
 #include <utility>
 
+#ifdef EMSCRIPTEN
+#include <emscripten.h>
+#endif
+
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::ui::dialogs;
 using namespace ::com::sun::star::ui::dialogs::TemplateDescription;
@@ -187,6 +191,128 @@ void QtFilePicker::prepareExecute()
     xDesktop->addTerminateListener(this);
 }
 
+#ifdef EMSCRIPTEN
+void QtFilePicker::headlessPdfConversionWASM()
+{
+    QLabel* fileInfo = new QLabel("Opened file:");
+    fileInfo->setTextInteractionFlags(Qt::TextSelectableByMouse);
+    QLabel* fileHash = new QLabel("Sha256:");
+    fileHash->setTextInteractionFlags(Qt::TextSelectableByMouse);
+    auto onFileReady = [=](const QString& fileName, const QByteArray& 
fileContents) {
+        if (fileName.isEmpty())
+        {
+            // No file selected
+        }
+        else
+        {
+            fileInfo->setText(
+                QString("Opened file: %1 sizei: 
%2").arg(fileName).arg(fileContents.size()));
+            auto computeDisplayFileHash = [=]() {
+                QByteArray hash
+                    = QCryptographicHash::hash(fileContents, 
QCryptographicHash::Sha256);
+                fileHash->setText(QString("Sha256: 
%1").arg(QString(hash.toHex())));
+            };
+            QTimer::singleShot(100, computeDisplayFileHash); // update UI 
before computing hash
+            std::string aFileName = "/android/default-document/" + 
fileName.toStdString();
+            EM_ASM(
+                { FS.writeFile(UTF8ToString($0), new 
Uint8Array(Module.HEAPU8.buffer, $1, $2)); },
+                aFileName.c_str(), fileContents.data(), fileContents.size());
+
+            exportFileToPDFWASM(toOUString(fileName));
+        }
+    };
+
+    QFileDialog::getOpenFileContent("*.*", onFileReady);
+}
+
+void QtFilePicker::exportFileToPDFWASM(const OUString& rfileName)
+{
+    utl::MediaDescriptor aMediaDescriptor;
+    // Explicitly enable the usage of the reference XObject markup.
+    uno::Sequence<beans::PropertyValue> aFilterData(
+        comphelper::InitPropertySequence({ { "UseReferenceXObject", 
uno::Any(true) } }));
+    aMediaDescriptor["FilterData"] <<= aFilterData;
+
+    INetURLObject aURL(OUString("file:///android/default-document/" + 
rfileName));
+    uno::Reference<lang::XComponent> xComponent
+        = 
loadFromDesktop(aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE));
+    if (xComponent.is())
+    {
+        uno::Reference<frame::XStorable> xStorable(xComponent, uno::UNO_QUERY);
+
+        if (xStorable.is())
+        {
+            OUString realfiltername = "writer_pdf_Export";
+            OUString aExt = aURL.getExtension();
+            if (aExt != "pdf")
+            {
+                if (aExt == "odt" || aExt == "ott")
+                {
+                    realfiltername = "writer_pdf_Export";
+                }
+                else if (aExt == "ods" || aExt == "ots")
+                {
+                    realfiltername = "calc_pdf_Export";
+                }
+                else if (aExt == "odp" || aExt == "otp")
+                {
+                    realfiltername = "impress_pdf_Export";
+                }
+                else if (aExt == "odg" || aExt == "otg")
+                {
+                    realfiltername = "draw_pdf_Export";
+                }
+                else
+                {
+                    // other types are not supported;
+                    return;
+                }
+                aURL.setExtension(std::u16string_view(u"pdf"));
+            }
+            aMediaDescriptor["FilterName"] <<= realfiltername;
+            aMediaDescriptor["FileName"]
+                <<= 
aURL.GetLastName(INetURLObject::DecodeMechanism::WithCharset);
+            
xStorable->storeToURL(aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE),
+                                  
aMediaDescriptor.getAsConstPropertyValueList());
+        }
+    }
+}
+
+uno::Reference<css::lang::XComponent>
+QtFilePicker::loadFromDesktop(const OUString& rURL, const OUString& 
rDocService,
+                              const uno::Sequence<beans::PropertyValue>& 
rExtraArgs)
+{
+    std::vector<beans::PropertyValue> args;
+
+    if (!rDocService.isEmpty())
+    {
+        beans::PropertyValue aValue;
+        aValue.Name = "DocumentService";
+        aValue.Handle = -1;
+        aValue.Value <<= rDocService;
+        aValue.State = beans::PropertyState_DIRECT_VALUE;
+        args.push_back(aValue);
+    }
+
+    args.insert(args.end(), rExtraArgs.begin(), rExtraArgs.end());
+
+    css::uno::Reference<css::uno::XComponentContext> xComponentContext;
+    
xComponentContext.set(comphelper::getComponentContext(comphelper::getProcessServiceFactory()));
+
+    css::uno::Reference<css::frame::XDesktop2> xDesktop;
+    xDesktop.set(frame::Desktop::create(xComponentContext));
+
+    if (xDesktop.is())
+    {
+        uno::Reference<lang::XComponent> xComponent = 
xDesktop->loadComponentFromURL(
+            rURL, "_default", 0, comphelper::containerToSequence(args));
+        return xComponent;
+    }
+
+    return uno::Reference<css::lang::XComponent>();
+}
+#endif
+
 void QtFilePicker::finished(int nResult)
 {
     SolarMutexGuard g;
@@ -217,8 +343,13 @@ sal_Int16 SAL_CALL QtFilePicker::execute()
         return ret;
     }
 
+#ifdef EMSCRIPTEN
+    headlessPdfConversionWASM();
+    int result = QFileDialog::Rejected;
+#else
     prepareExecute();
     int result = m_pFileDialog->exec();
+#endif
 
     if (QFileDialog::Rejected == result)
         return ExecutableDialogResults::CANCEL;
commit dff903db7e36f81dfba6bbe5cc26a91c1f2d6bb5
Author:     TheRock Builder <libo@therock>
AuthorDate: Thu Apr 28 14:19:46 2022 +0000
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sun Jan 15 01:19:14 2023 +0100

    Hack lokit API to be useable from JS
    
    So LOWA users/embeddings can call uno slots

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index f1903f1e9f44..82ba1b2ccf82 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1085,7 +1085,7 @@ static void 
doc_postWindowGestureEvent(LibreOfficeKitDocument* pThis,
                                       int nX,
                                       int nY,
                                       int nOffset);
-static void doc_postUnoCommand(LibreOfficeKitDocument* pThis,
+void doc_postUnoCommand(LibreOfficeKitDocument* pThis,
                                const char* pCommand,
                                const char* pArguments,
                                bool bNotifyWhenFinished);
@@ -4551,7 +4551,7 @@ void LibLibreOffice_Impl::dumpState(rtl::OStringBuffer 
&rState)
     vcl::lok::dumpState(rState);
 }
 
-static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* 
pCommand, const char* pArguments, bool bNotifyWhenFinished)
+void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pCommand, 
const char* pArguments, bool bNotifyWhenFinished)
 {
     comphelper::ProfileZone aZone("doc_postUnoCommand");
 
@@ -7342,9 +7342,19 @@ LibreOfficeKit *libreofficekit_hook_2(const char* 
install_path, const char* user
 }
 
 SAL_JNI_EXPORT
-LibreOfficeKit *libreofficekit_hook(const char* install_path)
+LibreOfficeKitDocument *libreofficekit_hook(const char*)
 {
-    return libreofficekit_hook_2(install_path, nullptr);
+    if (!gImpl)
+    {
+        gImpl = new LibLibreOffice_Impl();
+        xContext.set( ::comphelper::getProcessComponentContext(), 
uno::UNO_SET_THROW );    
+    }
+
+    uno::Reference<frame::XDesktop> xDesktop = 
frame::Desktop::create(xContext);
+    uno::Reference<lang::XComponent> xComponent = 
xDesktop->getCurrentComponent();
+    LibLODocument_Impl* pDocument = new LibLODocument_Impl(xComponent, 0);
+    
+    return pDocument;
 }
 
 SAL_JNI_EXPORT
commit 9ac05dc0b4ac2f0e1da65259ec9645574b4f292b
Author:     TheRock Builder <libo@therock>
AuthorDate: Thu Apr 28 14:19:22 2022 +0000
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sun Jan 15 01:19:14 2023 +0100

    Add more functions to export for LOWA

diff --git a/desktop/Executable_soffice_bin.mk 
b/desktop/Executable_soffice_bin.mk
index b0711af84952..4e321fa932e9 100644
--- a/desktop/Executable_soffice_bin.mk
+++ b/desktop/Executable_soffice_bin.mk
@@ -50,7 +50,7 @@ endif
 ifeq ($(OS),EMSCRIPTEN)
 
 $(eval $(call gb_Executable_add_ldflags,soffice_bin,\
-    -s 
EXPORTED_FUNCTIONS=["_main"$(COMMA)"_libreofficekit_hook"$(COMMA)"_libreofficekit_hook_2"$(COMMA)"_lok_preinit"$(COMMA)"_lok_preinit_2"]
 \
+       -s 
EXPORTED_FUNCTIONS=["_main"$(COMMA)"_libreofficekit_hook"$(COMMA)"_libreofficekit_hook_2"$(COMMA)"_lok_preinit"$(COMMA)"_lok_preinit_2"$(COMMA)"_doc_postUnoCommand"]
 \
 ))
 
 endif
commit 4664d148e2b8333e11ed1fe3dd8896806bcc1d86
Author:     TheRock Builder <libo@therock>
AuthorDate: Wed Apr 27 16:51:46 2022 +0000
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sun Jan 15 01:19:13 2023 +0100

    More fixup of gbuild

diff --git a/desktop/Executable_soffice_bin.mk 
b/desktop/Executable_soffice_bin.mk
index 123ccbe08ef4..b0711af84952 100644
--- a/desktop/Executable_soffice_bin.mk
+++ b/desktop/Executable_soffice_bin.mk
@@ -45,20 +45,12 @@ $(eval $(call gb_Executable_add_ldflags,soffice_bin,\
 
 endif
 
-ifeq ($(OS),EMSCRIPTEN)
-
-$(eval $(call gb_Executable_add_ldflags,soffice_bin,\
-    
-sEXPORTED_FUNCTIONS=_main,_libreofficekit_hook,_libreofficekit_hook_2,_lok_preinit,_lok_preinit_2
 \
-))
-
-endif
-
 endif
 
 ifeq ($(OS),EMSCRIPTEN)
 
 $(eval $(call gb_Executable_add_ldflags,soffice_bin,\
-       -s 
EXPORTED_FUNCTIONS=["_main"$(COMMA)"_libreofficekit_hook"$(COMMA)"_libreofficekit_hook_2"$(COMMA)"_lok_preinit"$(COMMA)"_lok_preinit_2"]
 \
+    -s 
EXPORTED_FUNCTIONS=["_main"$(COMMA)"_libreofficekit_hook"$(COMMA)"_libreofficekit_hook_2"$(COMMA)"_lok_preinit"$(COMMA)"_lok_preinit_2"]
 \
 ))
 
 endif
diff --git a/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk 
b/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk
index 8b825422453b..8f8155642852 100644
--- a/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk
+++ b/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk
@@ -24,14 +24,11 @@ gb_EMSCRIPTEN_LDFLAGS := $(gb_EMSCRIPTEN_CPPFLAGS)
 # Initial memory size and worker thread pool
 gb_EMSCRIPTEN_LDFLAGS += -s TOTAL_MEMORY=1GB -s PTHREAD_POOL_SIZE=4
 
-# add a few critical functions to export
-gb_EMSCRIPTEN_LDFLAGS += -sEXPORTED_RUNTIME_METHODS=ccall,cwrap
-
 # To keep the link time (and memory) down, prevent all rewriting options from 
wasm-emscripten-finalize
 # See emscripten.py, finalize_wasm, modify_wasm = True
 # So we need WASM_BIGINT=1 and ASSERTIONS=1 (2 implies STACK_OVERFLOW_CHECK)
 gb_EMSCRIPTEN_LDFLAGS += --bind -s FORCE_FILESYSTEM=1 -s WASM_BIGINT=1 -s 
ERROR_ON_UNDEFINED_SYMBOLS=1 -s FETCH=1 -s ASSERTIONS=1 -s EXIT_RUNTIME=0 -s 
EXPORTED_RUNTIME_METHODS=["UTF16ToString","stringToUTF16","UTF8ToString","allocateUTF8","printErr","ccall","cwrap"]
-gb_EMSCRIPTEN_QTDEFS := -DQT_NO_LINKED_LIST -DQT_NO_JAVA_STYLE_ITERATORS 
-DQT_NO_EXCEPTIONS -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB
+gb_EMSCRIPTEN_QTDEFS := -DQT_NO_LINKED_LIST -DQT_NO_JAVA_STYLE_ITERATORS 
-DQT_NO_EXCEPTIONS -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -DQT_NO_DEBUG 
-DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB
 
 gb_Executable_EXT := .html
 ifeq ($(ENABLE_WASM_EXCEPTIONS),TRUE)
commit 313c7f82fff028d2f6b30ad7360567c55e37fb37
Author:     TheRock Builder <libo@therock>
AuthorDate: Wed Apr 27 16:19:59 2022 +0000
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sun Jan 15 01:19:13 2023 +0100

    Fix logic

diff --git a/desktop/Executable_soffice_bin.mk 
b/desktop/Executable_soffice_bin.mk
index d1db854ec0fd..123ccbe08ef4 100644
--- a/desktop/Executable_soffice_bin.mk
+++ b/desktop/Executable_soffice_bin.mk
@@ -45,7 +45,7 @@ $(eval $(call gb_Executable_add_ldflags,soffice_bin,\
 
 endif
 
-ifeq (TRUE,$(EMSCRIPTEN))
+ifeq ($(OS),EMSCRIPTEN)
 
 $(eval $(call gb_Executable_add_ldflags,soffice_bin,\
     
-sEXPORTED_FUNCTIONS=_main,_libreofficekit_hook,_libreofficekit_hook_2,_lok_preinit,_lok_preinit_2
 \
commit 904cceefac67e1790298a1b688cf0b8832600f93
Author:     TheRock Builder <libo@therock>
AuthorDate: Wed Apr 27 15:36:25 2022 +0000
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sun Jan 15 01:19:13 2023 +0100

    Add LOKit functions and whitelist export for it to WASM
    
    For calling into LOWA from native JS, make lokit functions available

diff --git a/desktop/Executable_soffice_bin.mk 
b/desktop/Executable_soffice_bin.mk
index ce908c1be318..d1db854ec0fd 100644
--- a/desktop/Executable_soffice_bin.mk
+++ b/desktop/Executable_soffice_bin.mk
@@ -45,6 +45,14 @@ $(eval $(call gb_Executable_add_ldflags,soffice_bin,\
 
 endif
 
+ifeq (TRUE,$(EMSCRIPTEN))
+
+$(eval $(call gb_Executable_add_ldflags,soffice_bin,\
+    
-sEXPORTED_FUNCTIONS=_main,_libreofficekit_hook,_libreofficekit_hook_2,_lok_preinit,_lok_preinit_2
 \
+))
+
+endif
+
 endif
 
 ifeq ($(OS),EMSCRIPTEN)
diff --git a/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk 
b/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk
index 8831aeeb5d54..8b825422453b 100644
--- a/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk
+++ b/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk
@@ -24,6 +24,9 @@ gb_EMSCRIPTEN_LDFLAGS := $(gb_EMSCRIPTEN_CPPFLAGS)
 # Initial memory size and worker thread pool
 gb_EMSCRIPTEN_LDFLAGS += -s TOTAL_MEMORY=1GB -s PTHREAD_POOL_SIZE=4
 
+# add a few critical functions to export
+gb_EMSCRIPTEN_LDFLAGS += -sEXPORTED_RUNTIME_METHODS=ccall,cwrap
+
 # To keep the link time (and memory) down, prevent all rewriting options from 
wasm-emscripten-finalize
 # See emscripten.py, finalize_wasm, modify_wasm = True
 # So we need WASM_BIGINT=1 and ASSERTIONS=1 (2 implies STACK_OVERFLOW_CHECK)
commit b257193c66ad8bcc67026891342caca73b6e5025
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Tue Apr 26 18:11:55 2022 +0200
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sun Jan 15 01:19:13 2023 +0100

    WASM HACK fix NEH build
    
    Workaround a toolchain bug. Also see comment in ~Desktop().
    
    Change-Id: I158877b78794d81ccdc74e4d5fc023e2061c1d96

diff --git a/desktop/inc/app.hxx b/desktop/inc/app.hxx
index 3372e751dbf1..8eb71d3b13b5 100644
--- a/desktop/inc/app.hxx
+++ b/desktop/inc/app.hxx
@@ -166,7 +166,7 @@ class Desktop final : public Application
         BootstrapStatus         m_aBootstrapStatus;
 
         std::unique_ptr<Lockfile> m_xLockfile;
-        Timer                   m_firstRunTimer;
+        Timer                   *m_firstRunTimer;
         std::thread             m_aUpdateThread;
 };
 
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index 135a5b5fdb1f..11727f8af92e 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -426,14 +426,16 @@ Desktop::Desktop()
     , m_bServicesRegistered(false)
     , m_aBootstrapError(BE_OK)
     , m_aBootstrapStatus(BS_OK)
-    , m_firstRunTimer( "desktop::Desktop m_firstRunTimer" )
+    , m_firstRunTimer(new Timer("desktop::Desktop m_firstRunTimer"))
 {
-    m_firstRunTimer.SetTimeout(3000); // 3 sec.
-    m_firstRunTimer.SetInvokeHandler(LINK(this, Desktop, AsyncInitFirstRun));
+    m_firstRunTimer->SetTimeout(3000); // 3 sec.
+    m_firstRunTimer->SetInvokeHandler(LINK(this, Desktop, AsyncInitFirstRun));
 }
 
 Desktop::~Desktop()
 {
+// Uncommenting this delete breaks the WASM output with a runtime error
+//    delete m_firstRunTimer;
 }
 
 void Desktop::Init()
@@ -2560,7 +2562,7 @@ void Desktop::CheckFirstRun( )
 
     // use VCL timer, which won't trigger during shutdown if the
     // application exits before timeout
-    m_firstRunTimer.Start();
+    m_firstRunTimer->Start();
 
 #ifdef _WIN32
     // Check if Quickstarter should be started (on Windows only)
commit 85259486e754129d16d01e4b0f0ef61fc49ddf75
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Sun Feb 20 14:06:54 2022 +0100
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sun Jan 15 01:19:13 2023 +0100

    fixme static tests
    
    Change-Id: I2aaffa032bd531272257ca40d6f9b9d25c4de5aa

diff --git a/sal/cppunittester/cppunittester.cxx 
b/sal/cppunittester/cppunittester.cxx
index 2cab53d6c1f6..7026f7b60f75 100644
--- a/sal/cppunittester/cppunittester.cxx
+++ b/sal/cppunittester/cppunittester.cxx
@@ -245,6 +245,7 @@ public:
         , protectors(protectors_)
         , result(result_)
     {
+        (void) args_;
     }
     ProtectedFixtureFunctor(const ProtectedFixtureFunctor&) = delete;
     ProtectedFixtureFunctor& operator=(const ProtectedFixtureFunctor&) = 
delete;
commit 1aeed3a5babad0a7c51e987ed31b5f433f2e18eb
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Sun Jan 9 14:49:28 2022 +0100
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sun Jan 15 01:19:13 2023 +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 f2cf08f65107..a258e1ed0f3f 100644
--- a/static/CustomTarget_emscripten_fs_image.mk
+++ b/static/CustomTarget_emscripten_fs_image.mk
@@ -1409,6 +1409,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 \
        $(SRCDIR)/android/default-document/example_test.ods \
 
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 56e5f090875a2db46aaa29585831580284c6e92a
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Wed Nov 17 01:57:33 2021 +0100
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sun Jan 15 01:19:13 2023 +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 9b3fed6d5f23..b43eb3d3493a 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 <rtl/ref.hxx>
 #include <sfx2/dllapi.h>
@@ -44,6 +45,7 @@ class VCLXPopupMenu;
 
 namespace com::sun::star::awt { class XPopupMenu; }
 namespace vcl { class Window; }
+namespace com::sun::star::ui::dialogs { struct DialogClosedEvent; }
 
 enum class SfxDispatcherPopFlags
 {
@@ -138,8 +140,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 bc971a2088ec..f5f4c47cf6a2 100644
--- a/include/toolkit/awt/vclxmenu.hxx
+++ b/include/toolkit/awt/vclxmenu.hxx
@@ -25,9 +25,10 @@
 #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/ui/dialogs/XDialogClosedListener.hpp>
 
 #include <comphelper/servicehelper.hxx>
 #include <cppuhelper/weak.hxx>
@@ -38,6 +39,7 @@
 
 #include <vector>
 
+struct DialogClosedEvent;
 class Menu;
 class MenuBar;
 class PopupMenu;
@@ -50,9 +52,10 @@ 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::ui::dialogs::XDialogClosedListener,
                                     public ::cppu::OWeakObject
 {
 private:
@@ -74,7 +77,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);
@@ -132,10 +134,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 bb0ef8cee6db..161ee029e2a8 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
@@ -494,11 +496,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;
@@ -521,6 +528,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 4913d17747c6..479ce9395d61 100644
--- a/offapi/UnoApi_offapi.mk
+++ b/offapi/UnoApi_offapi.mk
@@ -1860,6 +1860,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 b21789c80137..b62f15250aeb 100644
--- a/sd/source/ui/view/drviews4.cxx
+++ b/sd/source/ui/view/drviews4.cxx
@@ -809,7 +809,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 e72f4706dd8e..5e042f056f6e 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,7 +1749,7 @@ 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;
         }
     }
@@ -1807,7 +1857,8 @@ boost::property_tree::ptree 
SfxDispatcher::fillPopupMenu(const rtl::Reference<VC
     return ::fillPopupMenu(pVCLMenu);
 }
 
-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 )),
@@ -1816,15 +1867,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;
 
     rtl::Reference< VCLXPopupMenu > xPopupMenu = new VCLXPopupMenu();
 
-    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();
 
@@ -1850,14 +1915,21 @@ 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);
+            pFin = new SfxDispatcherPopupFinish(xPopupController, rCloseFunc, 
xPopupMenu);
+            if (!rCloseFunc || !xPopupMenu->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 b0a320168924..3d4a37e37768 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -5610,7 +5610,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 52edfb5caa49..a48346ba1716 100644
--- a/toolkit/source/awt/vclxmenu.cxx
+++ b/toolkit/source/awt/vclxmenu.cxx
@@ -35,6 +35,7 @@
 #include <vcl/window.hxx>
 
 #include <com/sun/star/awt/KeyModifier.hpp>
+#include <com/sun/star/ui/dialogs/DialogClosedEvent.hpp>
 
 VCLXMenu::VCLXMenu()
     : maMenuListeners( *this )
@@ -487,6 +488,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 0fa36e82cab4..f50aab1ef440 100644
--- a/toolkit/source/helper/unowrapper.cxx
+++ b/toolkit/source/helper/unowrapper.cxx
@@ -189,7 +189,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 274d1ecd70b2..83068b8d9a7f 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 6bb0dbcab4ec..501caaf4d089 100644
--- a/vcl/inc/qt5/QtMenu.hxx
+++ b/vcl/inc/qt5/QtMenu.hxx
@@ -40,7 +40,7 @@ class QtFrame;
 class QtMenu : public QObject, public SalMenu
 {
     Q_OBJECT
-private:
+
     std::vector<QtMenuItem*> maItems;
     VclPtr<Menu> mpVCLMenu;
     QtMenu* mpParentSalMenu;
@@ -53,6 +53,9 @@ private:
     QMenu* mpQMenu;
     QButtonGroup* m_pButtonGroup;
 
+    css::uno::Reference<css::ui::dialogs::XDialogClosedListener> m_xListener;
+    FloatingWindow* m_pWin;
+
     void DoFullMenuUpdate(Menu* pMenuBar);
     static void NativeItemText(OUString& rItemText);
 
@@ -78,8 +81,9 @@ public:
     virtual void SetSubMenu(SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, 
unsigned nPos) override;
     virtual void SetFrame(const SalFrame* pFrame) override;
     const QtFrame* GetFrame() const;
-    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 50c1e9f4bc8a..473a4deebd62 100644
--- a/vcl/inc/salmenu.hxx
+++ b/vcl/inc/salmenu.hxx
@@ -23,6 +23,7 @@
 #include <utility>
 #include <vcl/menu.hxx>
 #include <vcl/image.hxx>
+#include <com/sun/star/ui/dialogs/XDialogClosedListener.hpp>
 
 struct SystemMenuData;
 class FloatingWindow;
@@ -83,7 +84,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 fc8ab760f5f5..f6b83052037d 100644
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
@@ -131,7 +131,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 60cafca71df4..b1a71f224f65 100644
--- a/vcl/osx/salmenu.cxx
+++ b/vcl/osx/salmenu.cxx
@@ -282,8 +282,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 dd259f32f979..758fd1765263 100644
--- a/vcl/qt5/QtMenu.cxx
+++ b/vcl/qt5/QtMenu.cxx
@@ -108,6 +108,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)
@@ -829,7 +839,8 @@ void QtMenu::ShowCloseButton(bool bShow)
 }
 
 bool QtMenu::ShowNativePopupMenu(FloatingWindow* pWin, const tools::Rectangle& 
rRect,
-                                 FloatWinPopupFlags nFlags)
+                                 FloatWinPopupFlags nFlags,
+                                 const 
css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* pListener)
 {
     assert(mpQMenu);
     DoFullMenuUpdate(mpVCLMenu);
@@ -840,7 +851,19 @@ bool QtMenu::ShowNativePopupMenu(FloatingWindow* pWin, 
const tools::Rectangle& r
     assert(pFrame);
     const tools::Rectangle aFloatRect = 
FloatingWindow::ImplConvertToAbsPos(xParent, rRect);
     const QRect aRect = toQRect(aFloatRect, 1 / pFrame->devicePixelRatioF());
-    mpQMenu->exec(aRect.topLeft());
+
+    if (pListener)
+    {
+        m_xListener = *pListener;
+        m_pWin = pWin;
+        mpQMenu->popup(aRect.topLeft());
+    }
+    else
+    {
+        m_xListener = nullptr;
+        m_pWin = nullptr;
+        mpQMenu->exec(aRect.topLeft());
+    }
 
     return true;
 }
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 733d78179500..e7afeb6950b1 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -217,7 +217,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 bf3065e71cdf..0bb521e201dd 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 bf02fab4c698..ec938dd76291 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -2660,6 +2660,7 @@ MenuFloatingWindow * PopupMenu::ImplGetFloatingWindow() 
const {
 }
 
 PopupMenu::PopupMenu()
+    : m_pState(nullptr)
 {
     mpSalMenu = ImplGetSVData()->mpDefInst->CreateMenu(false, this);
 }
@@ -2672,6 +2673,7 @@ PopupMenu::PopupMenu( const PopupMenu& rMenu )
 
 PopupMenu::~PopupMenu()
 {
+    assert(!m_pState);
     disposeOnce();
 }
 
@@ -2769,6 +2771,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?
@@ -2920,7 +2952,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 )
     {
@@ -2936,10 +2968,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);
@@ -2975,7 +3008,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;
 }
@@ -3020,11 +3058,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 bb4048485db9..f8b5d550a119 100644
--- a/vcl/unx/gtk3/gtksalmenu.cxx
+++ b/vcl/unx/gtk3/gtksalmenu.cxx
@@ -423,9 +423,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 40d3569a44f5ee98106423cb2b4585b6026779f9
Author:     Thorsten Behrens <thorsten.behr...@allotropia.de>
AuthorDate: Sat Nov 13 23:12:58 2021 +0100
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sat Jan 14 23:49:26 2023 +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 bdc4b1869ded..f1903f1e9f44 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -6932,7 +6932,11 @@ static void activateNotebookbar(std::u16string_view rApp)
 
     if (aAppNode.isValid())
     {
+#ifdef EMSCRIPTEN
+        aAppNode.setNodeValue("Active", Any(OUString("notebookbar.ui")));
+#else
         aAppNode.setNodeValue("Active", 
Any(OUString("notebookbar_online.ui")));
+#endif
         aAppNode.commit();
     }
 }
@@ -6993,7 +6997,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 f717178352fe40ce5b0b14b1e11831d5fc3df2a1
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Mon Dec 6 09:24:50 2021 +0100
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sat Jan 14 23:49:22 2023 +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 89eb990b3354..811e9cf27d7d 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 \
@@ -589,6 +589,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 854d46a8e6d4..81ba1b6f3c11 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 EMSCRIPTEN), \
                Library_lo-bootstrap) \
        Library_sal \
diff --git a/sal/cppunittester/cppunittester.cxx 
b/sal/cppunittester/cppunittester.cxx
index 8a9e184c431d..2cab53d6c1f6 100644
--- a/sal/cppunittester/cppunittester.cxx
+++ b/sal/cppunittester/cppunittester.cxx
@@ -231,13 +231,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 b16e3d0e5417..6ed65e40e608 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 += \
@@ -204,6 +210,11 @@ $(call gb_CppunitTest_get_target,$(1)) : EXTRA_ENV_VARS :=
 $(call gb_CppunitTest_get_target,$(1)) : NON_APPLICATION_FONT_USE :=
 $$(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 4f3814f2a5d2..849caa8c3079 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 44539cc5576d..6d2d401a6232 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 f14e9f1a1ed4..8958a95a1964 100644
--- a/solenv/gbuild/gbuild.mk
+++ b/solenv/gbuild/gbuild.mk
@@ -295,6 +295,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 bfb860a41fc2..d950f8dbd444 100644
--- a/solenv/gbuild/platform/unxgcc.mk
+++ b/solenv/gbuild/platform/unxgcc.mk
@@ -322,12 +322,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 9b98ec99c593..2e088d1bb06d 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 d0cf8cdbe9070578588d2630ab1bc375c56d5387
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Sat Jan 8 22:53:29 2022 +0100
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sat Jan 14 23:46:46 2023 +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 321df930b915..3489a507bf34 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 coverage internal.clean $(gb_Top_MODULE_CHECK_TARGETS)
diff --git a/bin/run b/bin/run
index 695905e09e6b..882f358403fd 100755
--- a/bin/run
+++ b/bin/run
@@ -107,6 +107,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 ece7650ded4c..0c0a3fbd5580 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>
 #include <o3tl/string_view.hxx>
@@ -65,7 +67,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).
@@ -75,7 +86,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 8e8353c717629e049aa15cda86bcd9a3ea205e84
Author:     Andrea Gelmini <andrea.gelm...@gelma.net>
AuthorDate: Sat Jan 14 18:48:59 2023 +0100
Commit:     Julien Nabet <serval2...@yahoo.fr>
CommitDate: Sat Jan 14 22:46:09 2023 +0000

    Fix typos and exec bits
    
    Change-Id: Ia23a7b507a8254a5d9143de055c28da9656425fc
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145515
    Tested-by: Jenkins
    Reviewed-by: Julien Nabet <serval2...@yahoo.fr>

diff --git a/drawinglayer/source/processor2d/SDPRProcessor2dTools.cxx 
b/drawinglayer/source/processor2d/SDPRProcessor2dTools.cxx
old mode 100755
new mode 100644
diff --git a/drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx 
b/drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx
index 4f7632ece672..e93e1375bc07 100644
--- a/drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx
@@ -1790,7 +1790,7 @@ void D2DPixelProcessor2D::processFillGraphicPrimitive2D(
     if (aPreparedBitmap.IsEmpty())
     {
         // output needed and Bitmap data empty, so no bitmap data based
-        // tiled rendering is suggested. Use fallback for paint (decompositon)
+        // tiled rendering is suggested. Use fallback for paint (decomposition)
         process(rFillGraphicPrimitive2D);
         return;
     }
diff --git a/include/drawinglayer/primitive2d/fillgraphicprimitive2d.hxx 
b/include/drawinglayer/primitive2d/fillgraphicprimitive2d.hxx
index 899851adc84e..d119c8f9c2b9 100644
--- a/include/drawinglayer/primitive2d/fillgraphicprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/fillgraphicprimitive2d.hxx
@@ -72,7 +72,7 @@ namespace drawinglayer::primitive2d
             /// local decomposition.
             virtual void create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& rViewInformation) const override;
 
-            // allow this single acessor to change it to set buggered data
+            // allow this single accessor to change it to set buggered data
             friend void drawinglayer::processor2d::setOffsetXYCreatedBitmap(
                 drawinglayer::primitive2d::FillGraphicPrimitive2D&,
                 const BitmapEx&);
commit 307206ba04e7ac3882b3bfd433f7f0a4d66c8738
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Sat Jan 14 19:36:16 2023 +0000
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Sat Jan 14 20:53:51 2023 +0000

    ooo_vba_VBAToOOEventDesc_get_implementation appears twice
    
    Change-Id: Ic11d112b92d0942a4246e80e4da8ca1065fd12c1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145521
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/solenv/bin/native-code.py b/solenv/bin/native-code.py
index 07f9f94ae481..7bb33ebe6f0f 100755
--- a/solenv/bin/native-code.py
+++ b/solenv/bin/native-code.py
@@ -648,8 +648,6 @@ calc_constructor_list = [
     "scaddins_ScaDateAddIn_get_implementation",
 # scaddins/source/pricing/pricing.component
     "scaddins_ScaPricingAddIn_get_implementation",
-# scripting/source/vbaevents/vbaevents.component
-    ("ooo_vba_VBAToOOEventDesc_get_implementation", "#if 
HAVE_FEATURE_SCRIPTING"),
 # svl/util/svl.component
     
"com_sun_star_uno_util_numbers_SvNumberFormatsSupplierServiceObject_get_implementation",
     
"com_sun_star_uno_util_numbers_SvNumberFormatterServiceObject_get_implementation",
commit 8f1c4f341deccead80dd7d0528e6fd4993428601
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Sat Jan 14 19:33:41 2023 +0000
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Sat Jan 14 20:53:38 2023 +0000

    com_sun_star_comp_chart2_ChartDocumentWrapper_get_implementation appears 
twice
    
    Change-Id: If413be43e68af71ce4f2d1f8e43e4c0d0a5bdc2a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145520
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/solenv/bin/native-code.py b/solenv/bin/native-code.py
index a0ccdcbb523b..07f9f94ae481 100755
--- a/solenv/bin/native-code.py
+++ b/solenv/bin/native-code.py
@@ -66,7 +66,6 @@ core_constructor_list = [
     "com_sun_star_comp_chart2_CartesianCoordinateSystem2d_get_implementation",
     "com_sun_star_comp_chart2_CartesianCoordinateSystem3d_get_implementation",
     "com_sun_star_comp_chart2_ChartController_get_implementation",
-    "com_sun_star_comp_chart2_ChartDocumentWrapper_get_implementation",
     "com_sun_star_comp_chart2_ChartModel_get_implementation",
     "com_sun_star_comp_chart2_ChartView_get_implementation",
     "com_sun_star_comp_chart2_ConfigDefaultColorScheme_get_implementation",
commit 516a3382a774565d4708766ec796c54196563f5a
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Sat Jan 14 09:20:41 2023 -0500
Commit:     Justin Luth <jl...@mail.com>
CommitDate: Sat Jan 14 18:35:43 2023 +0000

    tdf#117266 sc oox: import local macro without reference id
    
    This is what LO exports - a macro without a local ([0]!)
    or remote ([2]!) reference.
    
    It must be at least somewhat valid because MS Word imports
    these just fine. So why don't import what we export...
    
    Change-Id: I8f69c373552b559efcfe7cbb06ea3a706d8ad0d4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145511
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <jl...@mail.com>

diff --git a/sc/source/filter/oox/formulaparser.cxx 
b/sc/source/filter/oox/formulaparser.cxx
index f4eb7419b7cb..b832fa9636d7 100644
--- a/sc/source/filter/oox/formulaparser.cxx
+++ b/sc/source/filter/oox/formulaparser.cxx
@@ -1821,8 +1821,11 @@ OUString FormulaParser::importMacroName( 
std::u16string_view aFormulaString )
         document, ignoring the valid syntax 'Macro1!MyMacro' for sheet-local
         sheet macros.
      */
+    OUString aRemainder(aFormulaString);
+    if (aRemainder.indexOf('!') == -1)
+        return aRemainder;
+
     sal_Int32 nRefId = -1;
-    OUString aRemainder;
     if( lclExtractRefId( nRefId, aRemainder, aFormulaString ) && 
(aRemainder.getLength() > 1) && (aRemainder[ 0 ] == '!') )
     {
         /*  In BIFF12 documents, the reference identifier is always the
commit 93b042f488db7d036821efdb967747a1f9c838e0
Author:     Xisco Fauli <xiscofa...@libreoffice.org>
AuthorDate: Fri Jan 13 10:56:55 2023 +0100
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Sat Jan 14 17:26:33 2023 +0000

    svx: avoid divide by zero in SvxRuler::UpdateTabs()
    
    Prevent lDefTabDist from ending up in a zero state.
    
    See 
https://crashreport.libreoffice.org/stats/signature/SvxRuler::UpdateTabs()
    
    Change-Id: I9335f3be12de5db4f4f0c3f434057d91f96733ab
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145457
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/svx/source/dialog/svxruler.cxx b/svx/source/dialog/svxruler.cxx
index 4d873c23773e..be53a0c91c58 100644
--- a/svx/source/dialog/svxruler.cxx
+++ b/svx/source/dialog/svxruler.cxx
@@ -969,6 +969,9 @@ void SvxRuler::SetDefTabDist(tools::Long inDefTabDist)  // 
New distance for Defa
         UpdateFrame(); // hack: try to get lAppNullOffset initialized
     /* New distance is set for DefaultTabs */
     lDefTabDist = inDefTabDist;
+    if( !lDefTabDist )
+        lDefTabDist = 1;
+
     UpdateTabs();
 }
 
@@ -1026,9 +1029,6 @@ void SvxRuler::UpdateTabs()
 
         tools::Long nDefTabDist = ConvertHPosPixel(lDefTabDist);
 
-        if( !nDefTabDist )
-            nDefTabDist = 1;
-
         const sal_uInt16 nDefTabBuf = lPosPixel > lRightIndent || lLastTab > 
lRightIndent
                     ? 0
                     : static_cast<sal_uInt16>( (lRightIndent - lPosPixel) / 
nDefTabDist );
commit 79c7620c5e6f38959356ebf547c367bbc8a245ae
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Fri Jan 13 09:18:55 2023 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Sat Jan 14 17:25:02 2023 +0000

    XUnoTunnel->dynamic_cast in SecurityEnvironmentGpg
    
    Change-Id: I8535b32de2c7cb71a5108211af0e896029ff5608
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145501
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/xmlsecurity/source/gpg/SecurityEnvironment.cxx 
b/xmlsecurity/source/gpg/SecurityEnvironment.cxx
index 38d0563b161e..e6813228a457 100644
--- a/xmlsecurity/source/gpg/SecurityEnvironment.cxx
+++ b/xmlsecurity/source/gpg/SecurityEnvironment.cxx
@@ -90,23 +90,6 @@ SecurityEnvironmentGpg::~SecurityEnvironmentGpg()
 {
 }
 
-/* XUnoTunnel */
-sal_Int64 SAL_CALL SecurityEnvironmentGpg::getSomething( const Sequence< 
sal_Int8 >& aIdentifier )
-{
-    return comphelper::getSomethingImpl(aIdentifier, this);
-}
-
-/* XUnoTunnel extension */
-
-namespace
-{
-}
-
-const Sequence< sal_Int8>& SecurityEnvironmentGpg::getUnoTunnelId() {
-    static const comphelper::UnoIdInit theSecurityEnvironmentUnoTunnelId;
-    return theSecurityEnvironmentUnoTunnelId.getSeq();
-}
-
 OUString SecurityEnvironmentGpg::getSecurityEnvironmentInformation()
 {
     return OUString();
diff --git a/xmlsecurity/source/gpg/SecurityEnvironment.hxx 
b/xmlsecurity/source/gpg/SecurityEnvironment.hxx
index 262578682274..0c530c671596 100644
--- a/xmlsecurity/source/gpg/SecurityEnvironment.hxx
+++ b/xmlsecurity/source/gpg/SecurityEnvironment.hxx
@@ -18,13 +18,11 @@
 
 #include <com/sun/star/uno/Reference.hxx>
 #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
-#include <com/sun/star/lang/XUnoTunnel.hpp>
 
 namespace com::sun::star::security { class XCertificate; }
 namespace GpgME { class Context; }
 
-class SecurityEnvironmentGpg : public cppu::WeakImplHelper< 
css::xml::crypto::XSecurityEnvironment,
-                                                            
css::lang::XUnoTunnel >
+class SecurityEnvironmentGpg : public cppu::WeakImplHelper< 
css::xml::crypto::XSecurityEnvironment >
 {
     std::unique_ptr<GpgME::Context> m_ctx;
 

... etc. - the rest is truncated

Reply via email to