Various DND patches

Crispin Flowerday <[email protected]>
Newsgroups gmane.comp.web.galeon.devel
Message-ID <1058910011.14565.56.camel@drno>
Amongst other things recently I have been doing a bit of dnd work.

The attached patches enable the following things for dnd:

 - dropping onto tabs labels
 - dropping into the space to the right of the tab labels
 - dropping onto the bookmark folders
 - dragging from bookmarks

I could not work out how to allow dropping onto the bookmark toolbar. I
blame that on bonobo (roll on eggtoolbar)

The galeon_dnd helper diff is needed for both of the others. 

The change to the gul_notebook also changes some of the signals emitted.
The dropped signal is removed while adding 'tab_removed' 'tab_added' and
'tab_reordered'. These cover the dropped case while being slightly more
generic (the dnd hooks onto tab_added for adding the drag signals). We
will be able to use these signals to build a proper tab menu as well.

Cheers
-- 
Crispin

http://patches.theflowerdays.com
galeon_bookmark_dnd.diff (text/plain, 6.5 KB)
--- bookmarks/Makefile.am.~1.35.~	2003-02-14 18:58:04.000000000 +0000
+++ bookmarks/Makefile.am	2003-07-16 21:48:20.000000000 +0100
@@ -92,7 +92,9 @@
 	bookmarks-icon-provider.h \
 	bookmarks-icon-provider.c \
 	bookmarks-default-icon-provider.h \
-	bookmarks-default-icon-provider.c
+	bookmarks-default-icon-provider.c \
+	bookmarks-dnd.h \
+	bookmarks-dnd.c
 
 testbookmarks_SOURCES= \
 	testbookmarks.c
--- bookmarks/bookmarks-gtk-menu-item.c.~1.6.~	2003-01-01 21:48:27.000000000 +0000
+++ bookmarks/bookmarks-gtk-menu-item.c	2003-07-16 21:57:55.000000000 +0100
@@ -26,6 +26,7 @@
 #include "galeon-marshal.h"
 #include "gul-string.h"
 #include "bookmarks-context-menu.h"
+#include "bookmarks-dnd.h"
 
 #include <libgnome/gnome-i18n.h>
 #include <gtk/gtkimage.h>
@@ -149,6 +150,8 @@
 	{
 		g_signal_connect (ret, "button_press_event", 
 				  G_CALLBACK (gb_gtk_menu_item_button_press_cb), NULL);
+
+		gb_bookmark_dnd_drag_source_set (ret, bookmark);
 	}
 
 	gb_gtk_menu_item_rebuild (ret);
--- bookmarks/bookmarks-tb-widget.c.~1.7.~	2003-06-22 12:31:26.000000000 +0100
+++ bookmarks/bookmarks-tb-widget.c	2003-07-19 00:08:11.000000000 +0100
@@ -22,6 +22,7 @@
 
 #include "bookmarks-tb-widget.h"
 #include "bookmarks-context-menu.h"
+#include "bookmarks-dnd.h"
 #include "galeon-marshal.h"
 #include "gul-gobject-misc.h"
 
@@ -237,6 +238,13 @@
 			  G_CALLBACK (gb_tb_widget_popup_menu_cb), gtw);
 	g_signal_connect (w, "button_press_event",
 			  G_CALLBACK (gb_tb_widget_button_press_cb), gtw);
+	if (GB_IS_SITE(gtw->priv->bm)) {
+		gb_bookmark_dnd_drag_source_set (w, gtw->priv->bm);
+	} 
+	else if (GB_IS_FOLDER(gtw->priv->bm))
+	{
+		gb_bookmark_dnd_drag_dest_set (w, gtw->priv->bm);
+	}
 }
 
 static void
