Sophie

Sophie

distrib > Mandriva > 2009.0 > i586 > by-pkgid > 4389d83fd783921d4c6e81f39d1a3a3a > files > 2

xfce4-panel-4.4.2-4mdv2009.0.src.rpm

diff -Naur xfce4-panel-4.4.2/ChangeLog xfce4-panel-4.4.2.tpg/ChangeLog
--- xfce4-panel-4.4.2/ChangeLog	2007-11-17 19:31:00.000000000 +0000
+++ xfce4-panel-4.4.2.tpg/ChangeLog	2008-05-19 13:32:25.000000000 +0000
@@ -1,3 +1,9 @@
+2008-03-09 19:02  nick
+
+	* Fix bug 3815 and a crash in FreeBSD-amd64. Quite a lot (if not all)
+	  dnd code changed. So give it some testing if you're using the
+	  4.4 branch.
+
 2007-11-17 17:47  kelnos
 
 	* docs/API/libxfce4panel-decl-list.txt,
diff -Naur xfce4-panel-4.4.2/NEWS xfce4-panel-4.4.2.tpg/NEWS
--- xfce4-panel-4.4.2/NEWS	2007-11-17 19:31:00.000000000 +0000
+++ xfce4-panel-4.4.2.tpg/NEWS	2008-05-19 13:32:25.000000000 +0000
@@ -1,3 +1,12 @@
+4.4.3
+=====
+- Quite a bit code changed in the dnd code. Mostly to fix segfaul in
+  FreeBSD-amd64, but more problems were discovered and a lot of code
+  was simplified and a memory leak was plugged.
+- Don't respond the uri drags, we don't use it and it only causes problems
+  like hiding the panel when a file was dragged over the panel (Bug #3815).
+
+
 4.4.2
 =====
 - Fix window manager hints reporting width 1 pixel too wide (bug #3402).
diff -Naur xfce4-panel-4.4.2/panel/panel-dialogs.c xfce4-panel-4.4.2.tpg/panel/panel-dialogs.c
--- xfce4-panel-4.4.2/panel/panel-dialogs.c	2007-11-17 19:30:59.000000000 +0000
+++ xfce4-panel-4.4.2.tpg/panel/panel-dialogs.c	2008-05-19 13:32:25.000000000 +0000
@@ -140,50 +140,60 @@
     return FALSE;
 }
 
+static XfcePanelItemInfo *
+get_selected_tree_item (PanelItemsDialog *pid)
+{
+    GtkTreeSelection  *selection;
+    GtkTreeModel      *model;
+    GtkTreeIter        iter;
+    XfcePanelItemInfo *info = NULL;
+    
+    /* get the tree selection */
+    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pid->tree));
+    if (G_LIKELY (selection))
+    {
+        /* get the selected item */
+        if (gtk_tree_selection_get_selected (selection, &model, &iter))
+            gtk_tree_model_get (model, &iter, 0, &info, -1);
+    }
+    
+    return info;
+}
+
 
 static gboolean
 add_selected_item (PanelItemsDialog *pid)
 {
-    GtkTreeSelection *sel;
-    GtkTreeModel *model;
-    GtkTreeIter iter;
     XfcePanelItemInfo *info;
-    GtkWidget *item = NULL;
+    GtkWidget         *item = NULL;
 
-    sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (pid->tree));
-    
-    if (!sel)
-        return FALSE;
-
-    if (!gtk_tree_selection_get_selected (sel, &model, &iter))
-        return FALSE;
-
-    gtk_tree_model_get (model, &iter, 0, &info, -1);
-
-    if (!xfce_panel_item_manager_is_available (info->name))
-        return FALSE;
-   
-    if (pid->active)
+    /* get the selected item */
+    info = get_selected_tree_item (pid);
+    if (G_LIKELY (info && xfce_panel_item_manager_is_available (info->name)))
     {
-        PanelPrivate *priv = PANEL_GET_PRIVATE (pid->panel);
-        int n;
+        if (pid->active)
+        {
+            PanelPrivate *priv = PANEL_GET_PRIVATE (pid->panel);
+            gint          n;
 
-        n = xfce_itembar_get_item_index (XFCE_ITEMBAR (priv->itembar),
-                                         pid->active);
+            n = xfce_itembar_get_item_index (XFCE_ITEMBAR (priv->itembar), pid->active);
 
-        item = panel_insert_item (pid->panel, info->name, n + 1);
-    }
-    else
-    {
-        item = panel_add_item (pid->panel, info->name);
-    }
+            item = panel_insert_item (pid->panel, info->name, n + 1);
+         }
+         else
+         {
+            item = panel_add_item (pid->panel, info->name);
+         }
 
-    if (item)
-        g_idle_add ((GSourceFunc)item_configure_timeout, item);
-    else
-        xfce_err (_("Could not open \"%s\" module"), info->name);
+        if (item)
+            g_idle_add ((GSourceFunc)item_configure_timeout, item);
+        else
+            xfce_err (_("Could not open \"%s\" module"), info->name);
     
