Rebased ref, commits from common ancestor:
commit ecbb8e6b04ed1f474c3b9f1d83903118bb2b0d60
Author: Jan-Marek Glogowski <[email protected]>
AuthorDate: Sat Mar 26 20:46:56 2022 +0100
Commit: Jan-Marek Glogowski <[email protected]>
CommitDate: Tue Mar 29 20:11:36 2022 +0200
WASM fix native EH build since Emscripten 3.1.6
Building LO with WASM native EH and Emscripten 3.1.6+, the link
fails with a missing "emscripten_longjmp" symbol. Actually the
old build was simply wrong, because the emscripten_longjmp
function is just used for the Emscripten SjLj and not the native
WASM SjLj implementation. Linking just worked, because the used
libcompiler_rt-wasm-sjlj-mt.a lib was incorrectly providing that
symbol, which 3.1.6 removed.
But since running the NEH build still fails early in the same way
then before in FF nightly 100 and Chrome (= failure in the LO job
scheduler calling Task::UpdateMinPeriod for the "desktop::Desktop
m_firstRunTimer" timer, resulting in a WASM VM "RuntimeError:
indirect call signature mismatch"), there is still no way to know,
if nothing else it missing. The Emscripten / JS EH build still
works without any code changes. And it's not the first call on
a job object that fails...
And unfortunatly, because Qt itself also uses libpng, it also uses
SjLj for error handling, like LO in the image import, so the Qt
build must also be patched to build with "-s SUPPORT_LONGJMP=wasm".
Simply enough to do (see README.wasm.md). LO's configure now
detects that symbol and will bail out on incompatible Qt and LO
build setup.
See https://github.com/emscripten-core/emscripten/issues/16572
Change-Id: I3a1877f3aeb77873906176b9d3cd1ea92973f1f6
diff --git a/configure.ac b/configure.ac
index 9d97f42c4030..224faea12abf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4625,10 +4625,10 @@ check_use_ld()
fi
else
# I tried to use gcc's '-B<path>' and a directory + symlink setup
in
- # $BUILDDIR, but libtool always filtered-out that option, so gcc
wouldn't
- # pickup the alternative linker, when called by libtool for linking.
+ # $BUILDDIR, but libtool always filtered-out that option, so gcc
wouldn't
+ # pickup the alternative linker, when called by libtool for
linking.
# For mold, one can use LD_PRELOAD=/usr/lib/mold/mold-wrapper.so
instead.
- AC_MSG_ERROR([A linker path is just supported with clang, because
of libtool's -B filtering!])
+ AC_MSG_ERROR([A linker path is just supported with clang, because
of libtool's -B filtering!])
fi
fi
use_ld_fail_if_error=$2
@@ -12966,6 +12966,21 @@ then
if test ! -f "${qt5_platformsdir}"/libqwasm.a -o ! -f
"$QT5_PLATFORMS_SRCDIR"/wasm_shell.html; then
AC_MSG_ERROR([No Qt5 WASM QPA plugin found in ${qt5_platformsdir}
or ${QT5_PLATFORMS_SRCDIR}])
fi
+
+ EMSDK_LLVM_NM="$(em-config EMSCRIPTEN_ROOT)"/../bin/llvm-nm
+ if ! test -x "$EMSDK_LLVM_NM"; then
+ AC_MSG_ERROR([Missing llvm-nm expected to be found at
"$EMSDK_LLVM_NM".])
+ fi
+ if test ! -f "${qt5_libdir}"/libQt5Gui.a; then
+ AC_MSG_ERROR([No Qt5 WASM libQt5Gui.a in ${qt5_libdir}])
+ fi
+ QT5_WASM_SJLJ="`${EMSDK_LLVM_NM} "${qt5_libdir}"/libQt5Gui.a
2>/dev/null | $GREP emscripten_longjmp`"
+ if test "$ENABLE_WASM_EXCEPTIONS" = TRUE -a -n "$QT5_WASM_SJLJ"; then
+ AC_MSG_ERROR(['emscripten_longjmp' symbol found in libQt5Gui.a
(missing '-s SUPPORT_LONGJMP=wasm'). See static/README.wasm.md.])
+ fi
+ if test "$ENABLE_WASM_EXCEPTIONS" != TRUE -a -z "$QT5_WASM_SJLJ"; then
+ AC_MSG_ERROR(['emscripten_longjmp' symbol not found in
libQt5Gui.a. You probably use an incompatible Qt build with '-s
SUPPORT_LONGJMP=wasm'.])
+ fi
fi
QT5_CFLAGS="-I$qt5_incdir -DQT_CLEAN_NAMESPACE -DQT_THREAD_SUPPORT
-DQT_NO_VERSION_TAGGING"
diff --git a/external/cairo/ExternalProject_cairo.mk
b/external/cairo/ExternalProject_cairo.mk
index f1bf3ddbd1b2..0996572d63ba 100644
--- a/external/cairo/ExternalProject_cairo.mk
+++ b/external/cairo/ExternalProject_cairo.mk
@@ -48,7 +48,7 @@ $(call gb_ExternalProject_get_state_target,cairo,build) :
$(gb_RUN_CONFIGURE) ./configure \
$(if $(debug),STRIP=" ") \
$(if $(filter ANDROID iOS,$(OS)),CFLAGS="$(if $(debug),-g)
$(ZLIB_CFLAGS) $(gb_VISIBILITY_FLAGS)") \
- $(if $(filter EMSCRIPTEN,$(OS)),CFLAGS=" $(ZLIB_CFLAGS)
-Wno-enum-conversion" --enable-pthread=yes PTHREAD_LIBS="") \
+ $(if $(filter EMSCRIPTEN,$(OS)),CFLAGS=" $(ZLIB_CFLAGS)
-Wno-enum-conversion $(gb_EMSCRIPTEN_CPPFLAGS)" --enable-pthread=yes
PTHREAD_LIBS="") \
$(if $(filter-out EMSCRIPTEN ANDROID
iOS,$(OS)),CFLAGS="$(CFLAGS) $(if $(debug),-g) $(ZLIB_CFLAGS)" ) \
$(if $(filter ANDROID iOS,$(OS)),PKG_CONFIG=./dummy_pkg_config)
\
LIBS="$(ZLIB_LIBS)" \
diff --git a/external/cppunit/ExternalProject_cppunit.mk
b/external/cppunit/ExternalProject_cppunit.mk
index 3c6e18af71d2..f0b4ff06acce 100644
--- a/external/cppunit/ExternalProject_cppunit.mk
+++ b/external/cppunit/ExternalProject_cppunit.mk
@@ -28,7 +28,7 @@ $(call gb_ExternalProject_get_state_target,cppunit,build) :
$(call gb_Trace_EndRange,cppunit,EXTERNAL)
else
-cppunit_CXXFLAGS=$(CXXFLAGS)
+cppunit_CXXFLAGS=$(CXXFLAGS) $(gb_EMSCRIPTEN_CXXFLAGS)
cppunit_CXXFLAGS+=$(gb_COMPILERDEFS_STDLIB_DEBUG)
@@ -52,7 +52,7 @@ $(call gb_ExternalProject_get_state_target,cppunit,build) :
$(if $(filter SOLARIS,$(OS)),LIBS="-lm") \
$(if $(filter ANDROID,$(OS)),LIBS="$(gb_STDLIBS)") \
$(if
$(verbose),--disable-silent-rules,--enable-silent-rules) \
- CXXFLAGS="$(cppunit_CXXFLAGS)
$(gb_EMSCRIPTEN_CPPFLAGS)" \
+ CXXFLAGS="$(cppunit_CXXFLAGS)" \
&& cd src \
&& $(MAKE) \
)
diff --git a/external/freetype/ExternalProject_freetype.mk
b/external/freetype/ExternalProject_freetype.mk
index 57e7df357de4..7f3faca416ca 100644
--- a/external/freetype/ExternalProject_freetype.mk
+++ b/external/freetype/ExternalProject_freetype.mk
@@ -26,7 +26,7 @@ $(call gb_ExternalProject_get_state_target,freetype,build) :
--without-png \
--prefix=$(call
gb_UnpackedTarball_get_dir,freetype/instdir) \
$(gb_CONFIGURE_PLATFORMS) \
- CFLAGS="$(CFLAGS) $(if $(debug),-g)
$(gb_VISIBILITY_FLAGS)" \
+ CFLAGS="$(CFLAGS) $(if $(debug),-g)
$(gb_VISIBILITY_FLAGS) $(gb_EMSCRIPTEN_CPPFLAGS)" \
&& $(MAKE) install \
&& touch $@ )
$(call gb_Trace_EndRange,freetype,EXTERNAL)
diff --git a/external/libnumbertext/ExternalProject_libnumbertext.mk
b/external/libnumbertext/ExternalProject_libnumbertext.mk
index 976d1772c4b0..1716f9db8a12 100644
--- a/external/libnumbertext/ExternalProject_libnumbertext.mk
+++ b/external/libnumbertext/ExternalProject_libnumbertext.mk
@@ -16,9 +16,9 @@ $(eval $(call
gb_ExternalProject_register_targets,libnumbertext,\
build \
))
-libnumbertext_CXXFLAGS=$(CXXFLAGS) $(CXXFLAGS_CXX11) $(gb_EMSCRIPTEN_CPPFLAGS)
+libnumbertext_CXXFLAGS=$(CXXFLAGS) $(CXXFLAGS_CXX11) $(gb_EMSCRIPTEN_CXXFLAGS)
-libnumbertext_CPPFLAGS+=$(gb_COMPILERDEFS_STDLIB_DEBUG)
+libnumbertext_CPPFLAGS+=$(gb_COMPILERDEFS_STDLIB_DEBUG)
$(gb_EMSCRIPTEN_CPPFLAGS)
$(call gb_ExternalProject_get_state_target,libnumbertext,build):
$(call gb_Trace_StartRange,libnumbertext,EXTERNAL)
diff --git a/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk
b/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk
index 83e850a95f9f..61424f72c44f 100644
--- a/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk
+++ b/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk
@@ -33,6 +33,7 @@ gb_EMSCRIPTEN_QTDEFS := -DQT_NO_LINKED_LIST
-DQT_NO_JAVA_STYLE_ITERATORS -DQT_NO
gb_Executable_EXT := .html
ifeq ($(ENABLE_WASM_EXCEPTIONS),TRUE)
gb_EMSCRIPTEN_EXCEPT = -fwasm-exceptions -s SUPPORT_LONGJMP=wasm
+gb_EMSCRIPTEN_CPPFLAGS += -s SUPPORT_LONGJMP=wasm
else
gb_EMSCRIPTEN_EXCEPT = -s DISABLE_EXCEPTION_CATCHING=0
endif
@@ -40,7 +41,7 @@ endif
gb_CXXFLAGS += $(gb_EMSCRIPTEN_CPPFLAGS)
gb_LinkTarget_EXCEPTIONFLAGS += $(gb_EMSCRIPTEN_EXCEPT)
gb_LinkTarget_CFLAGS += $(gb_EMSCRIPTEN_CPPFLAGS) $(gb_EMSCRIPTEN_QTDEFS)
-gb_LinkTarget_CXXFLAGS += $(gb_EMSCRIPTEN_CPPFLAGS) $(gb_EMSCRIPTEN_QTDEFS)
+gb_LinkTarget_CXXFLAGS += $(gb_EMSCRIPTEN_CPPFLAGS) $(gb_EMSCRIPTEN_QTDEFS)
$(gb_EMSCRIPTEN_EXCEPT)
gb_LinkTarget_LDFLAGS += $(gb_EMSCRIPTEN_LDFLAGS) $(gb_EMSCRIPTEN_CPPFLAGS)
$(gb_EMSCRIPTEN_EXCEPT)
# Linker and compiler optimize + debug flags are handled in LinkTarget.mk
diff --git a/static/README.wasm.md b/static/README.wasm.md
index 4ea67ad03e6e..4624e87605b7 100644
--- a/static/README.wasm.md
+++ b/static/README.wasm.md
@@ -87,9 +87,10 @@ Use `emrun --serve_after_close` to run Qt WASM demos.
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
-is not essential).
+There's a distro config for WASM, but it just provides
--host=wasm32-local-emscripten, which
+should be enough setup. The build itself is a cross build and the
cross-toolset just depends
+on a minimal toolset (gcc, libc-dev, flex, bison); all else is build from
source, because the
+final result is not depending on the build system at all.
Recommended configure setup is thusly:
@@ -107,6 +108,21 @@ FWIW: it's also possible to build an almost static Linux
LibreOffice by just usi
--disable-dynloading --enable-customtarget-components. System externals are
still
linked dynamically, but everything else is static.
+#### Experimental (AKA currently broken) WASM exception + SjLj build
+
+You can build LO with WASM exceptions, which should be "much" faster then the
JS
+based Emscripten EH handling. For setjmp / longjmp (SjLj) used by the PNG and
JPEG
+libraries error handling, this needs Emscripten 3.1.3+. That builds, but
execution
+still fails early with a signature mismatch call to Task::UpdateMinPeriod in
LO's
+job scheduler code. Unfortunatly the build also needs a Qt build with
+"-s SUPPORT_LONGJMP=wasm", which is incompatible with the JS EH + SjLj.
+
+The LO configure flag is simply an additional --enable-wasm-exceptions. Qt5 can
+be patched in qtbase/mkspecs/wasm-emscripten/qmake.conf with the addition of
+
+ QMAKE_CFLAGS += -s SUPPORT_LONGJMP=wasm
+ QMAKE_CXXFLAGS += -s SUPPORT_LONGJMP=wasm
+
### "Deploying" soffice.wasm
tar -chf wasm.tar --xform 's/.*program/lo-wasm/' instdir/program/soffice.*
\
commit 02bcdecdfa05917905bf40418154d4d4cdaccdfa
Author: Jan-Marek Glogowski <[email protected]>
AuthorDate: Sun Feb 20 14:06:54 2022 +0100
Commit: Jan-Marek Glogowski <[email protected]>
CommitDate: Tue Mar 29 20:11:36 2022 +0200
fixme static tests
Change-Id: I2aaffa032bd531272257ca40d6f9b9d25c4de5aa
diff --git a/sal/cppunittester/cppunittester.cxx
b/sal/cppunittester/cppunittester.cxx
index 51d410d043f9..c5a72152fb33 100644
--- a/sal/cppunittester/cppunittester.cxx
+++ b/sal/cppunittester/cppunittester.cxx
@@ -244,6 +244,7 @@ public:
, protectors(protectors_)
, result(result_)
{
+ (void) args_;
}
ProtectedFixtureFunctor(const ProtectedFixtureFunctor&) = delete;
ProtectedFixtureFunctor& operator=(const ProtectedFixtureFunctor&) =
delete;
commit 135d03e494ad94fb54a8489899d04fce2447bb7f
Author: Jan-Marek Glogowski <[email protected]>
AuthorDate: Sun Jan 9 14:49:28 2022 +0100
Commit: Jan-Marek Glogowski <[email protected]>
CommitDate: Tue Mar 29 20:11:36 2022 +0200
Add a larger Writer example document
Change-Id: I4bc9a82c7f99563af8da62f889b51d1b583df760
diff --git a/android/default-document/example_larger.odt
b/android/default-document/example_larger.odt
new file mode 100644
index 000000000000..1b3a1dfb877a
Binary files /dev/null and b/android/default-document/example_larger.odt differ
diff --git a/static/CustomTarget_emscripten_fs_image.mk
b/static/CustomTarget_emscripten_fs_image.mk
index 8166802858e5..8c347de38d5a 100644
--- a/static/CustomTarget_emscripten_fs_image.mk
+++ b/static/CustomTarget_emscripten_fs_image.mk
@@ -1131,6 +1131,7 @@ gb_emscripten_fs_image_files := \
$(INSTROOT)/$(LIBO_SHARE_RESOURCE_FOLDER)/common/fonts/opens___.ttf \
$(INSTROOT)/$(LIBO_URE_ETC_FOLDER)/$(call gb_Helper_get_rcfile,uno) \
$(INSTROOT)/$(LIBO_URE_MISC_FOLDER)/services.rdb \
+ $(SRCDIR)/android/default-document/example_larger.odt \
$(SRCDIR)/android/default-document/example.odt \
ifneq ($(ENABLE_WASM_STRIP_CHART),TRUE)
diff --git a/static/emscripten/soffice_args.js
b/static/emscripten/soffice_args.js
index 7ecf7e8988e8..fa5e9dd4164d 100644
--- a/static/emscripten/soffice_args.js
+++ b/static/emscripten/soffice_args.js
@@ -2,5 +2,5 @@ Module['arguments'] = [
'--norestore',
'--nologo',
'--writer',
- '/android/default-document/example.odt'
+ '/android/default-document/example_larger.odt'
];
commit b3bcf823a61f54ec206791a5a23ba6a208c51ec0
Author: Jan-Marek Glogowski <[email protected]>
AuthorDate: Wed Nov 17 01:57:33 2021 +0100
Commit: Jan-Marek Glogowski <[email protected]>
CommitDate: Tue Mar 29 20:11:35 2022 +0200
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 ee445710b9c0..a1c0f9aa5ad2 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 @@ struct SfxDispatcher_Impl;
namespace com::sun::star::awt { class XPopupMenu; }
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 abad985775e4..4c91ac68d8f4 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 cdf62376c30f..74446eec0f42 100644
--- a/offapi/UnoApi_offapi.mk
+++ b/offapi/UnoApi_offapi.mk
@@ -1858,6 +1858,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 17edf97cc16d..cce1d7d9ec19 100644
--- a/sfx2/source/control/dispatch.cxx
+++ b/sfx2/source/control/dispatch.cxx
@@ -60,6 +60,7 @@
#include <svl/eitem.hxx>
#include <svl/itemiter.hxx>
#include <svl/itempool.hxx>
+#include <svtools/dialogclosedlistener.hxx>
#include <toolkit/awt/vclxmenu.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <tools/debug.hxx>
@@ -137,8 +138,12 @@ struct SfxDispatcher_Impl
SfxDisableFlags nDisableFlags;
bool bFlushed;
std::deque< std::deque<SfxToDo_Impl> > aToDoCopyStack;
+
+ static css::uno::Reference<css::frame::XPopupMenuController>*
m_pActivePopupController;
};
+css::uno::Reference<css::frame::XPopupMenuController>*
SfxDispatcher_Impl::m_pActivePopupController = nullptr;
+
/** This method checks if the stack of the SfxDispatchers is flushed, or if
push- or pop- commands are pending.
*/
@@ -1685,7 +1690,52 @@ bool SfxDispatcher::FillState_(const SfxSlotServer&
rSvr, SfxItemSet& rState,
return false;
}
-void SfxDispatcher::ExecutePopup( vcl::Window *pWin, const Point *pPos )
+namespace {
+
+static void
lcl_FinishPopupDispatch(css::uno::Reference<css::frame::XPopupMenuController>
xPopupController)
+{
+ css::uno::Reference<css::lang::XComponent> xComponent(xPopupController,
css::uno::UNO_QUERY);
+ if (xComponent.is())
+ xComponent->dispose();
+ SfxDispatcher_Impl::m_pActivePopupController = nullptr;
+}
+
+struct SfxDispatcherPopupFinish final
+{
+ css::uno::Reference<css::frame::XPopupMenuController> m_xPopupController;
+ std::function<void(sal_Int16)> m_aCloseFunc;
+ rtl::Reference<::svt::DialogClosedListener> m_xDialogListener;
+ css::uno::Reference<css::awt::XPopupMenu> m_xPopupMenu;
+
+ DECL_LINK(PopupClosedHdl, css::ui::dialogs::DialogClosedEvent*, void);
+
+
SfxDispatcherPopupFinish(css::uno::Reference<css::frame::XPopupMenuController>
xPopupController,
+ const std::function<void(sal_Int16)>& rCloseFunc,
+ css::uno::Reference<css::awt::XPopupMenu>
xPopupMenu)
+ : m_xPopupController(xPopupController)
+ , m_aCloseFunc(rCloseFunc)
+ , m_xDialogListener(new ::svt::DialogClosedListener())
+ , m_xPopupMenu(xPopupMenu)
+ {
+ m_xDialogListener->SetDialogClosedLink(LINK(this,
SfxDispatcherPopupFinish, PopupClosedHdl));
+ }
+};
+
+IMPL_LINK(SfxDispatcherPopupFinish, PopupClosedHdl,
css::ui::dialogs::DialogClosedEvent*, pEvt, void)
+{
+ assert(m_xPopupController.is());
+ if (!comphelper::LibreOfficeKit::isActive())
+ assert(SfxDispatcher_Impl::m_pActivePopupController ==
&m_xPopupController);
+ if (m_aCloseFunc)
+ m_aCloseFunc(pEvt ? pEvt->DialogResult : 0);
+ lcl_FinishPopupDispatch(m_xPopupController);
+ delete this;
+}
+
+} // anon namespace
+
+void SfxDispatcher::ExecutePopup(vcl::Window *pWin, const Point *pPos,
+ const std::function<void(sal_Int16)>& rCloseFunc)
{
SfxDispatcher &rDisp = *SfxGetpApp()->GetDispatcher_Impl();
sal_uInt16 nShLevel = 0;
@@ -1699,7 +1749,7 @@ void SfxDispatcher::ExecutePopup( vcl::Window *pWin,
const Point *pPos )
const OUString& rResName = pSh->GetInterface()->GetPopupMenuName();
if ( !rResName.isEmpty() )
{
- rDisp.ExecutePopup( rResName, pWin, pPos );
+ rDisp.ExecutePopup(rResName, pWin, pPos, rCloseFunc);
return;
}
}
@@ -1808,7 +1858,8 @@ boost::property_tree::ptree
SfxDispatcher::fillPopupMenu(const css::uno::Referen
return ::fillPopupMenu(pVCLMenu);
}
-void SfxDispatcher::ExecutePopup( const OUString& rResName, vcl::Window* pWin,
const Point* pPos )
+void SfxDispatcher::ExecutePopup( const OUString& rResName, vcl::Window* pWin,
const Point* pPos,
+ const std::function<void(sal_Int16)>& rCloseFunc)
{
css::uno::Sequence< css::uno::Any > aArgs{
css::uno::Any(comphelper::makePropertyValue( "Value", rResName )),
@@ -1817,16 +1868,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();
@@ -1852,14 +1916,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 feaacb1bdfea..c15cea74d861 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -5431,7 +5431,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 3eda26c81236..7b6f833cdb21 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 )
@@ -493,6 +494,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 79254d9f5fd5..6da1dae5f9e7 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;
@@ -73,7 +74,17 @@ public:
virtual void SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const
Image& rImage ) = 0;
virtual void SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem,
const vcl::KeyCode& rKeyCode, const OUString& rKeyName ) = 0;
virtual void GetSystemMenuData( SystemMenuData* pData ) = 0;
- virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const
tools::Rectangle& rRect, FloatWinPopupFlags nFlags);
+ /**
+ * @param pListener
+ * if !nullptr, the menu is supposed to be only shown and it'll run
async.
+ * Mainly means, when the menu is hidden, it must call the listener's
+ * dialogClosed. The listener will destroy the SalMenu!
+ *
+ * @return
+ * true, if the feature is implemented and was successful.
+ */
+ virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const
tools::Rectangle& rRect, FloatWinPopupFlags nFlags,
+ const
css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* pListener =
nullptr);
virtual void ShowCloseButton(bool bShow);
virtual bool AddMenuBarButton( const SalMenuButtonItem& ); // return false
if not implemented or failure
virtual void RemoveMenuBarButton( sal_uInt16 nId );
diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
index 85c0f5d3d893..5d5a487df8f1 100644
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
@@ -132,7 +132,8 @@ public:
#endif
void ReturnFocus();
- virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const
tools::Rectangle& rRect, FloatWinPopupFlags nFlags) override;
+ virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const
tools::Rectangle& rRect, FloatWinPopupFlags nFlags,
+ const
css::uno::Reference<css::ui::dialogs::XDialogClosedListener>* = nullptr)
override;
virtual void ShowCloseButton(bool bShow) override;
virtual bool AddMenuBarButton( const SalMenuButtonItem& rNewItem )
override;
virtual void RemoveMenuBarButton( sal_uInt16 nId ) override;
diff --git a/vcl/osx/salmenu.cxx b/vcl/osx/salmenu.cxx
index 3164ba873bae..0a91ab88cc36 100644
--- a/vcl/osx/salmenu.cxx
+++ b/vcl/osx/salmenu.cxx
@@ -281,8 +281,13 @@ AquaSalMenu::~AquaSalMenu()
}
}
-bool AquaSalMenu::ShowNativePopupMenu(FloatingWindow * pWin, const
tools::Rectangle& rRect, FloatWinPopupFlags nFlags)
+bool AquaSalMenu::ShowNativePopupMenu(
+ FloatingWindow* pWin, const tools::Rectangle& rRect, FloatWinPopupFlags
nFlags,
+ const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>*
pListener)
{
+ if (pListener)
+ return false;
+
// set offsets for positioning
const float offset = 9.0;
diff --git a/vcl/qt5/QtMenu.cxx b/vcl/qt5/QtMenu.cxx
index d9279fb9389a..b2d050291084 100644
--- a/vcl/qt5/QtMenu.cxx
+++ b/vcl/qt5/QtMenu.cxx
@@ -93,6 +93,16 @@ void QtMenu::InsertMenuItem(QtMenuItem* pSalMenuItem,
unsigned nPos)
// no QMenu set, instantiate own one
mpOwnedQMenu.reset(new QMenu);
mpQMenu = mpOwnedQMenu.get();
+
+ connect(mpQMenu, &QMenu::aboutToHide, this, [this] {
+ if (m_pWin && m_xListener.is())
+ {
+ QMenu* pMenu = mpOwnedQMenu.release();
+ css::ui::dialogs::DialogClosedEvent
aEvent(m_pWin->GetComponentInterface(), 0);
+ m_xListener->dialogClosed(aEvent);
+ pMenu->deleteLater();
+ }
+ });
}
if (pSalMenuItem->mpSubMenu)
@@ -672,15 +682,27 @@ void QtMenu::ShowCloseButton(bool bShow)
pButton->hide();
}
-bool QtMenu::ShowNativePopupMenu(FloatingWindow*, const tools::Rectangle&,
- FloatWinPopupFlags nFlags)
+bool QtMenu::ShowNativePopupMenu(
+ FloatingWindow* pWin, const tools::Rectangle&, FloatWinPopupFlags nFlags,
+ const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>*
pListener)
{
assert(mpQMenu);
DoFullMenuUpdate(mpVCLMenu);
mpQMenu->setTearOffEnabled(bool(nFlags &
FloatWinPopupFlags::AllowTearOff));
const QPoint aPos = QCursor::pos();
- mpQMenu->exec(aPos);
+ if (pListener)
+ {
+ m_xListener = *pListener;
+ m_pWin = pWin;
+ mpQMenu->popup(aPos);
+ }
+ else
+ {
+ m_xListener = nullptr;
+ m_pWin = nullptr;
+ mpQMenu->exec(aPos);
+ }
return true;
}
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index c21d66a15d0a..47e5a5309d7b 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -192,7 +192,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 47f938eea7c6..39f914fbc4a1 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 1e3706d7399b4aee2357c9b6f31f57e64a362b75
Author: Jan-Marek Glogowski <[email protected]>
AuthorDate: Sat Nov 20 15:06:35 2021 +0100
Commit: Jan-Marek Glogowski <[email protected]>
CommitDate: Tue Mar 29 20:11:35 2022 +0200
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 54df7ee66631..abad985775e4 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 4220fa533a3e..47f938eea7c6 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 71f0aef2a8f528bb92c04a8eebe14eb3d472e4f9
Author: Thorsten Behrens <[email protected]>
AuthorDate: Sat Nov 13 23:12:58 2021 +0100
Commit: Jan-Marek Glogowski <[email protected]>
CommitDate: Tue Mar 29 20:11:35 2022 +0200
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 933a119d696d..14a561c7bf18 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -6408,7 +6408,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();
}
}
@@ -6447,7 +6451,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 75a51ef2fa3d0fc7554a08478280e774c42444fb
Author: Jan-Marek Glogowski <[email protected]>
AuthorDate: Mon Dec 6 09:24:50 2021 +0100
Commit: Jan-Marek Glogowski <[email protected]>
CommitDate: Tue Mar 29 20:11:35 2022 +0200
gbuild: build static unit tests
While this generally works, the setup is not very practical. The
unit tests become all very large, if they use components. The best
static solution I can imagine is either just somehow linking them
on demand, or create a single huge liblibreoffice.so, so keeping
everthing almost static.
Change-Id: If00f9ac3b3f63b915e3b5dcd931d233681a58006
diff --git a/Repository.mk b/Repository.mk
index fac1440aad50..ee0ee4406594 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -32,7 +32,7 @@ $(eval $(call gb_Helper_register_executables,NONE, \
cfgex \
concat-deps \
cpp \
- cppunittester \
+ $(call gb_CondCppunitMainLibOrExe,,cppunittester) \
gbuildtojson \
$(if $(filter MSC,$(COM)), \
gcc-wrapper \
@@ -581,6 +581,7 @@ $(eval $(call gb_Helper_register_libraries,PLAINLIBS_NONE, \
$(if $(filter MSC,$(COM)),cli_cppuhelper) \
$(if $(filter $(OS),ANDROID),lo-bootstrap) \
$(if $(filter $(OS),MACOSX),OOoSpotlightImporter) \
+ $(call gb_CondCppunitMainLibOrExe,cppunitmain) \
))
$(eval $(call gb_Helper_register_libraries_for_install,PLAINLIBS_URE,ure, \
diff --git a/sal/Library_cppunitmain.mk b/sal/Library_cppunitmain.mk
new file mode 100644
index 000000000000..07f51e0c4821
--- /dev/null
+++ b/sal/Library_cppunitmain.mk
@@ -0,0 +1,42 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,cppunitmain))
+
+$(eval $(call gb_Library_set_include,cppunitmain,\
+ $$(INCLUDE) \
+ -I$(SRCDIR)/sal/inc \
+))
+
+$(eval $(call gb_Library_use_libraries,cppunitmain,\
+ sal \
+ unoexceptionprotector \
+ unobootstrapprotector \
+ vclbootstrapprotector \
+))
+
+$(eval $(call gb_Library_use_externals,cppunitmain,\
+ boost_headers \
+ cppunit \
+))
+
+$(eval $(call gb_Library_add_exception_objects,cppunitmain,\
+ sal/cppunittester/cppunittester \
+))
+
+ifeq ($(COM),MSC)
+
+$(eval $(call gb_Library_add_ldflags,cppunitmain,\
+ /STACK:10000000 \
+))
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/sal/Module_sal.mk b/sal/Module_sal.mk
index e0448a5085bf..6c18d6282977 100644
--- a/sal/Module_sal.mk
+++ b/sal/Module_sal.mk
@@ -10,7 +10,7 @@
$(eval $(call gb_Module_Module,sal))
$(eval $(call gb_Module_add_targets,sal,\
- $(if $(CROSS_COMPILING),,$(if $(filter
TRUE,$(DISABLE_DYNLOADING)),,Executable_cppunittester)) \
+ $(call
gb_CondCppunitMainLibOrExe,Library_cppunitmain,Executable_cppunittester) \
$(if $(filter $(OS),ANDROID), \
Library_lo-bootstrap) \
Library_sal \
diff --git a/sal/cppunittester/cppunittester.cxx
b/sal/cppunittester/cppunittester.cxx
index 7d5ce39edf12..51d410d043f9 100644
--- a/sal/cppunittester/cppunittester.cxx
+++ b/sal/cppunittester/cppunittester.cxx
@@ -230,13 +230,17 @@ class CPPUNIT_API ProtectedFixtureFunctor
{
private:
const std::string &testlib;
+#ifndef DISABLE_DYNLOADING
const std::string &args;
+#endif
std::vector<CppUnit::Protector *> &protectors;
CppUnit::TestResult &result;
public:
ProtectedFixtureFunctor(const std::string& testlib_, const std::string
&args_, std::vector<CppUnit::Protector*> &protectors_, CppUnit::TestResult
&result_)
: testlib(testlib_)
+#ifndef DISABLE_DYNLOADING
, args(args_)
+#endif
, protectors(protectors_)
, result(result_)
{
diff --git a/solenv/gbuild/Conditions.mk b/solenv/gbuild/Conditions.mk
index 0a7b88969557..4cb5688997e9 100644
--- a/solenv/gbuild/Conditions.mk
+++ b/solenv/gbuild/Conditions.mk
@@ -12,6 +12,10 @@
# just end in two (!) braces, otherwise you may need to use either the $(1)
# or the $(2) multiple times.
+define gb_CondCppunitMainLibOrExe
+$(if $(or $(CROSS_COMPILING),$(DISABLE_DYNLOADING)),$(1),$(2))
+endef
+
define gb_CondExeLockfile
$(if $(and $(filter-out ANDROID MACOSX iOS WNT,$(OS))),$(1),$(2))
endef
diff --git a/solenv/gbuild/CppunitTest.mk b/solenv/gbuild/CppunitTest.mk
index 995910cfbd0c..8e9392e5c397 100644
--- a/solenv/gbuild/CppunitTest.mk
+++ b/solenv/gbuild/CppunitTest.mk
@@ -21,6 +21,7 @@
gb_CppunitTest_UNITTESTFAILED ?=
$(GBUILDDIR)/platform/unittest-failed-default.sh
gb_CppunitTest_PYTHONDEPS ?= $(call gb_Library_get_target,pyuno_wrapper) $(if
$(SYSTEM_PYTHON),,$(call gb_Package_get_target,python3))
+gb_CppunitTest_KNOWN :=
ifneq ($(strip $(CPPUNITTRACE)),)
ifneq ($(filter gdb,$(CPPUNITTRACE)),)
@@ -70,8 +71,13 @@ endif
# defined by platform
# gb_CppunitTest_get_filename
+ifeq (,$(DISABLE_DYNLOADING))
gb_CppunitTest_RUNTIMEDEPS := $(call
gb_Executable_get_runtime_dependencies,cppunittester)
gb_CppunitTest_CPPTESTCOMMAND := $(call
gb_Executable_get_target_for_build,cppunittester)
+else
+gb_CppunitTest_RUNTIMEDEPS :=
+gb_CppunitTest_CPPTESTCOMMAND :=
+endif
# i18npool dlopens localedata_* libraries.
gb_CppunitTest_RUNTIMEDEPS += \
@@ -198,6 +204,11 @@ $(call gb_CppunitTest_get_target,$(1)) : HEADLESS :=
--headless
$(call gb_CppunitTest_get_target,$(1)) : EXTRA_ENV_VARS :=
$$(eval $$(call gb_Module_register_target,$(call
gb_CppunitTest_get_target,$(1)),$(call gb_CppunitTest_get_clean_target,$(1))))
$(call gb_Helper_make_userfriendly_targets,$(1),CppunitTest)
+ifeq ($(DISABLE_DYNLOADING),TRUE)
+$$(eval $$(call gb_CppunitTest_use_libraries,$(1),cppunitmain))
+$$(eval $$(call gb_CppunitTest_add_defs,$(1),-D__EMSCRIPTEN__))
+endif
+$(if $(filter $(1),$(gb_CppunitTest_KNOWN)),,gb_CppunitTest_KNOWN += $(1))
endef
diff --git a/solenv/gbuild/TargetLocations.mk b/solenv/gbuild/TargetLocations.mk
index 32d7eed72ec0..253e01acf5fd 100644
--- a/solenv/gbuild/TargetLocations.mk
+++ b/solenv/gbuild/TargetLocations.mk
@@ -53,6 +53,7 @@ gb_CompilerTest_get_target = $(WORKDIR)/CompilerTest/$(1)
gb_ComponentTarget_get_target = $(WORKDIR)/ComponentTarget/$(1).component
gb_ComponentTarget_get_target_for_build =
$(WORKDIR_FOR_BUILD)/ComponentTarget/$(1).component
gb_Configuration_get_preparation_target =
$(WORKDIR)/Configuration/$(1).prepared
+gb_CppunitTest_get_linktargetfile = $(call gb_LinkTarget_get_target,$(call
gb_CppunitTest_get_linktarget,$1))
gb_CppunitTest_get_target = $(WORKDIR)/CppunitTest/$(1).test
gb_CustomPackage_get_target = $(WORKDIR)/CustomPackage/$(1).filelist
gb_CustomTarget_get_repo_target = $(WORKDIR)/CustomTarget/$(2)_$(1).done
diff --git a/solenv/gbuild/extensions/post_SpeedUpTargets.mk
b/solenv/gbuild/extensions/post_SpeedUpTargets.mk
index 3db6355ab90d..6fcbe243a01f 100644
--- a/solenv/gbuild/extensions/post_SpeedUpTargets.mk
+++ b/solenv/gbuild/extensions/post_SpeedUpTargets.mk
@@ -52,7 +52,6 @@ endif
endif
-
ifneq (,$(filter build,$(gb_Module_SKIPTARGETS)))
gb_Module_add_target =
endif
diff --git a/solenv/gbuild/gbuild.mk b/solenv/gbuild/gbuild.mk
index d5ddcd8925ce..99fd8ef50b4f 100644
--- a/solenv/gbuild/gbuild.mk
+++ b/solenv/gbuild/gbuild.mk
@@ -285,6 +285,7 @@ gb_TEST_ENV_VARS +=
SAL_DISABLE_SYNCHRONOUS_PRINTER_DETECTION=1
ifeq (,$(SAL_USE_VCLPLUGIN))
gb_TEST_ENV_VARS += SAL_USE_VCLPLUGIN=svp
endif
+gb_TEST_ENV_VARS += STATIC_UNO_HOME=file://$$I/program
# This is used to detect whether LibreOffice is being built (as opposed to
building
# 3rd-party code). Used for tag deprecation for API we want to
diff --git a/solenv/gbuild/platform/unxgcc.mk b/solenv/gbuild/platform/unxgcc.mk
index b98732030b32..037f462d2795 100644
--- a/solenv/gbuild/platform/unxgcc.mk
+++ b/solenv/gbuild/platform/unxgcc.mk
@@ -312,12 +312,18 @@ endef
gb_CppunitTest_CPPTESTPRECOMMAND := \
$(call
gb_Helper_extend_ld_path,$(WORKDIR)/UnpackedTarball/cppunit/src/cppunit/.libs)
-gb_CppunitTest_get_filename = libtest_$(1).so
+ifeq (,$(DISABLE_DYNLOADING))
+gb_CppunitTest_get_filename = libtest_$(1)$(gb_Library_PLAINEXT)
+else
+gb_CppunitTest_get_filename = test_$(1)$(gb_Executable_EXT)
+endif
gb_CppunitTest_get_ilibfilename = $(gb_CppunitTest_get_filename)
gb_CppunitTest_malloc_check := -ex 'set environment MALLOC_CHECK_=2; set
environment MALLOC_PERTURB_=153'
define gb_CppunitTest_CppunitTest_platform
+ifeq (,$(DISABLE_DYNLOADING))
$(call gb_LinkTarget_get_target,$(2)) : RPATH := $(call
gb_Library__get_rpath,$(call gb_LinkTarget__get_rpath_for_layer,NONE))
+endif
endef
diff --git a/solenv/gbuild/static.mk b/solenv/gbuild/static.mk
index faa9a73db516..1b7f0214900a 100644
--- a/solenv/gbuild/static.mk
+++ b/solenv/gbuild/static.mk
@@ -198,6 +198,8 @@ $(foreach lib,$(gb_Library_KNOWNLIBS), \
$(eval $(call gb_LinkTarget__fill_all_deps,$(call
gb_Library_get_linktarget,$(lib)))))
$(foreach exec,$(gb_Executable_KNOWN), \
$(eval $(call gb_LinkTarget__expand_executable,$(call
gb_Executable_get_linktarget,$(exec)))))
+$(foreach cppunit,$(gb_CppunitTest_KNOWN), \
+ $(eval $(call gb_LinkTarget__expand_executable,$(call
gb_CppunitTest_get_linktarget,$(cppunit)))))
$(foreach workdir_linktargetname,$(gb_LinkTarget__ALL_TOUCHED), \
$(eval $(call gb_LinkTarget__remove_touch,$(workdir_linktargetname))))
@@ -235,11 +237,14 @@ endef
endef # gb_LinkTarget__expand_executable_template
ifneq (,$(gb_DEBUG_STATIC))
+$(info $(call gb_LinkTarget__expand_executable_template,CppunitTest))
$(info $(call gb_LinkTarget__expand_executable_template,Executable))
endif
+$(eval $(call gb_LinkTarget__expand_executable_template,CppunitTest))
$(eval $(call gb_LinkTarget__expand_executable_template,Executable))
$(foreach exec,$(gb_Executable_KNOWN),$(eval $(call
gb_Executable__expand_deps,$(exec))))
+$(foreach cppunit,$(gb_CppunitTest_KNOWN),$(eval $(call
gb_CppunitTest__expand_deps,$(cppunit))))
endif # gb_PARTIAL_BUILD
endif # gb_FULLDEPS
commit ee8eaf9dedaafbf3fd20dab2ac01d4e186213829
Author: Jan-Marek Glogowski <[email protected]>
AuthorDate: Sat Jan 8 22:53:29 2022 +0100
Commit: Jan-Marek Glogowski <[email protected]>
CommitDate: Tue Mar 29 20:11:35 2022 +0200
gbuild: set unorc lookup dir via environment
UNO tries hard to find the path of the executable to look at that
place for its unorc / uno.ini. All these approaches don't work for
static binaries, so just override the lookup with the environment
variable STATIC_UNO_HOME.
Change-Id: I0d80c91e474d9f869475ba752d708b77c99f8a56
diff --git a/Makefile.in b/Makefile.in
index 9c0f2aefb9da..30dd79a65787 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -7,6 +7,8 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
+unexport STATIC_UNO_HOME
+
gb_Top_MODULE_CHECK_TARGETS := slowcheck unitcheck subsequentcheck perfcheck
uicheck screenshot
.PHONY : check-if-root bootstrap gbuild build build-non-l10n-only
build-l10n-only check clean clean-build clean-host test-install distclean
distro-pack-install docs download etags fetch get-submodules id install
install-gdb-printers install-strip tags debugrun help showmodules translations
packageinfo internal.clean $(gb_Top_MODULE_CHECK_TARGETS)
diff --git a/bin/run b/bin/run
index 523da3c0e178..f812c2baadbb 100755
--- a/bin/run
+++ b/bin/run
@@ -67,6 +67,8 @@ else
fi
+test "${STATIC_UNO_HOME+set}" = set || export
STATIC_UNO_HOME="file://${dir}/instdir/program"
+
# echo "setting URE_BOOTSTRAP to: ${URE_BOOTSTRAP}"
# echo "setting search path to: ${SEARCH_PATH}"
# echo "execing: ${exedir}/$1"
diff --git a/cppuhelper/source/paths.cxx b/cppuhelper/source/paths.cxx
index b6a1e12600dd..b769fad73389 100644
--- a/cppuhelper/source/paths.cxx
+++ b/cppuhelper/source/paths.cxx
@@ -20,12 +20,14 @@
#include <config_folders.h>
#include <sal/config.h>
+#include <sal/log.hxx>
#include <cassert>
#include <com/sun/star/uno/DeploymentException.hpp>
#include <osl/file.hxx>
#include <osl/module.hxx>
+#include <osl/thread.h>
#include <rtl/ustring.hxx>
#include <sal/types.h>
@@ -64,7 +66,16 @@ OUString cppu::getUnoIniUri() {
#elif defined(EMSCRIPTEN)
OUString uri("file:///instdir/program");
#else
- OUString uri(get_this_libpath());
+
+ OUString uri;
+#ifdef DISABLE_DYNLOADING
+ static const char* uno_home = getenv("STATIC_UNO_HOME");
+ if (uno_home)
+ uri = OStringToOUString(uno_home, osl_getThreadTextEncoding());
+ else
+#endif
+ uri = get_this_libpath();
+
#ifdef MACOSX
// We keep the URE dylibs directly in "Frameworks" (that is,
LIBO_LIB_FOLDER) and unorc in
// "Resources/ure/etc" (LIBO_URE_ETC_FOLDER).
@@ -74,7 +85,9 @@ OUString cppu::getUnoIniUri() {
}
#endif
#endif
- return uri + "/" SAL_CONFIGFILE("uno");
+ uri += "/" SAL_CONFIGFILE("uno");
+ SAL_INFO("cppuhelper", "expected uno config: " << uri);
+ return uri;
}
bool cppu::nextDirectoryItem(osl::Directory & directory, OUString * url) {
diff --git a/desktop/scripts/soffice.sh b/desktop/scripts/soffice.sh
index 67cc0b89751f..1bfb60682648 100755
--- a/desktop/scripts/soffice.sh
+++ b/desktop/scripts/soffice.sh
@@ -176,6 +176,8 @@ else
unset LC_ALL
fi
+test "${STATIC_UNO_HOME+set}" = set || export
STATIC_UNO_HOME="file://${sd_prog}"
+
# run soffice.bin directly when you want to get the backtrace
if [ -n "$GDBTRACECHECK" ] ; then
exec $GDBTRACECHECK "$sd_prog/soffice.bin" "$@"
commit 8b175422fd00648085ddc604fcfbb05de3b2d343
Author: Luboš Luňák <[email protected]>
AuthorDate: Tue Mar 29 14:23:24 2022 +0200
Commit: Luboš Luňák <[email protected]>
CommitDate: Tue Mar 29 19:28:11 2022 +0200
allocate column in ScTable::FillSeries() when needed
There's an assert triggered by Test::testAutoFill()
if INITIALCOLCOUNT is set to 1.
Change-Id: I65ecd7df3bf6b38a8121a252f7f53dd7f5bbb0fd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132270
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <[email protected]>
diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx
index a67144253458..ba322db9ed57 100644
--- a/sc/source/core/data/table4.cxx
+++ b/sc/source/core/data/table4.cxx
@@ -2364,6 +2364,7 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL
nCol2, SCROW nRow2,
bOverflow = isOverflow( nVal, nMaxValue,
nStepValue, nStartVal, eFillCmd);
}
+ CreateColumnIfNotExists(nCol);
if (bError)
aCol[nCol].SetError(static_cast<SCROW>(nRow),
FormulaError::NoValue);
else if (!bOverflow && bNonEmpty)
commit b0dfc4101366ff4e42c5ad9ea48e43ca2b957202
Author: offtkp <[email protected]>
AuthorDate: Tue Mar 29 17:46:30 2022 +0300
Commit: Julien Nabet <[email protected]>
CommitDate: Tue Mar 29 18:31:08 2022 +0200
replace dynamic C style arrays with std::vector in Splines.cxx
replaced all instances of dynamic C style arrays, removed delete
statements as they are no longer needed
also now removed a pointless loop for an std::swap
Change-Id: I0438b1fa944dc6ae8c6a3cc488645504ab30c3df
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132278
Reviewed-by: Mike Kaganski <[email protected]>
Tested-by: Jenkins
diff --git a/chart2/source/view/charttypes/Splines.cxx
b/chart2/source/view/charttypes/Splines.cxx
index 92e568eaca11..1f97ec81d620 100644
--- a/chart2/source/view/charttypes/Splines.cxx
+++ b/chart2/source/view/charttypes/Splines.cxx
@@ -581,16 +581,15 @@ void SplineCalculater::CalculateCubicSplines(
pOld[ 0 ].PositionZ == pOld[nMaxIndexPoints].PositionZ &&
nMaxIndexPoints >=2 )
{ // periodic spline
- aSplineX.reset(new lcl_SplineCalculation( std::move(aInputX)));
- aSplineY.reset(new lcl_SplineCalculation( std::move(aInputY)));
- // aSplineZ = new lcl_SplineCalculation( aInputZ) ;
+ aSplineX =
std::make_unique<lcl_SplineCalculation>(std::move(aInputX));
+ aSplineY =
std::make_unique<lcl_SplineCalculation>(std::move(aInputY));
}
else // generate the kind "natural spline"
{
double fXDerivation = std::numeric_limits<double>::infinity();
double fYDerivation = std::numeric_limits<double>::infinity();
- aSplineX.reset(new lcl_SplineCalculation( std::move(aInputX),
fXDerivation, fXDerivation ));
- aSplineY.reset(new lcl_SplineCalculation( std::move(aInputY),
fYDerivation, fYDerivation ));
+ aSplineX =
std::make_unique<lcl_SplineCalculation>(std::move(aInputX), fXDerivation,
fXDerivation);
+ aSplineY =
std::make_unique<lcl_SplineCalculation>(std::move(aInputY), fYDerivation,
fYDerivation);
}
// fill result polygon with calculated values
@@ -679,29 +678,23 @@ void SplineCalculater::CalculateBSplines(
continue; // need at least 2 points, degree p needs at least n+1
points
// next piece of series
- std::unique_ptr<double[]> t(new double [n+1]);
- if (!createParameterT(aPointsIn, t.get()))
+ std::vector<double> t(n + 1);
+ if (!createParameterT(aPointsIn, t.data()))
{
continue; // next piece of series
}
lcl_tSizeType m = n + p + 1;
- std::unique_ptr<double[]> u(new double [m+1]);
- createKnotVector(n, p, t.get(), u.get());
+ std::vector<double> u(m + 1);
+ createKnotVector(n, p, t.data(), u.data());
// The matrix N contains the B-spline basis functions applied to
parameters.
// In each row only p+1 adjacent elements are non-zero. The starting
// column in a higher row is equal or greater than in the lower row.
// To store this matrix the non-zero elements are shifted to column 0
// and the amount of shifting is remembered in an array.
- std::unique_ptr<double*[]> aMatN(new double*[n+1]);
- for (lcl_tSizeType row = 0; row <=n; ++row)
- {
- aMatN[row] = new double[p+1];
- for (sal_uInt32 col = 0; col <= p; ++col)
- aMatN[row][col] = 0.0;
- }
- std::unique_ptr<lcl_tSizeType[]> aShift(new lcl_tSizeType[n+1]);
+ std::vector<std::vector<double>> aMatN(n + 1, std::vector<double>(p +
1));
+ std::vector<lcl_tSizeType> aShift(n + 1);
aMatN[0][0] = 1.0; //all others are zero
aShift[0] = 0;
aMatN[n][0] = 1.0;
@@ -721,7 +714,7 @@ void SplineCalculater::CalculateBSplines(
// index in reduced matrix aMatN = (index in full matrix N) - (i-p)
aShift[k] = i - p;
- applyNtoParameterT(i, t[k], p, u.get(), aMatN[k]);
+ applyNtoParameterT(i, t[k], p, u.data(), aMatN[k].data());
} // next row k
// Get matrix C of control points from the matrix equation aMatN * C =
aPointsIn
@@ -750,10 +743,7 @@ void SplineCalculater::CalculateBSplines(
// exchange total row r with total row c if necessary
if (r != c)
{
- for ( sal_uInt32 i = 0; i <= p ; ++i)
- {
- std::swap( aMatN[r][i], aMatN[c][i] );
- }
+ std::swap( aMatN[r], aMatN[c] );
std::swap( aPointsIn[r], aPointsIn[c] );
std::swap( aShift[r], aShift[c] );
}
@@ -823,7 +813,7 @@ void SplineCalculater::CalculateBSplines(
pNew[nNewSize -1 ].PositionX = aPointsIn[n].first;
pNew[nNewSize -1 ].PositionY = aPointsIn[n].second;
pNew[nNewSize -1 ].PositionZ = fZCoordinate;
- std::unique_ptr<double[]> aP(new double[m+1]);
+ std::vector<double> aP(m + 1);
lcl_tSizeType nLow = 0;
for ( lcl_tSizeType nTIndex = 0; nTIndex <= n-1; ++nTIndex)
{
@@ -875,10 +865,6 @@ void SplineCalculater::CalculateBSplines(
}
}
}
- for (lcl_tSizeType row = 0; row <=n; ++row)
- {
- delete[] aMatN[row];
- }
} // next piece of the series
}
commit fd8b0796092566576a80004cbffa95f3b05923f0
Author: Michael Weghorn <[email protected]>
AuthorDate: Tue Mar 29 14:46:29 2022 +0200
Commit: Julien Nabet <[email protected]>
CommitDate: Tue Mar 29 18:30:39 2022 +0200
qt: Fix typo in function name: lcl_MapUndrelineStyle
Change-Id: I50b2ffeb1b6bb490c14a307152634cc51022a426
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132276
Tested-by: Jenkins
Reviewed-by: Julien Nabet <[email protected]>
diff --git a/vcl/qt5/QtWidget.cxx b/vcl/qt5/QtWidget.cxx
index 77d9222a74f9..9685be9ffa57 100644
--- a/vcl/qt5/QtWidget.cxx
+++ b/vcl/qt5/QtWidget.cxx
@@ -637,7 +637,7 @@ QtWidget::QtWidget(QtFrame& rFrame, Qt::WindowFlags f)
setFocusPolicy(Qt::ClickFocus);
}
-static ExtTextInputAttr lcl_MapUndrelineStyle(QTextCharFormat::UnderlineStyle
us)
+static ExtTextInputAttr lcl_MapUnderlineStyle(QTextCharFormat::UnderlineStyle
us)
{
switch (us)
{
@@ -684,7 +684,7 @@ void QtWidget::inputMethodEvent(QInputMethodEvent* pEvent)
if (aCharFormat.isValid())
{
ExtTextInputAttr aETIP
- =
lcl_MapUndrelineStyle(aCharFormat.underlineStyle());
+ =
lcl_MapUnderlineStyle(aCharFormat.underlineStyle());
if
(aCharFormat.hasProperty(QTextFormat::BackgroundBrush))
aETIP |= ExtTextInputAttr::Highlight;
if (aCharFormat.fontStrikeOut())
commit 2525bab2fcca179263a4b3496bb929df61d0e2bf
Author: Julien Nabet <[email protected]>
AuthorDate: Mon Mar 28 21:12:24 2022 +0200
Commit: Julien Nabet <[email protected]>
CommitDate: Tue Mar 29 17:39:07 2022 +0200
tdf#148240: Make Outline-Folding non-experimental
Change-Id: I8de81ec13228d0742a3b12af97edb1b97643a790
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132243
Tested-by: Jenkins
Reviewed-by: Heiko Tietze <[email protected]>
Reviewed-by: Julien Nabet <[email protected]>
diff --git a/sw/source/ui/config/optpage.cxx b/sw/source/ui/config/optpage.cxx
index bfdbc877c869..4374751f0f95 100644
--- a/sw/source/ui/config/optpage.cxx
+++ b/sw/source/ui/config/optpage.cxx
@@ -107,16 +107,7 @@ SwContentOptPage::SwContentOptPage(weld::Container* pPage,
weld::DialogControlle
, m_xFieldHiddenCB(m_xBuilder->weld_check_button("hiddentextfield"))
, m_xFieldHiddenParaCB(m_xBuilder->weld_check_button("hiddenparafield"))
{
- if (!officecfg::Office::Common::Misc::ExperimentalMode::get())
- {
- m_xOutlineLabel->hide();
- m_xShowOutlineContentVisibilityButton->hide();
- m_xTreatSubOutlineLevelsAsContent->hide();
- }
- else
- {
- m_xShowOutlineContentVisibilityButton->connect_toggled(LINK(this,
SwContentOptPage, ShowOutlineContentVisibilityButtonHdl));
- }
+ m_xShowOutlineContentVisibilityButton->connect_toggled(LINK(this,
SwContentOptPage, ShowOutlineContentVisibilityButtonHdl));
/* This part is visible only with Writer/Web->View dialogue. */
const SfxUInt16Item* pItem = rCoreSet.GetItemIfSet(SID_HTML_MODE, false );
commit 3b53760bcd304c0a3efc58188d80cb963c24b484
Author: Stephan Bergmann <[email protected]>
AuthorDate: Tue Mar 29 16:16:34 2022 +0200
Commit: Stephan Bergmann <[email protected]>
CommitDate: Tue Mar 29 17:23:10 2022 +0200
Check for yet another consteval bug
...which caused at least recent Clang 15 trunk configured with
LLVM_ENABLE_ASSERTIONS=ON to crash when building --with-latest-c++ e.g.
sal/qa/rtl/strings/test_oustring_stringliterals.cxx since
21584b304b21bfe6b99b6f29018c6b754ea28fc0 "make OUString(OUStringLiteral)
constructor constexpr"
Change-Id: Icef2ae27bfc518b127aabfc4767212b4b6a95a77
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132273
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <[email protected]>
diff --git a/configure.ac b/configure.ac
index 250de34971ab..9d97f42c4030 100644
--- a/configure.ac
+++ b/configure.ac
@@ -14350,9 +14350,13 @@ dnl from consteval constructor initializing const
variable",
dnl <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98752> "wrong 'error: ‘this’
is not a constant
dnl expression' with consteval constructor",
<https://bugs.llvm.org/show_bug.cgi?id=50063> "code
dnl using consteval: 'clang/lib/CodeGen/Address.h:38: llvm::Value*
-dnl clang::CodeGen::Address::getPointer() const: Assertion `isValid()'
failed.'", or
+dnl clang::CodeGen::Address::getPointer() const: Assertion `isValid()'
failed.'",
dnl <https://developercommunity.visualstudio.com/t/1581879> "Bogus error C7595
with consteval
-dnl constructor in ternary expression (/std:c++latest)":
+dnl constructor in ternary expression (/std:c++latest)", or
+dnl <https://github.com/llvm/llvm-project/issues/54612> "C++20, consteval,
anonymous union:
+dnl llvm/lib/IR/Instructions.cpp:1491: void llvm::StoreInst::AssertOK():
Assertion
+dnl
`cast<PointerType>(getOperand(1)->getType())->isOpaqueOrPointeeTypeMatches(getOperand(0)->getType())
+dnl && "Ptr must be a pointer to Val type!"' failed.":
AC_LANG_PUSH([C++])
save_CXX=$CXX
if test "$COM" = MSC && test "$COM_IS_CLANG" != TRUE; then
@@ -14384,6 +14388,16 @@ AC_RUN_IFELSE([AC_LANG_PROGRAM([
struct S4 { consteval S4() = default; };
void f4(bool b) { b ? S4() : S4(); }
+
+ struct S5 {
+ consteval S5() { c = 0; }
+ char * f() { return &c; }
+ union {
+ char c;
+ int i;
+ };
+ };
+ auto s5 = S5().f();
], [
return (s.i == 1) ? 0 : 1;
])], [
commit f81800193a942b3f68c61a5cede634f3eeb47b1f
Author: Attila Bakos (NISZ) <[email protected]>
AuthorDate: Fri Mar 4 08:27:49 2022 +0100
Commit: László Németh <[email protected]>
CommitDate: Tue Mar 29 16:29:39 2022 +0200
tdf#73499 DOCX import: fix grouped linked textbox
Only ungrouped text boxes were imported correctly.
Grouped textboxes lost their linking, resulting
broken layout. Now the linking is fixed for DrawingML.
Note: in old MSO versions, linking needed grouping.
To import these DOC documents correctly, convert them
to DOCX/DrawingML in MSO before opening them in Writer.
Change-Id: Ib5a8744d783a9c95c42447d204e17891b3aea7bd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130950
Tested-by: László Németh <[email protected]>
Reviewed-by: László Németh <[email protected]>
diff --git a/sw/qa/extras/ooxmlexport/data/tdf73499.docx
b/sw/qa/extras/ooxmlexport/data/tdf73499.docx
new file mode 100644
index 000000000000..605c01e2b3ac
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf73499.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
index 486dc6c3d1e9..53e80df5a301 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
@@ -346,6 +346,34 @@ DECLARE_OOXMLEXPORT_TEST(testTdf148111, "tdf148111.docx")
CPPUNIT_ASSERT(!xFields->hasMoreElements());
}
+DECLARE_OOXMLEXPORT_TEST(TestTdf73499, "tdf73499.docx")
+{
+ // Ensure, the bugdoc is opened
+ CPPUNIT_ASSERT(mxComponent);
+ // Get the groupshape
+ uno::Reference<drawing::XShapes> xGroup(getShape(1), uno::UNO_QUERY_THROW);
+
+ // Get the textboxes of the groupshape
+ uno::Reference<text::XText> xTextBox1(xGroup->getByIndex(0),
uno::UNO_QUERY_THROW);
+ uno::Reference<text::XText> xTextBox2(xGroup->getByIndex(1),
uno::UNO_QUERY_THROW);
+
+ // Get the properties of the textboxes
+ uno::Reference<beans::XPropertySet> xTextBox1Properties(xTextBox1,
uno::UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> xTextBox2Properties(xTextBox2,
uno::UNO_QUERY_THROW);
+
+ // Get the name of the textboxes
+ uno::Reference<container::XNamed> xTextBox1Name(xTextBox1,
uno::UNO_QUERY_THROW);
+ uno::Reference<container::XNamed> xTextBox2Name(xTextBox2,
uno::UNO_QUERY_THROW);
+
+ // Check for the links, before the fix that were missing
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "Link name missing!", xTextBox2Name->getName(),
+
xTextBox1Properties->getPropertyValue("ChainNextName").get<OUString>());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "Link name missing!", xTextBox1Name->getName(),
+
xTextBox2Properties->getPropertyValue("ChainPrevName").get<OUString>());
+}
+
DECLARE_OOXMLEXPORT_TEST(testTdf81507, "tdf81507.docx")
{
xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index a3d6a4f69498..f8700faee88c 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -4634,20 +4634,103 @@ void DomainMapper_Impl::PopTextBoxContent()
void
DomainMapper_Impl::AttachTextBoxContentToShape(css::uno::Reference<css::drawing::XShape>
xShape)
{
+ // Without textbox or shape pointless to continue
if (m_xPendingTextBoxFrames.empty() || !xShape)
return;
uno::Reference< drawing::XShapes >xGroup(xShape, uno::UNO_QUERY);
uno::Reference< beans::XPropertySet >xProps(xShape, uno::UNO_QUERY);
+ // If this is a group go inside
if (xGroup)
for (sal_Int32 i = 0; i < xGroup->getCount(); ++i)
-
AttachTextBoxContentToShape(uno::Reference<drawing::XShape>(xGroup->getByIndex(i),uno::UNO_QUERY_THROW));
+ AttachTextBoxContentToShape(
+ uno::Reference<drawing::XShape>(xGroup->getByIndex(i),
uno::UNO_QUERY));
- if (xProps->getPropertyValue("TextBox").get<bool>())
+ // if this shape has to be a textbox, attach the frame
+ if (!xProps->getPropertyValue("TextBox").get<bool>())
+ return;
+
+ // if this is a textbox there must be a waiting frame
+ auto xTextBox = m_xPendingTextBoxFrames.front();
+ if (!xTextBox)
+ return;
+
+ // Pop the pending frames
+ m_xPendingTextBoxFrames.pop();
+
+ // Attach the textbox to the shape
+ try
+ {
+ xProps->setPropertyValue("TextBoxContent", uno::Any(xTextBox));
+ }
+ catch (...)
+ {
+ SAL_WARN("writerfilter.dmapper", "Exception while trying to attach
textboxes!");
+ return;
+ }
+
+ // If attaching is successful, then do the linking
+ try
+ {
+ // Get the name of the textbox
+ OUString sTextBoxName;
+ uno::Reference<container::XNamed> xName(xTextBox, uno::UNO_QUERY);
+ if (xName && !xName->getName().isEmpty())
+ sTextBoxName = xName->getName();
+
+ // Try to get the grabbag
+ uno::Sequence<beans::PropertyValue> aOldGrabBagSeq;
+ if (xProps->getPropertySetInfo()->hasPropertyByName("InteropGrabBag"))
+ xProps->getPropertyValue("InteropGrabBag") >>= aOldGrabBagSeq;
+
+ // If the grabbag successfully get...
+ if (!aOldGrabBagSeq.hasElements())
+ return;
+
+ // Check for the existing linking information
... etc. - the rest is truncated