From 3b51559d68131271aab6256093ad8a16d8373c43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= Date: Fri, 28 Feb 2014 17:13:55 +0000 Subject: [PATCH] Resolves: rhbz#1007697 Update on a Window deletes itself --- ...07697-Update-on-a-Window-triggering-.patch | 168 ++++++++++++++++++ libreoffice.spec | 6 +- 2 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 0001-Resolves-rhbz-1007697-Update-on-a-Window-triggering-.patch diff --git a/0001-Resolves-rhbz-1007697-Update-on-a-Window-triggering-.patch b/0001-Resolves-rhbz-1007697-Update-on-a-Window-triggering-.patch new file mode 100644 index 0000000..929e1a4 --- /dev/null +++ b/0001-Resolves-rhbz-1007697-Update-on-a-Window-triggering-.patch @@ -0,0 +1,168 @@ +From dfd483bf9ab7fad58882fb2abff5cbf7f79a4e37 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Fri, 28 Feb 2014 16:55:03 +0000 +Subject: [PATCH] Resolves: rhbz#1007697 Update on a Window triggering delete + on window +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-on: https://gerrit.libreoffice.org/8396 +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +(cherry picked from commit 1ec2880679d88c89901ce00fe30dd78e584f6960) + +Conflicts: + svx/source/svdraw/sdrpaintwindow.cxx + vcl/source/window/window.cxx + +Change-Id: Ic6374ce45e3a3ba97217ae77e91f9143f46e277b +--- + svx/source/svdraw/sdrpaintwindow.cxx | 96 +++++++++++++++++++++++++++++------- + vcl/source/window/window.cxx | 5 ++ + 2 files changed, 83 insertions(+), 18 deletions(-) + +diff --git a/svx/source/svdraw/sdrpaintwindow.cxx b/svx/source/svdraw/sdrpaintwindow.cxx +index 6abacc5..81dff0b 100644 +--- a/svx/source/svdraw/sdrpaintwindow.cxx ++++ b/svx/source/svdraw/sdrpaintwindow.cxx +@@ -22,35 +22,95 @@ + #include + #include + #include ++#include ++#include ++ ++//rhbz#1007697 do this in two loops, one to collect the candidates ++//and another to update them because updating a candidate can ++//trigger the candidate to be deleted, so asking for its ++//sibling after that is going to fail hard ++class CandidateMgr ++{ ++ std::vector m_aCandidates; ++ std::set m_aDeletedCandidates; ++ DECL_LINK(WindowEventListener, VclSimpleEvent*); ++public: ++ void PaintTransparentChildren(Window & rWindow, Rectangle const& rPixelRect); ++ ~CandidateMgr(); ++}; ++ ++IMPL_LINK(CandidateMgr, WindowEventListener, VclSimpleEvent*, pEvent) ++{ ++ VclWindowEvent* pWinEvent = dynamic_cast< VclWindowEvent* >( pEvent ); ++ if (pWinEvent) ++ { ++ Window* pWindow = pWinEvent->GetWindow(); ++ if (pWinEvent->GetId() == VCLEVENT_OBJECT_DYING) ++ { ++ m_aDeletedCandidates.insert(pWindow); ++ } ++ } + ++ return 0; ++} ++ ++CandidateMgr::~CandidateMgr() ++{ ++ for (std::vector::iterator aI = m_aCandidates.begin(); ++ aI != m_aCandidates.end(); ++aI) ++ { ++ Window* pCandidate = *aI; ++ if (m_aDeletedCandidates.find(pCandidate) != m_aDeletedCandidates.end()) ++ continue; ++ pCandidate->RemoveEventListener(LINK(this, CandidateMgr, WindowEventListener)); ++ } ++} + + void PaintTransparentChildren(Window & rWindow, Rectangle const& rPixelRect) + { +- if (rWindow.IsChildTransparentModeEnabled()) ++ if (!rWindow.IsChildTransparentModeEnabled()) ++ return; ++ ++ CandidateMgr aManager; ++ aManager.PaintTransparentChildren(rWindow, rPixelRect); ++} ++ ++void CandidateMgr::PaintTransparentChildren(Window & rWindow, Rectangle const& rPixelRect) ++{ ++ Window * pCandidate = rWindow.GetWindow( WINDOW_FIRSTCHILD ); ++ while (pCandidate) + { +- Window * pCandidate = rWindow.GetWindow( WINDOW_FIRSTCHILD ); +- while (pCandidate) ++ if (pCandidate->IsPaintTransparent()) + { +- if (pCandidate->IsPaintTransparent()) ++ const Rectangle aCandidatePosSizePixel( ++ pCandidate->GetPosPixel(), ++ pCandidate->GetSizePixel()); ++ ++ if (aCandidatePosSizePixel.IsOver(rPixelRect)) + { +- const Rectangle aCandidatePosSizePixel( +- pCandidate->GetPosPixel(), +- pCandidate->GetSizePixel()); +- +- if (aCandidatePosSizePixel.IsOver(rPixelRect)) +- { +- pCandidate->Invalidate( +- INVALIDATE_NOTRANSPARENT|INVALIDATE_CHILDREN ); +- // important: actually paint the child here! +- pCandidate->Update(); +- } ++ m_aCandidates.push_back(pCandidate); ++ pCandidate->AddEventListener(LINK(this, CandidateMgr, WindowEventListener)); + } +- pCandidate = pCandidate->GetWindow( WINDOW_NEXT ); + } ++ pCandidate = pCandidate->GetWindow( WINDOW_NEXT ); + } +-} + +-//////////////////////////////////////////////////////////////////////////////////////////////////// ++ for (std::vector::iterator aI = m_aCandidates.begin(); ++ aI != m_aCandidates.end(); ++aI) ++ { ++ pCandidate = *aI; ++ if (m_aDeletedCandidates.find(pCandidate) != m_aDeletedCandidates.end()) ++ continue; ++ //rhbz#1007697 this can cause the window itself to be ++ //deleted. So we are listening to see if that happens ++ //and if so, then skip the update ++ pCandidate->Invalidate(INVALIDATE_NOTRANSPARENT|INVALIDATE_CHILDREN); ++ // important: actually paint the child here! ++ if (m_aDeletedCandidates.find(pCandidate) != m_aDeletedCandidates.end()) ++ continue; ++ pCandidate->Update(); ++ } ++} + + SdrPreRenderDevice::SdrPreRenderDevice(OutputDevice& rOriginal) + : mrOutputDevice(rOriginal) +diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx +index 1ef62c1..60a14f1 100644 +--- a/vcl/source/window/window.cxx ++++ b/vcl/source/window/window.cxx +@@ -7561,6 +7561,8 @@ void Window::Update() + // if there is something to paint, trigger a Paint + if ( pUpdateWindow->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDREN) ) + { ++ ImplDelData aDogTag(this); ++ + // trigger an update also for system windows on top of us, + // otherwise holes would remain + Window* pUpdateOverlapWindow = ImplGetFirstOverlapWindow()->mpWindowImpl->mpFirstOverlap; +@@ -7571,6 +7573,9 @@ void Window::Update() + } + + pUpdateWindow->ImplCallPaint( NULL, pUpdateWindow->mpWindowImpl->mnPaintFlags ); ++ ++ if (aDogTag.IsDead()) ++ return; + bFlush = sal_True; + } + +-- +1.8.5.3 + diff --git a/libreoffice.spec b/libreoffice.spec index 7a479d5..f82640f 100644 --- a/libreoffice.spec +++ b/libreoffice.spec @@ -43,7 +43,7 @@ Summary: Free Software Productivity Suite Name: libreoffice Epoch: 1 Version: %{libo_version}.1 -Release: 2%{?libo_prerelease}%{?dist} +Release: 3%{?libo_prerelease}%{?dist} License: (MPLv1.1 or LGPLv3+) and LGPLv3 and LGPLv2+ and BSD and (MPLv1.1 or GPLv2 or LGPLv2 or Netscape) and Public Domain and ASL 2.0 and Artistic and MPLv2.0 Group: Applications/Productivity URL: http://www.libreoffice.org/default/ @@ -282,6 +282,7 @@ Patch19: 0001-explictly-list-common-lang-independant-template-dir.patch Patch20: 0001-rhbz-1057977-avoid-use-of-invalidated-pointers.patch Patch21: 0001-fdo-75540-setProcessServiceFactory-must-be-called-be.patch Patch22: 0001-KDE-don-t-throw-on-TemplatePathVariable.patch +Patch23: 0001-Resolves-rhbz-1007697-Update-on-a-Window-triggering-.patch %define instdir %{_libdir} %define baseinstdir %{instdir}/libreoffice @@ -2177,6 +2178,9 @@ update-desktop-database %{_datadir}/applications &> /dev/null || : %endif %changelog +* Fri Feb 28 2014 Caolán McNamara - 1:4.2.2.1-3 +- Resolves: rhbz#1007697 Update on a Window deletes itself + * Fri Feb 28 2014 Caolán McNamara - 1:4.2.2.1-2 - Related: rhbz#1065807 don't throw with no "Templates" dir under KDE