From: Vadim Zeitlin Date: Sun, 18 Aug 2013 13:28:09 +0000 (+0000) Subject: No changes, just change data structures used by mouse capture code. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/0c60a0e2b726073be874f45e5227ea93b63623f4 No changes, just change data structures used by mouse capture code. 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 --- diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index b3479ab8d0..8fd56980d5 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -3207,15 +3207,13 @@ wxHitTest wxWindowBase::DoHitTest(wxCoord x, wxCoord y) const 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 stack; // Flag preventing reentrancy in {Capture,Release}Mouse(). wxRecursionGuardFlag changing; @@ -3231,19 +3229,11 @@ void wxWindowBase::CaptureMouse() wxWindow *winOld = GetCapture(); if ( winOld ) - { ((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(); - wxMouseCapture::current = (wxWindow*)this; + + wxMouseCapture::stack.push_back(static_cast(this)); } 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( wxMouseCapture::current == this, - "attempt to release mouse, but this window hasn't captured it" ); 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"), @@ -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 ( 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(); } }