-    return TRUE;
+        return TRUE;
+    }
+    
+    return FALSE;
 }
 
 static gboolean
@@ -191,31 +201,12 @@
                    PanelItemsDialog *pid)
 {
     if (evt->button == 1 && evt->type == GDK_2BUTTON_PRESS)
-    {
-	return add_selected_item (pid);
-    }
+        return add_selected_item (pid);
 
     return FALSE;
 }
 
 static void
-cursor_changed (GtkTreeView * tv, PanelItemsDialog *pid)
-{
-    GtkTreeSelection *sel;
-    GtkTreeModel *model;
-    GtkTreeIter iter;
-    XfcePanelItemInfo *info;
-
-    if (!(sel = gtk_tree_view_get_selection (tv)))
-        return;
-
-    if (!gtk_tree_selection_get_selected (sel, &model, &iter))
-        return;
-
-    gtk_tree_model_get (model, &iter, 0, &info, -1);
-}
-
-static void
 treeview_destroyed (GtkWidget * tv)
 {
     GtkTreeModel *store;
@@ -226,7 +217,7 @@
 
 static void
 render_icon (GtkTreeViewColumn * col, GtkCellRenderer * cell,
-	     GtkTreeModel * model, GtkTreeIter * iter, gpointer data)
+       GtkTreeModel * model, GtkTreeIter * iter, gpointer data)
 {
     XfcePanelItemInfo *info;
 
@@ -244,7 +235,7 @@
 
 static void
 render_text (GtkTreeViewColumn * col, GtkCellRenderer * cell,
-	     GtkTreeModel * model, GtkTreeIter * iter, GtkWidget * treeview)
+       GtkTreeModel * model, GtkTreeIter * iter, GtkWidget * treeview)
 {
     XfcePanelItemInfo *info;
 
@@ -279,66 +270,83 @@
 static void
 treeview_data_received (GtkWidget *widget, GdkDragContext *context, 
                         gint x, gint y, GtkSelectionData *data, 
-                        guint info, guint time, gpointer user_data)
+                        guint info, guint time, PanelItemsDialog *pid)
 {
-    gboolean handled = FALSE;
-
-    DBG (" + drag data received: %d", info);
+    gboolean   succeeded = FALSE;
+    GtkWidget *item;
     
-    if (data->length && info == TARGET_PLUGIN_WIDGET)
-        handled = TRUE;
-     
-    gtk_drag_finish (context, handled, handled, time);
+    /* get the drag source */
+    item = gtk_drag_get_source_widget (context);
+    
+    if (item && XFCE_IS_PANEL_ITEM (item))
+    {
+        /* ask to remove the item */
+        xfce_panel_item_remove (XFCE_PANEL_ITEM (item));
+        
+        succeeded = TRUE;
+    }
+
+    /* finish the drag */
+    gtk_drag_finish (context, succeeded, FALSE, time);
 }
 
 static gboolean
 treeview_drag_drop (GtkWidget *widget, GdkDragContext *context, 
-                    gint x, gint y, guint time, gpointer user_data)
+                    gint x, gint y, guint time, PanelItemsDialog *pid)
 {
-    GdkAtom atom = gtk_drag_dest_find_target (widget, context, NULL);
+    GdkAtom target = gtk_drag_dest_find_target (widget, context, NULL);
+    
+    /* we cannot handle the drag data */
+    if (G_UNLIKELY (target == GDK_NONE))
+        return FALSE;
 
-    if (atom != GDK_NONE)
-    {
-        gtk_drag_get_data (widget, context, atom, time);
-        return TRUE;
-    }
+    /* request the drag data */
+    gtk_drag_get_data (widget, context, target, time);
+  
+    /* we call gtk_drag_finish later */
+    return TRUE;
+}
 
-    return FALSE;
+static void
+treeview_drag_begin (GtkWidget *treeview, GdkDragContext *context, 
+                     PanelItemsDialog *pid)
+{
+    XfcePanelItemInfo *item_info;
+  
+    DBG (" + drag begin");
+    
+    /* set nice drag icon */
+    item_info = get_selected_tree_item (pid);
+    if (G_LIKELY (item_info && item_info->icon))
+        gtk_drag_set_icon_pixbuf (context, item_info->icon, 0, 0);
 }
 
 static void
 treeview_data_get (GtkWidget *widget, GdkDragContext *drag_context, 
                    GtkSelectionData *data, guint info, 
-                   guint time, gpointer user_data)
+                   guint time, PanelItemsDialog *pid)
 {
+    XfcePanelItemInfo *item_info;
+    const gchar       *item_name;
+    
     DBG (" + drag data get: %d", info);
     
-    if (info == TARGET_PLUGIN_NAME)
+    if (G_LIKELY (info == TARGET_PLUGIN_NAME))
     {
-        GtkTreeSelection *sel;
-        GtkTreeModel *model;
-        GtkTreeIter iter;
-        XfcePanelItemInfo *info;
-
-        sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
-
-        if (!sel)
+        /* get the selected item info */
+        item_info = get_selected_tree_item (pid);
+        if (G_LIKELY (item_info))
         {
-            DBG ("No selection!");
-            return;
+            item_name = item_info->name;
+            
+            if (xfce_panel_item_manager_is_available (item_name))
+            {
+                DBG (" + set selection data: %s", item_name);
+                
+                /* set the selection data */
+                gtk_selection_data_set (data, data->target, 8, (guchar *) item_name, strlen (item_name));
+            }
         }
-        
-        if (!gtk_tree_selection_get_selected (sel, &model, &iter))
-            return;
-
-        gtk_tree_model_get (model, &iter, 0, &info, -1);
-
-        if (!xfce_panel_item_manager_is_available (info->name))
-            return;
-       
-        DBG (" + set data: %s", info->name);
-        gtk_selection_data_set (data, data->target, 8, 
-                                (guchar *)info->name, strlen (info->name));
     }
 }
 
