diff options
author | oliver <oliver@FreeBSD.org> | 2008-03-17 02:38:35 +0800 |
---|---|---|
committer | oliver <oliver@FreeBSD.org> | 2008-03-17 02:38:35 +0800 |
commit | 7b1bd2151fe569cb23b4a4d0204af4d1663edf29 (patch) | |
tree | 49649967fa00a4af304c772803f5a64a506fa6cd /x11-wm/xfce4-panel | |
parent | 3caf2103976875e8ff4409a122523010bb8fb365 (diff) | |
download | freebsd-ports-gnome-7b1bd2151fe569cb23b4a4d0204af4d1663edf29.tar.gz freebsd-ports-gnome-7b1bd2151fe569cb23b4a4d0204af4d1663edf29.tar.zst freebsd-ports-gnome-7b1bd2151fe569cb23b4a4d0204af4d1663edf29.zip |
fix the Drag and Drop problem on FreeBSD/amd64 7.0
the patch was taken from the xfce svn repo
bump PORTREVISION
PR: ports/118321
Diffstat (limited to 'x11-wm/xfce4-panel')
-rw-r--r-- | x11-wm/xfce4-panel/Makefile | 2 | ||||
-rw-r--r-- | x11-wm/xfce4-panel/files/patch-dnd | 1094 |
2 files changed, 1095 insertions, 1 deletions
diff --git a/x11-wm/xfce4-panel/Makefile b/x11-wm/xfce4-panel/Makefile index 13c5bd4c08da..87220d226447 100644 --- a/x11-wm/xfce4-panel/Makefile +++ b/x11-wm/xfce4-panel/Makefile @@ -7,7 +7,7 @@ PORTNAME= xfce4-panel PORTVERSION= 4.4.2 -PORTREVISION= 0 +PORTREVISION= 1 CATEGORIES= x11-wm xfce MASTER_SITES= ${MASTER_SITE_XFCE} DIST_SUBDIR= xfce4 diff --git a/x11-wm/xfce4-panel/files/patch-dnd b/x11-wm/xfce4-panel/files/patch-dnd new file mode 100644 index 000000000000..f6621dd4b532 --- /dev/null +++ b/x11-wm/xfce4-panel/files/patch-dnd @@ -0,0 +1,1094 @@ +Modified: ChangeLog +=================================================================== +--- ChangeLog 2008-03-06 14:44:26 UTC (rev 26668) ++++ ChangeLog 2008-03-09 18:03:37 UTC (rev 26669) +@@ -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, + +Modified: NEWS +=================================================================== +--- NEWS 2008-03-06 14:44:26 UTC (rev 26668) ++++ NEWS 2008-03-09 18:03:37 UTC (rev 26669) +@@ -1,3 +1,12 @@ ++4.4.3 ++===== ++- Quite a bit code changed in the dnd code. Mostly to fix a segfault in ++ FreeBSD-amd64, but more problems were discovered and a lot of code ++ was simplified. ++- 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). + +Modified: panel/panel-dialogs.c +=================================================================== +--- panel/panel-dialogs.c 2008-03-06 14:44:26 UTC (rev 26668) ++++ panel/panel-dialogs.c 2008-03-09 18:03:37 UTC (rev 26669) +@@ -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,19 +441,14 @@ + g_object_unref (G_OBJECT (store)); + + /* dnd */ +- panel_dnd_set_name_source (tv); ++ panel_dnd_set_source_name (tv); ++ panel_dnd_set_dest_name_and_widget (tv); + +- panel_dnd_set_widget_delete_dest (tv); +- +- 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-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); + +- g_signal_connect (tv, "drag-drop", +- G_CALLBACK (treeview_drag_drop), pid); +- + /* create the view */ + col = gtk_tree_view_column_new (); + gtk_tree_view_column_set_spacing (col, BORDER); +@@ -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,17 +484,12 @@ + 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); + gtk_tree_path_free (path); +@@ -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); + +Modified: panel/panel-dnd.c +=================================================================== +--- panel/panel-dnd.c 2008-03-06 14:44:26 UTC (rev 26668) ++++ panel/panel-dnd.c 2008-03-09 18:03:37 UTC (rev 26669) +@@ -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); ++ widget_target_list, G_N_ELEMENTS (widget_target_list), GDK_ACTION_MOVE); + } + + void +-panel_dnd_unset_dest (GtkWidget *widget) ++panel_dnd_set_source_name (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)); +-} +- +-void +-panel_dnd_set_name_source (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); ++ widget_target_list, G_N_ELEMENTS (widget_target_list), GDK_ACTION_COPY); + } + +-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)); +-} +- +-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); ++ } + } + + +Modified: panel/panel-dnd.h +=================================================================== +--- panel/panel-dnd.h 2008-03-06 14:44:26 UTC (rev 26668) ++++ panel/panel-dnd.h 2008-03-09 18:03:37 UTC (rev 26669) +@@ -27,27 +27,17 @@ + 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_source_widget (GtkWidget *widget); + +- +-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_begin_drag (GtkWidget *widget); + + #endif /* _PANEL_DND_H */ + +Modified: panel/panel-private.h +=================================================================== +--- panel/panel-private.h 2008-03-06 14:44:26 UTC (rev 26668) ++++ panel/panel-private.h 2008-03-09 18:03:37 UTC (rev 26669) +@@ -55,7 +55,6 @@ + { + GtkWidget *itembar; + GtkWidget *menu; +- GtkWidget *drag_widget; + + int size; + int monitor; + +Modified: panel/panel-properties.c +=================================================================== +--- panel/panel-properties.c 2008-03-06 14:44:26 UTC (rev 26668) ++++ panel/panel-properties.c 2008-03-09 18:03:37 UTC (rev 26669) +@@ -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); + } + +Modified: panel/panel.c +=================================================================== +--- panel/panel.c 2008-03-06 14:44:26 UTC (rev 26668) ++++ panel/panel.c 2008-03-09 18:03:37 UTC (rev 26669) +@@ -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)); ++ /* 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--; + +- 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); +- ++ 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); ++ 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; +- } +- +- 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,112 +531,29 @@ + 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"); ++ /* 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); + } + +-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; +- } +-} +- + /* pass through right-click events when the event window of itembar is raised + */ + static gboolean +@@ -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, + |