From 69c7a8c405e511f5fde50bf13fe7286ef850891d Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Wed, 13 May 2015 10:13:49 -0700 Subject: [PATCH] backport mouse capture fixes 00cc023 and dc555a9 00cc023 "fix releasing mouse capture before showing modal dialog" dc555a9 "notify all windows in capture stack about capture lost, and empty the stack" closes #16647 --- src/gtk/dialog.cpp | 4 +--- src/gtk/msgdlg.cpp | 10 ++++------ src/gtk/utilsgtk.cpp | 9 +++++++++ src/gtk/window.cpp | 24 +++++++++++++++++------- 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/gtk/dialog.cpp b/src/gtk/dialog.cpp index c30d349e3f..b57b9b4992 100644 --- a/src/gtk/dialog.cpp +++ b/src/gtk/dialog.cpp @@ -136,9 +136,7 @@ int wxDialog::ShowModal() // 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(); + GTKReleaseMouseAndNotify(); wxWindow * const parent = GetParentForModalDialog(); if ( parent ) diff --git a/src/gtk/msgdlg.cpp b/src/gtk/msgdlg.cpp index 8bc0dae840..9ff9896732 100644 --- a/src/gtk/msgdlg.cpp +++ b/src/gtk/msgdlg.cpp @@ -277,12 +277,6 @@ int wxMessageDialog::ShowModal() { WX_HOOK_MODAL_DIALOG(); - // 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(); @@ -290,6 +284,10 @@ int wxMessageDialog::ShowModal() wxT("failed to create GtkMessageDialog") ); } + // break the mouse capture as it would interfere with modal dialog (see + // wxDialog::ShowModal) + GTKReleaseMouseAndNotify(); + // This should be necessary, but otherwise the // parent TLW will disappear.. if (m_parent) diff --git a/src/gtk/utilsgtk.cpp b/src/gtk/utilsgtk.cpp index 34a16108a3..27dc43d838 100644 --- a/src/gtk/utilsgtk.cpp +++ b/src/gtk/utilsgtk.cpp @@ -299,6 +299,15 @@ bool wxGUIAppTraits::ShowAssertDialog(const wxString& msg) GtkWidget *dialog = gtk_assert_dialog_new(); gtk_assert_dialog_set_message(GTK_ASSERT_DIALOG(dialog), msg.mb_str()); + GdkDisplay* display = gtk_widget_get_display(dialog); +#ifdef __WXGTK3__ + GdkDeviceManager* manager = gdk_display_get_device_manager(display); + GdkDevice* device = gdk_device_manager_get_client_pointer(manager); + gdk_device_ungrab(device, unsigned(GDK_CURRENT_TIME)); +#else + gdk_display_pointer_ungrab(display, unsigned(GDK_CURRENT_TIME)); +#endif + #if wxUSE_STACKWALKER // save the current stack ow... StackDump dump(GTK_ASSERT_DIALOG(dialog)); diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 1e28eed8e4..e290ad0bd0 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -2030,9 +2030,7 @@ gtk_window_grab_broken( GtkWidget*, // Mouse capture has been lost involuntarily, notify the application if(!event->keyboard && wxWindow::GetCapture() == win) { - wxMouseCaptureLostEvent evt( win->GetId() ); - evt.SetEventObject( win ); - win->HandleWindowEvent( evt ); + wxWindowGTK::GTKHandleCaptureLost(); } return false; } @@ -4799,10 +4797,22 @@ void wxWindowGTK::DoReleaseMouse() void wxWindowGTK::GTKReleaseMouseAndNotify() { - DoReleaseMouse(); - wxMouseCaptureLostEvent evt(GetId()); - evt.SetEventObject( this ); - HandleWindowEvent( evt ); + GdkDisplay* display = gtk_widget_get_display(m_widget); +#ifdef __WXGTK3__ + GdkDeviceManager* manager = gdk_display_get_device_manager(display); + GdkDevice* device = gdk_device_manager_get_client_pointer(manager); + gdk_device_ungrab(device, unsigned(GDK_CURRENT_TIME)); +#else + gdk_display_pointer_ungrab(display, unsigned(GDK_CURRENT_TIME)); +#endif + g_captureWindow = NULL; + NotifyCaptureLost(); +} + +void wxWindowGTK::GTKHandleCaptureLost() +{ + g_captureWindow = NULL; + NotifyCaptureLost(); } /* static */