--- bookmarks/bookmarks-dnd.c	2003-07-20 21:33:28.000000000 +0100
+++ bookmarks/bookmarks-dnd.c	2003-07-16 23:14:23.000000000 +0100
@@ -0,0 +1,130 @@
+/*
+ *  Copyright (C) 2003 Crispin Flowerday
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "bookmarks.h"
+#include "bookmarks-dnd.h"
+#include "galeon-dnd.h"
+
+/**
+ * Private functions, only availble from this file
+ */
+
+static void   gb_bookmark_drag_data_get_cb (GtkWidget *widget,
+                                            GdkDragContext *context,
+                                            GtkSelectionData *selection_data,
+                                            guint info,
+                                            guint32 time,
+                                            GbBookmark *bm);
+
+static void   gb_bookmark_drag_data_received_cb (GtkWidget *widget,
+						 GdkDragContext *dc,
+						 gint x, gint y,
+						 GtkSelectionData *selection_data,
+						 guint info,
+						 guint t,
+						 GbBookmark *bm);
+
+
+static void
+each_url_get_data_binder (GaleonDragEachSelectedItemDataGet iteratee, 
+        		  gpointer iterator_context, gpointer data)
+{
+	GbBookmark *bm = GB_BOOKMARK(iterator_context);
+	const gchar *url = GB_IS_SITE (bm) ? GB_SITE (bm)->url : NULL;
+
+	if ( url ) 
+		iteratee (url, -1, -1, -1, -1, data);
+}
+
+
+static void
+gb_bookmark_drag_data_get_cb (GtkWidget *widget,
+			      GdkDragContext *context,
+			      GtkSelectionData *selection_data,
+			      guint info,
+			      guint32 time,
+			      GbBookmark *bm)
+{
+        g_assert (widget != NULL);
+        g_return_if_fail (context != NULL);
+
+        galeon_dnd_drag_data_get (widget, context, selection_data,
+                info, time, bm, each_url_get_data_binder);
+}
+
+
+static void
+each_url_receive_data_binder (const char * url, const char * title, gpointer context)
+{
+	GbBookmark *bm = GB_BOOKMARK(context);
+	GbSite *niu;
+
+	g_return_if_fail (GB_IS_FOLDER (bm));
+
+	if (!title) title = url;
+
+	niu = gb_site_new (bm->set, title, url);
+
+	gb_folder_add_child (GB_FOLDER (bm), GB_BOOKMARK (niu), -1);
+	g_object_unref (niu);
+}
+
+
+
+static void
+gb_bookmark_drag_data_received_cb (GtkWidget *widget,
+				   GdkDragContext *dc,
+				   gint x, gint y,
+				   GtkSelectionData *selection_data,
+				   guint info,
+				   guint t,
+				   GbBookmark *bm)
+{
+	galeon_dnd_drag_data_receive( widget, dc, x, y, selection_data,
+			info, t, bm, each_url_receive_data_binder);
+}
+
+
+
+void
+gb_bookmark_dnd_drag_source_set (GtkWidget *widget, GbBookmark *bm)
+{
+	if (GB_IS_SITE(bm)) {
+		galeon_dnd_url_drag_source_set (widget);
+
+		g_signal_connect (G_OBJECT (widget),
+				  "drag_data_get",
+				  G_CALLBACK (gb_bookmark_drag_data_get_cb),
+				  bm);
+	}
+}
+
+
+
+void
+gb_bookmark_dnd_drag_dest_set (GtkWidget *widget, GbBookmark *bm)
+{
+	if (GB_IS_FOLDER(bm)) {
+		galeon_dnd_url_drag_dest_set (widget);
+
+		g_signal_connect (G_OBJECT (widget),
+				  "drag_data_received",
+				  G_CALLBACK (gb_bookmark_drag_data_received_cb),
+				  bm);
+	}
+}
--- bookmarks/bookmarks-dnd.h	2003-07-20 21:33:28.000000000 +0100
+++ bookmarks/bookmarks-dnd.h	2003-07-16 22:36:27.000000000 +0100
@@ -0,0 +1,31 @@
+/*
+ *  Copyright (C) 2003 Crispin Flowerday
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __bookmarks_dnd_h
+#define __bookmarks_dnd_h
+
+G_BEGIN_DECLS
+
+void gb_bookmark_dnd_drag_source_set (GtkWidget *widget, GbBookmark *bm);
+
+void gb_bookmark_dnd_drag_dest_set   (GtkWidget *widget, GbBookmark *bm);
+
+G_END_DECLS
+
+
+#endif
galeon_dnd_helper.diff (text/x-patch, 4.3 KB)
Index: utils/galeon-dnd.c
===================================================================
RCS file: /cvs/gnome/galeon/utils/galeon-dnd.c,v
retrieving revision 1.2
diff -u -r1.2 galeon-dnd.c
--- utils/galeon-dnd.c	27 Jun 2002 12:54:02 -0000	1.2
+++ utils/galeon-dnd.c	22 Jul 2003 20:40:44 -0000
@@ -20,6 +20,8 @@
 
 #include <gtk/gtkselection.h>
 
+#include <string.h>
+
 static GtkTargetEntry url_drag_types [] = 
 {
         { GALEON_DND_URI_LIST_TYPE,   0, GALEON_DND_URI_LIST },
@@ -27,6 +29,13 @@
         { GALEON_DND_URL_TYPE,        0, GALEON_DND_URL }
 };
 
+
+const GtkTargetEntry url_drop_types[] =
+{
+        { GALEON_DND_URI_LIST_TYPE,   0, GALEON_DND_URI_LIST },
+        { GALEON_DND_URL_TYPE,        0, GALEON_DND_URL }
+};
+
 /* Encode a "_NETSCAPE_URL_" selection.
  * As far as I can tell, Netscape is expecting a single
  * URL to be returned.  I cannot discover a way to construct
@@ -97,4 +106,81 @@
 			     url_drag_types,
 			     G_N_ELEMENTS (url_drag_types),
                              GDK_ACTION_COPY);
+}
+
+
+gboolean
+galeon_dnd_drag_data_receive (GtkWidget *widget,
+			      GdkDragContext *context,
+			      gint x,
+			      gint y,
+			      GtkSelectionData *selection_data,
+			      guint info,
+			      guint32 time,
+			      gpointer container_context,
+			      GaleonDragEachReceivedItemIterator each_received_item_iterator)
+{
+	char * data = selection_data->data;
+
+	g_signal_stop_emission_by_name (widget, "drag_data_received");
+
+        switch (info) {
+        case GALEON_DND_URI_LIST: {
+		gchar** split = g_strsplit(selection_data->data, "\n", 0);
+		int i;
+		for (i = 0 ; split[i] ; i++) {
+			gchar *url = split[i];
+			int len = strlen( url );
+			if ( len && url[len-1] == '\r' ) 
+			{
+				len--;
+				url[len] = 0;
+			}
+			if (!len) continue;
+
+			(* each_received_item_iterator) (url, 0, container_context);
+		}
+		g_strfreev (split);
+                break;
+	}
+        case GALEON_DND_URL: {
+		/* Mozilla passes the page title as the second line */
+		gchar** split = g_strsplit(data, "\n", 2);
+		if ( split )
+		{
+			(* each_received_item_iterator) (split[0], split[1], container_context);
+			g_strfreev (split);
+		}
+		else
+		{
+			(* each_received_item_iterator) (data, 0, container_context);
+		}
+                break;
+	}
+                
+        default:
+		return FALSE;
+        }
+	return TRUE;
+}
+
+
+void
+galeon_dnd_url_drag_dest_set (GtkWidget *widget)
+{
+	gtk_drag_dest_set (widget, 
+			   GTK_DEST_DEFAULT_ALL,
+			   url_drop_types,
+			   G_N_ELEMENTS (url_drop_types),
+			   GDK_ACTION_COPY);
+}
+
+void
+galeon_dnd_url_drag_dest_set_with_flags (GtkWidget *widget, GtkDestDefaults flags)
+{
+	gtk_drag_dest_set (widget, 
+			   flags,
+			   url_drop_types,
+			   G_N_ELEMENTS (url_drop_types),
+			   GDK_ACTION_COPY);
 }