@@ -408,10 +416,10 @@
     scroll = gtk_scrolled_window_new (NULL, NULL);
     gtk_widget_show (scroll);
     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
-				    GTK_POLICY_NEVER, 
+            GTK_POLICY_NEVER, 
                                     GTK_POLICY_NEVER);
     gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll),
-					 GTK_SHADOW_IN);
+           GTK_SHADOW_IN);
     gtk_box_pack_start (GTK_BOX (pid->items_box), scroll, TRUE, TRUE, 0);
     
     store = gtk_list_store_new (1, G_TYPE_POINTER);
@@ -433,18 +441,13 @@
     g_object_unref (G_OBJECT (store));
 
     /* dnd */
-    panel_dnd_set_name_source (tv);
-
-    panel_dnd_set_widget_delete_dest (tv);
-
-    g_signal_connect (tv, "drag-data-get", G_CALLBACK (treeview_data_get), 
-                      pid);
+    panel_dnd_set_source_name (tv);
+    panel_dnd_set_dest_name_and_widget (tv);
 
-    g_signal_connect (tv, "drag-data-received", 
-                      G_CALLBACK (treeview_data_received), pid);
-    
-    g_signal_connect (tv, "drag-drop", 
-                      G_CALLBACK (treeview_drag_drop), pid);
+    g_signal_connect (tv, "drag-data-get", G_CALLBACK (treeview_data_get), pid);
+    g_signal_connect (tv, "drag-data-received", G_CALLBACK (treeview_data_received), pid);
+    g_signal_connect (tv, "drag-drop", G_CALLBACK (treeview_drag_drop), pid);
+    g_signal_connect (tv, "drag-begin", G_CALLBACK (treeview_drag_begin), pid);
     
     /* create the view */
     col = gtk_tree_view_column_new ();
@@ -454,14 +457,14 @@
     cell = gtk_cell_renderer_pixbuf_new ();
     gtk_tree_view_column_pack_start (col, cell, FALSE);
     gtk_tree_view_column_set_cell_data_func (col, cell,
-					     (GtkTreeCellDataFunc)
-					     render_icon, NULL, NULL);
+               (GtkTreeCellDataFunc)
+               render_icon, NULL, NULL);
 
     cell = gtk_cell_renderer_text_new ();
     gtk_tree_view_column_pack_start (col, cell, TRUE);
     gtk_tree_view_column_set_cell_data_func (col, cell,
-					     (GtkTreeCellDataFunc)
-					     render_text, tv, NULL);
+               (GtkTreeCellDataFunc)
+               render_text, tv, NULL);
 
     color = &(tv->style->fg[GTK_STATE_INSENSITIVE]);
     g_object_set (cell, "foreground-gdk", color, NULL);
@@ -481,16 +484,11 @@
                                             GTK_POLICY_ALWAYS);
         }    
 
-	gtk_list_store_append (store, &iter);
-	gtk_list_store_set (store, &iter, 0, 
-                            g_ptr_array_index (pid->items, i), -1);
+        gtk_list_store_append (store, &iter);
+        gtk_list_store_set (store, &iter, 0, g_ptr_array_index (pid->items, i), -1);
     }
 
-    g_signal_connect (tv, "cursor_changed", G_CALLBACK (cursor_changed),
-		      pid);
-
-    g_signal_connect (tv, "button-press-event",
-		      G_CALLBACK (treeview_dblclick), pid);
+    g_signal_connect (tv, "button-press-event", G_CALLBACK (treeview_dblclick), pid);
 
     path = gtk_tree_path_new_from_string ("0");
     gtk_tree_view_set_cursor (GTK_TREE_VIEW (tv), path, NULL, FALSE);
@@ -505,9 +503,6 @@
     panel_block_autohide (panel);
 
     xfce_itembar_raise_event_window (XFCE_ITEMBAR (priv->itembar));
-    
-    panel_dnd_set_dest (priv->itembar);
-    panel_dnd_set_widget_source (priv->itembar);
 
     panel_set_items_sensitive (panel, FALSE);
 
@@ -524,9 +519,6 @@
     xfce_itembar_lower_event_window (XFCE_ITEMBAR (priv->itembar));
 
     panel_set_items_sensitive (panel, TRUE);
