Correctly detect cancelled drag-and-drop operations in wxGTK.

The status of the drop operation wasn't propagated back to the initiator of
drag and drop, so failing to drop data over a possibly accepting recipient
could result in wrong behaviour and even data loss.

Closes #15930.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@75745 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2014-01-30 19:40:35 +00:00
parent 98da482d7a
commit d0d22874c8
2 changed files with 18 additions and 0 deletions

View File

@ -33,6 +33,7 @@ All (GUI):
wxGTK:
- Support building wxGTK3 under Windows (Kolya Kosenko).
- Correctly detect cancelled drag-and-drop operations (Kinaou Hervé).
wxMSW:

View File

@ -311,6 +311,9 @@ static gboolean target_drag_drop( GtkWidget *widget,
{
wxLogTrace(TRACE_DND, wxT( "Drop target: OnDrop returned FALSE") );
// change drag and drop status if drop operation failed
gdk_drag_status( context, (GdkDragAction)0, time );
/* cancel the whole thing */
gtk_drag_finish( context,
FALSE, /* no success */
@ -365,6 +368,9 @@ static void target_drag_data_received( GtkWidget *WXUNUSED(widget),
if (gtk_selection_data_get_length(data) <= 0 || gtk_selection_data_get_format(data) != 8)
{
// change drag and drop status if drop operation failed
gdk_drag_status( context, (GdkDragAction)0, time );
/* negative data length and non 8-bit data format
qualifies for junk */
gtk_drag_finish (context, FALSE, FALSE, time);
@ -384,6 +390,9 @@ static void target_drag_data_received( GtkWidget *WXUNUSED(widget),
{
wxLogTrace(TRACE_DND, wxT( "Drop target: OnData returned true") );
// change drag and drop status if drop operation failed
gdk_drag_status( context, (GdkDragAction)0, time );
/* tell GTK that data transfer was successful */
gtk_drag_finish( context, TRUE, FALSE, time );
}
@ -880,6 +889,14 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
while (m_waiting)
gtk_main_iteration();
if ( m_retValue != wxDragCancel &&
m_retValue != wxDragError )
{
// if wxDropTarget::OnDrop has been processed and has succeeded
// check the return value of wxDropTarget::OnData
m_retValue = ConvertFromGTK( context->action );
}
g_signal_handlers_disconnect_by_func (m_iconWindow,
(gpointer) gtk_dnd_window_configure_callback, this);