From: Vadim Zeitlin Date: Wed, 15 Aug 2007 21:01:30 +0000 (+0000) Subject: relinquish the mouse capture when a dialog is about to be made modal to ensure that... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/7738af5957ace396793ee291a280d5a3dbd4821f?hp=b1294ada8e87725409f290328da02306e5c8f4eb relinquish the mouse capture when a dialog is about to be made modal to ensure that the mouse can be used in it (patch 1754648) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@48121 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h index c28f5532c9..d5a4dd88ab 100644 --- a/include/wx/gtk/window.h +++ b/include/wx/gtk/window.h @@ -178,6 +178,10 @@ public: // there is also the exception of wxMenuBar) virtual bool GTKNeedsParent() const { return !IsTopLevel(); } + // This is called when capture is taken from the window. It will + // fire off capture lost events. + void GTKReleaseMouseAndNotify(); + protected: // Override GTKWidgetNeedsMnemonic and return true if your // needs to set its mnemonic widget, such as for a diff --git a/src/gtk/dialog.cpp b/src/gtk/dialog.cpp index 63c13c0c98..056a469fea 100644 --- a/src/gtk/dialog.cpp +++ b/src/gtk/dialog.cpp @@ -112,6 +112,13 @@ int wxDialog::ShowModal() return GetReturnCode(); } + // release the mouse if it's currently captured as the window having it + // will be disabled when this dialog is shown -- but will still keep the + // capture making it impossible to do anything in the modal dialog itself + wxWindow * const win = wxWindow::GetCapture(); + if ( win ) + win->GTKReleaseMouseAndNotify(); + // use the apps top level window as parent if none given unless explicitly // forbidden if ( !GetParent() && !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT) ) diff --git a/src/gtk/msgdlg.cpp b/src/gtk/msgdlg.cpp index 267d54db07..7202ba2a32 100644 --- a/src/gtk/msgdlg.cpp +++ b/src/gtk/msgdlg.cpp @@ -137,6 +137,12 @@ void wxMessageDialog::GTKCreateMsgDialog() int wxMessageDialog::ShowModal() { + // break the mouse capture as it would interfere with modal dialog (see + // wxDialog::ShowModal) + wxWindow * const win = wxWindow::GetCapture(); + if ( win ) + win->GTKReleaseMouseAndNotify(); + if ( !m_widget ) { GTKCreateMsgDialog(); diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index a113e7105f..0d6438904b 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -2107,6 +2107,25 @@ void gtk_window_size_callback( GtkWidget *WXUNUSED(widget), } } +//----------------------------------------------------------------------------- +// "grab_broken" +//----------------------------------------------------------------------------- + +static void +gtk_window_grab_broken( GtkWidget *m_widget, + GdkEventGrabBroken *event, + wxWindow *win ) +{ + // Mouse capture has been lost involuntarily, notify the application + if( !event->keyboard && win && wxWindow::GetCapture() == win ) + { + wxMouseCaptureLostEvent evt( win->GetId() ); + evt.SetEventObject( win ); + win->GetEventHandler()->ProcessEvent( evt ); + } +} + + } // extern "C" // ---------------------------------------------------------------------------- @@ -2521,6 +2540,16 @@ void wxWindowGTK::PostCreation() // Catch native resize events g_signal_connect (m_wxwindow, "size_allocate", G_CALLBACK (gtk_window_size_callback), this); + // Make sure we can notify the app when mouse capture is lost + g_signal_connect (m_wxwindow, "grab_broken_event", + G_CALLBACK (gtk_window_grab_broken), this); + } + + if ( connect_widget != m_wxwindow ) + { + // Make sure we can notify app code when mouse capture is lost + g_signal_connect (connect_widget, "grab_broken_event", + G_CALLBACK (gtk_window_grab_broken), this); } #if wxUSE_COMBOBOX @@ -4069,6 +4098,14 @@ void wxWindowGTK::DoReleaseMouse() gdk_pointer_ungrab ( (guint32)GDK_CURRENT_TIME ); } +void wxWindowGTK::GTKReleaseMouseAndNotify() +{ + DoReleaseMouse(); + wxMouseCaptureLostEvent evt(GetId()); + evt.SetEventObject( this ); + GetEventHandler()->ProcessEvent( evt ); +} + /* static */ wxWindow *wxWindowBase::GetCapture() {