-    
-    panel_dnd_unset_dest (priv->itembar);
-    panel_dnd_unset_source (priv->itembar);
 
     priv->edit_mode = FALSE;
 }
@@ -537,9 +529,7 @@
     if (response != GTK_RESPONSE_HELP)
     {
         if (response == GTK_RESPONSE_OK)
-        {
             add_selected_item (pid);
-        }
 
         items_dialog_widget = NULL;
         g_ptr_array_foreach (pid->panels, (GFunc)item_dialog_closed, NULL);
diff -Naur xfce4-panel-4.4.2/panel/panel-dnd.c xfce4-panel-4.4.2.tpg/panel/panel-dnd.c
--- xfce4-panel-4.4.2/panel/panel-dnd.c	2007-11-17 19:30:59.000000000 +0000
+++ xfce4-panel-4.4.2.tpg/panel/panel-dnd.c	2008-05-19 13:32:25.000000000 +0000
@@ -36,110 +36,72 @@
 static const GtkTargetEntry dest_target_list[] = 
 {
     { "application/x-xfce-panel-plugin-name", 0, TARGET_PLUGIN_NAME },
-    { "application/x-xfce-panel-plugin-widget", 
-      GTK_TARGET_SAME_APP, TARGET_PLUGIN_WIDGET },
-    { "text/plain", 0, TARGET_FILE },
-    { "text/uri-list", 0, TARGET_FILE },
-    { "UTF8_STRING", 0, TARGET_FILE }
+    { "application/x-xfce-panel-plugin-widget", GTK_TARGET_SAME_APP, TARGET_PLUGIN_WIDGET }
 };
 
-static const guint n_dest_targets = G_N_ELEMENTS (dest_target_list);
-
 static const GtkTargetEntry name_target_list[] = 
 {
     { "application/x-xfce-panel-plugin-name", 0, TARGET_PLUGIN_NAME }
 };
 
-static const guint n_name_targets = G_N_ELEMENTS (name_target_list);
-
 static const GtkTargetEntry widget_target_list[] = 
 {
-    { "application/x-xfce-panel-plugin-widget", 0, TARGET_PLUGIN_WIDGET }
+    { "application/x-xfce-panel-plugin-widget", GTK_TARGET_SAME_APP, TARGET_PLUGIN_WIDGET }
 };
 
-static guint n_widget_targets = G_N_ELEMENTS (widget_target_list);
-
 /* public API */
 
 void 
-panel_dnd_set_dest (GtkWidget *widget)
+panel_dnd_set_dest_name_and_widget (GtkWidget *widget)
 {
     gtk_drag_dest_set (widget, 
                        GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_MOTION,
-                       dest_target_list, n_dest_targets, GDK_ACTION_COPY);
+                       dest_target_list, G_N_ELEMENTS (dest_target_list),
+                       GDK_ACTION_MOVE | GDK_ACTION_COPY);
 }
 
 void 
-panel_dnd_set_widget_delete_dest (GtkWidget *widget)
+panel_dnd_set_dest_widget (GtkWidget *widget)
 {
     gtk_drag_dest_set (widget, 
                        GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_MOTION,
-                       widget_target_list, n_widget_targets, 
-                       GDK_ACTION_MOVE);
-}
-
-void 
-panel_dnd_unset_dest (GtkWidget *widget)
-{
-    gtk_drag_dest_unset (widget);
-}
-
-GtkWidget *
-panel_dnd_get_plugin_from_data (GtkSelectionData *data)
-{
-    glong *n;
-
-    n = (glong *)data->data;
-    DBG (" + get pointer: %ld", *n);
-    
-    return GTK_WIDGET (GINT_TO_POINTER (*n));
+                       widget_target_list, G_N_ELEMENTS (widget_target_list), GDK_ACTION_MOVE);
 }
 
 void 
-panel_dnd_set_name_source (GtkWidget *widget)
+panel_dnd_set_source_name (GtkWidget *widget)
 {
     gtk_drag_source_set (widget, GDK_BUTTON1_MASK, 
-                         name_target_list, n_name_targets, 
-                         GDK_ACTION_COPY);
+                         name_target_list, G_N_ELEMENTS (name_target_list), GDK_ACTION_COPY);
 }
 
 void 
