// reset the dangling pointer our parent window may keep to us
if ( m_parent )
{
- if ( m_parent->GetDefaultItem() == this )
- {
- m_parent->SetDefaultItem(NULL);
- }
-
m_parent->RemoveChild(this);
}
#endif
)
{
- // our minimal acceptable size is such that all our visible child windows fit inside
+ // our minimal acceptable size is such that all our visible child
+ // windows fit inside
int maxX = 0,
maxY = 0;
node = node->GetNext() )
{
wxWindow *win = node->GetData();
- if ( win->IsTopLevel() || ( ! win->IsShown() )
+ if ( win->IsTopLevel()
+ || !win->IsShown()
#if wxUSE_STATUSBAR
- || wxDynamicCast(win, wxStatusBar)
+ || wxDynamicCast(win, wxStatusBar)
#endif // wxUSE_STATUSBAR
)
{
maxY = wy + wh;
}
- // for compatibility with the old versions and because it really looks
- // slightly more pretty like this, add a pad
- maxX += 7;
- maxY += 14;
-
best = wxSize(maxX, maxY);
}
else // ! has children
wxWindow *win;
wxWindowNext *next;
} *wxWindowBase::ms_winCaptureNext = NULL;
+wxWindow *wxWindowBase::ms_winCaptureCurrent = NULL;
+bool wxWindowBase::ms_winCaptureChanging = false;
void wxWindowBase::CaptureMouse()
{
- wxLogTrace(_T("mousecapture"), _T("CaptureMouse(%p)"), this);
+ wxLogTrace(_T("mousecapture"), _T("CaptureMouse(%p)"), wx_static_cast(void*, this));
+
+ wxASSERT_MSG( !ms_winCaptureChanging, _T("recursive CaptureMouse call?") );
+
+ ms_winCaptureChanging = true;
wxWindow *winOld = GetCapture();
if ( winOld )
//else: no mouse capture to save
DoCaptureMouse();
+ ms_winCaptureCurrent = (wxWindow*)this;
+
+ ms_winCaptureChanging = false;
}
void wxWindowBase::ReleaseMouse()
{
- wxLogTrace(_T("mousecapture"), _T("ReleaseMouse(%p)"), this);
+ wxLogTrace(_T("mousecapture"), _T("ReleaseMouse(%p)"), wx_static_cast(void*, this));
+
+ wxASSERT_MSG( !ms_winCaptureChanging, _T("recursive ReleaseMouse call?") );
wxASSERT_MSG( GetCapture() == this, wxT("attempt to release mouse, but this window hasn't captured it") );
+ ms_winCaptureChanging = true;
+
DoReleaseMouse();
+ ms_winCaptureCurrent = NULL;
if ( ms_winCaptureNext )
{
((wxWindowBase*)ms_winCaptureNext->win)->DoCaptureMouse();
+ ms_winCaptureCurrent = ms_winCaptureNext->win;
wxWindowNext *item = ms_winCaptureNext;
ms_winCaptureNext = item->next;
}
//else: stack is empty, no previous capture
+ ms_winCaptureChanging = false;
+
wxLogTrace(_T("mousecapture"),
(const wxChar *) _T("After ReleaseMouse() mouse is captured by %p"),
- GetCapture());
+ wx_static_cast(void*, GetCapture()));
+}
+
+static void DoNotifyWindowAboutCaptureLost(wxWindow *win)
+{
+ wxMouseCaptureLostEvent event(win->GetId());
+ event.SetEventObject(win);
+ if ( !win->GetEventHandler()->ProcessEvent(event) )
+ {
+ wxFAIL_MSG( _T("window that captured the mouse didn't process wxEVT_MOUSE_CAPTURE_LOST") );
+ }
+}
+
+/* static */
+void wxWindowBase::NotifyCaptureLost()
+{
+ // don't do anything if capture lost was expected, i.e. resulted from
+ // a wx call to ReleaseMouse or CaptureMouse:
+ if ( ms_winCaptureChanging )
+ return;
+
+ // if the capture was lost unexpectedly, notify every window that has
+ // capture (on stack or current) about it and clear the stack:
+
+ if ( ms_winCaptureCurrent )
+ {
+ DoNotifyWindowAboutCaptureLost(ms_winCaptureCurrent);
+ ms_winCaptureCurrent = NULL;
+ }
+
+ while ( ms_winCaptureNext )
+ {
+ wxWindowNext *item = ms_winCaptureNext;
+ ms_winCaptureNext = item->next;
+
+ DoNotifyWindowAboutCaptureLost(item->win);
+
+ delete item;
+ }
}
#if wxUSE_HOTKEY