From 23847e9f0e8568f2dbb70896b7504262704309d6 Mon Sep 17 00:00:00 2001 From: Michael Meeks Date: Tue, 17 Dec 2019 17:40:51 +0000 Subject: [PATCH] lok: vcl: fix multiple floatwin removal case more robustly. Instead of this over-clever approach of recursively removing items which can easily fail, build a list, then iterate it in-line while disabling recursion. Change-Id: I846a0d44401500d60dcc2a7f16f222324c6c621b Reviewed-on: https://gerrit.libreoffice.org/85335 Tested-by: Jenkins CollaboraOffice Reviewed-by: Andras Timar --- include/vcl/floatwin.hxx | 3 ++- vcl/source/window/floatwin.cxx | 24 +++++++++++++++--------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/include/vcl/floatwin.hxx b/include/vcl/floatwin.hxx index 7cb1e38b9914..127e35c11631 100644 --- a/include/vcl/floatwin.hxx +++ b/include/vcl/floatwin.hxx @@ -57,10 +57,11 @@ enum class FloatWinPopupEndFlags TearOff = 0x02, DontCallHdl = 0x04, CloseAll = 0x08, + NoCloseChildren = 0x10, }; namespace o3tl { - template<> struct typed_flags : is_typed_flags {}; + template<> struct typed_flags : is_typed_flags {}; } enum class FloatWinTitleType diff --git a/vcl/source/window/floatwin.cxx b/vcl/source/window/floatwin.cxx index 55784bdb2aa2..9de1efdaf221 100644 --- a/vcl/source/window/floatwin.cxx +++ b/vcl/source/window/floatwin.cxx @@ -818,24 +818,30 @@ void FloatingWindow::StartPopupMode( ToolBox* pBox, FloatWinPopupFlags nFlags ) void FloatingWindow::ImplEndPopupMode( FloatWinPopupEndFlags nFlags, const VclPtr& xFocusId ) { + if ( !mbInPopupMode ) + return; + ImplSVData* pSVData = ImplGetSVData(); mbInCleanUp = true; // prevent killing this window due to focus change while working with it - // stop the PopupMode also for all following PopupMode windows - while (pSVData->mpWinData->mpFirstFloat && pSVData->mpWinData->mpFirstFloat.get() != this) - pSVData->mpWinData->mpFirstFloat->EndPopupMode(FloatWinPopupEndFlags::Cancel); + if (!(nFlags & FloatWinPopupEndFlags::NoCloseChildren)) + { + // stop the PopupMode also for all PopupMode windows created after us + std::vector> aCancelFloats; + // stop the PopupMode also for all following PopupMode windows + for (auto pFloat = pSVData->mpWinData->mpFirstFloat; + pFloat != nullptr && pFloat != this; + pFloat = pFloat->mpNextFloat) + aCancelFloats.push_back(pFloat); + for (auto it : aCancelFloats) + it->EndPopupMode(FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::NoCloseChildren); + } // delete window from the list pSVData->mpWinData->mpFirstFloat = mpNextFloat; mpNextFloat = nullptr; - if ( !mbInPopupMode ) - { - mbInCleanUp = false; - return; - } - FloatWinPopupFlags nPopupModeFlags = mnPopupModeFlags; mbPopupModeTearOff = nFlags & FloatWinPopupEndFlags::TearOff && nPopupModeFlags & FloatWinPopupFlags::AllowTearOff; -- 2.11.4.GIT