Fix bug with mouse wheel scrolling wxStyledTextCtrl in long running programs.

In long running programs the wxEvent time stamp could wrap around resulting in
all mouse wheel events being ignored in wxStyledTextCtrl as the comparison of
the (positive) time until which all the subsequent events were supposed to be
blocked and the (now negative) current event time stamp would be always false.

Fix this by using wxStopWatch::TimeInMicro() to avoid wraparound instead of
wxEvent::GetTimestamp().

Also rename the variable to have a more clear name as the original code wasn't
easy to understand.

Closes #9057.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@70500 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2012-02-03 00:21:45 +00:00
parent 9447a0d6af
commit 7bd2132891
4 changed files with 30 additions and 20 deletions

View File

@ -4292,9 +4292,8 @@ protected:
bool m_lastKeyDownConsumed;
// the timestamp that consists of the last wheel event
// added to the time taken to process that event.
long m_lastWheelTimestamp;
// Time until when we should ignore any new mouse wheel events.
wxLongLong m_timeToBlockWheelEventsUntil;
friend class ScintillaWX;
friend class Platform;

View File

@ -199,7 +199,7 @@ bool wxStyledTextCtrl::Create(wxWindow *parent,
m_swx = new ScintillaWX(this);
m_stopWatch.Start();
m_lastKeyDownConsumed = false;
m_lastWheelTimestamp = 0;
m_timeToBlockWheelEventsUntil = 0;
m_vScrollBar = NULL;
m_hScrollBar = NULL;
#if wxUSE_UNICODE
@ -4264,18 +4264,24 @@ void wxStyledTextCtrl::OnContextMenu(wxContextMenuEvent& evt) {
void wxStyledTextCtrl::OnMouseWheel(wxMouseEvent& evt)
{
// prevent having an event queue with wheel events that cannot be processed
// reasonably fast (see ticket #9057)
if ( m_lastWheelTimestamp <= evt.GetTimestamp() )
// Prevent having an event queue with wheel events that cannot be processed
// reasonably fast (see ticket #9057) by ignoring all of them that happen
// during the time interval corresponding to the time it took us to handle
// the last one.
//
// Notice the use of TimeInMicro() instead of Time() to avoid overflow in
// long running programs.
if ( m_timeToBlockWheelEventsUntil <= m_stopWatch.TimeInMicro() )
{
m_lastWheelTimestamp = m_stopWatch.Time();
const wxLongLong beforeMouseWheel = m_stopWatch.TimeInMicro();
m_swx->DoMouseWheel(evt.GetWheelRotation(),
evt.GetWheelDelta(),
evt.GetLinesPerAction(),
evt.ControlDown(),
evt.IsPageScroll());
m_lastWheelTimestamp = m_stopWatch.Time() - m_lastWheelTimestamp;
m_lastWheelTimestamp += evt.GetTimestamp();
const wxLongLong afterMouseWheel = m_stopWatch.TimeInMicro();
m_timeToBlockWheelEventsUntil = afterMouseWheel;
m_timeToBlockWheelEventsUntil += afterMouseWheel - beforeMouseWheel;
}
}

View File

@ -199,7 +199,7 @@ bool wxStyledTextCtrl::Create(wxWindow *parent,
m_swx = new ScintillaWX(this);
m_stopWatch.Start();
m_lastKeyDownConsumed = false;
m_lastWheelTimestamp = 0;
m_timeToBlockWheelEventsUntil = 0;
m_vScrollBar = NULL;
m_hScrollBar = NULL;
#if wxUSE_UNICODE
@ -764,18 +764,24 @@ void wxStyledTextCtrl::OnContextMenu(wxContextMenuEvent& evt) {
void wxStyledTextCtrl::OnMouseWheel(wxMouseEvent& evt)
{
// prevent having an event queue with wheel events that cannot be processed
// reasonably fast (see ticket #9057)
if ( m_lastWheelTimestamp <= evt.GetTimestamp() )
// Prevent having an event queue with wheel events that cannot be processed
// reasonably fast (see ticket #9057) by ignoring all of them that happen
// during the time interval corresponding to the time it took us to handle
// the last one.
//
// Notice the use of TimeInMicro() instead of Time() to avoid overflow in
// long running programs.
if ( m_timeToBlockWheelEventsUntil <= m_stopWatch.TimeInMicro() )
{
m_lastWheelTimestamp = m_stopWatch.Time();
const wxLongLong beforeMouseWheel = m_stopWatch.TimeInMicro();
m_swx->DoMouseWheel(evt.GetWheelRotation(),
evt.GetWheelDelta(),
evt.GetLinesPerAction(),
evt.ControlDown(),
evt.IsPageScroll());
m_lastWheelTimestamp = m_stopWatch.Time() - m_lastWheelTimestamp;
m_lastWheelTimestamp += evt.GetTimestamp();
const wxLongLong afterMouseWheel = m_stopWatch.TimeInMicro();
m_timeToBlockWheelEventsUntil = afterMouseWheel;
m_timeToBlockWheelEventsUntil += afterMouseWheel - beforeMouseWheel;
}
}

View File

@ -490,9 +490,8 @@ protected:
bool m_lastKeyDownConsumed;
// the timestamp that consists of the last wheel event
// added to the time taken to process that event.
long m_lastWheelTimestamp;
// Time until when we should ignore any new mouse wheel events.
wxLongLong m_timeToBlockWheelEventsUntil;
friend class ScintillaWX;
friend class Platform;