diff --git a/sfx2/source/control/dispatch.cxx b/sfx2/source/control/dispatch.cxx index 1959b5e81efa..9fd3a0153a66 100644 --- a/sfx2/source/control/dispatch.cxx +++ b/sfx2/source/control/dispatch.cxx @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -1902,6 +1903,23 @@ void SfxDispatcher::ExecutePopup( const OUString& rResName, vcl::Window* pWin, c css::uno::Reference< css::frame::XPopupMenuController > xPopupController( xContext->getServiceManager()->createInstanceWithArgumentsAndContext( u"com.sun.star.comp.framework.ResourceMenuController"_ustr, aArgs, xContext ), css::uno::UNO_QUERY ); +#if defined EMSCRIPTEN && ENABLE_QT5 + // At least under Emscripten with Qt5, the QMenu::exec underlying the below call to + // xPopupMenu->execute returns immediately, without going into a new event loop, and we need to + // keep the underlying QMenu instance alive via the static lastPopupController chain here, until + // the next popup menu is opened (there can only ever be a single popup menu open, so it + // suffices to have a single static lastPopupController instance): + static css::uno::Reference lastPopupController; + if (lastPopupController.is()) { + if (css::uno::Reference component( + lastPopupController, css::uno::UNO_QUERY); + component.is()) + { + component->dispose(); + } + lastPopupController = xPopupController; + } +#endif rtl::Reference< VCLXPopupMenu > xPopupMenu = new VCLXPopupMenu(); @@ -1938,9 +1956,11 @@ void SfxDispatcher::ExecutePopup( const OUString& rResName, vcl::Window* pWin, c } } +#if !(defined EMSCRIPTEN && ENABLE_QT5) css::uno::Reference< css::lang::XComponent > xComponent( xPopupController, css::uno::UNO_QUERY ); if ( xComponent.is() ) xComponent->dispose(); +#endif } /** With this method the SfxDispatcher can be locked and released. A locked