[empathy] Make the ChatWindow handle dropping items itself



commit 6b4d4954a4231209d261ced4ae0140ae11de6814
Author: Sjoerd Simons <sjoerd simons collabora co uk>
Date:   Mon Feb 15 12:05:09 2010 +0000

    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 files changed, 31 insertions(+), 20 deletions(-)
---
diff --git a/src/empathy-chat-window.c b/src/empathy-chat-window.c
index 2b2d707..7531cb8 100644
--- a/src/empathy-chat-window.c
+++ b/src/empathy-chat-window.c
@@ -1531,6 +1531,28 @@ chat_window_focus_in_event_cb (GtkWidget        *widget,
 }
 
 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,
 			 int               x,
@@ -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);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]