diff options
-rw-r--r-- | framework/source/dispatch/closedispatcher.cxx | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/framework/source/dispatch/closedispatcher.cxx b/framework/source/dispatch/closedispatcher.cxx index 991c3e9f5734..eedefcd36da5 100644 --- a/framework/source/dispatch/closedispatcher.cxx +++ b/framework/source/dispatch/closedispatcher.cxx @@ -23,6 +23,8 @@ #include <services.h> #include <general.h> +#include <com/sun/star/bridge/BridgeFactory.hpp> +#include <com/sun/star/bridge/XBridgeFactory2.hpp> #include <com/sun/star/frame/Desktop.hpp> #include <com/sun/star/frame/XController.hpp> #include <com/sun/star/frame/CommandGroup.hpp> @@ -293,6 +295,12 @@ IMPL_LINK_NOARG(CloseDispatcher, impl_asyncCallback, LinkParamNone*, void) css::uno::Reference< css::frame::XFramesSupplier > xDesktop( css::frame::Desktop::create(xContext), css::uno::UNO_QUERY_THROW); FrameListAnalyzer aCheck1(xDesktop, xCloseFrame, FrameListAnalyzer::E_HELP | FrameListAnalyzer::E_BACKINGCOMPONENT); + // Check for existing UNO connections. + // NOTE: There is a race between checking this and connections being created/destroyed before + // we close the frame / terminate the app. + css::uno::Reference<css::bridge::XBridgeFactory2> bridgeFac( css::bridge::BridgeFactory::create(xContext) ); + bool bHasActiveConnections = bridgeFac->getExistingBridges().getLength() > 0; + // a) If the current frame (where the close dispatch was requested for) does not have // any parent frame ... it will close this frame only. Such frame isn't part of the // global desktop tree ... and such frames are used as "implementation details" only. @@ -310,13 +318,15 @@ IMPL_LINK_NOARG(CloseDispatcher, impl_asyncCallback, LinkParamNone*, void) else if (aCheck1.m_bReferenceIsHelp) bCloseFrame = true; - // c) If we are already in "backing mode", we have to terminate - // the application, if this special frame is closed. - // It doesn't matter, how many other frames (can be the help or hidden frames only) - // are open then. - // => terminate the application! - else if (aCheck1.m_bReferenceIsBacking) - bTerminateApp = true; + // c) If we are already in "backing mode", we terminate the application, if no active UNO connections are found. + // If there is an active UNO connection, we only close the frame and leave the application alive. + // It doesn't matter, how many other frames (can be the help or hidden frames only) are open then. + else if (aCheck1.m_bReferenceIsBacking) { + if (bHasActiveConnections) + bCloseFrame = true; + else + bTerminateApp = true; + } // d) Otherwhise we have to: close all views to the same document, close the // document inside our own frame and decide then again, what has to be done! @@ -352,7 +362,9 @@ IMPL_LINK_NOARG(CloseDispatcher, impl_asyncCallback, LinkParamNone*, void) // application or establish the backing mode now. // And that depends from the dispatched URL ... { - if (eOperation == E_CLOSE_FRAME) + if (bHasActiveConnections) + bCloseFrame = true; + else if (eOperation == E_CLOSE_FRAME) bTerminateApp = true; else if( SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::EModule::STARTMODULE) ) bEstablishBackingMode = true; |