[Libreoffice-commits] .: vcl/unx

Lubos Lunak llunak at kemper.freedesktop.org
Tue Mar 8 07:16:22 PST 2011


 vcl/unx/inc/salframe.h             |    4 +++
 vcl/unx/source/window/salframe.cxx |   38 +++++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

New commits:
commit 3c4e713c58972bdd7569ccc16af8e507e325fa2d
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Tue Mar 8 16:14:48 2011 +0100

    avoid race condition with multiple window resizing (bnc#674806)

diff --git a/vcl/unx/inc/salframe.h b/vcl/unx/inc/salframe.h
index 25bb004..f243334 100644
--- a/vcl/unx/inc/salframe.h
+++ b/vcl/unx/inc/salframe.h
@@ -140,6 +140,7 @@ class VCL_DLLPUBLIC X11SalFrame : public SalFrame
     int             m_nCurClipRect;
     int             m_nMaxClipRect;
     
+    bool mPendingSizeEvent;
     
     void			GetPosSize( Rectangle &rPosSize );
     void			SetSize   ( const Size      &rSize );
@@ -279,6 +280,9 @@ public:
 
     static void SaveYourselfDone( SalFrame* );
     static Bool checkKeyReleaseForRepeat( Display*, XEvent*, XPointer pX11SalFrame );
+
+    /// @internal
+    void setPendingSizeEvent();
 };
 
 #ifdef _SV_SALDISP_HXX
diff --git a/vcl/unx/source/window/salframe.cxx b/vcl/unx/source/window/salframe.cxx
index 9affd50..0ff6030 100644
--- a/vcl/unx/source/window/salframe.cxx
+++ b/vcl/unx/source/window/salframe.cxx
@@ -3611,9 +3611,37 @@ void X11SalFrame::RestackChildren()
     }
 }
 
+static Bool size_event_predicate( Display*, XEvent* event, XPointer arg )
+{
+    if( event->type != ConfigureNotify )
+        return False;
+    X11SalFrame* frame = reinterpret_cast< X11SalFrame* >( arg );
+    XConfigureEvent* pEvent = &event->xconfigure;
+    if( pEvent->window != frame->GetShellWindow()
+        && pEvent->window != frame->GetWindow()
+        && pEvent->window != frame->GetForeignParent()
+        && pEvent->window != frame->GetStackingWindow())
+    { // ignored at top of HandleSizeEvent()
+        return False;
+    }
+    if( pEvent->window == frame->GetStackingWindow())
+        return False; // filtered later in HandleSizeEvent()
+    // at this point we know that there is another similar event in the queue
+    frame->setPendingSizeEvent();
+    return False; // but do not process the new event out of order
+}
+
+void X11SalFrame::setPendingSizeEvent()
+{
+    mPendingSizeEvent = true;
+}
+
 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 long X11SalFrame::HandleSizeEvent( XConfigureEvent *pEvent )
 {
+    // NOTE: if you add more tests in this function, make sure to update size_event_predicate()
+    // so that it finds exactly the same events
+
     if (   pEvent->window != GetShellWindow()
            && pEvent->window != GetWindow()
            && pEvent->window != GetForeignParent()
@@ -3661,6 +3689,16 @@ long X11SalFrame::HandleSizeEvent( XConfigureEvent *pEvent )
     if( SHOWSTATE_UNKNOWN == nShowState_ && bMapped_ )
         nShowState_ = SHOWSTATE_NORMAL;
 
+    // Avoid a race condition where resizing this window to one size and shortly after that
+    // to another size generates first size event with the old size and only after that
+    // with the new size, temporarily making us think the old size is valid (bnc#674806).
+    // So if there is another size event for this window pending, ignore this one.
+    mPendingSizeEvent = false;
+    XEvent dummy;
+    XCheckIfEvent( GetXDisplay(), &dummy, size_event_predicate, reinterpret_cast< XPointer >( this ));
+    if( mPendingSizeEvent )
+        return 1;
+
     nWidth_ 	= pEvent->width;
     nHeight_	= pEvent->height;
 


More information about the Libreoffice-commits mailing list