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