[libreoffice] Resolves: rhbz#1007697 Update on a Window deletes itself

Caolán McNamara caolanm at fedoraproject.org
Fri Feb 28 17:13:11 UTC 2014


commit 3b51559d68131271aab6256093ad8a16d8373c43
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Feb 28 17:13:55 2014 +0000

    Resolves: rhbz#1007697 Update on a Window deletes itself

 ...bz-1007697-Update-on-a-Window-triggering-.patch |  168 ++++++++++++++++++++
 libreoffice.spec                                   |    6 +-
 2 files changed, 173 insertions(+), 1 deletions(-)
---
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?= <caolanm at 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 at redhat.com>
+Tested-by: Caolán McNamara <caolanm at 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
+
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 <caolanm at 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 at redhat.com> - 1:4.2.2.1-2
 - Related: rhbz#1065807 don't throw with no "Templates" dir under KDE
 


More information about the scm-commits mailing list