From 1cfd935c260b3391074b84ef6c494400d80144c8 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 14 Feb 2015 19:09:39 +0000 Subject: [PATCH] Use non-static reentrancy guard in wxScrollHelper::AdjustScrollbars(). This prevented calls to AdjustScrollbars() of another window from doing anything if they were called due to a size change from AdjustScrollbars() of an outer window. Closes #16852. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_3_0_BRANCH@78491 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + src/generic/scrlwing.cpp | 58 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index eb8774adcb..44bfcce9a6 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -583,6 +583,7 @@ All (GUI): - Restore support for wxFD_OVERWRITE_PROMPT and wxFD_FILE_MUST_EXIST in wxGenericFileDialog which was accidentally lost some time ago (Carl Godkin). - Fix handling of fast consecutive clicks in wxRibbonBar (atobi). +- Fix updating nested window scrollbars in some cases (sbrowne). wxGTK: diff --git a/src/generic/scrlwing.cpp b/src/generic/scrlwing.cpp index 6291815209..d494cbf280 100644 --- a/src/generic/scrlwing.cpp +++ b/src/generic/scrlwing.cpp @@ -39,8 +39,6 @@ #include "wx/scrolbar.h" #endif -#include "wx/recguard.h" - #ifdef __WXMSW__ #include // for DLGC_WANTARROWS #include "wx/msw/winundef.h" @@ -58,6 +56,58 @@ #endif #endif +typedef wxVector wxScrollHelperRecGuardFlags; +class wxScrollHelperRecGuard +{ +public: + wxScrollHelperRecGuard(wxScrollHelper *instance, wxScrollHelperRecGuardFlags& flags) + : m_flags(flags), m_instance(instance), m_inside(false) + { + // Determine if our instance is already inside a guard + for ( wxScrollHelperRecGuardFlags::iterator iter = flags.begin(); + iter != flags.end(); + ++iter ) + { + if ( *iter == instance ) + { + m_inside = true; + return; + } + } + + // Not inside so add it to the back + flags.push_back(instance); + } + + ~wxScrollHelperRecGuard() + { + if ( IsInside() ) + return; + + for ( wxScrollHelperRecGuardFlags::iterator iter = m_flags.begin(); + iter != m_flags.end(); + ++iter ) + { + if ( *iter == m_instance ) + { + m_flags.erase(iter); + break; + } + } + } + + bool IsInside() const { return m_inside; } + +private: + wxScrollHelperRecGuardFlags& m_flags; + wxScrollHelper* m_instance; + + // true if the flag had been already set when we were created + bool m_inside; + + wxDECLARE_NO_COPY_CLASS(wxScrollHelperRecGuard); +}; + /* TODO PROPERTIES style wxHSCROLL | wxVSCROLL @@ -1303,8 +1353,8 @@ wxScrollHelper::DoAdjustScrollbar(int orient, void wxScrollHelper::AdjustScrollbars() { - static wxRecursionGuardFlag s_flagReentrancy; - wxRecursionGuard guard(s_flagReentrancy); + static wxScrollHelperRecGuardFlags s_flagReentrancy; + wxScrollHelperRecGuard guard(this, s_flagReentrancy); if ( guard.IsInside() ) { // don't reenter AdjustScrollbars() while another call to