Fix X server hang in DND.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@43422 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -44,6 +44,10 @@ static long gs_flagsForDrag = 0;
|
|||||||
// (there are quite a few of them, so don't enable this by default)
|
// (there are quite a few of them, so don't enable this by default)
|
||||||
static const wxChar *TRACE_DND = _T("dnd");
|
static const wxChar *TRACE_DND = _T("dnd");
|
||||||
|
|
||||||
|
extern GdkEvent *g_lastMouseEvent;
|
||||||
|
|
||||||
|
extern int g_lastButtonNumber;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// standard icons
|
// standard icons
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -851,29 +855,8 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
|
|||||||
}
|
}
|
||||||
delete[] array;
|
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 */
|
/* don't start dragging if no button is down */
|
||||||
if (button_number)
|
if (g_lastButtonNumber)
|
||||||
{
|
{
|
||||||
int action = GDK_ACTION_COPY;
|
int action = GDK_ACTION_COPY;
|
||||||
if ( flags & wxDrag_AllowMove )
|
if ( flags & wxDrag_AllowMove )
|
||||||
@@ -887,8 +870,8 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
|
|||||||
GdkDragContext *context = gtk_drag_begin( m_widget,
|
GdkDragContext *context = gtk_drag_begin( m_widget,
|
||||||
target_list,
|
target_list,
|
||||||
(GdkDragAction)action,
|
(GdkDragAction)action,
|
||||||
button_number, /* number of mouse button which started drag */
|
g_lastButtonNumber, // number of mouse button which started drag
|
||||||
(GdkEvent*) &event );
|
(GdkEvent*) g_lastMouseEvent );
|
||||||
|
|
||||||
m_dragContext = context;
|
m_dragContext = context;
|
||||||
|
|
||||||
@@ -902,22 +885,10 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
|
|||||||
m_retValue = wxDragCancel;
|
m_retValue = wxDragCancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if wxUSE_THREADS
|
|
||||||
/* re-enable GUI threads */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
g_blockEventsOnDrag = false;
|
g_blockEventsOnDrag = false;
|
||||||
|
|
||||||
UnregisterWindow();
|
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;
|
return m_retValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -210,6 +210,10 @@ wxWindowGTK *g_focusWindowLast = (wxWindowGTK*) NULL;
|
|||||||
// yet, defer setting the focus to idle time.
|
// yet, defer setting the focus to idle time.
|
||||||
wxWindowGTK *g_delayedFocus = (wxWindowGTK*) NULL;
|
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;
|
extern bool g_mainThreadLocked;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -1462,6 +1466,8 @@ gtk_window_button_press_callback( GtkWidget *widget,
|
|||||||
{
|
{
|
||||||
wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win);
|
wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win);
|
||||||
|
|
||||||
|
g_lastButtonNumber = gdk_event->button;
|
||||||
|
|
||||||
if (win->m_wxwindow && (g_focusWindow != win) && win->AcceptsFocus())
|
if (win->m_wxwindow && (g_focusWindow != win) && win->AcceptsFocus())
|
||||||
{
|
{
|
||||||
gtk_widget_grab_focus( win->m_wxwindow );
|
gtk_widget_grab_focus( win->m_wxwindow );
|
||||||
@@ -1578,6 +1584,8 @@ gtk_window_button_press_callback( GtkWidget *widget,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_lastMouseEvent = (GdkEvent*) gdk_event;
|
||||||
|
|
||||||
wxMouseEvent event( event_type );
|
wxMouseEvent event( event_type );
|
||||||
InitMouseEvent( win, event, gdk_event );
|
InitMouseEvent( win, event, gdk_event );
|
||||||
|
|
||||||
@@ -1633,6 +1641,8 @@ gtk_window_button_release_callback( GtkWidget *widget,
|
|||||||
{
|
{
|
||||||
wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win);
|
wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win);
|
||||||
|
|
||||||
|
g_lastButtonNumber = 0;
|
||||||
|
|
||||||
wxEventType event_type = wxEVT_NULL;
|
wxEventType event_type = wxEVT_NULL;
|
||||||
|
|
||||||
switch (gdk_event->button)
|
switch (gdk_event->button)
|
||||||
@@ -1654,6 +1664,8 @@ gtk_window_button_release_callback( GtkWidget *widget,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_lastMouseEvent = (GdkEvent*) gdk_event;
|
||||||
|
|
||||||
wxMouseEvent event( event_type );
|
wxMouseEvent event( event_type );
|
||||||
InitMouseEvent( win, event, gdk_event );
|
InitMouseEvent( win, event, gdk_event );
|
||||||
|
|
||||||
@@ -1693,6 +1705,8 @@ gtk_window_motion_notify_callback( GtkWidget *widget,
|
|||||||
gdk_event->y = y;
|
gdk_event->y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_lastMouseEvent = (GdkEvent*) gdk_event;
|
||||||
|
|
||||||
wxMouseEvent event( wxEVT_MOTION );
|
wxMouseEvent event( wxEVT_MOTION );
|
||||||
InitMouseEvent(win, event, gdk_event);
|
InitMouseEvent(win, event, gdk_event);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user