Resolves: rhbz#1007697 Update on a Window deletes itself

f41
Caolán McNamara 11 years ago
parent f1e27fccd8
commit 3b51559d68

@ -0,0 +1,168 @@
From dfd483bf9ab7fad58882fb2abff5cbf7f79a4e37 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
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 <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
(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 <svx/svdpntv.hxx>
#include <vcl/gdimtf.hxx>
#include <vcl/svapp.hxx>
+#include <set>
+#include <vector>
+
+//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<Window*> m_aCandidates;
+ std::set<Window*> 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<Window*>::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<Window*>::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

@ -43,7 +43,7 @@ Summary: Free Software Productivity Suite
Name: libreoffice Name: libreoffice
Epoch: 1 Epoch: 1
Version: %{libo_version}.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 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 Group: Applications/Productivity
URL: http://www.libreoffice.org/default/ 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 Patch20: 0001-rhbz-1057977-avoid-use-of-invalidated-pointers.patch
Patch21: 0001-fdo-75540-setProcessServiceFactory-must-be-called-be.patch Patch21: 0001-fdo-75540-setProcessServiceFactory-must-be-called-be.patch
Patch22: 0001-KDE-don-t-throw-on-TemplatePathVariable.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 instdir %{_libdir}
%define baseinstdir %{instdir}/libreoffice %define baseinstdir %{instdir}/libreoffice
@ -2177,6 +2178,9 @@ update-desktop-database %{_datadir}/applications &> /dev/null || :
%endif %endif
%changelog %changelog
* Fri Feb 28 2014 Caolán McNamara <caolanm@redhat.com> - 1:4.2.2.1-3
- Resolves: rhbz#1007697 Update on a Window deletes itself
* Fri Feb 28 2014 Caolán McNamara <caolanm@redhat.com> - 1:4.2.2.1-2 * Fri Feb 28 2014 Caolán McNamara <caolanm@redhat.com> - 1:4.2.2.1-2
- Related: rhbz#1065807 don't throw with no "Templates" dir under KDE - Related: rhbz#1065807 don't throw with no "Templates" dir under KDE

Loading…
Cancel
Save