]> git.saurik.com Git - wxWidgets.git/commitdiff
No changes, just change data structures used by mouse capture code.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 18 Aug 2013 13:28:09 +0000 (13:28 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 18 Aug 2013 13:28:09 +0000 (13:28 +0000)
Use a simple stack of windows instead of a separate singly linked list and a
separate current capture pointer.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74675 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/common/wincmn.cpp

index b3479ab8d031ab939431cab645f2590f04c5d4ff..8fd56980d543a35365bffafb80699dc4f5214b3e 100644 (file)
@@ -3207,15 +3207,13 @@ wxHitTest wxWindowBase::DoHitTest(wxCoord x, wxCoord y) const
 namespace wxMouseCapture
 {
 
 namespace wxMouseCapture
 {
 
-// the stack of windows which have captured the mouse
-struct WindowNext
-{
-    wxWindow *win;
-    WindowNext *next;
-} *next = NULL;
-
-// the window that currently has mouse capture
-wxWindow *current = NULL;
+// Stack of the windows which previously had the capture, the top most element
+// is the window that has the mouse capture now.
+//
+// NB: We use wxVector and not wxStack to be able to examine all of the stack
+//     elements for debug checks, but only the stack operations should be
+//     performed with this vector.
+wxVector<wxWindow*> stack;
 
 // Flag preventing reentrancy in {Capture,Release}Mouse().
 wxRecursionGuardFlag changing;
 
 // Flag preventing reentrancy in {Capture,Release}Mouse().
 wxRecursionGuardFlag changing;
@@ -3231,19 +3229,11 @@ void wxWindowBase::CaptureMouse()
 
     wxWindow *winOld = GetCapture();
     if ( winOld )
 
     wxWindow *winOld = GetCapture();
     if ( winOld )
-    {
         ((wxWindowBase*) winOld)->DoReleaseMouse();
 
         ((wxWindowBase*) winOld)->DoReleaseMouse();
 
-        // save it on stack
-        wxMouseCapture::WindowNext *item = new wxMouseCapture::WindowNext;
-        item->win = winOld;
-        item->next = wxMouseCapture::next;
-        wxMouseCapture::next = item;
-    }
-    //else: no mouse capture to save
-
     DoCaptureMouse();
     DoCaptureMouse();
-    wxMouseCapture::current = (wxWindow*)this;
+
+    wxMouseCapture::stack.push_back(static_cast<wxWindow*>(this));
 }
 
 void wxWindowBase::ReleaseMouse()
 }
 
 void wxWindowBase::ReleaseMouse()
@@ -3255,22 +3245,21 @@ void wxWindowBase::ReleaseMouse()
 
     wxASSERT_MSG( GetCapture() == this,
                   "attempt to release mouse, but this window hasn't captured it" );
 
     wxASSERT_MSG( GetCapture() == this,
                   "attempt to release mouse, but this window hasn't captured it" );
-    wxASSERT_MSG( wxMouseCapture::current == this,
-                  "attempt to release mouse, but this window hasn't captured it" );
 
     DoReleaseMouse();
 
     DoReleaseMouse();
-    wxMouseCapture::current = NULL;
 
 
-    if ( wxMouseCapture::next )
-    {
-        ((wxWindowBase*)wxMouseCapture::next->win)->DoCaptureMouse();
-        wxMouseCapture::current = wxMouseCapture::next->win;
+    wxCHECK_RET( !wxMouseCapture::stack.empty(),
+                    "Releasing mouse capture but capture stack empty?" );
+    wxCHECK_RET( wxMouseCapture::stack.back() == this,
+                    "Window releasing mouse capture not top of capture stack?" );
+
+    wxMouseCapture::stack.pop_back();
 
 
-        wxMouseCapture::WindowNext *item = wxMouseCapture::next;
-        wxMouseCapture::next = item->next;
-        delete item;
+    // Restore the capture to the previous window, if any.
+    if ( !wxMouseCapture::stack.empty() )
+    {
+        ((wxWindowBase*)wxMouseCapture::stack.back())->DoCaptureMouse();
     }
     }
-    //else: stack is empty, no previous capture
 
     wxLogTrace(wxT("mousecapture"),
         (const wxChar *) wxT("After ReleaseMouse() mouse is captured by %p"),
 
     wxLogTrace(wxT("mousecapture"),
         (const wxChar *) wxT("After ReleaseMouse() mouse is captured by %p"),
@@ -3302,21 +3291,11 @@ void wxWindowBase::NotifyCaptureLost()
 
     // if the capture was lost unexpectedly, notify every window that has
     // capture (on stack or current) about it and clear the stack:
 
     // if the capture was lost unexpectedly, notify every window that has
     // capture (on stack or current) about it and clear the stack:
-
-    if ( wxMouseCapture::current )
+    while ( !wxMouseCapture::stack.empty() )
     {
     {
-        DoNotifyWindowAboutCaptureLost(wxMouseCapture::current);
-        wxMouseCapture::current = NULL;
-    }
-
-    while ( wxMouseCapture::next )
-    {
-        wxMouseCapture::WindowNext *item = wxMouseCapture::next;
-        wxMouseCapture::next = item->next;
-
-        DoNotifyWindowAboutCaptureLost(item->win);
+        DoNotifyWindowAboutCaptureLost(wxMouseCapture::stack.back());
 
 
-        delete item;
+        wxMouseCapture::stack.pop_back();
     }
 }
 
     }
 }