From 4a0f506f0d8c2a017f0cf880481d3c0c32a48909 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Wed, 17 Jan 2018 17:24:35 +0100 Subject: framework: disable layout manager in hidden frames The point of hidden frames is that they are not visible on the UI, only their doc model / layout is accessible via the API or file format conversion. That means that laying out the UI elements like menus and toolbars is pointless. So change Frame::initialize() and Frame::setLayoutManager() to not enable the layout manager for hidden frames. To do this, we need a new window style flag, as both hidden and visible frames have an underlying hidden window at the time the framework layout manager would be enabled. Times for 200 hello world inputs: 5780 -> 5054 ms is spent in XHTML-load + ODT export + close (87% of original). Change-Id: I841507bbb62f8fc2979d20e2d579d0bb47b98f37 Reviewed-on: https://gerrit.libreoffice.org/48068 Reviewed-by: Miklos Vajna Tested-by: Jenkins --- framework/source/classes/taskcreator.cxx | 10 ++++++++-- framework/source/loadenv/loadenv.cxx | 4 +++- framework/source/services/desktop.cxx | 4 ++-- framework/source/services/frame.cxx | 23 ++++++++++++++++------- framework/source/services/taskcreatorsrv.cxx | 9 +++++++++ 5 files changed, 38 insertions(+), 12 deletions(-) (limited to 'framework/source') diff --git a/framework/source/classes/taskcreator.cxx b/framework/source/classes/taskcreator.cxx index 612ab433e7e3..0bf720b510ac 100644 --- a/framework/source/classes/taskcreator.cxx +++ b/framework/source/classes/taskcreator.cxx @@ -57,7 +57,7 @@ TaskCreator::~TaskCreator() /*-**************************************************************************************************** TODO document me *//*-*****************************************************************************************************/ -css::uno::Reference< css::frame::XFrame > TaskCreator::createTask( const OUString& sName ) +css::uno::Reference< css::frame::XFrame > TaskCreator::createTask( const OUString& sName, const utl::MediaDescriptor& rDescriptor ) { css::uno::Reference< css::lang::XSingleServiceFactory > xCreator; OUString sCreator = IMPLEMENTATIONNAME_FWK_TASKCREATOR; @@ -86,7 +86,7 @@ css::uno::Reference< css::frame::XFrame > TaskCreator::createTask( const OUStrin if ( ! xCreator.is()) xCreator = css::frame::TaskCreator::create(m_xContext); - css::uno::Sequence< css::uno::Any > lArgs(5); + css::uno::Sequence< css::uno::Any > lArgs(6); css::beans::NamedValue aArg; aArg.Name = ARGUMENT_PARENTFRAME; @@ -109,6 +109,12 @@ css::uno::Reference< css::frame::XFrame > TaskCreator::createTask( const OUStrin aArg.Value <<= sName; lArgs[4] <<= aArg; + bool bHidden + = rDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_HIDDEN(), false); + aArg.Name = "Hidden"; + aArg.Value <<= bHidden; + lArgs[5] <<= aArg; + css::uno::Reference< css::frame::XFrame > xTask(xCreator->createInstanceWithArguments(lArgs), css::uno::UNO_QUERY_THROW); return xTask; } diff --git a/framework/source/loadenv/loadenv.cxx b/framework/source/loadenv/loadenv.cxx index 6fd8f5b54061..d5819ebb6675 100644 --- a/framework/source/loadenv/loadenv.cxx +++ b/framework/source/loadenv/loadenv.cxx @@ -87,6 +87,7 @@ #include #include #include +#include const char PROP_TYPES[] = "Types"; const char PROP_NAME[] = "Name"; @@ -989,7 +990,8 @@ bool LoadEnv::impl_loadContent() { if (! impl_furtherDocsAllowed()) return false; - m_xTargetFrame = m_xBaseFrame->findFrame(SPECIALTARGET_BLANK, 0); + TaskCreator aCreator(m_xContext); + m_xTargetFrame = aCreator.createTask(SPECIALTARGET_BLANK, m_lMediaDescriptor); m_bCloseFrameOnError = m_xTargetFrame.is(); } else diff --git a/framework/source/services/desktop.cxx b/framework/source/services/desktop.cxx index b7fc1a152ed3..fbfe5cd9f7c6 100644 --- a/framework/source/services/desktop.cxx +++ b/framework/source/services/desktop.cxx @@ -967,7 +967,7 @@ css::uno::Reference< css::frame::XFrame > SAL_CALL Desktop::findFrame( const OUS if ( sTargetFrameName==SPECIALTARGET_BLANK ) { TaskCreator aCreator( m_xContext ); - xTarget = aCreator.createTask(sTargetFrameName); + xTarget = aCreator.createTask(sTargetFrameName, utl::MediaDescriptor()); } // I.II) "_top" @@ -1051,7 +1051,7 @@ css::uno::Reference< css::frame::XFrame > SAL_CALL Desktop::findFrame( const OUS ) { TaskCreator aCreator( m_xContext ); - xTarget = aCreator.createTask(sTargetFrameName); + xTarget = aCreator.createTask(sTargetFrameName, utl::MediaDescriptor()); } } diff --git a/framework/source/services/frame.cxx b/framework/source/services/frame.cxx index adc174a8ad3a..0357a4955b82 100644 --- a/framework/source/services/frame.cxx +++ b/framework/source/services/frame.cxx @@ -412,6 +412,8 @@ private: bool m_bSelfClose; /// indicates, if this frame is used in hidden mode or not bool m_bIsHidden; + /// The container window has WindowExtendedStyle::DocHidden set. + bool m_bDocHidden = false; /// is used to layout the child windows of the frame. css::uno::Reference< css::frame::XLayoutManager2 > m_xLayoutManager; css::uno::Reference< css::frame::XDispatchInformationProvider > m_xDispatchInfoHelper; @@ -772,8 +774,13 @@ void SAL_CALL Frame::initialize( const css::uno::Reference< css::awt::XWindow >& // if window is initially visible, we will never get a windowShowing event VclPtr pWindow = VCLUnoHelper::GetWindow(xWindow); - if (pWindow && pWindow->IsVisible()) - m_bIsHidden = false; + if (pWindow) + { + if (pWindow->IsVisible()) + m_bIsHidden = false; + m_bDocHidden + = static_cast(pWindow->GetExtendedStyle() & WindowExtendedStyle::DocHidden); + } css::uno::Reference< css::frame::XLayoutManager2 > xLayoutManager = m_xLayoutManager; @@ -782,7 +789,9 @@ void SAL_CALL Frame::initialize( const css::uno::Reference< css::awt::XWindow >& aWriteLock.clear(); /* UNSAFE AREA --------------------------------------------------------------------------------------------- */ - if (xLayoutManager.is()) + // Avoid enabling the layout manager for hidden frames: it's expensive and + // provides little value. + if (xLayoutManager.is() && !m_bDocHidden) lcl_enableLayoutManager(xLayoutManager, this); // create progress helper @@ -971,7 +980,7 @@ css::uno::Reference< css::frame::XFrame > SAL_CALL Frame::findFrame( const OUStr if ( sTargetFrameName==SPECIALTARGET_BLANK ) { TaskCreator aCreator(m_xContext); - xTarget = aCreator.createTask(sTargetFrameName); + xTarget = aCreator.createTask(sTargetFrameName, utl::MediaDescriptor()); } // I.II) "_parent" @@ -1171,7 +1180,7 @@ css::uno::Reference< css::frame::XFrame > SAL_CALL Frame::findFrame( const OUStr ) { TaskCreator aCreator(m_xContext); - xTarget = aCreator.createTask(sTargetFrameName); + xTarget = aCreator.createTask(sTargetFrameName, utl::MediaDescriptor()); } } @@ -1825,7 +1834,7 @@ void SAL_CALL Frame::setLayoutManager(const css::uno::Reference SAL_CALL TaskCreatorService::createI css::uno::Reference< css::awt::XWindow > xContainerWindow = lArgs.getUnpackedValueOrDefault(ARGUMENT_CONTAINERWINDOW , css::uno::Reference< css::awt::XWindow >() ); bool bSupportPersistentWindowState = lArgs.getUnpackedValueOrDefault(ARGUMENT_SUPPORTPERSISTENTWINDOWSTATE , false ); bool bEnableTitleBarUpdate = lArgs.getUnpackedValueOrDefault(ARGUMENT_ENABLE_TITLEBARUPDATE , true ); + // If the frame is explicitly requested to be hidden. + bool bHidden = lArgs.getUnpackedValueOrDefault("Hidden", false); // We use FrameName property to set it as API name of the new created frame later. // But those frame names must be different from the set of special target names as e.g. _blank, _self etcpp ! @@ -167,6 +169,13 @@ css::uno::Reference< css::uno::XInterface > SAL_CALL TaskCreatorService::createI //-------------------> // create the new frame + VclPtr pContainerWindow = VCLUnoHelper::GetWindow(xContainerWindow); + if (pContainerWindow && bHidden) + { + WindowExtendedStyle eStyle = pContainerWindow->GetExtendedStyle(); + eStyle |= WindowExtendedStyle::DocHidden; + pContainerWindow->SetExtendedStyle(eStyle); + } css::uno::Reference< css::frame::XFrame2 > xFrame = implts_createFrame(xParentFrame, xContainerWindow, sRightName); // special freature: -- cgit v1.2.1