From 6b4d4954a4231209d261ced4ae0140ae11de6814 Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Mon, 15 Feb 2010 12:05:09 +0000 Subject: Make the ChatWindow handle dropping items itself Both GtkNotebook and EmpathChatWindow take action when drag-data-received is signalled (moving the tab or adding a contact). Drag data is received after the program has asked for it, usually when a drop occurs. Now this can be done in two ways 0) Handle the drop signal yourself and call gtk_drag_get_data yourself or 1) set GTK_DEST_DEFAULT_DROP and let gtk call it for you. GtkNotebook takes option 0, EmpathyChatWindow decided to use option 1.. This causes all kind of strange issues as the drag data is now requested twice and thus the signal handlers are called twice causing all kinds of fun issues (trying to move a tab that's already moved etc). Change the drag dest flags to GTK_DEST_DEFAULT_HIGHLIGHT which provides some extra visual clues but is other harmless and handle drops directly. Also remove some cases where ChatWindow meddles with tab dragging as GtkNotebook will handle these for us --- src/empathy-chat-window.c | 51 ++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/empathy-chat-window.c b/src/empathy-chat-window.c index 2b2d70718..7531cb840 100644 --- a/src/empathy-chat-window.c +++ b/src/empathy-chat-window.c @@ -1530,6 +1530,28 @@ chat_window_focus_in_event_cb (GtkWidget *widget, return FALSE; } +static gboolean +chat_window_drag_drop (GtkWidget *widget, + GdkDragContext *context, + int x, + int y, + guint time_, + gpointer user_data) +{ + GdkAtom target, uri_target, contact_target; + + target = gtk_drag_dest_find_target (widget, context, NULL); + uri_target = gdk_atom_intern_static_string ("text/uri-list"); + contact_target = gdk_atom_intern_static_string ("text/contact-id"); + + if (target == uri_target || target == contact_target) { + gtk_drag_get_data (widget, context, target, time_); + return TRUE; + } + + return FALSE; +} + static gboolean chat_window_drag_motion (GtkWidget *widget, GdkDragContext *context, @@ -1587,9 +1609,7 @@ chat_window_drag_motion (GtkWidget *widget, return TRUE; } - /* Otherwise, it must be a notebook tab drag. Set to MOVE. */ - gdk_drag_status (context, GDK_ACTION_MOVE, time_); - return TRUE; + return FALSE; } static void @@ -1708,23 +1728,10 @@ chat_window_drag_data_received (GtkWidget *widget, EmpathyChatWindowPriv *priv; priv = GET_PRIV (window); - - if (old_window == window) { - DEBUG ("DND tab (within same window)"); - priv->dnd_same_window = TRUE; - gtk_drag_finish (context, TRUE, FALSE, time_); - return; - } - - priv->dnd_same_window = FALSE; + priv->dnd_same_window = (old_window == window); + DEBUG ("DND tab (within same window: %s)", + priv->dnd_same_window ? "Yes" : "No"); } - - /* We should return TRUE to remove the data when doing - * GDK_ACTION_MOVE, but we don't here otherwise it has - * weird consequences, and we handle that internally - * anyway with add_chat () and remove_chat (). - */ - gtk_drag_finish (context, TRUE, FALSE, time_); } else { DEBUG ("DND from unknown source"); gtk_drag_finish (context, FALSE, FALSE, time_); @@ -1921,7 +1928,7 @@ empathy_chat_window_init (EmpathyChatWindow *window) /* Set up drag and drop */ gtk_drag_dest_set (GTK_WIDGET (priv->notebook), - GTK_DEST_DEFAULT_ALL, + GTK_DEST_DEFAULT_HIGHLIGHT, drag_types_dest, G_N_ELEMENTS (drag_types_dest), GDK_ACTION_MOVE | GDK_ACTION_COPY); @@ -1935,6 +1942,10 @@ empathy_chat_window_init (EmpathyChatWindow *window) "drag-data-received", G_CALLBACK (chat_window_drag_data_received), window); + g_signal_connect (priv->notebook, + "drag-drop", + G_CALLBACK (chat_window_drag_drop), + window); chat_windows = g_list_prepend (chat_windows, window); -- cgit v1.2.3