From 94633ad9f171fefbe96b7cde1aa0a29090e627bc Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 19 Jan 2002 19:31:19 +0000 Subject: [PATCH] maintaint the mouse capture stack in all ports, not just wxUniv git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13659 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/gtk/window.h | 9 ++++---- include/wx/gtk1/window.h | 9 ++++---- include/wx/msw/window.h | 5 +++-- include/wx/univ/window.h | 7 ------ include/wx/window.h | 13 ++++++++--- src/common/wincmn.cpp | 47 ++++++++++++++++++++++++++++++++++++++++ src/gtk/window.cpp | 20 ++++++++--------- src/gtk1/window.cpp | 20 ++++++++--------- src/msw/window.cpp | 4 ++-- src/univ/winuniv.cpp | 47 ---------------------------------------- 10 files changed, 92 insertions(+), 89 deletions(-) diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h index ce6b0332d4..746f9c61a6 100644 --- a/include/wx/gtk/window.h +++ b/include/wx/gtk/window.h @@ -65,8 +65,6 @@ public: virtual bool Reparent( wxWindowBase *newParent ); virtual void WarpPointer(int x, int y); - virtual void CaptureMouse(); - virtual void ReleaseMouse(); virtual void Refresh( bool eraseBackground = TRUE, const wxRect *rect = (const wxRect *) NULL ); @@ -159,7 +157,7 @@ public: // the layouting functions have to be called later on // (i.e. in idle time, implemented in OnInternalIdle() ). void GtkUpdateSize() { m_sizeSet = FALSE; } - + // position and size of the window int m_x, m_y; int m_width, m_height; @@ -168,7 +166,7 @@ public: // see the docs in src/gtk/window.cpp GtkWidget *m_widget; // mostly the widget seen by the rest of GTK GtkWidget *m_wxwindow; // mostly the client area as per wxWindows - + // this widget will be queried for GTK's focus events GtkWidget *m_focusWidget; @@ -229,6 +227,9 @@ public: virtual void DoSetClientSize(int width, int height); virtual void DoMoveWindow(int x, int y, int width, int height); + virtual void DoCaptureMouse(); + virtual void DoReleaseMouse(); + #if wxUSE_TOOLTIPS virtual void DoSetToolTip( wxToolTip *tip ); #endif // wxUSE_TOOLTIPS diff --git a/include/wx/gtk1/window.h b/include/wx/gtk1/window.h index ce6b0332d4..746f9c61a6 100644 --- a/include/wx/gtk1/window.h +++ b/include/wx/gtk1/window.h @@ -65,8 +65,6 @@ public: virtual bool Reparent( wxWindowBase *newParent ); virtual void WarpPointer(int x, int y); - virtual void CaptureMouse(); - virtual void ReleaseMouse(); virtual void Refresh( bool eraseBackground = TRUE, const wxRect *rect = (const wxRect *) NULL ); @@ -159,7 +157,7 @@ public: // the layouting functions have to be called later on // (i.e. in idle time, implemented in OnInternalIdle() ). void GtkUpdateSize() { m_sizeSet = FALSE; } - + // position and size of the window int m_x, m_y; int m_width, m_height; @@ -168,7 +166,7 @@ public: // see the docs in src/gtk/window.cpp GtkWidget *m_widget; // mostly the widget seen by the rest of GTK GtkWidget *m_wxwindow; // mostly the client area as per wxWindows - + // this widget will be queried for GTK's focus events GtkWidget *m_focusWidget; @@ -229,6 +227,9 @@ public: virtual void DoSetClientSize(int width, int height); virtual void DoMoveWindow(int x, int y, int width, int height); + virtual void DoCaptureMouse(); + virtual void DoReleaseMouse(); + #if wxUSE_TOOLTIPS virtual void DoSetToolTip( wxToolTip *tip ); #endif // wxUSE_TOOLTIPS diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h index aa039d5869..ec980f4392 100644 --- a/include/wx/msw/window.h +++ b/include/wx/msw/window.h @@ -90,8 +90,6 @@ public: virtual bool Reparent(wxWindowBase *newParent); virtual void WarpPointer(int x, int y); - virtual void CaptureMouse(); - virtual void ReleaseMouse(); virtual void Refresh( bool eraseBackground = TRUE, const wxRect *rect = (const wxRect *) NULL ); @@ -438,6 +436,9 @@ protected: int sizeFlags = wxSIZE_AUTO); virtual void DoSetClientSize(int width, int height); + virtual void DoCaptureMouse(); + virtual void DoReleaseMouse(); + // move the window to the specified location and resize it: this is called // from both DoSetSize() and DoSetClientSize() and would usually just call // ::MoveWindow() except for composite controls which will want to arrange diff --git a/include/wx/univ/window.h b/include/wx/univ/window.h index cfe3c89bb7..78cf266257 100644 --- a/include/wx/univ/window.h +++ b/include/wx/univ/window.h @@ -200,13 +200,6 @@ public: // we refresh the window when it is dis/enabled virtual bool Enable(bool enable = TRUE); - // our Capture/ReleaseMouse() maintains the stack of windows which had - // captured the mouse and when ReleaseMouse() is called, the mouse freed - // only if the stack is empty, otherwise it is captured back by the window - // on top of the stack - virtual void CaptureMouse(); - virtual void ReleaseMouse(); - protected: // common part of all ctors void Init(); diff --git a/include/wx/window.h b/include/wx/window.h index 3abbf6a330..b84b83dd60 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -460,9 +460,12 @@ public: // move the mouse to the specified position virtual void WarpPointer(int x, int y) = 0; - // start or end mouse capture - virtual void CaptureMouse() = 0; - virtual void ReleaseMouse() = 0; + // start or end mouse capture, these functions maintain the stack of + // windows having captured the mouse and after calling ReleaseMouse() + // the mouse is not released but returns to the window which had had + // captured it previously (if any) + void CaptureMouse(); + void ReleaseMouse(); // get the window which currently captures the mouse or NULL static wxWindow *GetCapture(); @@ -883,6 +886,10 @@ protected: virtual wxHitTest DoHitTest(wxCoord x, wxCoord y) const; + // capture/release the mouse, used by Capture/ReleaseMouse() + virtual void DoCaptureMouse(); + virtual void DoReleaseMouse(); + // retrieve the position/size of the window virtual void DoGetPosition( int *x, int *y ) const = 0; virtual void DoGetSize( int *width, int *height ) const = 0; diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 3a1fd0f2d8..bd4ec6de1e 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -1612,3 +1612,50 @@ wxHitTest wxWindowBase::DoHitTest(wxCoord x, wxCoord y) const return outside ? wxHT_WINDOW_OUTSIDE : wxHT_WINDOW_INSIDE; } +// ---------------------------------------------------------------------------- +// mouse capture +// ---------------------------------------------------------------------------- + +struct WXDLLEXPORT wxWindowNext +{ + wxWindow *win; + wxWindowNext *next; +} *wxWindow::ms_winCaptureNext = NULL; + +void wxWindow::CaptureMouse() +{ + wxLogTrace(_T("mousecapture"), _T("CaptureMouse(0x%08x)"), this); + + wxWindow *winOld = GetCapture(); + if ( winOld ) + { + // save it on stack + wxWindowNext *item = new wxWindowNext; + item->win = winOld; + item->next = ms_winCaptureNext; + ms_winCaptureNext = item; + } + //else: no mouse capture to save + + DoCaptureMouse(); +} + +void wxWindow::ReleaseMouse() +{ + DoReleaseMouse(); + + if ( ms_winCaptureNext ) + { + ms_winCaptureNext->win->CaptureMouse(); + + wxWindowNext *item = ms_winCaptureNext; + ms_winCaptureNext = item->next; + delete item; + } + //else: stack is empty, no previous capture + + wxLogTrace(_T("mousecapture"), + _T("After ReleaseMouse() mouse is captured by 0x%08x"), + GetCapture()); +} + diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 475c60be0f..21dbf1774a 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -1356,9 +1356,9 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton InitMouseEvent( win, event, gdk_event ); AdjustEventButtonState(event); - + // wxListBox actually get mouse events from the item - + if (win->m_isListBox) { event.m_x += widget->allocation.x; @@ -1489,7 +1489,7 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto AdjustEventButtonState(event); // wxListBox actually get mouse events from the item - + if (win->m_isListBox) { event.m_x += widget->allocation.x; @@ -2370,7 +2370,7 @@ void wxWindowGTK::Init() m_noExpose = FALSE; m_nativeSizeEvent = FALSE; - + m_hasScrolling = FALSE; m_isScrolling = FALSE; @@ -2545,7 +2545,7 @@ bool wxWindowGTK::Create( wxWindow *parent, if (m_parent) m_parent->DoAddChild( this ); - + m_focusWidget = m_wxwindow; PostCreation(); @@ -2639,7 +2639,7 @@ bool wxWindowGTK::PreCreation( wxWindowGTK *parent, const wxPoint &pos, const w void wxWindowGTK::PostCreation() { wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") ); - + if (m_wxwindow) { if (!m_noExpose) @@ -3087,7 +3087,7 @@ void wxWindowGTK::DoGetPosition( int *x, int *y ) const dx = pizza->xoffset; dy = pizza->yoffset; } - + if (x) (*x) = m_x - dx; if (y) (*y) = m_y - dy; } @@ -3280,7 +3280,7 @@ void wxWindowGTK::SetFocus() // ? } } - + #if 0 wxPrintf( "SetFocus finished in " ); if (GetClassInfo() && GetClassInfo()->GetClassName()) @@ -3872,7 +3872,7 @@ bool wxWindowGTK::SetFont( const wxFont &font ) return TRUE; } -void wxWindowGTK::CaptureMouse() +void wxWindowGTK::DoCaptureMouse() { wxCHECK_RET( m_widget != NULL, wxT("invalid window") ); @@ -3901,7 +3901,7 @@ void wxWindowGTK::CaptureMouse() g_captureWindowHasMouse = TRUE; } -void wxWindowGTK::ReleaseMouse() +void wxWindowGTK::DoReleaseMouse() { wxCHECK_RET( m_widget != NULL, wxT("invalid window") ); diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp index 475c60be0f..21dbf1774a 100644 --- a/src/gtk1/window.cpp +++ b/src/gtk1/window.cpp @@ -1356,9 +1356,9 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton InitMouseEvent( win, event, gdk_event ); AdjustEventButtonState(event); - + // wxListBox actually get mouse events from the item - + if (win->m_isListBox) { event.m_x += widget->allocation.x; @@ -1489,7 +1489,7 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto AdjustEventButtonState(event); // wxListBox actually get mouse events from the item - + if (win->m_isListBox) { event.m_x += widget->allocation.x; @@ -2370,7 +2370,7 @@ void wxWindowGTK::Init() m_noExpose = FALSE; m_nativeSizeEvent = FALSE; - + m_hasScrolling = FALSE; m_isScrolling = FALSE; @@ -2545,7 +2545,7 @@ bool wxWindowGTK::Create( wxWindow *parent, if (m_parent) m_parent->DoAddChild( this ); - + m_focusWidget = m_wxwindow; PostCreation(); @@ -2639,7 +2639,7 @@ bool wxWindowGTK::PreCreation( wxWindowGTK *parent, const wxPoint &pos, const w void wxWindowGTK::PostCreation() { wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") ); - + if (m_wxwindow) { if (!m_noExpose) @@ -3087,7 +3087,7 @@ void wxWindowGTK::DoGetPosition( int *x, int *y ) const dx = pizza->xoffset; dy = pizza->yoffset; } - + if (x) (*x) = m_x - dx; if (y) (*y) = m_y - dy; } @@ -3280,7 +3280,7 @@ void wxWindowGTK::SetFocus() // ? } } - + #if 0 wxPrintf( "SetFocus finished in " ); if (GetClassInfo() && GetClassInfo()->GetClassName()) @@ -3872,7 +3872,7 @@ bool wxWindowGTK::SetFont( const wxFont &font ) return TRUE; } -void wxWindowGTK::CaptureMouse() +void wxWindowGTK::DoCaptureMouse() { wxCHECK_RET( m_widget != NULL, wxT("invalid window") ); @@ -3901,7 +3901,7 @@ void wxWindowGTK::CaptureMouse() g_captureWindowHasMouse = TRUE; } -void wxWindowGTK::ReleaseMouse() +void wxWindowGTK::DoReleaseMouse() { wxCHECK_RET( m_widget != NULL, wxT("invalid window") ); diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 45e349fff9..271f8f0cb8 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -546,7 +546,7 @@ wxString wxWindowMSW::GetTitle() const return wxGetWindowText(GetHWND()); } -void wxWindowMSW::CaptureMouse() +void wxWindowMSW::DoCaptureMouse() { HWND hWnd = GetHwnd(); if ( hWnd ) @@ -555,7 +555,7 @@ void wxWindowMSW::CaptureMouse() } } -void wxWindowMSW::ReleaseMouse() +void wxWindowMSW::DoReleaseMouse() { if ( !::ReleaseCapture() ) { diff --git a/src/univ/winuniv.cpp b/src/univ/winuniv.cpp index dbb420c484..a6dad52328 100644 --- a/src/univ/winuniv.cpp +++ b/src/univ/winuniv.cpp @@ -933,53 +933,6 @@ wxRect wxWindow::ScrollNoRefresh(int dx, int dy, const wxRect *rectTotal) return rect; } -// ---------------------------------------------------------------------------- -// mouse capture -// ---------------------------------------------------------------------------- - -struct WXDLLEXPORT wxWindowNext -{ - wxWindow *win; - wxWindowNext *next; -} *wxWindow::ms_winCaptureNext = NULL; - -void wxWindow::CaptureMouse() -{ - wxLogTrace(_T("mousecapture"), _T("CaptureMouse(0x%08x)"), this); - - wxWindow *winOld = GetCapture(); - if ( winOld ) - { - // save it on stack - wxWindowNext *item = new wxWindowNext; - item->win = winOld; - item->next = ms_winCaptureNext; - ms_winCaptureNext = item; - } - //else: no mouse capture to save - - wxWindowNative::CaptureMouse(); -} - -void wxWindow::ReleaseMouse() -{ - wxWindowNative::ReleaseMouse(); - - if ( ms_winCaptureNext ) - { - ms_winCaptureNext->win->CaptureMouse(); - - wxWindowNext *item = ms_winCaptureNext; - ms_winCaptureNext = item->next; - delete item; - } - //else: stack is empty, no previous capture - - wxLogTrace(_T("mousecapture"), - _T("After ReleaseMouse() mouse is captured by 0x%08x"), - GetCapture()); -} - // ---------------------------------------------------------------------------- // accelerators and menu hot keys // ---------------------------------------------------------------------------- -- 2.45.2