]> git.saurik.com Git - wxWidgets.git/commitdiff
Fix bug with mouse wheel scrolling wxStyledTextCtrl in long running programs.
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 3 Feb 2012 00:21:45 +0000 (00:21 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 3 Feb 2012 00:21:45 +0000 (00:21 +0000)
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

include/wx/stc/stc.h
src/stc/stc.cpp
src/stc/stc.cpp.in
src/stc/stc.h.in

index 559f8823d445eae7a5b90c9c92c6d105a5b84637..26ee4d5eba19ca4c814ac7115e4cb5cbfefad8c4 100644 (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;
index c31f350f55f9ee09f129cb392f0280cc56793dea..65713e1b492b716650398b16822419fcccd780d9 100644 (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;
     }
 }
 
index 2dfa4ec02a43727ee3b8d0e213efb330724536ab..ec2e890e47b5e9574017487a19412dced14ba7f9 100644 (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;
     }
 }
 
index 73fa5603c9e28d256c81151975fea8d08324032f..55e0501f788fd5465e62dfdf25e5b3dd7705083f 100644 (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;