-panel_dnd_set_widget_source (GtkWidget *widget)
+panel_dnd_set_source_widget (GtkWidget *widget)
 {
     gtk_drag_source_set (widget, GDK_BUTTON1_MASK, 
-                         widget_target_list, n_widget_targets, 
-                         GDK_ACTION_COPY|GDK_ACTION_MOVE);
-}
-
-void panel_dnd_unset_source (GtkWidget *widget)
-{
-    gtk_drag_source_unset (widget);
-}
-
-void
-panel_dnd_set_widget_data (GtkSelectionData *data, GtkWidget *widget)
-{
-    glong n = GPOINTER_TO_INT (widget);
-    
-    DBG (" + set pointer: %ld", n);
-    
-    gtk_selection_data_set (data, data->target, 32, (guchar *) &n, sizeof (n));
+                         widget_target_list, G_N_ELEMENTS (widget_target_list), GDK_ACTION_COPY);
 }
 
 void
 panel_dnd_begin_drag (GtkWidget *widget)
 {
-    static GtkTargetList *list = NULL;
-    GdkEvent *ev;
+    GtkTargetList *target_list ;
+    GdkEvent      *event;
     
-    if (G_UNLIKELY (list == NULL))
+    event = gtk_get_current_event();
+    if (G_LIKELY (event))
     {
-        list = gtk_target_list_new (widget_target_list, n_widget_targets);
-    }
+        /* create a new target list */
+        target_list = gtk_target_list_new (widget_target_list, G_N_ELEMENTS (widget_target_list));
+
+        /* begin the drag */
+        gtk_drag_begin (widget, target_list, GDK_ACTION_MOVE, 1, event);
     
-    ev = gtk_get_current_event();
-    gtk_drag_begin (widget, list, GDK_ACTION_COPY, 1, ev);
+        /* release the target list */
+        gtk_target_list_unref (target_list);
 
-    gdk_event_free (ev);
+        /* free the event */
+        gdk_event_free (event);
+    }
 }
 
diff -Naur xfce4-panel-4.4.2/panel/panel-dnd.h xfce4-panel-4.4.2.tpg/panel/panel-dnd.h
--- xfce4-panel-4.4.2/panel/panel-dnd.h	2007-11-17 19:30:59.000000000 +0000
+++ xfce4-panel-4.4.2.tpg/panel/panel-dnd.h	2008-05-19 13:32:25.000000000 +0000
@@ -27,26 +27,16 @@
 enum 
 {
     TARGET_PLUGIN_NAME,
-    TARGET_PLUGIN_WIDGET,
-    TARGET_FILE
+    TARGET_PLUGIN_WIDGET
 };
 
-void panel_dnd_set_dest (GtkWidget *widget);
+void panel_dnd_set_dest_name_and_widget (GtkWidget *widget);
 
-void panel_dnd_set_widget_delete_dest (GtkWidget *widget);
+void panel_dnd_set_dest_widget (GtkWidget *widget);
 
-void panel_dnd_unset_dest (GtkWidget *widget);
+void panel_dnd_set_source_name (GtkWidget *widget);
 
-GtkWidget *panel_dnd_get_plugin_from_data (GtkSelectionData *data);
-
-
-void panel_dnd_set_name_source (GtkWidget *widget);
-
-void panel_dnd_set_widget_source (GtkWidget *widget);
-
-void panel_dnd_unset_source (GtkWidget *widget);
-
-void panel_dnd_set_widget_data (GtkSelectionData *data, GtkWidget *plugin);
+void panel_dnd_set_source_widget (GtkWidget *widget);
 
 void panel_dnd_begin_drag (GtkWidget *widget);
 
diff -Naur xfce4-panel-4.4.2/panel/panel-private.h xfce4-panel-4.4.2.tpg/panel/panel-private.h
--- xfce4-panel-4.4.2/panel/panel-private.h	2007-11-17 19:30:59.000000000 +0000
+++ xfce4-panel-4.4.2.tpg/panel/panel-private.h	2008-05-19 13:32:25.000000000 +0000
@@ -55,7 +55,6 @@
 {
     GtkWidget *itembar;
     GtkWidget *menu;
-    GtkWidget *drag_widget;
 
     int size;
     int monitor;
diff -Naur xfce4-panel-4.4.2/panel/panel-properties.c xfce4-panel-4.4.2.tpg/panel/panel-properties.c
--- xfce4-panel-4.4.2/panel/panel-properties.c	2007-11-17 19:30:59.000000000 +0000
+++ xfce4-panel-4.4.2.tpg/panel/panel-properties.c	2008-05-19 13:32:25.000000000 +0000
@@ -939,7 +939,7 @@
     
     g_signal_connect (panel, "move-end", G_CALLBACK (panel_move_end), NULL);
 
-    panel_dnd_set_dest (GTK_WIDGET (panel));
+    panel_dnd_set_dest_name_and_widget (GTK_WIDGET (panel));
     g_signal_connect (panel, "drag-motion", G_CALLBACK (drag_motion), NULL);
     g_signal_connect (panel, "drag-leave", G_CALLBACK (drag_leave), NULL);
 }
diff -Naur xfce4-panel-4.4.2/panel/panel.c xfce4-panel-4.4.2.tpg/panel/panel.c
--- xfce4-panel-4.4.2/panel/panel.c	2007-11-17 19:30:59.000000000 +0000
+++ xfce4-panel-4.4.2.tpg/panel/panel.c	2008-05-19 13:32:25.000000000 +0000
@@ -87,6 +87,7 @@
 static void panel_menu_deactivated (GtkWidget *item);
 
 static void panel_menu_opened (GtkWidget *item);
