Rebased ref, commits from common ancestor: commit 0381606c401422b95e3ded4277e40b83f5b86042 Author: Jan-Marek Glogowski <glo...@fbihome.de> AuthorDate: Sun Jan 9 14:49:28 2022 +0100 Commit: Jan-Marek Glogowski <glo...@fbihome.de> CommitDate: Mon Jan 10 05:25:47 2022 +0100
Add a larger Writer example document Change-Id: I4bc9a82c7f99563af8da62f889b51d1b583df760 diff --git a/android/default-document/example_larger.odt b/android/default-document/example_larger.odt new file mode 100644 index 000000000000..1b3a1dfb877a Binary files /dev/null and b/android/default-document/example_larger.odt differ diff --git a/static/CustomTarget_wasm_fs_image.mk b/static/CustomTarget_wasm_fs_image.mk index e11d57e359e5..e88d5f422a63 100644 --- a/static/CustomTarget_wasm_fs_image.mk +++ b/static/CustomTarget_wasm_fs_image.mk @@ -1169,6 +1169,7 @@ gb_wasm_fs_image_files := \ $(INSTROOT)/$(LIBO_SHARE_RESOURCE_FOLDER)/common/fonts/opens___.ttf \ $(INSTROOT)/$(LIBO_URE_ETC_FOLDER)/$(call gb_Helper_get_rcfile,uno) \ $(INSTROOT)/$(LIBO_URE_MISC_FOLDER)/services.rdb \ + $(SRCDIR)/android/default-document/example_larger.odt \ $(SRCDIR)/android/default-document/example.odt \ ifneq ($(ENABLE_WASM_STRIP_CHART),TRUE) diff --git a/static/emscripten/soffice_args.js b/static/emscripten/soffice_args.js index 7ecf7e8988e8..fa5e9dd4164d 100644 --- a/static/emscripten/soffice_args.js +++ b/static/emscripten/soffice_args.js @@ -2,5 +2,5 @@ Module['arguments'] = [ '--norestore', '--nologo', '--writer', - '/android/default-document/example.odt' + '/android/default-document/example_larger.odt' ]; commit fab9e2f78f42c0f598c16ad8b9a0441b5f94b2b3 Author: Jan-Marek Glogowski <glo...@fbihome.de> AuthorDate: Wed Nov 17 01:57:33 2021 +0100 Commit: Jan-Marek Glogowski <glo...@fbihome.de> CommitDate: Mon Jan 10 05:25:47 2022 +0100 WIP: async popup menus A first patch to get some feedback. Asnyc LO popup menus are still buggy, as I'm not sure where to call the PopupMenu::Finish for them. Also the XDialogClosedListener is currently just for convenience and might want some separate notifier. Fun fact, that ImplExecute / ImplPopup is called for submenu, but then doesn't execute. And generally the naming of some variables is IMHO wrong; I might also prefix Menu members with "m_" for easier readability. Change-Id: Id8b413aa6b4699201e58db0113649c6b224d33b6 diff --git a/include/sfx2/dispatch.hxx b/include/sfx2/dispatch.hxx index 6e87c89217f4..0f6cbeb55fdc 100644 --- a/include/sfx2/dispatch.hxx +++ b/include/sfx2/dispatch.hxx @@ -20,6 +20,7 @@ #define INCLUDED_SFX2_DISPATCH_HXX #include <memory> +#include <functional> #include <sal/config.h> #include <sfx2/dllapi.h> #include <sfx2/toolbarids.hxx> @@ -42,6 +43,7 @@ class Point; struct SfxDispatcher_Impl; namespace vcl { class Window; } +namespace com::sun::star::ui::dialogs { struct DialogClosedEvent; } enum class SfxDispatcherPopFlags { @@ -136,8 +138,14 @@ public: SfxViewFrame* GetFrame() const; SfxModule* GetModule() const; - void ExecutePopup( const OUString &rResName, vcl::Window *pWin = nullptr, const Point *pPos = nullptr ); - static void ExecutePopup( vcl::Window *pWin = nullptr, const Point *pPosPixel = nullptr ); + /** + * @param rCloseFunc + * If this is !nullptr, the popup will be just shown / run async and rCloseFunc will be called on close. + */ + void ExecutePopup(const OUString &rResName, vcl::Window *pWin = nullptr, const Point *pPos = nullptr, + const std::function<void(sal_Int16)>& rCloseFunc = nullptr); + static void ExecutePopup(vcl::Window *pWin = nullptr, const Point *pPosPixel = nullptr, + const std::function<void(sal_Int16)>& rCloseFunc = nullptr); bool IsAppDispatcher() const; bool IsFlushed() const; diff --git a/include/toolkit/awt/vclxmenu.hxx b/include/toolkit/awt/vclxmenu.hxx index 096c370bce82..ffa89e9a8511 100644 --- a/include/toolkit/awt/vclxmenu.hxx +++ b/include/toolkit/awt/vclxmenu.hxx @@ -25,10 +25,11 @@ #include <toolkit/helper/listenermultiplexer.hxx> #include <com/sun/star/awt/XMenuBar.hpp> -#include <com/sun/star/awt/XPopupMenu.hpp> +#include <com/sun/star/awt/XPopupMenuAsync.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/lang/XTypeProvider.hpp> #include <com/sun/star/lang/XUnoTunnel.hpp> +#include <com/sun/star/ui/dialogs/XDialogClosedListener.hpp> #include <comphelper/servicehelper.hxx> #include <cppuhelper/weak.hxx> @@ -39,6 +40,7 @@ #include <vector> +struct DialogClosedEvent; class Menu; class MenuBar; class PopupMenu; @@ -51,10 +53,11 @@ typedef ::std::vector< typedef void (*MenuUserDataReleaseFunction)(void*); class TOOLKIT_DLLPUBLIC VCLXMenu : public css::awt::XMenuBar, - public css::awt::XPopupMenu, + public css::awt::XPopupMenuAsync, public css::lang::XServiceInfo, public css::lang::XTypeProvider, public css::lang::XUnoTunnel, + public css::ui::dialogs::XDialogClosedListener, public ::cppu::OWeakObject { private: @@ -76,7 +79,6 @@ public: VCLXMenu( Menu* pMenu ); virtual ~VCLXMenu() override; - Menu* GetMenu() const { return mpMenu; } bool IsPopupMenu() const; void setUserValue(sal_uInt16 nItemId, void* nUserValue, MenuUserDataReleaseFunction aFunc); @@ -137,10 +139,20 @@ public: virtual void SAL_CALL setItemImage( ::sal_Int16 nItemId, const css::uno::Reference< css::graphic::XGraphic >& xGraphic, sal_Bool bScale ) override; virtual css::uno::Reference< css::graphic::XGraphic > SAL_CALL getItemImage( ::sal_Int16 nItemId ) override; + // css::awt::XPopupMenuAsync + virtual sal_Bool SAL_CALL popup(const css::uno::Reference< css::awt::XWindowPeer >& Parent, const css::awt::Rectangle& Position, + ::sal_Int16 Direction, const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>& xListener) override; + // css::lang::XServiceInfo virtual OUString SAL_CALL getImplementationName( ) override; virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + + // css::ui::dialogs::XDialogClosedListener + virtual void SAL_CALL dialogClosed(const css::ui::dialogs::DialogClosedEvent& aEvent) override; + + // XEventListener (base of XDialogClosedListener) + virtual void SAL_CALL disposing(css::lang::EventObject const & Source) override; }; class UNLESS_MERGELIBS(TOOLKIT_DLLPUBLIC) VCLXMenuBar final : public VCLXMenu diff --git a/include/vcl/menu.hxx b/include/vcl/menu.hxx index 87108359dab1..89a9d2a058c8 100644 --- a/include/vcl/menu.hxx +++ b/include/vcl/menu.hxx @@ -44,6 +44,7 @@ class Menu; class MenuItemList; class Image; class PopupMenu; +struct PopupMenuFinishState; class KeyEvent; class MenuFloatingWindow; class SalMenu; @@ -54,6 +55,7 @@ enum class FloatWinPopupFlags; enum class VclEventId; namespace com::sun::star::awt { class XPopupMenu; } +namespace com::sun::star::ui::dialogs { class XDialogClosedListener; } namespace com::sun::star::accessibility { class XAccessible; } namespace vcl @@ -492,11 +494,16 @@ class VCL_DLLPUBLIC PopupMenu final : public Menu friend struct MenuItemData; private: + struct PopupMenuFinishState* m_pState; + SAL_DLLPRIVATE MenuFloatingWindow * ImplGetFloatingWindow() const; SAL_DLLPRIVATE bool PrepareRun(const VclPtr<vcl::Window>& pParentWin, tools::Rectangle& rRect, FloatWinPopupFlags& nPopupModeFlags, Menu* pSFrom, bool& bRealExecute, VclPtr<MenuFloatingWindow>&); - SAL_DLLPRIVATE bool Run(const VclPtr<MenuFloatingWindow>&, bool bRealExecute, bool bPreSelectFirst, FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, const tools::Rectangle& rRect); + SAL_DLLPRIVATE bool Run(const VclPtr<MenuFloatingWindow>&, bool bRealExecute, bool bPreSelectFirst, FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, const tools::Rectangle& rRect, + const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* xListener); SAL_DLLPRIVATE void FinishRun(const VclPtr<MenuFloatingWindow>&, const VclPtr<vcl::Window>& pParentWin, bool bRealExecute, bool bIsNativeMenu); SAL_DLLPRIVATE sal_uInt16 ImplExecute(const VclPtr<vcl::Window>& pParentWin, const tools::Rectangle& rRect, FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, bool bPreSelectFirst); + SAL_DLLPRIVATE bool ImplPopup(const VclPtr<vcl::Window>& pParentWin, const tools::Rectangle& rRect, FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, bool bPreSelectFirst, + const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>&); SAL_DLLPRIVATE void ImplFlushPendingSelect(); SAL_DLLPRIVATE tools::Long ImplCalcHeight( sal_uInt16 nEntries ) const; SAL_DLLPRIVATE sal_uInt16 ImplCalcVisEntries( tools::Long nMaxHeight, sal_uInt16 nStartEntry, sal_uInt16* pLastVisible = nullptr ) const; @@ -519,6 +526,12 @@ public: sal_uInt16 Execute( vcl::Window* pWindow, const Point& rPopupPos ); sal_uInt16 Execute( vcl::Window* pWindow, const tools::Rectangle& rRect, PopupMenuFlags nFlags = PopupMenuFlags::NONE ); + bool Popup(vcl::Window* pParentWin, const Point& rPopupPos, + const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>&); + bool Popup(vcl::Window* pParentWin, const tools::Rectangle& rRect, + const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>&, PopupMenuFlags = PopupMenuFlags::NONE); + void Finish(); + // for the TestTool void EndExecute(); virtual void SelectItem(sal_uInt16 nId) override; diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk index 3eb002520e42..209541509e08 100644 --- a/offapi/UnoApi_offapi.mk +++ b/offapi/UnoApi_offapi.mk @@ -1859,6 +1859,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/awt,\ XPatternField \ XPointer \ XPopupMenu \ + XPopupMenuAsync \ XPrinter \ XPrinterPropertySet \ XPrinterServer \ diff --git a/offapi/com/sun/star/awt/XPopupMenuAsync.idl b/offapi/com/sun/star/awt/XPopupMenuAsync.idl new file mode 100644 index 000000000000..d3f7b317f086 --- /dev/null +++ b/offapi/com/sun/star/awt/XPopupMenuAsync.idl @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ +#ifndef __com_sun_star_awt_XPopupMenuAsync_idl__ +#define __com_sun_star_awt_XPopupMenuAsync_idl__ + +#include <com/sun/star/awt/XPopupMenu.idl> +#include <com/sun/star/ui/dialogs/XDialogClosedListener.idl> + +module com { module sun { module star { module awt { + +/** shows a pop-up menu without blocking. + */ +interface XPopupMenuAsync: XPopupMenu +{ + /** just shows the popup menu without blocking and calls the + XDialogClosedListener when closed, + + @param Parent + the parent window. + + @param Position + a Rectangle representing the coordinates system + where the popup menu should be executed. + + @param Direction + the direction in which a popup menu will grow, as specified + by one of the PopupMenuDirection constants. + + @param xListener + notified, if the popup is closed. + + @return + returns true, if the popup has started to run async. + May fail, if the native backend doesn't implement async popups. + */ + boolean popup([in] XWindowPeer Parent, [in] Rectangle Position, [in] short Direction, + [in] ::com::sun::star::ui::dialogs::XDialogClosedListener xListener); +}; + +}; }; }; }; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/view/drviews4.cxx b/sd/source/ui/view/drviews4.cxx index b07279844265..548504af7746 100644 --- a/sd/source/ui/view/drviews4.cxx +++ b/sd/source/ui/view/drviews4.cxx @@ -800,7 +800,7 @@ void DrawViewShell::Command(const CommandEvent& rCEvt, ::sd::Window* pWin) bool bShouldDisableEditHyperlink = ShouldDisableEditHyperlink(); if(rCEvt.IsMouseEvent()) - GetViewFrame()->GetDispatcher()->ExecutePopup( aPopupId ); + GetViewFrame()->GetDispatcher()->ExecutePopup(aPopupId, nullptr, nullptr, [](sal_Int16){}); else { //don't open contextmenu at mouse position if not opened via mouse diff --git a/sfx2/source/control/dispatch.cxx b/sfx2/source/control/dispatch.cxx index b0eee6eefb22..c182e67723ab 100644 --- a/sfx2/source/control/dispatch.cxx +++ b/sfx2/source/control/dispatch.cxx @@ -60,6 +60,7 @@ #include <svl/eitem.hxx> #include <svl/itemiter.hxx> #include <svl/itempool.hxx> +#include <svtools/dialogclosedlistener.hxx> #include <toolkit/awt/vclxmenu.hxx> #include <toolkit/helper/vclunohelper.hxx> #include <tools/debug.hxx> @@ -137,8 +138,12 @@ struct SfxDispatcher_Impl SfxDisableFlags nDisableFlags; bool bFlushed; std::deque< std::deque<SfxToDo_Impl> > aToDoCopyStack; + + static css::uno::Reference<css::frame::XPopupMenuController>* m_pActivePopupController; }; +css::uno::Reference<css::frame::XPopupMenuController>* SfxDispatcher_Impl::m_pActivePopupController = nullptr; + /** This method checks if the stack of the SfxDispatchers is flushed, or if push- or pop- commands are pending. */ @@ -1685,7 +1690,52 @@ bool SfxDispatcher::FillState_(const SfxSlotServer& rSvr, SfxItemSet& rState, return false; } -void SfxDispatcher::ExecutePopup( vcl::Window *pWin, const Point *pPos ) +namespace { + +static void lcl_FinishPopupDispatch(css::uno::Reference<css::frame::XPopupMenuController> xPopupController) +{ + css::uno::Reference<css::lang::XComponent> xComponent(xPopupController, css::uno::UNO_QUERY); + if (xComponent.is()) + xComponent->dispose(); + SfxDispatcher_Impl::m_pActivePopupController = nullptr; +} + +struct SfxDispatcherPopupFinish final +{ + css::uno::Reference<css::frame::XPopupMenuController> m_xPopupController; + std::function<void(sal_Int16)> m_aCloseFunc; + rtl::Reference<::svt::DialogClosedListener> m_xDialogListener; + css::uno::Reference<css::awt::XPopupMenu> m_xPopupMenu; + + DECL_LINK(PopupClosedHdl, css::ui::dialogs::DialogClosedEvent*, void); + + SfxDispatcherPopupFinish(css::uno::Reference<css::frame::XPopupMenuController> xPopupController, + const std::function<void(sal_Int16)>& rCloseFunc, + css::uno::Reference<css::awt::XPopupMenu> xPopupMenu) + : m_xPopupController(xPopupController) + , m_aCloseFunc(rCloseFunc) + , m_xDialogListener(new ::svt::DialogClosedListener()) + , m_xPopupMenu(xPopupMenu) + { + m_xDialogListener->SetDialogClosedLink(LINK(this, SfxDispatcherPopupFinish, PopupClosedHdl)); + } +}; + +IMPL_LINK(SfxDispatcherPopupFinish, PopupClosedHdl, css::ui::dialogs::DialogClosedEvent*, pEvt, void) +{ + assert(m_xPopupController.is()); + if (!comphelper::LibreOfficeKit::isActive()) + assert(SfxDispatcher_Impl::m_pActivePopupController == &m_xPopupController); + if (m_aCloseFunc) + m_aCloseFunc(pEvt ? pEvt->DialogResult : 0); + lcl_FinishPopupDispatch(m_xPopupController); + delete this; +} + +} // anon namespace + +void SfxDispatcher::ExecutePopup(vcl::Window *pWin, const Point *pPos, + const std::function<void(sal_Int16)>& rCloseFunc) { SfxDispatcher &rDisp = *SfxGetpApp()->GetDispatcher_Impl(); sal_uInt16 nShLevel = 0; @@ -1699,13 +1749,14 @@ void SfxDispatcher::ExecutePopup( vcl::Window *pWin, const Point *pPos ) const OUString& rResName = pSh->GetInterface()->GetPopupMenuName(); if ( !rResName.isEmpty() ) { - rDisp.ExecutePopup( rResName, pWin, pPos ); + rDisp.ExecutePopup(rResName, pWin, pPos, rCloseFunc); return; } } } -void SfxDispatcher::ExecutePopup( const OUString& rResName, vcl::Window* pWin, const Point* pPos ) +void SfxDispatcher::ExecutePopup( const OUString& rResName, vcl::Window* pWin, const Point* pPos, + const std::function<void(sal_Int16)>& rCloseFunc) { css::uno::Sequence< css::uno::Any > aArgs{ css::uno::Any(comphelper::makePropertyValue( "Value", rResName )), @@ -1714,16 +1765,29 @@ void SfxDispatcher::ExecutePopup( const OUString& rResName, vcl::Window* pWin, c }; css::uno::Reference< css::uno::XComponentContext > xContext = comphelper::getProcessComponentContext(); - css::uno::Reference< css::frame::XPopupMenuController > xPopupController( - xContext->getServiceManager()->createInstanceWithArgumentsAndContext( - "com.sun.star.comp.framework.ResourceMenuController", aArgs, xContext ), css::uno::UNO_QUERY ); + + if (!comphelper::LibreOfficeKit::isActive()) + assert(!xImp->m_pActivePopupController); + if (!comphelper::LibreOfficeKit::isActive() && xImp->m_pActivePopupController) + return; + + css::uno::Reference<css::frame::XPopupMenuController> xPopupController = + css::uno::Reference<css::frame::XPopupMenuController>( + xContext->getServiceManager()->createInstanceWithArgumentsAndContext( + "com.sun.star.comp.framework.ResourceMenuController", aArgs, xContext), css::uno::UNO_QUERY); + if (!xPopupController.is()) + return; + SfxDispatcher_Impl::m_pActivePopupController = &xPopupController; css::uno::Reference< css::awt::XPopupMenu > xPopupMenu( xContext->getServiceManager()->createInstanceWithContext( "com.sun.star.awt.PopupMenu", xContext ), css::uno::UNO_QUERY ); - - if ( !xPopupController.is() || !xPopupMenu.is() ) + if (!xPopupMenu.is()) + { + lcl_FinishPopupDispatch(xPopupController); return; + } + struct SfxDispatcherPopupFinish* pFin = nullptr; vcl::Window* pWindow = pWin ? pWin : xImp->pFrame->GetFrame().GetWorkWindow_Impl()->GetWindow(); Point aPos = pPos ? *pPos : pWindow->GetPointerPosPixel(); @@ -1751,14 +1815,22 @@ void SfxDispatcher::ExecutePopup( const OUString& rResName, vcl::Window* pWin, c OUString aMenuURL = "private:resource/popupmenu/" + rResName; if (GetFrame()->GetViewShell()->TryContextMenuInterception(xPopupMenu, aMenuURL, aEvent)) { + const sal_Int16 nFlags = css::awt::PopupMenuDirection::EXECUTE_DOWN; + const css::awt::Rectangle aRect(aPos.X(), aPos.Y(), 1, 1); css::uno::Reference<css::awt::XWindowPeer> xParent(aEvent.SourceWindow, css::uno::UNO_QUERY); - xPopupMenu->execute(xParent, css::awt::Rectangle(aPos.X(), aPos.Y(), 1, 1), css::awt::PopupMenuDirection::EXECUTE_DOWN); + css::uno::Reference<css::awt::XPopupMenuAsync> xAsyncPopup(xPopupMenu, css::uno::UNO_QUERY); + pFin = new SfxDispatcherPopupFinish(xPopupController, rCloseFunc, xPopupMenu); + if (!rCloseFunc || !xAsyncPopup.is() || !xAsyncPopup->popup(xParent, aRect, nFlags, pFin->m_xDialogListener)) + { + delete pFin; + pFin = nullptr; + xPopupMenu->execute(xParent, aRect, nFlags); + } } } - css::uno::Reference< css::lang::XComponent > xComponent( xPopupController, css::uno::UNO_QUERY ); - if ( xComponent.is() ) - xComponent->dispose(); + if (!pFin) + lcl_FinishPopupDispatch(xPopupController); } /** With this method the SfxDispatcher can be locked and released. A locked diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx index 0da4d250a7bd..2aab66f44b05 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -5427,7 +5427,7 @@ void SwEditWin::Command( const CommandEvent& rCEvt ) } } else if ( !m_rView.ExecSpellPopup( aDocPos ) ) - SfxDispatcher::ExecutePopup(this, &aPixPos); + SfxDispatcher::ExecutePopup(this, &aPixPos, [](sal_Int16){}); } else if (m_pApplyTempl->nUndo < rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount()) { diff --git a/toolkit/inc/helper/unowrapper.hxx b/toolkit/inc/helper/unowrapper.hxx index 03a9b525cc18..fdc65988bb62 100644 --- a/toolkit/inc/helper/unowrapper.hxx +++ b/toolkit/inc/helper/unowrapper.hxx @@ -56,7 +56,7 @@ public: virtual VclPtr<vcl::Window> GetWindow(const css::uno::Reference<css::awt::XWindow>& rxWindow) override; // Menu - virtual css::uno::Reference<css::awt::XPopupMenu> CreateMenuInterface( PopupMenu* pPopupMenu ) override; + virtual css::uno::Reference<css::awt::XPopupMenu> CreateMenuInterface(PopupMenu* pPopupMenu) override; void WindowDestroyed( vcl::Window* pWindow ) override; diff --git a/toolkit/source/awt/vclxmenu.cxx b/toolkit/source/awt/vclxmenu.cxx index cbeb1ef7f810..a13ced69163a 100644 --- a/toolkit/source/awt/vclxmenu.cxx +++ b/toolkit/source/awt/vclxmenu.cxx @@ -37,6 +37,7 @@ #include <vcl/window.hxx> #include <com/sun/star/awt/KeyModifier.hpp> +#include <com/sun/star/ui/dialogs/DialogClosedEvent.hpp> VCLXMenu::VCLXMenu() : maMenuListeners( *this ) @@ -492,6 +493,33 @@ sal_Int16 VCLXMenu::execute( static_cast<PopupMenuFlags>(nFlags) | PopupMenuFlags::NoMouseUpClose ); } +sal_Bool VCLXMenu::popup( + const css::uno::Reference< css::awt::XWindowPeer >& rxWindowPeer, + const css::awt::Rectangle& rPos, sal_Int16 nFlags, + const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>& xListener) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + if (!mpMenu || !IsPopupMenu()) + return false; + + return static_cast<PopupMenu*>(mpMenu.get())->Popup(VCLUnoHelper::GetWindow(rxWindowPeer), + VCLRectangle(rPos), xListener.is() ? xListener : this, + static_cast<PopupMenuFlags>(nFlags) | PopupMenuFlags::NoMouseUpClose); +} + +void SAL_CALL VCLXMenu::dialogClosed(const css::ui::dialogs::DialogClosedEvent&) +{ + SolarMutexGuard aSolarGuard; + std::unique_lock aGuard( maMutex ); + + assert(mpMenu && IsPopupMenu()); + if (mpMenu && IsPopupMenu()) + static_cast<PopupMenu*>(mpMenu.get())->Finish(); +} + +void SAL_CALL VCLXMenu::disposing(css::lang::EventObject const&) {} void SAL_CALL VCLXMenu::setCommand( sal_Int16 nItemId, diff --git a/toolkit/source/helper/unowrapper.cxx b/toolkit/source/helper/unowrapper.cxx index 5d5ce94a9b8f..b73ad471f0d1 100644 --- a/toolkit/source/helper/unowrapper.cxx +++ b/toolkit/source/helper/unowrapper.cxx @@ -191,7 +191,7 @@ void UnoWrapper::SetWindowInterface( vcl::Window* pWindow, const css::uno::Refer } } -css::uno::Reference<css::awt::XPopupMenu> UnoWrapper::CreateMenuInterface( PopupMenu* pPopupMenu ) +css::uno::Reference<css::awt::XPopupMenu> UnoWrapper::CreateMenuInterface(PopupMenu* pPopupMenu) { return new VCLXPopupMenu(pPopupMenu); } diff --git a/vcl/inc/osx/salmenu.h b/vcl/inc/osx/salmenu.h index 597180cc1ac3..dae1a1035cae 100644 --- a/vcl/inc/osx/salmenu.h +++ b/vcl/inc/osx/salmenu.h @@ -67,7 +67,9 @@ public: virtual void SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const Image& rImage) override; virtual void SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, const vcl::KeyCode& rKeyCode, const OUString& rKeyName ) override; virtual void GetSystemMenuData( SystemMenuData* pData ) override; - virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const tools::Rectangle& rRect, FloatWinPopupFlags nFlags) override; + virtual bool ShowNativePopupMenu( + FloatingWindow*, const tools::Rectangle&, FloatWinPopupFlags, + const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* = nullptr) override; virtual bool AddMenuBarButton( const SalMenuButtonItem& ) override; virtual void RemoveMenuBarButton( sal_uInt16 nId ) override; virtual tools::Rectangle GetMenuBarButtonRectPixel( sal_uInt16 i_nItemId, SalFrame* i_pReferenceFrame ) override; diff --git a/vcl/inc/qt5/QtMenu.hxx b/vcl/inc/qt5/QtMenu.hxx index 55275ae6e099..738c98e336a3 100644 --- a/vcl/inc/qt5/QtMenu.hxx +++ b/vcl/inc/qt5/QtMenu.hxx @@ -38,7 +38,7 @@ class QtFrame; class QtMenu : public QObject, public SalMenu { Q_OBJECT -private: + std::vector<QtMenuItem*> maItems; VclPtr<Menu> mpVCLMenu; QtMenu* mpParentSalMenu; @@ -52,6 +52,9 @@ private: QPushButton* mpCloseButton; QMetaObject::Connection maCloseButtonConnection; + css::uno::Reference<css::ui::dialogs::XDialogClosedListener> m_xListener; + FloatingWindow* m_pWin; + void DoFullMenuUpdate(Menu* pMenuBar); static void NativeItemText(OUString& rItemText); @@ -72,8 +75,9 @@ public: virtual void SetFrame(const SalFrame* pFrame) override; const QtFrame* GetFrame() const; virtual void ShowMenuBar(bool bVisible) override; - virtual bool ShowNativePopupMenu(FloatingWindow* pWin, const tools::Rectangle& rRect, - FloatWinPopupFlags nFlags) override; + virtual bool ShowNativePopupMenu( + FloatingWindow*, const tools::Rectangle&, FloatWinPopupFlags, + const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* = nullptr) override; QtMenu* GetTopLevel(); virtual void SetItemBits(unsigned nPos, MenuItemBits nBits) override; virtual void CheckItem(unsigned nPos, bool bCheck) override; diff --git a/vcl/inc/salmenu.hxx b/vcl/inc/salmenu.hxx index c696503549e6..60840a020460 100644 --- a/vcl/inc/salmenu.hxx +++ b/vcl/inc/salmenu.hxx @@ -22,6 +22,7 @@ #include <vcl/menu.hxx> #include <vcl/image.hxx> +#include <com/sun/star/ui/dialogs/XDialogClosedListener.hpp> struct SystemMenuData; class FloatingWindow; @@ -75,7 +76,17 @@ public: virtual void SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const Image& rImage ) = 0; virtual void SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, const vcl::KeyCode& rKeyCode, const OUString& rKeyName ) = 0; virtual void GetSystemMenuData( SystemMenuData* pData ) = 0; - virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const tools::Rectangle& rRect, FloatWinPopupFlags nFlags); + /** + * @param pListener + * if !nullptr, the menu is supposed to be only shown and it'll run async. + * Mainly means, when the menu is hidden, it must call the listener's + * dialogClosed. The listener will destroy the SalMenu! + * + * @return + * true, if the feature is implemented and was successful. + */ + virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const tools::Rectangle& rRect, FloatWinPopupFlags nFlags, + const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* pListener = nullptr); virtual void ShowCloseButton(bool bShow); virtual bool AddMenuBarButton( const SalMenuButtonItem& ); // return false if not implemented or failure virtual void RemoveMenuBarButton( sal_uInt16 nId ); diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx index 85c0f5d3d893..5d5a487df8f1 100644 --- a/vcl/inc/unx/gtk/gtksalmenu.hxx +++ b/vcl/inc/unx/gtk/gtksalmenu.hxx @@ -132,7 +132,8 @@ public: #endif void ReturnFocus(); - virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const tools::Rectangle& rRect, FloatWinPopupFlags nFlags) override; + virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const tools::Rectangle& rRect, FloatWinPopupFlags nFlags, + const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* = nullptr) override; virtual void ShowCloseButton(bool bShow) override; virtual bool AddMenuBarButton( const SalMenuButtonItem& rNewItem ) override; virtual void RemoveMenuBarButton( sal_uInt16 nId ) override; diff --git a/vcl/osx/salmenu.cxx b/vcl/osx/salmenu.cxx index 3164ba873bae..0a91ab88cc36 100644 --- a/vcl/osx/salmenu.cxx +++ b/vcl/osx/salmenu.cxx @@ -281,8 +281,13 @@ AquaSalMenu::~AquaSalMenu() } } -bool AquaSalMenu::ShowNativePopupMenu(FloatingWindow * pWin, const tools::Rectangle& rRect, FloatWinPopupFlags nFlags) +bool AquaSalMenu::ShowNativePopupMenu( + FloatingWindow* pWin, const tools::Rectangle& rRect, FloatWinPopupFlags nFlags, + const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* pListener) { + if (pListener) + return false; + // set offsets for positioning const float offset = 9.0; diff --git a/vcl/qt5/QtMenu.cxx b/vcl/qt5/QtMenu.cxx index c6224b137665..7cddbbe8b69d 100644 --- a/vcl/qt5/QtMenu.cxx +++ b/vcl/qt5/QtMenu.cxx @@ -93,6 +93,16 @@ void QtMenu::InsertMenuItem(QtMenuItem* pSalMenuItem, unsigned nPos) // no QMenu set, instantiate own one mpOwnedQMenu.reset(new QMenu); mpQMenu = mpOwnedQMenu.get(); + + connect(mpQMenu, &QMenu::aboutToHide, this, [this] { + if (m_pWin && m_xListener.is()) + { + QMenu* pMenu = mpOwnedQMenu.release(); + css::ui::dialogs::DialogClosedEvent aEvent(m_pWin->GetComponentInterface(), 0); + m_xListener->dialogClosed(aEvent); + pMenu->deleteLater(); + } + }); } if (pSalMenuItem->mpSubMenu) @@ -672,15 +682,27 @@ void QtMenu::ShowCloseButton(bool bShow) pButton->hide(); } -bool QtMenu::ShowNativePopupMenu(FloatingWindow*, const tools::Rectangle&, - FloatWinPopupFlags nFlags) +bool QtMenu::ShowNativePopupMenu( + FloatingWindow* pWin, const tools::Rectangle&, FloatWinPopupFlags nFlags, + const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* pListener) { assert(mpQMenu); DoFullMenuUpdate(mpVCLMenu); mpQMenu->setTearOffEnabled(bool(nFlags & FloatWinPopupFlags::AllowTearOff)); const QPoint aPos = QCursor::pos(); - mpQMenu->exec(aPos); + if (pListener) + { + m_xListener = *pListener; + m_pWin = pWin; + mpQMenu->popup(aPos); + } + else + { + m_xListener = nullptr; + m_pWin = nullptr; + mpQMenu->exec(aPos); + } return true; } diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index e19d055b8253..2362838a1396 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -176,7 +176,9 @@ SalObject::~SalObject() {} SalMenu::~SalMenu() {} -bool SalMenu::ShowNativePopupMenu(FloatingWindow*, const tools::Rectangle&, FloatWinPopupFlags) +bool SalMenu::ShowNativePopupMenu( + FloatingWindow*, const tools::Rectangle&, FloatWinPopupFlags, + const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>*) { return false; } diff --git a/vcl/source/control/managedmenubutton.cxx b/vcl/source/control/managedmenubutton.cxx index 880730721ce2..f671cdd9c695 100644 --- a/vcl/source/control/managedmenubutton.cxx +++ b/vcl/source/control/managedmenubutton.cxx @@ -13,6 +13,7 @@ #include <managedmenubutton.hxx> #include <vcl/menu.hxx> +#include <com/sun/star/awt/XPopupMenuAsync.hpp> #include <com/sun/star/frame/ModuleManager.hpp> #include <com/sun/star/frame/theDesktop.hpp> #include <com/sun/star/frame/thePopupMenuControllerFactory.hpp> diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx index 2fd136429061..f7055dbf92f4 100644 --- a/vcl/source/window/menu.cxx +++ b/vcl/source/window/menu.cxx @@ -2657,6 +2657,7 @@ MenuFloatingWindow * PopupMenu::ImplGetFloatingWindow() const { } PopupMenu::PopupMenu() + : m_pState(nullptr) { mpSalMenu = ImplGetSVData()->mpDefInst->CreateMenu(false, this); } @@ -2669,6 +2670,7 @@ PopupMenu::PopupMenu( const PopupMenu& rMenu ) PopupMenu::~PopupMenu() { + assert(!m_pState); disposeOnce(); } @@ -2766,6 +2768,36 @@ sal_uInt16 PopupMenu::Execute( vcl::Window* pExecWindow, const tools::Rectangle& return ImplExecute( pExecWindow, rRect, lcl_TranslateFlags(nFlags), nullptr, false ); } +struct PopupMenuFinishState final +{ + VclPtr<PopupMenu> pSelf; + VclPtr<vcl::Window> pParentWin; + VclPtr<MenuFloatingWindow> pWin; + bool bRealExecute; + bool bIsNativeMenu; + + void clean() + { + pWin = nullptr; + pParentWin = nullptr; + pSelf = nullptr; + } +}; + +bool PopupMenu::Popup(vcl::Window* pExecWindow, const Point& rPopupPos, + const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>& listener) +{ + return Popup(pExecWindow, tools::Rectangle(rPopupPos, rPopupPos), listener, PopupMenuFlags::ExecuteDown); +} + +bool PopupMenu::Popup(vcl::Window* pExecWindow, const tools::Rectangle& rRect, + const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>& listener, PopupMenuFlags nFlags) +{ + assert(!m_pState); + ENSURE_OR_RETURN(pExecWindow, "PopupMenu::Popup: need a non-NULL window!", false); + return ImplPopup(pExecWindow, rRect, lcl_TranslateFlags(nFlags), nullptr, false, listener); +} + void PopupMenu::ImplFlushPendingSelect() { // is there still Select? @@ -2917,7 +2949,7 @@ bool PopupMenu::PrepareRun(const VclPtr<vcl::Window>& pParentWin, tools::Rectang if (pStartedFrom && pStartedFrom->IsMenuBar()) nMaxHeight -= pParentWin->GetSizePixel().Height(); sal_Int32 nLeft, nTop, nRight, nBottom; - pWindow->GetBorder( nLeft, nTop, nRight, nBottom ); + pWindow->GetBorder(nLeft, nTop, nRight, nBottom); nMaxHeight -= nTop+nBottom; if ( aSz.Height() > nMaxHeight ) { @@ -2933,10 +2965,11 @@ bool PopupMenu::PrepareRun(const VclPtr<vcl::Window>& pParentWin, tools::Rectang } bool PopupMenu::Run(const VclPtr<MenuFloatingWindow>& pWin, const bool bRealExecute, const bool bPreSelectFirst, - const FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, const tools::Rectangle& rRect) + const FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, const tools::Rectangle& rRect, + const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* xListener) { SalMenu* pMenu = ImplGetSalMenu(); - if (pMenu && bRealExecute && pMenu->ShowNativePopupMenu(pWin, rRect, nPopupModeFlags)) + if (pMenu && bRealExecute && pMenu->ShowNativePopupMenu(pWin, rRect, nPopupModeFlags, xListener)) return true; pWin->StartPopupMode(rRect, nPopupModeFlags); @@ -2972,7 +3005,12 @@ bool PopupMenu::Run(const VclPtr<MenuFloatingWindow>& pWin, const bool bRealExec } if (bRealExecute) - pWin->Execute(); + { + if (!xListener) + pWin->Execute(); + else + pWin->Popup(*xListener); + } return false; } @@ -3017,11 +3055,42 @@ sal_uInt16 PopupMenu::ImplExecute(const VclPtr<vcl::Window>& pParentWin, const t VclPtr<MenuFloatingWindow> pWin; if (!PrepareRun(pParentWin, aRect, nPopupModeFlags, pSFrom, bRealExecute, pWin)) return 0; - const bool bNative = Run(pWin, bRealExecute, bPreSelectFirst, nPopupModeFlags, pSFrom, aRect); + const bool bNative = Run(pWin, bRealExecute, bPreSelectFirst, nPopupModeFlags, pSFrom, aRect, nullptr); FinishRun(pWin, pParentWin, bRealExecute, bNative); return nSelectedId; } +bool PopupMenu::ImplPopup(const VclPtr<vcl::Window>& pParentWin, const tools::Rectangle& rRect, + FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, bool bPreSelectFirst, + const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>& xListener) +{ + // tdf#126054 hold this until after function completes + VclPtr<PopupMenu> xThis(this); + bool bRealExecute = false; + tools::Rectangle aRect(rRect); + VclPtr<MenuFloatingWindow> pWin; + if (!PrepareRun(pParentWin, aRect, nPopupModeFlags, pSFrom, bRealExecute, pWin)) + return false; + assert(!m_pState); + m_pState = new PopupMenuFinishState; + m_pState->bIsNativeMenu = Run(pWin, bRealExecute, bPreSelectFirst, nPopupModeFlags, pSFrom, aRect, &xListener); + m_pState->pWin = pWin; + m_pState->pParentWin = pParentWin; + m_pState->bRealExecute = bRealExecute; + m_pState->pSelf = xThis; + return true; +} + +void PopupMenu::Finish() +{ + if (!m_pState) + return; + FinishRun(m_pState->pWin, m_pState->pParentWin, m_pState->bRealExecute, m_pState->bIsNativeMenu); + m_pState->clean(); + delete m_pState; + m_pState = nullptr; +} + sal_uInt16 PopupMenu::ImplCalcVisEntries( tools::Long nMaxHeight, sal_uInt16 nStartEntry, sal_uInt16* pLastVisible ) const { nMaxHeight -= 2 * ImplGetFloatingWindow()->GetScrollerHeight(); diff --git a/vcl/source/window/menufloatingwindow.cxx b/vcl/source/window/menufloatingwindow.cxx index cfd6a6ae190e..075fb97f5632 100644 --- a/vcl/source/window/menufloatingwindow.cxx +++ b/vcl/source/window/menufloatingwindow.cxx @@ -308,8 +308,15 @@ IMPL_LINK_NOARG(MenuFloatingWindow, PopupEnd, FloatingWindow*, void) pMenu->pStartedFrom->ClosePopup(pMenu); } - if ( pM ) + if (pM) + { pM->pStartedFrom = nullptr; + if (m_xListener.is()) + { + css::ui::dialogs::DialogClosedEvent aEvent(GetComponentInterface(), pM->GetCurItemId()); + m_xListener->dialogClosed(aEvent); + } + } } IMPL_LINK_NOARG(MenuFloatingWindow, AutoScroll, Timer *, void) @@ -443,21 +450,31 @@ void MenuFloatingWindow::End() Window::EndSaveFocus(xFocusId); } + Finish(); + bInExecute = false; } -void MenuFloatingWindow::Execute() +void MenuFloatingWindow::Popup(const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>& xListener) { ImplSVData* pSVData = ImplGetSVData(); - pSVData->maAppData.mpActivePopupMenu = static_cast<PopupMenu*>(pMenu.get()); - + m_xListener = xListener; Start(); +} +void MenuFloatingWindow::Finish() +{ + ImplSVData* pSVData = ImplGetSVData(); + pSVData->maAppData.mpActivePopupMenu = nullptr; +} + +void MenuFloatingWindow::Execute() +{ + Popup(); while (bInExecute && !Application::IsQuit()) Application::Yield(); - - pSVData->maAppData.mpActivePopupMenu = nullptr; + Finish(); } void MenuFloatingWindow::StopExecute() @@ -474,6 +491,7 @@ void MenuFloatingWindow::StopExecute() // notify parent, needed for accessibility if( pMenu && pMenu->pStartedFrom ) pMenu->pStartedFrom->ImplCallEventListeners( VclEventId::MenuSubmenuDeactivate, nPosInParent ); + Finish(); } void MenuFloatingWindow::KillActivePopup( PopupMenu* pThisOnly ) @@ -502,6 +520,7 @@ void MenuFloatingWindow::KillActivePopup( PopupMenu* pThisOnly ) PaintImmediately(); } + pPopup->Finish(); } void MenuFloatingWindow::EndExecute() diff --git a/vcl/source/window/menufloatingwindow.hxx b/vcl/source/window/menufloatingwindow.hxx index f26fb50373ca..b6c8b54738ce 100644 --- a/vcl/source/window/menufloatingwindow.hxx +++ b/vcl/source/window/menufloatingwindow.hxx @@ -46,6 +46,7 @@ private: sal_uInt16 nScrollerHeight; sal_uInt16 nFirstEntry; sal_uInt16 nPosInParent; + css::uno::Reference<css::ui::dialogs::XDialogClosedListener> m_xListener; bool bInExecute : 1; bool bScrollMenu : 1; @@ -67,6 +68,7 @@ private: void Start(); void End(); + static void Finish(); protected: vcl::Region ImplCalcClipRegion() const; @@ -107,6 +109,8 @@ public: bool IsScrollMenu() const { return bScrollMenu; } sal_uInt16 GetScrollerHeight() const { return nScrollerHeight; } + void Popup(const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>& xListener = nullptr); + void Execute(); void StopExecute(); void EndExecute(); diff --git a/vcl/unx/gtk3/gtksalmenu.cxx b/vcl/unx/gtk3/gtksalmenu.cxx index ac71e3390d87..0ccda0b66fb8 100644 --- a/vcl/unx/gtk3/gtksalmenu.cxx +++ b/vcl/unx/gtk3/gtksalmenu.cxx @@ -422,9 +422,13 @@ static void MenuClosed(GtkPopover* pWidget, GMainLoop* pLoop) g_main_loop_quit(pLoop); } -bool GtkSalMenu::ShowNativePopupMenu(FloatingWindow* pWin, const tools::Rectangle& rRect, - FloatWinPopupFlags nFlags) +bool GtkSalMenu::ShowNativePopupMenu + (FloatingWindow* pWin, const tools::Rectangle& rRect, FloatWinPopupFlags nFlags, + const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* pListener) { + if (pListener) + return false; + VclPtr<vcl::Window> xParent = pWin->ImplGetWindowImpl()->mpRealParent; mpFrame = static_cast<GtkSalFrame*>(xParent->ImplGetFrame()); commit 48de6352bb97cd2c126e624cbc5e8d76d9e99575 Author: Jan-Marek Glogowski <glo...@fbihome.de> AuthorDate: Sat Nov 20 15:06:35 2021 +0100 Commit: Jan-Marek Glogowski <glo...@fbihome.de> CommitDate: Mon Jan 10 05:25:46 2022 +0100 Refactor PopupMenu::ImplExecute for async support Splits ImplExecute into PrepareRun, Run and FinishRun. Change-Id: Ifddb1e968b468c9757eeece0bb19513cc26a9c8d diff --git a/include/vcl/menu.hxx b/include/vcl/menu.hxx index a6699a7e71d9..87108359dab1 100644 --- a/include/vcl/menu.hxx +++ b/include/vcl/menu.hxx @@ -493,7 +493,10 @@ class VCL_DLLPUBLIC PopupMenu final : public Menu private: SAL_DLLPRIVATE MenuFloatingWindow * ImplGetFloatingWindow() const; - SAL_DLLPRIVATE sal_uInt16 ImplExecute( const VclPtr<vcl::Window>& pW, const tools::Rectangle& rRect, FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, bool bPreSelectFirst ); + SAL_DLLPRIVATE bool PrepareRun(const VclPtr<vcl::Window>& pParentWin, tools::Rectangle& rRect, FloatWinPopupFlags& nPopupModeFlags, Menu* pSFrom, bool& bRealExecute, VclPtr<MenuFloatingWindow>&); + SAL_DLLPRIVATE bool Run(const VclPtr<MenuFloatingWindow>&, bool bRealExecute, bool bPreSelectFirst, FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, const tools::Rectangle& rRect); + SAL_DLLPRIVATE void FinishRun(const VclPtr<MenuFloatingWindow>&, const VclPtr<vcl::Window>& pParentWin, bool bRealExecute, bool bIsNativeMenu); + SAL_DLLPRIVATE sal_uInt16 ImplExecute(const VclPtr<vcl::Window>& pParentWin, const tools::Rectangle& rRect, FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, bool bPreSelectFirst); SAL_DLLPRIVATE void ImplFlushPendingSelect(); SAL_DLLPRIVATE tools::Long ImplCalcHeight( sal_uInt16 nEntries ) const; SAL_DLLPRIVATE sal_uInt16 ImplCalcVisEntries( tools::Long nMaxHeight, sal_uInt16 nStartEntry, sal_uInt16* pLastVisible = nullptr ) const; diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx index 6af85523f8a1..2fd136429061 100644 --- a/vcl/source/window/menu.cxx +++ b/vcl/source/window/menu.cxx @@ -2742,10 +2742,8 @@ sal_uInt16 PopupMenu::Execute( vcl::Window* pExecWindow, const Point& rPopupPos return Execute( pExecWindow, tools::Rectangle( rPopupPos, rPopupPos ), PopupMenuFlags::ExecuteDown ); } -sal_uInt16 PopupMenu::Execute( vcl::Window* pExecWindow, const tools::Rectangle& rRect, PopupMenuFlags nFlags ) +static FloatWinPopupFlags lcl_TranslateFlags(PopupMenuFlags nFlags) { - ENSURE_OR_RETURN( pExecWindow, "PopupMenu::Execute: need a non-NULL window!", 0 ); - FloatWinPopupFlags nPopupModeFlags = FloatWinPopupFlags::NONE; if ( nFlags & PopupMenuFlags::ExecuteDown ) nPopupModeFlags = FloatWinPopupFlags::Down; @@ -2759,7 +2757,13 @@ sal_uInt16 PopupMenu::Execute( vcl::Window* pExecWindow, const tools::Rectangle& if (nFlags & PopupMenuFlags::NoMouseUpClose ) // allow popup menus to stay open on mouse button up nPopupModeFlags |= FloatWinPopupFlags::NoMouseUpClose; // useful if the menu was opened on mousebutton down (eg toolbox configuration) - return ImplExecute( pExecWindow, rRect, nPopupModeFlags, nullptr, false ); + return nPopupModeFlags; +} + +sal_uInt16 PopupMenu::Execute( vcl::Window* pExecWindow, const tools::Rectangle& rRect, PopupMenuFlags nFlags ) +{ + ENSURE_OR_RETURN( pExecWindow, "PopupMenu::Execute: need a non-NULL window!", 0 ); + return ImplExecute( pExecWindow, rRect, lcl_TranslateFlags(nFlags), nullptr, false ); } void PopupMenu::ImplFlushPendingSelect() @@ -2775,10 +2779,14 @@ void PopupMenu::ImplFlushPendingSelect() } } -sal_uInt16 PopupMenu::ImplExecute( const VclPtr<vcl::Window>& pW, const tools::Rectangle& rRect, FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, bool bPreSelectFirst ) +bool PopupMenu::PrepareRun(const VclPtr<vcl::Window>& pParentWin, tools::Rectangle& rRect, + FloatWinPopupFlags& nPopupModeFlags, Menu* pSFrom, + bool& bRealExecute, VclPtr<MenuFloatingWindow>& pWin) { - if ( !pSFrom && ( vcl::IsInPopupMenuExecute() || !GetItemCount() ) ) - return 0; + bRealExecute = false; + const sal_uInt16 nItemCount = GetItemCount(); + if (!pSFrom && (vcl::IsInPopupMenuExecute() || !nItemCount)) + return false; mpLayoutData.reset(); @@ -2790,7 +2798,6 @@ sal_uInt16 PopupMenu::ImplExecute( const VclPtr<vcl::Window>& pW, const tools::R bCanceled = false; VclPtr<vcl::Window> xFocusId; - bool bRealExecute = false; if ( !pStartedFrom ) { pSVData->mpWinData->mbNoDeactivate = true; @@ -2806,25 +2813,24 @@ sal_uInt16 PopupMenu::ImplExecute( const VclPtr<vcl::Window>& pW, const tools::R } SAL_WARN_IF( ImplGetWindow(), "vcl", "Win?!" ); - tools::Rectangle aRect( rRect ); - aRect.SetPos( pW->OutputToScreenPixel( aRect.TopLeft() ) ); + rRect.SetPos(pParentWin->OutputToScreenPixel(rRect.TopLeft())); + nPopupModeFlags |= FloatWinPopupFlags::NoKeyClose | FloatWinPopupFlags::AllMouseButtonClose | FloatWinPopupFlags::GrabFocus; if (bRealExecute) nPopupModeFlags |= FloatWinPopupFlags::NewLevel; - nPopupModeFlags |= FloatWinPopupFlags::NoKeyClose | FloatWinPopupFlags::AllMouseButtonClose; bInCallback = true; // set it here, if Activate overridden Activate(); bInCallback = false; - if ( pW->isDisposed() ) - return 0; // Error + if (pParentWin->isDisposed()) + return false; if ( bCanceled || bKilled ) - return 0; + return false; - if ( !GetItemCount() ) - return 0; + if (!nItemCount) + return false; // The flag MenuFlags::HideDisabledEntries is inherited. if ( pSFrom ) @@ -2854,10 +2860,10 @@ sal_uInt16 PopupMenu::ImplExecute( const VclPtr<vcl::Window>& pW, const tools::R ImplCallEventListeners(VclEventId::MenuSubmenuChanged, nPos); } - VclPtrInstance<MenuFloatingWindow> pWin( this, pW, WB_BORDER | WB_SYSTEMWINDOW ); + pWin = VclPtrInstance<MenuFloatingWindow>(this, pParentWin, WB_BORDER | WB_SYSTEMWINDOW); if (comphelper::LibreOfficeKit::isActive() && get_id() == "editviewspellmenu") { - VclPtr<vcl::Window> xNotifierParent = pW->GetParentWithLOKNotifier(); + VclPtr<vcl::Window> xNotifierParent = pParentWin->GetParentWithLOKNotifier(); assert(xNotifierParent && xNotifierParent->GetLOKNotifier() && "editview menu without LOKNotifier"); pWin->SetLOKNotifier(xNotifierParent->GetLOKNotifier()); } @@ -2876,9 +2882,9 @@ sal_uInt16 PopupMenu::ImplExecute( const VclPtr<vcl::Window>& pW, const tools::R vcl::Window* pDeskW = pWindow->GetWindow( GetWindowType::RealParent ); if( ! pDeskW ) pDeskW = pWindow; - Point aDesktopTL( pDeskW->OutputToAbsoluteScreenPixel( aRect.TopLeft() ) ); + Point aDesktopTL(pDeskW->OutputToAbsoluteScreenPixel(rRect.TopLeft())); aDesktopRect = Application::GetScreenPosSizePixel( - Application::GetBestScreen( tools::Rectangle( aDesktopTL, aRect.GetSize() ) )); + Application::GetBestScreen(tools::Rectangle(aDesktopTL, rRect.GetSize()))); } tools::Long nMaxHeight = aDesktopRect.GetHeight(); @@ -2893,8 +2899,8 @@ sal_uInt16 PopupMenu::ImplExecute( const VclPtr<vcl::Window>& pW, const tools::R if ( pRef->GetParent() ) pRef = pRef->GetParent(); - tools::Rectangle devRect( pRef->OutputToAbsoluteScreenPixel( aRect.TopLeft() ), - pRef->OutputToAbsoluteScreenPixel( aRect.BottomRight() ) ); + tools::Rectangle devRect(pRef->OutputToAbsoluteScreenPixel(rRect.TopLeft()), + pRef->OutputToAbsoluteScreenPixel(rRect.BottomRight())); tools::Long nHeightAbove = devRect.Top() - aDesktopRect.Top(); tools::Long nHeightBelow = aDesktopRect.Bottom() - devRect.Bottom(); @@ -2909,7 +2915,7 @@ sal_uInt16 PopupMenu::ImplExecute( const VclPtr<vcl::Window>& pW, const tools::R nMaxHeight = std::max(nMaxHeight, tools::Long(768)); if (pStartedFrom && pStartedFrom->IsMenuBar()) - nMaxHeight -= pW->GetSizePixel().Height(); + nMaxHeight -= pParentWin->GetSizePixel().Height(); sal_Int32 nLeft, nTop, nRight, nBottom; pWindow->GetBorder( nLeft, nTop, nRight, nBottom ); nMaxHeight -= nTop+nBottom; @@ -2921,43 +2927,34 @@ sal_uInt16 PopupMenu::ImplExecute( const VclPtr<vcl::Window>& pW, const tools::R aSz.setHeight( ImplCalcHeight( nEntries ) ); } - // tdf#126054 hold this until after function completes - VclPtr<PopupMenu> xThis(this); - pWin->SetFocusId( xFocusId ); pWin->SetOutputSizePixel( aSz ); - if ( GetItemCount() ) + return true; +} + +bool PopupMenu::Run(const VclPtr<MenuFloatingWindow>& pWin, const bool bRealExecute, const bool bPreSelectFirst, + const FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, const tools::Rectangle& rRect) +{ + SalMenu* pMenu = ImplGetSalMenu(); + if (pMenu && bRealExecute && pMenu->ShowNativePopupMenu(pWin, rRect, nPopupModeFlags)) + return true; + + pWin->StartPopupMode(rRect, nPopupModeFlags); + if (pSFrom) { - SalMenu* pMenu = ImplGetSalMenu(); - if( pMenu && bRealExecute && pMenu->ShowNativePopupMenu( pWin, aRect, nPopupModeFlags | FloatWinPopupFlags::GrabFocus ) ) - { - pWin->StopExecute(); - pWin->doShutdown(); - pWindow.disposeAndClear(); - ImplClosePopupToolBox(pW); - ImplFlushPendingSelect(); - return nSelectedId; - } + sal_uInt16 aPos; + if (pSFrom->IsMenuBar()) + aPos = static_cast<MenuBarWindow *>(pSFrom->pWindow.get())->GetHighlightedItem(); else - { - pWin->StartPopupMode( aRect, nPopupModeFlags | FloatWinPopupFlags::GrabFocus ); - } - if( pSFrom ) - { - sal_uInt16 aPos; - if (pSFrom->IsMenuBar()) - aPos = static_cast<MenuBarWindow *>(pSFrom->pWindow.get())->GetHighlightedItem(); - else - aPos = static_cast<MenuFloatingWindow *>(pSFrom->pWindow.get())->GetHighlightedItem(); + aPos = static_cast<MenuFloatingWindow *>(pSFrom->pWindow.get())->GetHighlightedItem(); - pWin->SetPosInParent( aPos ); // store position to be sent in SUBMENUDEACTIVATE - pSFrom->ImplCallEventListeners( VclEventId::MenuSubmenuActivate, aPos ); - } + pWin->SetPosInParent(aPos); // store position to be sent in SUBMENUDEACTIVATE + pSFrom->ImplCallEventListeners(VclEventId::MenuSubmenuActivate, aPos); } + if ( bPreSelectFirst ) { - size_t nCount = pItemList->size(); - for ( size_t n = 0; n < nCount; n++ ) + for (size_t n = 0; n < static_cast<size_t>(GetItemCount()); n++) { MenuItemData* pData = pItemList->GetDataFromPos( n ); if ( ( pData->bEnabled @@ -2968,22 +2965,30 @@ sal_uInt16 PopupMenu::ImplExecute( const VclPtr<vcl::Window>& pW, const tools::R && ImplIsSelectable( n ) ) { - pWin->ChangeHighlightItem( n, false ); + pWin->ChangeHighlightItem(n, false); break; } } } - if ( bRealExecute ) - { + + if (bRealExecute) pWin->Execute(); - if (pWin->isDisposed()) - return 0; - xFocusId = pWin->GetFocusId(); + return false; +} + +void PopupMenu::FinishRun(const VclPtr<MenuFloatingWindow>& pWin, const VclPtr<vcl::Window>& pParentWin, const bool bRealExecute, const bool bIsNativeMenu) +{ + if (!bRealExecute || pWin->isDisposed()) + return; + + if (!bIsNativeMenu) + { + VclPtr<vcl::Window> xFocusId = pWin->GetFocusId(); assert(xFocusId == nullptr && "Focus should already be restored by MenuFloatingWindow::End"); pWin->ImplEndPopupMode(FloatWinPopupEndFlags::NONE, xFocusId); - if ( nSelectedId ) // then clean up .. ( otherwise done by TH ) + if (nSelectedId) // then clean up .. ( otherwise done by TH ) { PopupMenu* pSub = pWin->GetActivePopup(); while ( pSub ) @@ -2992,13 +2997,29 @@ sal_uInt16 PopupMenu::ImplExecute( const VclPtr<vcl::Window>& pW, const tools::R pSub = pSub->ImplGetFloatingWindow()->GetActivePopup(); } } - pWin->doShutdown(); - pWindow.disposeAndClear(); - ImplClosePopupToolBox(pW); - ImplFlushPendingSelect(); } + else + pWin->StopExecute(); - return bRealExecute ? nSelectedId : 0; + pWin->doShutdown(); + pWindow.disposeAndClear(); + ImplClosePopupToolBox(pParentWin); + ImplFlushPendingSelect(); +} + +sal_uInt16 PopupMenu::ImplExecute(const VclPtr<vcl::Window>& pParentWin, const tools::Rectangle& rRect, + FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, bool bPreSelectFirst) +{ + // tdf#126054 hold this until after function completes + VclPtr<PopupMenu> xThis(this); + bool bRealExecute = false; + tools::Rectangle aRect(rRect); + VclPtr<MenuFloatingWindow> pWin; + if (!PrepareRun(pParentWin, aRect, nPopupModeFlags, pSFrom, bRealExecute, pWin)) + return 0; + const bool bNative = Run(pWin, bRealExecute, bPreSelectFirst, nPopupModeFlags, pSFrom, aRect); + FinishRun(pWin, pParentWin, bRealExecute, bNative); + return nSelectedId; } sal_uInt16 PopupMenu::ImplCalcVisEntries( tools::Long nMaxHeight, sal_uInt16 nStartEntry, sal_uInt16* pLastVisible ) const commit aa79b96dd650e487262d6eb20491d3ff7b321978 Author: Jan-Marek Glogowski <glo...@fbihome.de> AuthorDate: Mon Jan 10 04:50:03 2022 +0100 Commit: Jan-Marek Glogowski <glo...@fbihome.de> CommitDate: Mon Jan 10 05:25:46 2022 +0100 WASM update README.wasm.md Change-Id: Ic38a7a0637ab007f12a6046655cb7d36e24fae33 diff --git a/static/README.wasm.md b/static/README.wasm.md index bfe930ef6775..ccc7a5b8aec7 100644 --- a/static/README.wasm.md +++ b/static/README.wasm.md @@ -4,23 +4,20 @@ This module provides support for emscripten cross build ## Status - $ make +The build generates a Writer-only LO build. You should be able to run either -You can run the WASM mandelbrot Qt example, if you copy its HTML -and the qtloader.js from the Qt's example folder after build with: - - $ emrun --serve_after_close workdir/LinkTarget/Executable/mandelbrot.html + $ emrun --serve_after_close instdir/program/qt_soffice.html + $ emrun --serve_after_close workdir/LinkTarget/Executable/qt_vcldemo.html + $ emrun --serve_after_close workdir/LinkTarget/Executable/qt_wasm-qt5-mandelbrot.html REMINDER: Always start new tabs in the browser, reload might fail / cache! - +INFO: latest browser won't work anymore with 0.0.0.0 and need 127.0.0.1. ## Setup for the LO WASM build (with Qt) -We're using Qt 5.15 with the officially supported emscripten v1.39.8. -But there are several potential problems with threads and exceptions, so this will likely -change later to a newer emscripten. - -Qt WASM is not yet used with LO, just if you're wondering! +We're using Qt 5.15.2 with Emscripten 2.0.31. There are a bunch of Qt patches +to fix the most grave bugs. Also newer Emscripten versions have various bugs +with the FS image support. - See below under Docker build for another build option @@ -29,8 +26,8 @@ Qt WASM is not yet used with LO, just if you're wondering! <https://emscripten.org/docs/getting_started/index.html> git clone https://github.com/emscripten-core/emsdk.git - ./emsdk install 1.39.8 - ./emsdk activate --embedded 1.39.8 + ./emsdk install 2.0.31 + ./emsdk activate --embedded 2.0.31 Example `bashrc` scriptlet: @@ -41,41 +38,54 @@ Example `bashrc` scriptlet: <https://doc.qt.io/qt-5/wasm.html> -I originally build the Qt 5.15 branch, but probably better to build a tag like v5.15.2. +Most of the information from <https://doc.qt.io/qt-6/wasm.html> is still valid for Qt5; +generally the Qt6 WASM documentation is much better, because it incorporated many +information from the Qt Wiki. + +FWIW: Qt 5.15 LTS is not maintained publically and Qt WASM has quite a few bugs. Most +WASM fixes from Qt 6 are needed for Qt 5.15 too. They can mainly be cherry-picked from: +- git log origin/dev src/plugins/platforms/wasm/ +- git log --grep wasm origin/dev -So: +We will probably offer our own Qt repository clone at some point. + +But even the public Qt 5.15 branch is still broken, so better start with the v5.15.2 tag. git clone https://github.com/qt/qt5.git cd qt5 git checkout v5.15.2 - ./init-repository - ./configure -xplatform wasm-emscripten -feature-thread -compile-examples -prefix $PWD/qtbase - make -j<CORES> module-qtbase module-qtdeclarative - + ./init-repository --module-subset=qtbase + ./configure -xplatform wasm-emscripten -feature-thread -prefix $PWD/install-5.15.2 + make -j<CORES> module-qtbase + +Optionally you can add the configure flag "-compile-examples". But then you also have to +patch at least mkspecs/wasm-emscripten/qmake.conf with EXIT_RUNTIME=0, otherwise they will +fail to run. In addition, building with examples will break with some of them, but at that +point Qt already works and also most examples. Building with examples will break with some of them, but at that point Qt already works. +Or just skip them. Other interesting flags might be "-nomake tests -no-pch -ccache". -At some point Qt configure failed for me with: +Linking takes quite a long time, because emscripten-finalize rewrites the whole WASM files +with some options. This way the LO WASM needs at least 64GB RAM. For faster link times add +"-s WASM_BIGINT=1", change to ASSERTIONS=1 nd use -g3 to prevent rewriting the WASM file +and generating source maps (see emscripten.py, finalize_wasm, and avoid modify_wasm = True). +This is just needed for Qt examples, as LO already uses the correct flags! -"Checking for target architecture... Project ERROR: target architecture detection binary not found." +The install is not really needed, as LO currently just uses qtbase on it's own. You can do -What seems to have fixed this was to run "emsdk activate 1.39.8" again. + make -j<CORES> install +or + make -j8 -C qtbase/src install_subtargets Current Qt fails to start the demo webserver: <https://bugreports.qt.io/browse/QTCREATORBUG-24072> -Use `emrun --serve_after_close` to run Qt WASM demos - -Enabling multi-thread support in Firefox is a bit of work with older versions: - -- <https://bugzilla.mozilla.org/show_bug.cgi?id=1477743#c7> -- <https://wiki.qt.io/Qt_for_WebAssembly#Multithreading_Support> -- <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer> - +Use `emrun --serve_after_close` to run Qt WASM demos. ### Setup LO -`autogen.sh` is patched to use emconfigure. That basically sets various environment vars, -especially `EMMAKEN_JUST_CONFIGURE`, which will create the correct output file names, checked by -`configure` (`a.out`). +`autogen.sh` is patched to use emconfigure. That basically sets various +environment vars, especially `EMMAKEN_JUST_CONFIGURE`, which will create the +correct output file names, checked by `configure` (`a.out`). There's a distro config for WASM (work in progress), that gets your defaults right (and currently disables a ton of 3rd party stuff which @@ -93,6 +103,35 @@ Recommended configure setup is thusly: `--with-build-platform-configure-options=--enable-ccache` `--enable-ccache` +FWIW: it's also possible to build an almost static Linux LibreOffice by just using +--disable-dynloading --enable-customtarget-components. System externals are still +linked dynamically, but everything else is static. + +### "Deploying" soffice.wasm + + tar -chf wasm.tar --xform 's/.*program/lo-wasm/' instdir/program/soffice.* \ + instdir/program/qt* + +Your HTTP server needs to provide aditional headers: +* add_header Cross-Origin-Opener-Policy same-origin +* add_header Cross-Origin-Embedder-Policy require-corp + +The default html to use should be qt_soffice.html + +### Debugging setup + +Since a few months you can use DWARF information embedded by LLVM into the WASM +to debug WASM in Chrome. You need to enable an experimental feature and install +an additional extension. The whole setup is described in: + +https://developer.chrome.com/blog/wasm-debugging-2020/ + +This way you don't need source maps (much faster linking!) and can resolve local +WASM variables to C++ names! + +Per default, the WASM debug build splits the DWARF information into an additional +WASM file, postfixed '.debug.wasm'. + ### Using Docker to cross-build with emscripten If you prefer a controlled environment (sadly emsdk install/activate @@ -109,7 +148,8 @@ Run in the lode/docker dir to get the container prepared. Run - PARALLELISM=4 BUILD_OPTIONS= BUILD_TARGET=build docker-compose run --rm -e PARALLELISM -e BUILD_TARGET -e BUILD_OPTIONS builder + PARALLELISM=4 BUILD_OPTIONS= BUILD_TARGET=build docker-compose run --rm \ + -e PARALLELISM -e BUILD_TARGET -e BUILD_OPTIONS builder to perform an actual `srcdir != builddir` build; the container mounts checked-out git repo and output dir via `docker-compose.yml` (so make @@ -152,27 +192,6 @@ WASM dynamic dispatch: - <https://fitzgeraldnick.com/2018/04/26/how-does-dynamic-dispatch-work-in-wasm.html> - -## Workaround for eventual clang WASM compiler bug - -```` -sc/source/core/data/attarray.cxx:378:44: error: call to member function 'erase' is ambiguous - aNewCondFormatData.erase(nIndex); - ~~~~~~~~~~~~~~~~~~~^~~~~ -include/o3tl/sorted_vector.hxx:86:15: note: candidate function - size_type erase( const Value& x ) - ^ -include/o3tl/sorted_vector.hxx:97:10: note: candidate function - void erase( size_t index ) -```` - -This is currently patched by using `x.erase` (`x.begin() + nIndex`). - -There shouldn't be an ambiguity, because of "[WebAssembly] Change size_t to `unsigned long`." -<https://reviews.llvm.org/rGdf07a35912d78781ed6a62a7c032bfef5085a4f5#change-IrS9f6jH6PFq>, -from "Jul 23 2018" which pre-dates the emscripten tag 1.39.8 from 02/14/2020 by ~1.5y. - - ## Tools for problem diagnosis * `nm -s` should list the symbols in the archive, based on the index generated by ranlib. @@ -185,7 +204,6 @@ This is closed, but not really fixed IMHO: - <https://github.com/emscripten-core/emscripten/issues/3922> - ## Dynamic libraries `/` modules in emscripten There is a good summary in: commit e9f5772b39aac478f0591a60e73a4dec4b356cab Author: Thorsten Behrens <thorsten.behr...@allotropia.de> AuthorDate: Sat Nov 13 23:12:58 2021 +0100 Commit: Jan-Marek Glogowski <glo...@fbihome.de> CommitDate: Mon Jan 10 05:25:46 2022 +0100 WASM default to notebookbar ..and use the full, desktop variant.. Change-Id: Ib00aad8cd130b4a3433209c540fe82970c45c98e diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 407c1c0ebf33..b4cff0a3ac35 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -6426,7 +6426,11 @@ static void activateNotebookbar(std::u16string_view rApp) if (aAppNode.isValid()) { +#ifdef EMSCRIPTEN + aAppNode.setNodeValue("Active", makeAny(OUString("notebookbar.ui"))); +#else aAppNode.setNodeValue("Active", makeAny(OUString("notebookbar_online.ui"))); +#endif aAppNode.commit(); } } @@ -6465,7 +6469,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 2166d347c6bdcbb2d6c659b93459756d76dc4974 Author: Jan-Marek Glogowski <glo...@fbihome.de> AuthorDate: Tue Nov 30 19:32:56 2021 +0100 Commit: Jan-Marek Glogowski <glo...@fbihome.de> CommitDate: Mon Jan 10 05:25:45 2022 +0100 WASM show the compiled-in English help Even without XMLHELP support, the default English help strings can be shown. Change-Id: I0ac7a617d7209f70cc7c3cdd34bf0f17a5d4133a diff --git a/sfx2/source/appl/app.cxx b/sfx2/source/appl/app.cxx index 5fe23fa6257f..b8bec0d6ff5e 100644 --- a/sfx2/source/appl/app.cxx +++ b/sfx2/source/appl/app.cxx @@ -124,6 +124,8 @@ SfxApplication* SfxApplication::GetOrCreate() ::framework::SetIsDockingWindowVisible( IsDockingWindowVisible ); #if HAVE_FEATURE_XMLHELP Application::SetHelp( pSfxHelp ); +#endif +#if HAVE_FEATURE_XMLHELP || defined(EMSCRIPTEN) bool bHelpTip = officecfg::Office::Common::Help::Tip::get(); bool bExtendedHelpTip = officecfg::Office::Common::Help::ExtendedTip::get(); if (!utl::ConfigManager::IsFuzzing() && bHelpTip) commit f01b80f8f0a911cc1155018eeaa5cfe1a1b9740c Author: Jan-Marek Glogowski <glo...@fbihome.de> AuthorDate: Tue Nov 30 19:21:17 2021 +0100 Commit: Jan-Marek Glogowski <glo...@fbihome.de> CommitDate: Mon Jan 10 05:25:45 2022 +0100 WASM add toolkit and Emscripten version to About Change-Id: I095cbb17accf04654a928bf0d89c0fbf1f443c9b diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx index 6570985b32ca..c1f3b4a5bccf 100644 --- a/vcl/source/app/svapp.cxx +++ b/vcl/source/app/svapp.cxx @@ -1221,7 +1221,7 @@ OUString Application::GetHWOSConfInfo(const int bSelection, const bool bLocalize #endif appendDetails(u"", Localize(SV_APP_DEFAULT, bLocalize)); -#if (defined LINUX || defined _WIN32 || defined MACOSX || defined __FreeBSD__) +#if (defined LINUX || defined _WIN32 || defined MACOSX || defined __FreeBSD__ || defined EMSCRIPTEN) appendDetails(u"; ", SV_APP_VCLBACKEND + GetToolkitName()); #endif } diff --git a/vcl/unx/generic/app/geninst.cxx b/vcl/unx/generic/app/geninst.cxx index 0093f64376c6..fb36b38f61f1 100644 --- a/vcl/unx/generic/app/geninst.cxx +++ b/vcl/unx/generic/app/geninst.cxx @@ -87,11 +87,14 @@ OUString SalGenericInstance::getOSVersion() if ( c == ' ' || c == '-' || ( c == '.' && nDots++ > 0 ) ) break; } - return OUString::createFromAscii( stName.sysname ) + " " + + aKernelVer = OUString::createFromAscii( stName.sysname ) + " " + aKernelVer.copy( 0, nIndex ); -#else - return aKernelVer; +#elif defined(EMSCRIPTEN) +#define str(s) #s +#define xstr(s) str(s) + aKernelVer = "Emscripten " xstr(__EMSCRIPTEN_major__) "." xstr(__EMSCRIPTEN_minor__) "." xstr(__EMSCRIPTEN_tiny__); #endif + return aKernelVer; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 4370e528d15b1d121a4d9bbaac2c71248d17ab7c Author: Jan-Marek Glogowski <glo...@fbihome.de> AuthorDate: Tue Nov 30 19:15:13 2021 +0100 Commit: Jan-Marek Glogowski <glo...@fbihome.de> CommitDate: Mon Jan 10 05:25:44 2022 +0100 WASM open links in new browser tabs I quickly gave up trying to understand what exactly clashes between the Emscripten macros and OUString templates / initializers. Not sure it can actually be "fixed". Change-Id: I8b13f179629ea63ff221584030556d2bedadc01b diff --git a/postprocess/Module_postprocess.mk b/postprocess/Module_postprocess.mk index 8a8ec0891540..0fbede6a9f2b 100644 --- a/postprocess/Module_postprocess.mk +++ b/postprocess/Module_postprocess.mk @@ -40,7 +40,7 @@ endif # contain content from at least one of external/more_fonts/fc_local.snippet # (conditional on MORE_FONTS in BUILD_TYPE) and # extras/source/truetype/symbol/fc_local.snippet (unconditional): -ifneq ($(USING_X11)$(DISABLE_GUI)$(filter ANDROID,$(OS)),) +ifneq ($(USING_X11)$(DISABLE_GUI)$(filter ANDROID EMSCRIPTEN,$(OS)),) $(eval $(call gb_Module_add_targets,postprocess, \ CustomTarget_fontconfig \ Package_fontconfig \ diff --git a/shell/Library_syssh.mk b/shell/Library_syssh.mk index e83a85262dcf..d059d6c5b671 100644 --- a/shell/Library_syssh.mk +++ b/shell/Library_syssh.mk @@ -43,6 +43,12 @@ $(eval $(call gb_Library_add_exception_objects,syssh,\ shell/source/unix/exec/shellexec \ )) +ifeq ($(OS),EMSCRIPTEN) +$(eval $(call gb_Library_add_exception_objects,syssh,\ + shell/source/unix/exec/shellexec_em \ +)) +endif + endif # OS # vim: set shiftwidth=4 tabstop=4 noexpandtab: diff --git a/shell/source/unix/exec/shellexec.cxx b/shell/source/unix/exec/shellexec.cxx index 5248c934ab16..2e2b2040af1b 100644 --- a/shell/source/unix/exec/shellexec.cxx +++ b/shell/source/unix/exec/shellexec.cxx @@ -39,6 +39,11 @@ #include <sys/stat.h> #endif +#ifdef EMSCRIPTEN +#include <rtl/uri.hxx> +extern void execute_browser(const char* sUrl); +#endif + using com::sun::star::system::XSystemShellExecute; using com::sun::star::system::SystemShellExecuteException; @@ -47,6 +52,7 @@ using namespace ::com::sun::star::lang; using namespace ::com::sun::star::system::SystemShellExecuteFlags; using namespace cppu; +#ifndef EMSCRIPTEN namespace { void escapeForShell( OStringBuffer & rBuffer, const OString & rURL) @@ -63,6 +69,7 @@ namespace } } } +#endif ShellExec::ShellExec( const Reference< XComponentContext >& xContext ) : m_xContext(xContext) @@ -71,6 +78,7 @@ ShellExec::ShellExec( const Reference< XComponentContext >& xContext ) : void SAL_CALL ShellExec::execute( const OUString& aCommand, const OUString& aParameter, sal_Int32 nFlags ) { +#ifndef EMSCRIPTEN OStringBuffer aBuffer, aLaunchBuffer; if (comphelper::LibreOfficeKit::isActive()) @@ -228,6 +236,22 @@ void SAL_CALL ShellExec::execute( const OUString& aCommand, const OUString& aPar int nerr = errno; throw SystemShellExecuteException(OUString::createFromAscii( strerror( nerr ) ), static_cast < XSystemShellExecute * > (this), nerr ); +#else // EMSCRIPTEN + (void)nFlags; + + css::uno::Reference< css::uri::XUriReference > uri( + css::uri::UriReferenceFactory::create(m_xContext)->parse(aCommand)); + if (!uri.is() || !uri->isAbsolute()) + throw SystemShellExecuteException("Emscripten can just open absolute URIs.", + static_cast<XSystemShellExecute*>(this), 42); + if (!aParameter.isEmpty()) + throw SystemShellExecuteException("Emscripten can't process parameters; encode in URI.", + static_cast<XSystemShellExecute*>(this), 42); + + OUString sEscapedURI(rtl::Uri::encode(aCommand, rtl_UriCharClassUric, + rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8)); + execute_browser(sEscapedURI.toUtf8().getStr()); +#endif } // XServiceInfo diff --git a/shell/source/unix/exec/shellexec_em.cxx b/shell/source/unix/exec/shellexec_em.cxx new file mode 100644 index 000000000000..219eac969416 --- /dev/null +++ b/shell/source/unix/exec/shellexec_em.cxx @@ -0,0 +1,28 @@ +/* -*- 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/. + */ + +/** + * Some of our templating stuff clashes with EM_ASM / MAIN_THREAD_EM_ASM: + * + * shellexec.cxx:250:5: error: called object type 'const char *' is not a function or function pointer + * MAIN_THREAD_EM_ASM( + * ^ + * git_emsdk/upstream/emscripten/cache/sysroot/include/emscripten/em_asm.h:208:39: note: expanded from macro 'MAIN_THREAD_EM_ASM' + * #define MAIN_THREAD_EM_ASM(code, ...) ((void)emscripten_asm_const_int_sync_on_main_thread(CODE_EXPR(#code) _EM_ASM_PREP_ARGS(__VA_ARGS__))) + * ^ + * 1 error generated. + * + * so as a workaround the EM_ASM call is now in an extra file. + */ + +#include <emscripten.h> + +void execute_browser(const char* sUrl) { EM_ASM("window.open(UTF8ToString($0));", sUrl); } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/control/fixedhyper.cxx b/vcl/source/control/fixedhyper.cxx index f5d49057228d..c278236f027c 100644 --- a/vcl/source/control/fixedhyper.cxx +++ b/vcl/source/control/fixedhyper.cxx @@ -176,9 +176,9 @@ IMPL_LINK(FixedHyperlink, HandleClick, FixedHyperlink&, rHyperlink, void) uno::Any exc(cppu::getCaughtException()); OUString msg(comphelper::anyToString(exc)); SolarMutexGuard g; - std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Error, VclButtonsType::Ok, msg)); + std::shared_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Error, VclButtonsType::Ok, msg)); xErrorBox->set_title(rHyperlink.GetText()); - xErrorBox->run(); + xErrorBox->runAsync(xErrorBox, [](sal_Int32){}); } } commit c9a45c84e5bf1cbb6c42c50bdce85ca0dc3303a7 Author: Jan-Marek Glogowski <glo...@fbihome.de> AuthorDate: Tue Nov 30 18:58:10 2021 +0100 Commit: Jan-Marek Glogowski <glo...@fbihome.de> CommitDate: Mon Jan 10 05:25:44 2022 +0100 WASM add fontconfig data to FS image We probably want to pre-create the fontconfig cache in the image. Startup time still is not really worse for me, but YMMV. Change-Id: I419682339dd6d943753de9043ff82f2fb877b168 diff --git a/Repository.mk b/Repository.mk index 5d4904aa1d95..46df85c648a6 100644 --- a/Repository.mk +++ b/Repository.mk @@ -1042,7 +1042,7 @@ $(eval $(call gb_Helper_register_packages_for_install,ooo,\ $(eval $(call gb_Helper_register_packages_for_install,ooo_fonts,\ extras_fonts \ - $(if $(USING_X11)$(DISABLE_GUI)$(filter ANDROID,$(OS)), \ + $(if $(USING_X11)$(DISABLE_GUI)$(filter ANDROID EMSCRIPTEN,$(OS)), \ postprocess_fontconfig) \ $(call gb_Helper_optional,MORE_FONTS,\ fonts_alef \ diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk index b542aac239f0..df9ee908f078 100644 --- a/RepositoryExternal.mk +++ b/RepositoryExternal.mk @@ -1271,9 +1271,15 @@ $(call gb_LinkTarget_add_libs,$(1),$(FONTCONFIG_LIBS)) endef +ifeq ($(OS),EMSCRIPTEN) +$(eval $(call gb_Helper_register_packages_for_install,ooo,\ + libfontconfig_data \ +)) +endif + gb_ExternalProject__use_fontconfig := -else +else # SYSTEM_FONTCONFIG define gb_LinkTarget__use_fontconfig $(call gb_LinkTarget_use_external_project,$(1),fontconfig) diff --git a/external/fontconfig/ExternalPackage_fontconfig_data.mk b/external/fontconfig/ExternalPackage_fontconfig_data.mk new file mode 100644 index 000000000000..cc33c26705d7 --- /dev/null +++ b/external/fontconfig/ExternalPackage_fontconfig_data.mk @@ -0,0 +1,58 @@ +# -*- 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_ExternalPackage_ExternalPackage,fontconfig_data,fontconfig)) + +$(eval $(call gb_ExternalPackage_use_external_project,fontconfig_data,fontconfig)) + +$(eval $(call gb_ExternalPackage_add_files,fontconfig_data,$(LIBO_SHARE_FOLDER)/fontconfig,\ + fonts.conf \ +)) + +$(eval $(call gb_ExternalPackage_add_unpacked_files,fontconfig_data,$(LIBO_SHARE_FOLDER)/fontconfig/conf.d,\ + conf.d/05-reset-dirs-sample.conf \ + conf.d/09-autohint-if-no-hinting.conf \ + conf.d/10-autohint.conf \ + conf.d/10-hinting-full.conf \ + conf.d/10-hinting-medium.conf \ + conf.d/10-hinting-none.conf \ + conf.d/10-hinting-slight.conf \ + conf.d/10-no-sub-pixel.conf \ + conf.d/10-scale-bitmap-fonts.conf \ + conf.d/10-sub-pixel-bgr.conf \ + conf.d/10-sub-pixel-rgb.conf \ + conf.d/10-sub-pixel-vbgr.conf \ + conf.d/10-sub-pixel-vrgb.conf \ + conf.d/10-unhinted.conf \ + conf.d/11-lcdfilter-default.conf \ + conf.d/11-lcdfilter-legacy.conf \ + conf.d/11-lcdfilter-light.conf \ + conf.d/20-unhint-small-vera.conf \ + conf.d/25-unhint-nonlatin.conf \ + conf.d/30-metric-aliases.conf \ + conf.d/35-lang-normalize.conf \ + conf.d/40-nonlatin.conf \ + conf.d/45-generic.conf \ + conf.d/45-latin.conf \ + conf.d/49-sansserif.conf \ + conf.d/50-user.conf \ + conf.d/51-local.conf \ + conf.d/60-generic.conf \ + conf.d/60-latin.conf \ + conf.d/65-fonts-persian.conf \ + conf.d/65-khmer.conf \ + conf.d/65-nonlatin.conf \ + conf.d/69-unifont.conf \ + conf.d/70-no-bitmaps.conf \ + conf.d/70-yes-bitmaps.conf \ + conf.d/80-delicious.conf \ + conf.d/90-synthetic.conf \ +)) + +# vim: set shiftwidth=4 tabstop=4 noexpandtab: diff --git a/external/fontconfig/ExternalProject_fontconfig.mk b/external/fontconfig/ExternalProject_fontconfig.mk index 1d65173ce0f5..fa3a8e4515d7 100644 --- a/external/fontconfig/ExternalProject_fontconfig.mk +++ b/external/fontconfig/ExternalProject_fontconfig.mk @@ -29,8 +29,13 @@ $(call gb_ExternalProject_get_state_target,fontconfig,build) : --with-expat-includes=$(call gb_UnpackedTarball_get_dir,expat)/lib \ --with-expat-lib=$(gb_StaticLibrary_WORKDIR) \ --build=$(BUILD_PLATFORM) --host=$(HOST_PLATFORM) \ - $(if $(filter EMSCRIPTEN,$(OS)),ac_cv_func_fstatfs=no ac_cv_func_fstatvfs=no) \ - && $(MAKE) -C src \ + $(if $(filter EMSCRIPTEN,$(OS)), \ + --with-baseconfigdir=/instdir/share/fontconfig \ + --with-cache-dir=/instdir/share/fontconfig/cache \ + --with-add-fonts=/instdir/share/fonts \ + ac_cv_func_fstatfs=no ac_cv_func_fstatvfs=no \ + ) \ + && $(MAKE) -C src && $(MAKE) fonts.conf \ ) $(call gb_Trace_EndRange,fontconfig,EXTERNAL) diff --git a/external/fontconfig/Module_fontconfig.mk b/external/fontconfig/Module_fontconfig.mk index e755f8610db1..2f8f9c8f54d6 100644 --- a/external/fontconfig/Module_fontconfig.mk +++ b/external/fontconfig/Module_fontconfig.mk @@ -11,6 +11,7 @@ $(eval $(call gb_Module_Module,fontconfig)) $(eval $(call gb_Module_add_targets,fontconfig,\ ExternalProject_fontconfig \ + $(if $(filter EMSCRIPTEN,$(OS)),ExternalPackage_fontconfig_data) \ UnpackedTarball_fontconfig \ )) diff --git a/static/CustomTarget_wasm_fs_image.mk b/static/CustomTarget_wasm_fs_image.mk index 44d8407758ef..e11d57e359e5 100644 --- a/static/CustomTarget_wasm_fs_image.mk +++ b/static/CustomTarget_wasm_fs_image.mk @@ -1104,6 +1104,45 @@ gb_wasm_fs_image_files := \ $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/wizard/form/styles/red.css \ $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/wizard/form/styles/violet.css \ $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/wizard/form/styles/water.css \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/05-reset-dirs-sample.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/09-autohint-if-no-hinting.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/10-autohint.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/10-hinting-full.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/10-hinting-medium.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/10-hinting-none.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/10-hinting-slight.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/10-no-sub-pixel.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/10-scale-bitmap-fonts.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/10-sub-pixel-bgr.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/10-sub-pixel-rgb.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/10-sub-pixel-vbgr.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/10-sub-pixel-vrgb.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/10-unhinted.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/11-lcdfilter-default.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/11-lcdfilter-legacy.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/11-lcdfilter-light.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/20-unhint-small-vera.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/25-unhint-nonlatin.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/30-metric-aliases.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/35-lang-normalize.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/40-nonlatin.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/45-generic.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/45-latin.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/49-sansserif.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/50-user.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/51-local.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/60-generic.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/60-latin.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/65-fonts-persian.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/65-khmer.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/65-nonlatin.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/69-unifont.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/70-no-bitmaps.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/70-yes-bitmaps.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/80-delicious.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/conf.d/90-synthetic.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fontconfig/fonts.conf \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/fonts/truetype/fc_local.conf \ $(INSTROOT)/$(LIBO_SHARE_FOLDER)/gallery/fontwork.sdg \ $(INSTROOT)/$(LIBO_SHARE_FOLDER)/gallery/fontwork.sdv \ $(INSTROOT)/$(LIBO_SHARE_FOLDER)/gallery/fontwork.thm \ @@ -1199,6 +1238,7 @@ gb_wasm_fs_image_autoinstall += $(call gb_AutoInstall_get_target,ooo_fonts) endif gb_wasm_fs_image_filelists += $(call gb_ExternalPackage_get_target,liblangtag_data) +gb_wasm_fs_image_filelists += $(call gb_Package_get_target,fontconfig_data) # # Ruleset commit 7ae2cf08f3e1067c43a5d7c5262619e1aacf7369 Author: Armin Le Grand (Allotropia) <armin.le.gr...@me.com> AuthorDate: Thu Nov 18 03:09:14 2021 +0100 Commit: Jan-Marek Glogowski <glo...@fbihome.de> CommitDate: Mon Jan 10 05:25:43 2022 +0100 WASM re-activate and fix the Chart build Change-Id: I13c50ac005e1e990bd185115b6e1717ce2c6bb45 diff --git a/chart2/source/controller/main/ChartController.cxx b/chart2/source/controller/main/ChartController.cxx index 19c314da2635..856ddcdd7dc7 100644 --- a/chart2/source/controller/main/ChartController.cxx +++ b/chart2/source/controller/main/ChartController.cxx @@ -20,6 +20,7 @@ #include <memory> #include <sal/config.h> +#include <config_wasm_strip.h> #include <ChartController.hxx> #include <servicenames.hxx> #include <ResId.hxx> @@ -41,7 +42,9 @@ #include "ChartDropTargetHelper.hxx" #include <dlg_ChartType.hxx> +#ifndef ENABLE_WASM_STRIP_ACCESSIBILITY #include <AccessibleChartView.hxx> +#endif #include "DrawCommandDispatch.hxx" #include "ShapeController.hxx" #include "UndoActions.hxx" @@ -1431,8 +1434,13 @@ uno::Reference< uno::XInterface > SAL_CALL { uno::Reference< uno::XInterface > xResult; +#ifndef ENABLE_WASM_STRIP_ACCESSIBILITY if( aServiceSpecifier == CHART_ACCESSIBLE_TEXT_SERVICE_NAME ) xResult.set( impl_createAccessibleTextContext()); +#else + (void)aServiceSpecifier; +#endif + return xResult; } @@ -1546,9 +1554,13 @@ void ChartController::SetAndApplySelection(const Reference<drawing::XShape>& rxS uno::Reference< XAccessible > ChartController::CreateAccessible() { +#ifndef ENABLE_WASM_STRIP_ACCESSIBILITY uno::Reference< XAccessible > xResult = new AccessibleChartView( GetDrawViewWrapper() ); impl_initializeAccessible( uno::Reference< lang::XInitialization >( xResult, uno::UNO_QUERY ) ); return xResult; +#else + return uno::Reference< XAccessible >(); +#endif } void ChartController::impl_invalidateAccessible() diff --git a/chart2/source/controller/main/ChartController_TextEdit.cxx b/chart2/source/controller/main/ChartController_TextEdit.cxx index f2aa1b5db47f..896243771d81 100644 --- a/chart2/source/controller/main/ChartController_TextEdit.cxx +++ b/chart2/source/controller/main/ChartController_TextEdit.cxx @@ -26,7 +26,9 @@ #include <TitleHelper.hxx> #include <ObjectIdentifier.hxx> #include <ControllerLockGuard.hxx> +#ifndef ENABLE_WASM_STRIP_ACCESSIBILITY #include <AccessibleTextHelper.hxx> +#endif #include <strings.hrc> #include <chartview/DrawModelWrapper.hxx> #include <osl/diagnose.h> @@ -215,10 +217,14 @@ void ChartController::executeDispatch_InsertSpecialCharacter() uno::Reference< css::accessibility::XAccessibleContext > ChartController::impl_createAccessibleTextContext() { +#ifndef ENABLE_WASM_STRIP_ACCESSIBILITY uno::Reference< css::accessibility::XAccessibleContext > xResult( new AccessibleTextHelper( m_pDrawViewWrapper.get() )); return xResult; +#else + return uno::Reference< css::accessibility::XAccessibleContext >(); +#endif } } //namespace chart diff --git a/chart2/source/controller/main/ChartWindow.cxx b/chart2/source/controller/main/ChartWindow.cxx index 9f1ff9342c98..a1e6cee68f08 100644 --- a/chart2/source/controller/main/ChartWindow.cxx +++ b/chart2/source/controller/main/ChartWindow.cxx @@ -17,6 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <config_wasm_strip.h> #include <ChartWindow.hxx> #include <ChartController.hxx> #include <helpids.h> @@ -181,10 +182,14 @@ void ChartWindow::KeyInput( const KeyEvent& rKEvt ) uno::Reference< css::accessibility::XAccessible > ChartWindow::CreateAccessible() { +#ifndef ENABLE_WASM_STRIP_ACCESSIBILITY if( m_pWindowController ) return m_pWindowController->CreateAccessible(); else return Window::CreateAccessible(); +#else + return uno::Reference< css::accessibility::XAccessible >(); +#endif } void ChartWindow::DataChanged( const DataChangedEvent& rDCEvt ) diff --git a/config_host.mk.in b/config_host.mk.in index 3fd4b172b6e3..ef06f2a1c9c7 100644 --- a/config_host.mk.in +++ b/config_host.mk.in @@ -216,7 +216,7 @@ export ENABLE_WASM_STRIP=@ENABLE_WASM_STRIP@ export ENABLE_WASM_STRIP_ACCESSIBILITY=@ENABLE_WASM_STRIP@ export ENABLE_WASM_STRIP_BASIC_CALC_DRAW_MATH_IMPRESS=@ENABLE_WASM_STRIP@ export ENABLE_WASM_STRIP_CANVAS=@ENABLE_WASM_STRIP@ -export ENABLE_WASM_STRIP_CHART=@ENABLE_WASM_STRIP@ +export ENABLE_WASM_STRIP_CHART= export ENABLE_WASM_STRIP_DBACCESS=@ENABLE_WASM_STRIP@ export ENABLE_WASM_STRIP_EPUB=@ENABLE_WASM_STRIP@ export ENABLE_WASM_STRIP_EXTRA=@ENABLE_WASM_STRIP@ diff --git a/config_host/config_wasm_strip.h.in b/config_host/config_wasm_strip.h.in index 12ec0f5f816b..81415284f05b 100644 --- a/config_host/config_wasm_strip.h.in +++ b/config_host/config_wasm_strip.h.in @@ -7,7 +7,7 @@ #define ENABLE_WASM_STRIP #define ENABLE_WASM_STRIP_ACCESSIBILITY #define ENABLE_WASM_STRIP_CANVAS -#define ENABLE_WASM_STRIP_CHART +// #define ENABLE_WASM_STRIP_CHART #define ENABLE_WASM_STRIP_DBACCESS #define ENABLE_WASM_STRIP_EPUB #define ENABLE_WASM_STRIP_EXTRA diff --git a/static/CustomTarget_wasm_fs_image.mk b/static/CustomTarget_wasm_fs_image.mk index 42b2b635864c..44d8407758ef 100644 --- a/static/CustomTarget_wasm_fs_image.mk +++ b/static/CustomTarget_wasm_fs_image.mk @@ -1132,6 +1132,65 @@ gb_wasm_fs_image_files := \ $(INSTROOT)/$(LIBO_URE_MISC_FOLDER)/services.rdb \ $(SRCDIR)/android/default-document/example.odt \ +ifneq ($(ENABLE_WASM_STRIP_CHART),TRUE) +gb_wasm_fs_image_files += \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/menubar/menubar.xml \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/popupmenu/drawtext.xml \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/popupmenu/draw.xml \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/statusbar/statusbar.xml \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/toolbar/arrowshapes.xml \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/toolbar/basicshapes.xml \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/toolbar/calloutshapes.xml \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/toolbar/drawbar.xml \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/toolbar/flowchartshapes.xml \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/toolbar/standardbar.xml \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/toolbar/starshapes.xml \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/toolbar/symbolshapes.xml \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/toolbar/toolbar.xml \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/3dviewdialog.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/attributedialog.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/chardialog.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/chartdatadialog.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/charttypedialog.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/columnfragment.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/combobox.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/datarangedialog.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/dlg_DataLabel.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/dlg_InsertErrorBars.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/dlg_InsertLegend.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/imagefragment.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/insertaxisdlg.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/insertgriddlg.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/inserttitledlg.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/paradialog.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/sidebaraxis.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/sidebarelements.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/sidebarerrorbar.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/sidebarseries.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/sidebartype.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/smoothlinesdlg.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/steppedlinesdlg.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/titlerotationtabpage.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/tp_3D_SceneAppearance.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/tp_3D_SceneGeometry.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/tp_3D_SceneIllumination.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/tp_axisLabel.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/tp_AxisPositions.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/tp_ChartType.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/tp_DataLabel.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/tp_DataPointOption.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/tp_DataSource.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/tp_ErrorBars.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/tp_LegendPosition.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/tp_PolarOptions.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/tp_RangeChooser.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/tp_Scale.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/tp_SeriesToAxis.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/tp_Trendline.ui \ + $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/modules/schart/ui/wizelementspage.ui \ + +endif # !ENABLE_WASM_STRIP_CHART + $(foreach theme,$(WITH_THEMES), \ $(eval gb_wasm_fs_image_files += $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/images_$(theme).zip)) commit d69a475b321d77fb9da5f6c4e9ae31c6f47dc3d6 Author: Armin Le Grand (Allotropia) <armin.le.gr...@me.com> AuthorDate: Fri Nov 12 17:16:32 2021 +0100 Commit: Jan-Marek Glogowski <glo...@fbihome.de> CommitDate: Mon Jan 10 05:25:43 2022 +0100 WASM make test file loading work Change-Id: Ic34104534c3e0e73791cf867bfb2e1246dc79cf8 diff --git a/framework/source/helper/statusindicatorfactory.cxx b/framework/source/helper/statusindicatorfactory.cxx index a3f9b864dbe8..6aacbd040d3b 100644 --- a/framework/source/helper/statusindicatorfactory.cxx +++ b/framework/source/helper/statusindicatorfactory.cxx @@ -87,6 +87,9 @@ void SAL_CALL StatusIndicatorFactory::initialize(const css::uno::Sequence< css:: } } +#ifdef EMSCRIPTEN + m_bDisableReschedule = true; +#endif impl_createProgress(); } diff --git a/package/source/zipapi/ZipFile.cxx b/package/source/zipapi/ZipFile.cxx index 2b298e0ebdf8..3e9d24858df1 100644 --- a/package/source/zipapi/ZipFile.cxx +++ b/package/source/zipapi/ZipFile.cxx @@ -651,11 +651,13 @@ uno::Reference< XInputStream > ZipFile::createStreamForZipEntry( return xSrcStream; uno::Reference<io::XInputStream> xBufStream; +#ifndef EMSCRIPTEN static const sal_Int32 nThreadingThreshold = 10000; if( xSrcStream->available() > nThreadingThreshold ) xBufStream = new XBufferedThreadedStream(xSrcStream, xSrcStream->getSize()); else +#endif xBufStream = new XBufferedStream(xSrcStream); return xBufStream; diff --git a/sax/source/fastparser/fastparser.cxx b/sax/source/fastparser/fastparser.cxx index f6fe5ee43bec..e4f0915421af 100644 --- a/sax/source/fastparser/fastparser.cxx +++ b/sax/source/fastparser/fastparser.cxx @@ -838,6 +838,9 @@ void FastSaxParserImpl::parseStream(const InputSource& rStructSource) rEntity.mxDocumentHandler->startDocument(); } +#ifdef EMSCRIPTEN + rEntity.mbEnableThreads = false; +#else if (!getenv("SAX_DISABLE_THREADS") && !m_bDisableThreadedParser) { Reference<css::io::XSeekable> xSeekable(rEntity.maStructSource.aInputStream, UNO_QUERY); @@ -845,6 +848,7 @@ void FastSaxParserImpl::parseStream(const InputSource& rStructSource) rEntity.mbEnableThreads = (xSeekable.is() && xSeekable->getLength() > 10000) || (rEntity.maStructSource.aInputStream->available() > 10000); } +#endif if (rEntity.mbEnableThreads) { commit 34e389e2a42b9fb6dc3b099e46c74fbc5e2be97f Author: Jan-Marek Glogowski <glo...@fbihome.de> AuthorDate: Sun Jan 9 02:15:12 2022 +0100 Commit: Jan-Marek Glogowski <glo...@fbihome.de> CommitDate: Mon Jan 10 05:25:42 2022 +0100 WASM merge wasm-qt into static module Change-Id: I1ed26685561fd79d26cc0844faa3dfe4c00d439a diff --git a/Repository.mk b/Repository.mk index ca1416bc6215..5d4904aa1d95 100644 --- a/Repository.mk +++ b/Repository.mk @@ -83,6 +83,7 @@ $(eval $(call gb_Helper_register_executables,NONE, \ visualbackendtest \ listfonts \ $(if $(and $(ENABLE_GTK3), $(filter LINUX %BSD SOLARIS,$(OS))), gtktiledviewer) \ + $(if $(filter EMSCRIPTEN,$(OS)),wasm-qt5-mandelbrot) \ )) $(eval $(call gb_Helper_register_executables_for_install,SDK,sdk, \ diff --git a/RepositoryModule_host.mk b/RepositoryModule_host.mk index 49118cd6259d..3661cae0c4c4 100644 --- a/RepositoryModule_host.mk +++ b/RepositoryModule_host.mk @@ -154,7 +154,7 @@ $(eval $(call gb_Module_add_moduledirs,libreoffice,\ $(if $(ENABLE_WASM_STRIP_BASIC_CALC_DRAW_MATH_IMPRESS),, \ starmath \ ) \ - $(if $(ENABLE_CUSTOMTARGET_COMPONENTS),static) \ + static \ stoc \ store \ svl \ diff --git a/wasm-qt/CustomTarget_wasm-qt5-mandelbrot_moc.mk b/static/CustomTarget_wasm-qt5-mandelbrot_moc.mk similarity index 64% rename from wasm-qt/CustomTarget_wasm-qt5-mandelbrot_moc.mk rename to static/CustomTarget_wasm-qt5-mandelbrot_moc.mk index 6267db3f5b8d..d3da8235c5f9 100644 --- a/wasm-qt/CustomTarget_wasm-qt5-mandelbrot_moc.mk +++ b/static/CustomTarget_wasm-qt5-mandelbrot_moc.mk @@ -7,15 +7,15 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. # -$(eval $(call gb_CustomTarget_CustomTarget,wasm-qt/qt5-mandelbrot)) +$(eval $(call gb_CustomTarget_CustomTarget,static/qt5-mandelbrot)) -$(call gb_CustomTarget_get_target,wasm-qt/qt5-mandelbrot) : \ - $(call gb_CustomTarget_get_workdir,wasm-qt/qt5-mandelbrot)/renderthread.moc \ - $(call gb_CustomTarget_get_workdir,wasm-qt/qt5-mandelbrot)/mandelbrotwidget.moc \ +$(call gb_CustomTarget_get_target,static/qt5-mandelbrot) : \ + $(call gb_CustomTarget_get_workdir,static/qt5-mandelbrot)/renderthread.moc \ ... etc. - the rest is truncated