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
This commit is contained in:
Vadim Zeitlin
2013-08-18 13:28:09 +00:00
parent b0ad1918b9
commit 0c60a0e2b7

View 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 // Stack of the windows which previously had the capture, the top most element
struct WindowNext // is the window that has the mouse capture now.
{ //
wxWindow *win; // NB: We use wxVector and not wxStack to be able to examine all of the stack
WindowNext *next; // elements for debug checks, but only the stack operations should be
} *next = NULL; // performed with this vector.
wxVector<wxWindow*> stack;
// the window that currently has mouse capture
wxWindow *current = NULL;
// Flag preventing reentrancy in {Capture,Release}Mouse(). // Flag preventing reentrancy in {Capture,Release}Mouse().
wxRecursionGuardFlag changing; wxRecursionGuardFlag changing;
@@ -3231,19 +3229,11 @@ void wxWindowBase::CaptureMouse()
wxWindow *winOld = GetCapture(); wxWindow *winOld = GetCapture();
if ( winOld ) 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, wxASSERT_MSG( GetCapture() == this,
"attempt to release mouse, but this window hasn't captured it" ); "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 ) 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();
// Restore the capture to the previous window, if any.
if ( !wxMouseCapture::stack.empty() )
{ {
((wxWindowBase*)wxMouseCapture::next->win)->DoCaptureMouse(); ((wxWindowBase*)wxMouseCapture::stack.back())->DoCaptureMouse();
wxMouseCapture::current = wxMouseCapture::next->win;
wxMouseCapture::WindowNext *item = wxMouseCapture::next;
wxMouseCapture::next = item->next;
delete item;
} }
//else: stack is empty, no previous capture
wxLogTrace(wxT("mousecapture"), wxLogTrace(wxT("mousecapture"),
(const wxChar *) wxT("After ReleaseMouse() mouse is captured by %p"), (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 // if the capture was lost unexpectedly, notify every window that has
// capture (on stack or current) about it and clear the stack: // capture (on stack or current) about it and clear the stack:
while ( !wxMouseCapture::stack.empty() )
if ( wxMouseCapture::current )
{ {
DoNotifyWindowAboutCaptureLost(wxMouseCapture::current); DoNotifyWindowAboutCaptureLost(wxMouseCapture::stack.back());
wxMouseCapture::current = NULL;
}
while ( wxMouseCapture::next ) wxMouseCapture::stack.pop_back();
{
wxMouseCapture::WindowNext *item = wxMouseCapture::next;
wxMouseCapture::next = item->next;
DoNotifyWindowAboutCaptureLost(item->win);
delete item;
} }
} }