+static void _item_start_move (GtkWidget *item, Panel     *panel);
 
 /* DND dest */
 static void _panel_drag_data_received (GtkWidget        *widget, 
@@ -110,21 +111,6 @@
                                GdkDragContext *drag_context, 
                                Panel          *panel);
 
-static void _panel_drag_end (GtkWidget      *widget, 
-                             GdkDragContext *drag_context, 
-                             Panel          *panel);
-
-static void _panel_drag_data_get (GtkWidget        *widget, 
-                                  GdkDragContext   *drag_context, 
-                                  GtkSelectionData *data, 
-                                  guint             info, 
-                                  guint             time, 
-                                  Panel            *panel);
-
-static void _panel_drag_data_delete (GtkWidget      *widget, 
-                                     GdkDragContext *drag_context, 
-                                     Panel          *panel);
-
 /* pass through button press events */
 static gboolean _panel_itembar_button_pressed (GtkWidget      *widget, 
                                                GdkEventButton *ev, 
@@ -255,6 +241,9 @@
     priv->itembar = xfce_itembar_new (GTK_ORIENTATION_HORIZONTAL);
     gtk_widget_show (priv->itembar);
     gtk_container_add (GTK_CONTAINER (panel), priv->itembar);
+    
+    panel_dnd_set_dest_name_and_widget (priv->itembar);
+    panel_dnd_set_source_widget (priv->itembar);
 
     /* don't allow the wm to close the panel window */
     g_signal_connect (panel, "delete-event", G_CALLBACK (gtk_true), NULL);
@@ -269,15 +258,6 @@
     g_signal_connect (priv->itembar, "drag-begin", 
                       G_CALLBACK (_panel_drag_begin), panel);
 
-    g_signal_connect (priv->itembar, "drag-end", 
-                      G_CALLBACK (_panel_drag_end), panel);
-
-    g_signal_connect (priv->itembar, "drag-data-get", 
-                      G_CALLBACK (_panel_drag_data_get), panel);
-
-    g_signal_connect (priv->itembar, "drag-data-delete", 
-                      G_CALLBACK (_panel_drag_data_delete), panel);
-
     /* mouse click */
     g_signal_connect (priv->itembar, "button-press-event",
                       G_CALLBACK (_panel_itembar_button_pressed), panel);
@@ -441,76 +421,87 @@
                            guint             time, 
                            Panel            *panel)
 {
-    gboolean handled = FALSE;
+    XfceItembar   *itembar = XFCE_ITEMBAR (widget);;
+    PanelPrivate  *priv = panel->priv;
+    XfcePanelItem *item;
+    GtkWidget     *plugin;
+    gint           index;
+    gint           oldindex;
+    gboolean       expand;
+    gboolean       succeed = FALSE;
 
     DBG (" + drag data received: %d", info);
     
-    if (data->length > 0)
+    /* get the drop index */
+    index = xfce_itembar_get_drop_index (itembar, x, y);
+    
+    switch (info)
     {
-        XfceItembar   *itembar;
-        PanelPrivate  *priv;
-        XfcePanelItem *item;
-        GtkWidget     *plugin;
-        int            index;
-        int            oldindex = -1;
-        gboolean       expand;
-
-        itembar = XFCE_ITEMBAR (widget);
-
-        switch (info)
-        {
-            case TARGET_PLUGIN_NAME:
-                handled = TRUE;
-                index = xfce_itembar_get_drop_index (itembar, x, y);
-                panel_insert_item (panel, (const char *)data->data, index);
+        case TARGET_PLUGIN_NAME:
+            if (data->length > 0)
+            {
+                /* insert the new plugin */
+                panel_insert_item (panel, (const gchar *) data->data, index);
+                
+                /* succeeded */
+                succeed = TRUE;
+            }
+            break;
+           
+        case TARGET_PLUGIN_WIDGET:
+            /* get the plugin from the drag context */
+            plugin = gtk_drag_get_source_widget (context);
+            
+            /* try the drag_widget or leave */
+            if (!plugin || !XFCE_IS_PANEL_ITEM (plugin))
                 break;
+            
+            if (gtk_widget_get_parent (plugin) != widget)
+            {
+                /* get the plugin and information */
+                item   = XFCE_PANEL_ITEM (plugin);
+                expand = xfce_panel_item_get_expand (item);
                 
-            case TARGET_PLUGIN_WIDGET:
-                plugin = panel_dnd_get_plugin_from_data (data);
-                if (!plugin || !GTK_IS_WIDGET (plugin))
-                    break;                
-
-                handled = TRUE;
-                index = xfce_itembar_get_drop_index (itembar, x, y);
-
-                if (plugin->parent != widget)
-                {
-                    item   = XFCE_PANEL_ITEM (plugin);
-                    expand = xfce_panel_item_get_expand (item);
-                    priv   = panel->priv;
-
-                    g_object_freeze_notify (G_OBJECT (widget));
-                    
-                    gtk_widget_reparent (GTK_WIDGET (plugin), widget);
-                    
-                    xfce_panel_item_set_size (item, priv->size);
-                    
-                    xfce_panel_item_set_screen_position (item,
-                                                         priv->screen_position);
+                /* freeze plugin notifications */
+                g_object_freeze_notify (G_OBJECT (widget));
+                
+                /* move the plugin from the old panel to the new one */
+                gtk_widget_reparent (GTK_WIDGET (plugin), widget);
+                
+                /* update the plugin */
+                xfce_panel_item_set_size (item, priv->size);
+                xfce_panel_item_set_screen_position (item, priv->screen_position);
+                
+                /* update the itembar */
+                xfce_itembar_reorder_child (itembar, plugin, index);
+                xfce_itembar_set_child_expand (itembar, plugin, expand);
+                
+                /* thaw update notifications */
+                g_object_thaw_notify (G_OBJECT (widget));
+            }
+            else /* move on same panel */
+            {
+                /* get the old index */
+                oldindex = xfce_itembar_get_item_index (itembar, plugin);
+                
+                if (index > oldindex)
+                    index--;
                     
+                if (index != oldindex)
                     xfce_itembar_reorder_child (itembar, plugin, index);
-
-                    g_object_thaw_notify (G_OBJECT (widget));
-
-                    xfce_itembar_set_child_expand (itembar, plugin, expand);
-                }
-                else /* only when moving on the same panel */
-                {
-                    oldindex = xfce_itembar_get_item_index (itembar, plugin);
-
-                    if (index > oldindex) index--;
-                    
-                    if (index != oldindex)
-                        xfce_itembar_reorder_child (itembar, plugin, index);
-                }
-                break;
-                
-            default:
-                break;
-        }
+            }
+            
+            /* properly handled */
+            succeed = TRUE;
+            
+            break;
+           
+        default:
+            break;
     }
-     
-    gtk_drag_finish (context, handled, FALSE, time);
+    
+    /* finish the drag */
+    gtk_drag_finish (context, succeed, FALSE, time);
 }
 
 static gboolean