Index: utils/galeon-dnd.h
===================================================================
RCS file: /cvs/gnome/galeon/utils/galeon-dnd.h,v
retrieving revision 1.2
diff -u -r1.2 galeon-dnd.h
--- utils/galeon-dnd.h	27 Jun 2002 12:54:02 -0000	1.2
+++ utils/galeon-dnd.h	22 Jul 2003 20:40:44 -0000
@@ -44,6 +44,9 @@
                                                      gpointer iterator_context, 
                                                      gpointer data);
 
+typedef void (* GaleonDragEachReceivedItemIterator) (const char * url, const char * title,
+                                                     gpointer data);
+
 gboolean galeon_dnd_drag_data_get 		(GtkWidget *widget,
                                     		 GdkDragContext *context,
                                     		 GtkSelectionData *selection_data,
@@ -54,5 +57,21 @@
 
 void     galeon_dnd_url_drag_source_set 	(GtkWidget *widget); 
 
+
+gboolean galeon_dnd_drag_data_receive 		(GtkWidget *widget,
+                                    		 GdkDragContext *context,
+						 gint x,
+						 gint y,
+                                    		 GtkSelectionData *selection_data,
+                                    		 guint info,
+                                    		 guint32 time,
+                                    		 gpointer container_context,
+                                    		 GaleonDragEachReceivedItemIterator each_received_item_iterator);
+
+
+
+void	 galeon_dnd_url_drag_dest_set		(GtkWidget *widget);
+
+void	 galeon_dnd_url_drag_dest_set_with_flags (GtkWidget *widget, GtkDestDefaults flags);
 
 G_END_DECLS
galeon_tab_dnd.diff (text/x-patch, 8.3 KB)
Index: utils/gul-notebook.c
===================================================================
RCS file: /cvs/gnome/galeon/utils/gul-notebook.c,v
retrieving revision 1.26
diff -u -r1.26 gul-notebook.c
--- utils/gul-notebook.c	22 Jul 2003 12:19:26 -0000	1.26
+++ utils/gul-notebook.c	22 Jul 2003 20:42:30 -0000
@@ -76,7 +76,9 @@
 /* Signals */
 enum
 {
-	TAB_DROPPED,
+	TAB_ADDED,
+	TAB_REMOVED,
+	TABS_REORDERED,
 	TAB_DETACHED,
 	LAST_SIGNAL
 };
@@ -118,19 +120,26 @@
 	object_class->finalize = gul_notebook_finalize;
 
 	/* init signals */
-	gul_notebook_signals[TAB_DROPPED] =
-		g_signal_new ("tab_dropped",
+	gul_notebook_signals[TAB_ADDED] =
+		g_signal_new ("tab_added",
 			      G_OBJECT_CLASS_TYPE (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (GulNotebookClass, 
-					       tab_dropped),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (GulNotebookClass, tab_added),
 			      NULL, NULL,
-			      galeon_marshal_VOID__OBJECT_OBJECT_INT,
+			      galeon_marshal_VOID__OBJECT,
 			      G_TYPE_NONE,
-			      3, 
-			      GTK_TYPE_WIDGET,
-			      GUL_NOTEBOOK_TYPE,
-			      G_TYPE_INT);
+			      1,
+			      GTK_TYPE_WIDGET);
+	gul_notebook_signals[TAB_REMOVED] =
+		g_signal_new ("tab_removed",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (GulNotebookClass, tab_removed),
+			      NULL, NULL,
+			      galeon_marshal_VOID__OBJECT,
+			      G_TYPE_NONE,
+			      1,
+			      GTK_TYPE_WIDGET);
 	gul_notebook_signals[TAB_DETACHED] =
 		g_signal_new ("tab_detached",
 			      G_OBJECT_CLASS_TYPE (object_class),
@@ -144,6 +153,16 @@
 			      G_TYPE_INT,
 			      G_TYPE_INT,
 			      G_TYPE_INT);
+	gul_notebook_signals[TABS_REORDERED] =
+		g_signal_new ("tabs_reordered",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (GulNotebookClass, tabs_reordered),
+			      NULL, NULL,
+			      galeon_marshal_VOID__VOID,
+			      G_TYPE_NONE,
+			      0);
+
 
 }
 
@@ -327,6 +346,18 @@
 gul_notebook_move_page (GulNotebook *src, GulNotebook *dest, 
 			GtkWidget *src_page,  gint dest_page)
 {
+	if (dest == NULL || src == dest)
+	{
+		gtk_notebook_reorder_child (GTK_NOTEBOOK (src), src_page, dest_page);
+		
+		if (src->priv->drag_in_progress == FALSE)
+		{
+			g_signal_emit (G_OBJECT (src), 
+				       gul_notebook_signals[TABS_REORDERED], 0);
+		}
+		return;
+	}
+
 	GtkWidget *tab_label;
 	GtkWidget *menu_label;
 
@@ -464,16 +495,6 @@
 				       cur_page_num, (gint)event->x_root, 
 				       (gint)event->y_root);
 		}
