summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2019-12-12 01:44:23 +0000
committerMichael Meeks <michael.meeks@collabora.com>2019-12-18 15:10:24 +0100
commit280f54a942ce9fe0177100312fc45a398955bd8a (patch)
tree544c22f9a250164b24afa521a8c4731bcb908011
parent189d498f5c0c633f8cd87b3f1b6d57020371a952 (diff)
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. also includes: lok: vcl: fix multiple floatwin removal case. We need to progress in our while loop to remove children, even if they are currently not in popup-mode; fixes infinite loop with two popups present concurrently. Change-Id: Ic7b7f8e13a466d254abe53b77bc166c6a89fa8c3 Reviewed-on: https://gerrit.libreoffice.org/85368 Tested-by: Jenkins Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
-rw-r--r--include/vcl/floatwin.hxx3
-rw-r--r--vcl/source/window/floatwin.cxx15
2 files changed, 14 insertions, 4 deletions
diff --git a/include/vcl/floatwin.hxx b/include/vcl/floatwin.hxx
index e924807ca44d..91a6ae3c8c0e 100644
--- a/include/vcl/floatwin.hxx
+++ b/include/vcl/floatwin.hxx
@@ -56,10 +56,11 @@ enum class FloatWinPopupEndFlags
TearOff = 0x02,
DontCallHdl = 0x04,
CloseAll = 0x08,
+ NoCloseChildren = 0x10,
};
namespace o3tl
{
- template<> struct typed_flags<FloatWinPopupEndFlags> : is_typed_flags<FloatWinPopupEndFlags, 0x0f> {};
+ template<> struct typed_flags<FloatWinPopupEndFlags> : is_typed_flags<FloatWinPopupEndFlags, 0x1f> {};
}
enum class FloatWinTitleType
diff --git a/vcl/source/window/floatwin.cxx b/vcl/source/window/floatwin.cxx
index dc834d9f9acd..d846cba8ddd4 100644
--- a/vcl/source/window/floatwin.cxx
+++ b/vcl/source/window/floatwin.cxx
@@ -825,9 +825,18 @@ void FloatingWindow::ImplEndPopupMode( FloatWinPopupEndFlags nFlags, const VclPt
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<VclPtr<FloatingWindow>> 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;