@@ -521,15 +512,17 @@
                   guint           time, 
                   Panel          *panel)
 {
-    GdkAtom atom = gtk_drag_dest_find_target (widget, context, NULL);
-
-    if (atom != GDK_NONE)
-    {
-        gtk_drag_get_data (widget, context, atom, time);
-        return TRUE;
-    }
-
-    return FALSE;
+    GdkAtom target = gtk_drag_dest_find_target (widget, context, NULL);
+    
+    /* we cannot handle the drag data */
+    if (G_UNLIKELY (target == GDK_NONE))
+        return FALSE;
+
+    /* request the drag data */
+    gtk_drag_get_data (widget, context, target, time);
+  
+    /* we call gtk_drag_finish later */
+    return TRUE;
 }
 
 /* DND source */
@@ -538,110 +531,27 @@
                    GdkDragContext *drag_context, 
                    Panel          *panel)
 {
-    int           x, y, rootx, rooty, w, h;
-    GtkWidget    *plugin;
-    GdkPixbuf    *pb;
-    PanelPrivate *priv = panel->priv;
-
+    gint         x, y, rootx, rooty;
+    GtkWidget   *plugin;
+    
     DBG (" + drag begin");
     
-    if (priv->drag_widget)
-    {
-        plugin = priv->drag_widget;
-
-        /* allow menu to close, in order to not mess up the snapshot of the
-         * plugin -- TODO: find a better way to do this */
-        while (gtk_events_pending ())
-            gtk_main_iteration ();
-    }
-    else
-    {
-        x = y = 0;
-        gdk_display_get_pointer (gtk_widget_get_display (widget), 
-                                 NULL, &x, &y, NULL);
-        gdk_window_get_root_origin (widget->window, &rootx, &rooty);
-        x -= rootx;
-        y -= rooty;
-
-        plugin = xfce_itembar_get_item_at_point (XFCE_ITEMBAR (widget), x, y);
-    }
-
-    if (plugin)
-    {
-        GdkDrawable *d = GDK_DRAWABLE (plugin->window);
-        
-        gdk_drawable_get_size (d, &w, &h);
-        pb = gdk_pixbuf_get_from_drawable (NULL, d, NULL, 0, 0, 0, 0, w, h);
-        gtk_drag_set_icon_pixbuf (drag_context, pb, 0, 0);
-        g_object_unref (G_OBJECT (pb));
-
-        priv->drag_widget = plugin;
-    }
-    else
-        DBG ("No Plugin");
-}
-
-static void
-_panel_drag_end (GtkWidget      *widget, 
-                 GdkDragContext *drag_context, 
-                 Panel          *panel)
-{
-    PanelPrivate *priv = panel->priv;
-
-    priv->drag_widget = NULL;
-
-    if (!priv->edit_mode)
-    {
-        const GPtrArray *panels = panel_app_get_panel_list ();
-        int i;
-        
-        for (i = 0; i < panels->len; ++i)
-        {
-            Panel *p = g_ptr_array_index (panels, i);
-            
-            priv = p->priv;
-
-            xfce_itembar_lower_event_window (XFCE_ITEMBAR (priv->itembar));
-            panel_dnd_unset_dest (priv->itembar);
-            panel_dnd_unset_source (priv->itembar);
-            panel_set_items_sensitive (p, TRUE);
-
-            panel_unblock_autohide (p);
-        }
-    }
-}
-
-static void
-_panel_drag_data_get (GtkWidget        *widget, 
-                      GdkDragContext   *drag_context, 
-                      GtkSelectionData *data, 
-                      guint             info, 
-                      guint             time, 
-                      Panel            *panel)
-{
-    if (info == TARGET_PLUGIN_WIDGET)
-    {
-        PanelPrivate *priv = panel->priv;
-
-        if (priv->drag_widget)
-        {
-            panel_dnd_set_widget_data (data, priv->drag_widget);
-        }
-    }
-}
-
-static void
-_panel_drag_data_delete (GtkWidget      *widget, 
-                         GdkDragContext *drag_context, 
-                         Panel          *panel)
-{
-    PanelPrivate *priv = panel->priv;
-
-    if (priv->drag_widget)
-    {
-        xfce_panel_item_remove (XFCE_PANEL_ITEM (priv->drag_widget));
-        priv->drag_widget = NULL;
-    }
+    /* get the pointer position */
+    gdk_display_get_pointer (gtk_widget_get_display (widget), NULL, &x, &y, NULL);
+    
+    /* get the window root coordinates */
+    gdk_window_get_root_origin (widget->window, &rootx, &rooty);
+    
+    /* calc the position inside the panel */
+    x -= rootx;
+    y -= rooty;
+    
+    /* get the plugin on the itembar at this position */
+    plugin = xfce_itembar_get_item_at_point (XFCE_ITEMBAR (widget), x, y);
+    
+    /* start an item move */
+    if (G_LIKELY (plugin))
+        _item_start_move (plugin, panel);
 }
 
 /* pass through right-click events when the event window of itembar is raised
@@ -651,6 +561,8 @@
                                GdkEventButton *ev, 
                                Panel          *panel)
 {
+    GtkWidget *plugin;
+    
     if (xfce_itembar_event_window_is_raised (XFCE_ITEMBAR (widget)))
     {
         guint modifiers;
@@ -660,8 +572,6 @@
         if (ev->button == 3 || (ev->button == 1 && 
             (ev->state & modifiers) == GDK_CONTROL_MASK))
         {
-            GtkWidget *plugin;
-
             plugin = xfce_itembar_get_item_at_point (XFCE_ITEMBAR (widget),
                                                      ev->x, ev->y);
             if (plugin)
@@ -670,14 +580,6 @@
                 return TRUE;
             }
         }
-        else if (ev->button == 1)
-        {
-            PanelPrivate *priv = panel->priv;
-            
-            priv->drag_widget = 
-                xfce_itembar_get_item_at_point (XFCE_ITEMBAR (widget), 
-                                                ev->x, ev->y);
-        }
     }
     
     return FALSE;
@@ -863,13 +765,44 @@
 }
 
 static void
+_item_start_move_end (GtkWidget      *item,
+                      GdkDragContext *context,
+                      Panel          *panel)
+{
+    PanelPrivate *priv = panel->priv;
+    Panel        *p;
+    
+    DBG ("+ finish item drag");
+    
+    /* disconnect drag end signal */
+    g_signal_handlers_disconnect_by_func (G_OBJECT (item), G_CALLBACK (_item_start_move_end), panel);
+    
+    if (!priv->edit_mode)
+    {
+        const GPtrArray *panels = panel_app_get_panel_list ();
+        gint i;
+        
+        for (i = 0; i < panels->len; ++i)
+        {
+            p = g_ptr_array_index (panels, i);
+            priv = p->priv;
+
+            xfce_itembar_lower_event_window (XFCE_ITEMBAR (priv->itembar));
+            panel_set_items_sensitive (p, TRUE);
+
+            panel_unblock_autohide (p);
+        }
+    }
+}
+
+static void
 _item_start_move (GtkWidget *item, 
                   Panel     *panel)
 {
     const GPtrArray *panels = panel_app_get_panel_list ();
     PanelPrivate    *priv;
     Panel           *p;
-    int              i;
+    gint             i;
     
     for (i = 0; i < panels->len; ++i)
     {
@@ -879,19 +812,16 @@
         if (!priv->edit_mode)
         {
             panel_set_items_sensitive (p, FALSE);
-
-            panel_dnd_set_dest (priv->itembar);
-            panel_dnd_set_widget_source (priv->itembar);
             xfce_itembar_raise_event_window (XFCE_ITEMBAR (priv->itembar));
-
             panel_block_autohide (p);
         }
     }
 
-    priv = panel->priv;
-    priv->drag_widget = item;
-
-    panel_dnd_begin_drag (priv->itembar);
+    /* start the drag */
+    panel_dnd_begin_drag (item);
+    
+    /* signal to make panels sensitive after a drop */
+    g_signal_connect (G_OBJECT (item), "drag-end", G_CALLBACK (_item_start_move_end), panel);
 }
 
 extern void panel_set_hidden (Panel    *panel,