framework/source/uielement/menubarmanager.cxx | 41 +++++++++++++++++--------- 1 file changed, 28 insertions(+), 13 deletions(-)
New commits: commit e931c4e9399ba96054ed153204627579242a5cc6 Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Fri Jun 13 21:44:21 2025 +0500 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Sat Jun 14 08:41:13 2025 +0200 tdf#166996: handle menu commands asynchronously Instead of doing that command by command, this change tries to do it globally, posting user event with the command data; it will run when event loop gets to it; the menu gets closed by that time. Change-Id: Ifdea666be8557a576dd6cd934898343631a3a95e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186470 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> diff --git a/framework/source/uielement/menubarmanager.cxx b/framework/source/uielement/menubarmanager.cxx index caa0aaa36ce3..f740121f386c 100644 --- a/framework/source/uielement/menubarmanager.cxx +++ b/framework/source/uielement/menubarmanager.cxx @@ -773,11 +773,29 @@ IMPL_LINK_NOARG( MenuBarManager, AsyncSettingsHdl, Timer*, void) } } -IMPL_LINK( MenuBarManager, Select, Menu *, pMenu, bool ) +namespace +{ +struct MenuExecData { - URL aTargetURL; + URL aTargetURL; std::vector<beans::PropertyValue> aArgs; - Reference< XDispatch > xDispatch; + Reference<XDispatch> xDispatch; +}; + +void AsyncMenuExecute(void* /*instance*/, void* data) +{ + std::unique_ptr<MenuExecData> pData(static_cast<MenuExecData*>(data)); + { + SolarMutexReleaser aReleaser; + pData->xDispatch->dispatch(pData->aTargetURL, + comphelper::containerToSequence(pData->aArgs)); + } +} +} + +IMPL_LINK( MenuBarManager, Select, Menu *, pMenu, bool ) +{ + auto pData = std::make_unique<MenuExecData>(); { SolarMutexGuard g; @@ -790,13 +808,13 @@ IMPL_LINK( MenuBarManager, Select, Menu *, pMenu, bool ) MenuItemHandler* pMenuItemHandler = GetMenuItemHandler( nCurItemId ); if ( pMenuItemHandler && pMenuItemHandler->xMenuItemDispatch.is() ) { - aTargetURL.Complete = pMenuItemHandler->aMenuItemURL; - m_xURLTransformer->parseStrict( aTargetURL ); + pData->aTargetURL.Complete = pMenuItemHandler->aMenuItemURL; + m_xURLTransformer->parseStrict( pData->aTargetURL ); if ( pMenu->GetUserValue( nCurItemId ) ) { // addon menu item selected - aArgs.push_back( + pData->aArgs.push_back( comphelper::makePropertyValue(u"Referer"_ustr, u"private:user"_ustr)); } @@ -806,19 +824,16 @@ IMPL_LINK( MenuBarManager, Select, Menu *, pMenu, bool ) const sal_Int16 nKeys = pWindow ? pWindow->GetPointerState().mnState & KEY_MODIFIERS_MASK : 0; if (nKeys) - aArgs.push_back(comphelper::makePropertyValue(u"KeyModifier"_ustr, nKeys)); + pData->aArgs.push_back(comphelper::makePropertyValue(u"KeyModifier"_ustr, nKeys)); - xDispatch = pMenuItemHandler->xMenuItemDispatch; + pData->xDispatch = pMenuItemHandler->xMenuItemDispatch; } } } - // tdf#126054 don't let dispatch destroy this until after function completes - rtl::Reference<MenuBarManager> xKeepAlive(this); - if (xDispatch.is()) + if (pData->xDispatch.is()) { - SolarMutexReleaser aReleaser; - xDispatch->dispatch(aTargetURL, comphelper::containerToSequence(aArgs)); + Application::PostUserEvent(LINK_NONMEMBER(nullptr, AsyncMenuExecute), pData.release()); } if ( !m_bHasMenuBar )