-		else
-		{
-			/* Tab was dragged and dropped (but it may have stayed
-			   in the same place) */
-			g_signal_emit (G_OBJECT(notebook), 
-				       gul_notebook_signals[TAB_DROPPED], 0,
-				       cur_page, 
-				       notebook->priv->src_notebook, 
-				       notebook->priv->src_page);
-		}
 
 		/* ungrab the pointer if it's grabbed */
 		if (gdk_pointer_is_grabbed ())
@@ -799,6 +820,9 @@
 		g_object_set_data (G_OBJECT (child), "jump_to", 
 				   GINT_TO_POINTER (jump_to));
 	}
+
+	g_signal_emit (G_OBJECT (nb), gul_notebook_signals[TAB_ADDED], 
+		       0, child);
 }
 
 static void
@@ -862,9 +886,20 @@
 		smart_tab_switching_on_closure (nb, child);
 	}
 	
+	/**
+	 * we ref the child so that it's still alive while the tabs_removed
+	 * signal is processed.
+	 */
+	g_object_ref (child);
+
 	gtk_notebook_remove_page (GTK_NOTEBOOK (nb), position);
 
 	update_tabs_visibility (nb, FALSE);
+
+	g_signal_emit (G_OBJECT (nb), gul_notebook_signals[TAB_REMOVED], 
+		       0, child);
+
+	g_object_unref (child);
 }
 
 void
