From b69b4206c6a9bcae5837662a872872a2d9bddb61 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 10 Jul 2019 11:54:17 +0200 Subject: [PATCH] Add wxScrollWindow::ShouldScrollToChildOnFocus() virtual hook This method can be overridden to indicate that the scrolled window doesn't want its children to be scrolled into view when they're focused, which is the default behaviour. Also reuse this method for Mac-specific scrollbar workaround. --- include/wx/scrolwin.h | 19 +++++++++++++++++++ interface/wx/scrolwin.h | 13 +++++++++++++ src/generic/scrlwing.cpp | 7 ++++--- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/include/wx/scrolwin.h b/include/wx/scrolwin.h index c7a858feea..bc3c90723c 100644 --- a/include/wx/scrolwin.h +++ b/include/wx/scrolwin.h @@ -14,6 +14,10 @@ #include "wx/control.h" #include "wx/panel.h" +#ifdef __WXOSX__ + #include "wx/scrolbar.h" +#endif + class WXDLLIMPEXP_FWD_CORE wxScrollHelperEvtHandler; class WXDLLIMPEXP_FWD_BASE wxTimer; @@ -305,6 +309,21 @@ protected: return size; } + // Can be overridden to return false if the child window shouldn't be + // scrolled into view automatically when it gets focus, which is the + // default behaviour. + virtual bool ShouldScrollToChildOnFocus(wxWindow* child) + { +#if defined(__WXOSX__) && wxUSE_SCROLLBAR + if ( wxDynamicCast(child, wxScrollBar) ) + return false; +#else + wxUnusedVar(child); +#endif + + return true; + } + double m_scaleX; double m_scaleY; diff --git a/interface/wx/scrolwin.h b/interface/wx/scrolwin.h index fc62e085b6..6e5ca6b7a4 100644 --- a/interface/wx/scrolwin.h +++ b/interface/wx/scrolwin.h @@ -581,6 +581,19 @@ public: */ virtual bool SendAutoScrollEvents(wxScrollWinEvent& event) const; + /** + This method can be overridden in a derived class to prevent scrolling + the child window into view automatically when it gets focus. + + The default behaviour is to scroll this window to show its currently + focused child automatically, to ensure that the user can interact with + it. This is usually helpful, but can be undesirable for some windows, + in which case this method can be overridden to return @false for them + to prevent any scrolling from taking place when such windows get focus. + + @since 3.1.3 + */ + virtual bool ShouldScrollToChildOnFocus(wxWindow* child) protected: /** diff --git a/src/generic/scrlwing.cpp b/src/generic/scrlwing.cpp index a55f832d94..906680689b 100644 --- a/src/generic/scrlwing.cpp +++ b/src/generic/scrlwing.cpp @@ -1070,10 +1070,11 @@ void wxScrollHelperBase::HandleOnChildFocus(wxChildFocusEvent& event) if ( win == m_targetWindow ) return; // nothing to do -#if defined( __WXOSX__ ) && wxUSE_SCROLLBAR - if (wxDynamicCast(win, wxScrollBar)) + if ( !ShouldScrollToChildOnFocus(win) ) + { + // the window does not require to be scrolled into view return; -#endif + } // Fixing ticket: https://trac.wxwidgets.org/ticket/9563 // When a child inside a wxControlContainer receives a focus, the