]> git.saurik.com Git - wxWidgets.git/commitdiff
relinquish the mouse capture when a dialog is about to be made modal to ensure that...
authorVadim Zeitlin <vadim@wxwidgets.org>
Wed, 15 Aug 2007 21:01:30 +0000 (21:01 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Wed, 15 Aug 2007 21:01:30 +0000 (21:01 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@48121 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/gtk/window.h
src/gtk/dialog.cpp
src/gtk/msgdlg.cpp
src/gtk/window.cpp

index c28f5532c9b79c31464fed5d0d07df68d8f1b111..d5a4dd88abc7305566794e70090df5d72e9c074c 100644 (file)
@@ -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
index 63c13c0c98e22210d5ad4fb0ea1430c9a4dd1fdf..056a469fea74c21b83ddde63d15c10067115707a 100644 (file)
@@ -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) )
index 267d54db07a006af8ee616becad40b5f19172367..7202ba2a3249ba44c8857946c796fa18d5b84ff9 100644 (file)
@@ -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();
index a113e7105fddd884147f1c9246714768fafe6572..0d6438904bfc137ad2f279508e17f45c0736fdcc 100644 (file)
@@ -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()
 {