Index: utils/gul-notebook.h
===================================================================
RCS file: /cvs/gnome/galeon/utils/gul-notebook.h,v
retrieving revision 1.8
diff -u -r1.8 gul-notebook.h
--- utils/gul-notebook.h	6 Feb 2003 16:24:38 -0000	1.8
+++ utils/gul-notebook.h	22 Jul 2003 20:42:30 -0000
@@ -52,11 +52,15 @@
         GtkNotebookClass parent_class;
 
 	/* Signals */
-	void (* tab_dropped)       (GulNotebook *dest,
-				    GtkWidget *widget,
-				    GulNotebook *src,
-				    gint src_page);
-	void (* tab_detached)      (GulNotebook *dest,
+	void (* tab_added)	   (GulNotebook *notebook,
+				    GtkWidget *child);
+
+	void (* tab_removed)	   (GulNotebook *notebook,
+				    GtkWidget *child);
+
+	void (* tabs_reordered)	   (GulNotebook *notebook);
+
+	void (* tab_detached)	   (GulNotebook *dest,
 				    gint cur_page,
 				    gint root_x, gint root_y);
 
Index: src/galeon-window.c
===================================================================
RCS file: /cvs/gnome/galeon/src/galeon-window.c,v
retrieving revision 1.173
diff -u -r1.173 galeon-window.c
--- src/galeon-window.c	12 Jul 2003 17:51:46 -0000	1.173
+++ src/galeon-window.c	22 Jul 2003 20:42:31 -0000
@@ -22,6 +22,7 @@
 
 #include "galeon-window.h"
 #include "galeon-sidebar.h"
+#include "galeon-dnd.h"
 #include "gul-state.h"
 #include "gul-gobject-misc.h"
 #include "gul-notebook.h"
@@ -227,9 +232,18 @@
 				     GbBookmarkEventActivated *ev,
 				     GaleonWindow *w);
 
+static void
+galeon_window_tab_detached_cb (GulNotebook *notebook, gint page, 
+			       gint x, gint y, GaleonWindow *window);
+
+static void             
+galeon_window_tab_drag_data_received_cb (GtkWidget* widget, GdkDragContext *context,
+					 gint x, gint y, GtkSelectionData *selection_data,
+					 guint info, guint time, GtkWidget *child);
+
 static void             
