From 8f9850dd777bea1b661d9a0aa94c1fa42e05bbfd Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Tue, 14 Nov 2006 21:19:52 +0000 Subject: [PATCH] Fix X server hang in DND. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@43422 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/gtk/dnd.cpp | 43 +++++++------------------------------------ src/gtk/window.cpp | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 36 deletions(-) diff --git a/src/gtk/dnd.cpp b/src/gtk/dnd.cpp index 6ef44f891a..6424b24ee5 100644 --- a/src/gtk/dnd.cpp +++ b/src/gtk/dnd.cpp @@ -44,6 +44,10 @@ static long gs_flagsForDrag = 0; // (there are quite a few of them, so don't enable this by default) static const wxChar *TRACE_DND = _T("dnd"); +extern GdkEvent *g_lastMouseEvent; + +extern int g_lastButtonNumber; + //---------------------------------------------------------------------------- // standard icons //---------------------------------------------------------------------------- @@ -851,29 +855,8 @@ wxDragResult wxDropSource::DoDragDrop(int flags) } delete[] array; - GdkEventMotion event; - event.window = m_widget->window; - int x = 0; - int y = 0; - GdkModifierType state; - gdk_window_get_pointer( event.window, &x, &y, &state ); - event.x = x; - event.y = y; - event.state = state; - event.time = (guint32)GDK_CURRENT_TIME; - - /* GTK wants to know which button was pressed which caused the dragging */ - int button_number = 0; - if (event.state & GDK_BUTTON1_MASK) button_number = 1; - else if (event.state & GDK_BUTTON2_MASK) button_number = 2; - else if (event.state & GDK_BUTTON3_MASK) button_number = 3; - -#if wxUSE_THREADS - /* disable GUI threads */ -#endif - /* don't start dragging if no button is down */ - if (button_number) + if (g_lastButtonNumber) { int action = GDK_ACTION_COPY; if ( flags & wxDrag_AllowMove ) @@ -887,8 +870,8 @@ wxDragResult wxDropSource::DoDragDrop(int flags) GdkDragContext *context = gtk_drag_begin( m_widget, target_list, (GdkDragAction)action, - button_number, /* number of mouse button which started drag */ - (GdkEvent*) &event ); + g_lastButtonNumber, // number of mouse button which started drag + (GdkEvent*) g_lastMouseEvent ); m_dragContext = context; @@ -902,22 +885,10 @@ wxDragResult wxDropSource::DoDragDrop(int flags) m_retValue = wxDragCancel; } -#if wxUSE_THREADS - /* re-enable GUI threads */ -#endif - g_blockEventsOnDrag = false; UnregisterWindow(); - // this shouldn't be needed but somehow, sometimes, without this the cursor - // stays grabbed even when the DND operation ends and the application - // becomes unresponsive and has to be killed resulting in loss of all - // unsaved data, so while this fix is ugly it's still better than - // alternative - if ( gdk_pointer_is_grabbed() ) - gdk_pointer_ungrab(GDK_CURRENT_TIME); - return m_retValue; } diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 6ed4187eba..a772737691 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -210,6 +210,10 @@ wxWindowGTK *g_focusWindowLast = (wxWindowGTK*) NULL; // yet, defer setting the focus to idle time. wxWindowGTK *g_delayedFocus = (wxWindowGTK*) NULL; +// Save the last mouse event for drag start +GdkEvent *g_lastMouseEvent = (GdkEvent*) NULL; +int g_lastButtonNumber = 0; + extern bool g_mainThreadLocked; //----------------------------------------------------------------------------- @@ -1462,6 +1466,8 @@ gtk_window_button_press_callback( GtkWidget *widget, { wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win); + g_lastButtonNumber = gdk_event->button; + if (win->m_wxwindow && (g_focusWindow != win) && win->AcceptsFocus()) { gtk_widget_grab_focus( win->m_wxwindow ); @@ -1578,6 +1584,8 @@ gtk_window_button_press_callback( GtkWidget *widget, return FALSE; } + g_lastMouseEvent = (GdkEvent*) gdk_event; + wxMouseEvent event( event_type ); InitMouseEvent( win, event, gdk_event ); @@ -1633,6 +1641,8 @@ gtk_window_button_release_callback( GtkWidget *widget, { wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win); + g_lastButtonNumber = 0; + wxEventType event_type = wxEVT_NULL; switch (gdk_event->button) @@ -1654,6 +1664,8 @@ gtk_window_button_release_callback( GtkWidget *widget, return FALSE; } + g_lastMouseEvent = (GdkEvent*) gdk_event; + wxMouseEvent event( event_type ); InitMouseEvent( win, event, gdk_event ); @@ -1693,6 +1705,8 @@ gtk_window_motion_notify_callback( GtkWidget *widget, gdk_event->y = y; } + g_lastMouseEvent = (GdkEvent*) gdk_event; + wxMouseEvent event( wxEVT_MOTION ); InitMouseEvent(win, event, gdk_event);