-galeon_window_tab_detached_cb    (GulNotebook *notebook, gint page,
-				  gint x, gint y, GaleonWindow *window);
+galeon_window_tab_added_cb  (GulNotebook *notebook, GtkWidget* child, 
+			     GaleonWindow *window);
 
 void /* yes, this is not static */
 galeon_window_bookmark_activate (GaleonWindow *w, GbBookmarkEventActivated *ev);
@@ -499,6 +513,18 @@
 			  G_CALLBACK (galeon_window_tab_detached_cb), 
 			  window);
 
+	g_signal_connect (G_OBJECT (notebook), "tab_added", 
+			  G_CALLBACK (galeon_window_tab_added_cb), 
+			  window);
+
+	galeon_dnd_url_drag_dest_set_with_flags( GTK_WIDGET(notebook),
+						 GTK_DEST_DEFAULT_MOTION |
+						 GTK_DEST_DEFAULT_DROP);
+
+	g_signal_connect (G_OBJECT(notebook), "drag_data_received",
+			  G_CALLBACK(galeon_window_tab_drag_data_received_cb),
+			  NULL);
+
 	eel_gconf_notification_add(CONF_TABS_TABBED_EDGE,
 				   (GConfClientNotifyFunc)tabbed_position_gconf_changed_cb,
 				   notebook);
@@ -2457,6 +2498,87 @@
 						GaleonWindow *w)
 {
 	galeon_window_load_url (w, url);
+}
+
+
+struct url_receive_context {
+	GaleonEmbed * embed;
+	GaleonWindow * window;
+	GaleonTab * tab;
+	int num;
+};
+
+static void
+each_url_receive_data_binder (const char * url, const char * title, 
+			      gpointer data )
+{
+	struct url_receive_context * context = (struct url_receive_context*)data;
+	GaleonEmbed * embed = context->embed;
+	int num = context->num++;
+
+	if (num == 0 && embed != NULL)
+	{
+		/**
+		 * The first url is special: if the drag was to an
+		 * existing tab, load it there
+		 */
+		galeon_embed_load_url (embed, url);
+	}
+	else
+	{
+		context->tab =
+			galeon_shell_new_tab (galeon_shell, context->window,
+					      context->tab, url,
+					      GALEON_NEW_TAB_IN_EXISTING_WINDOW |
+					      GALEON_NEW_TAB_APPEND);
+	}
+}
+
+
+static void
+galeon_window_tab_drag_data_received_cb(GtkWidget *widget,
+					GdkDragContext *dc,
+					gint x, gint y,
+					GtkSelectionData *selection_data,
+					guint info,
+					guint t,
+					GtkWidget * child)
+{
+	struct url_receive_context context;
+	GtkWidget * toplevel;
+	context.embed = child ? GALEON_EMBED( child ) : 0;
+	context.num = 0;
+
+	toplevel = gtk_widget_get_toplevel (widget);
+	g_return_if_fail (IS_GALEON_WINDOW (toplevel));
+	
+	context.window = GALEON_WINDOW (toplevel);
+
+	if (context.embed)
+	{
+		context.tab = GALEON_TAB (g_object_get_data (G_OBJECT (context.embed), 
+							     "GaleonTab"));
+	} 
+	else 
+	{
+		context.tab = 0;
+	}
+
+	galeon_dnd_drag_data_receive( widget, dc, x, y, selection_data,
+			 info, t, &context, each_url_receive_data_binder);
+}
+
+
+static void             
+galeon_window_tab_added_cb  (GulNotebook *notebook, GtkWidget *child, GaleonWindow *window)
+{
+	GtkWidget * label = gtk_notebook_get_tab_label( GTK_NOTEBOOK(notebook), child );
+
+	galeon_dnd_url_drag_dest_set( label );
+
+	g_signal_connect (G_OBJECT(label), "drag_data_received",
+			  G_CALLBACK(galeon_window_tab_drag_data_received_cb),
+			  child);
 }
 
 void
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.