Updating branch refs/heads/eric/bugzilla-patches to cf1ba8ecefacca369c4f83ece0b6d03b718fce06 (commit) from 82e69c54b00a07e6ffd52b0c2f475dd9ba76dfa7 (commit)
commit cf1ba8ecefacca369c4f83ece0b6d03b718fce06 Author: Eric Koegel <eric.koe...@gmail.com> Date: Mon Feb 6 08:45:06 2012 +0300 Right-click Drag and Drop Drag and drop right-click to and from the desktop will cause a menu pop-up. Additionally, this patch also fixes the issue where files that were dropped onto the desktop were always copied by default instead of doing a move when they were on the same filesystem. They were combined because the move/copy bug requires code implemented in this right click drag and drop patch. src/xfdesktop-file-icon-manager.c | 146 ++++++++++++++++++++++++++++++++++++- src/xfdesktop-icon-view.c | 20 +++-- 2 files changed, 156 insertions(+), 10 deletions(-) diff --git a/src/xfdesktop-file-icon-manager.c b/src/xfdesktop-file-icon-manager.c index d3ca2eb..8b82fdc 100644 --- a/src/xfdesktop-file-icon-manager.c +++ b/src/xfdesktop-file-icon-manager.c @@ -2778,6 +2778,92 @@ xfdesktop_file_icon_manager_drag_drop(XfdesktopIconViewManager *manager, return TRUE; } +static void xfdesktop_dnd_item(GtkWidget *item, GdkDragAction *action) +{ + *action = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(item), "action")); +} + +static void xfdesktop_dnd_item_cancel(GtkWidget *item, GdkDragAction *action) +{ + *action = 0; +} + +/** + * xfdesktop_dnd_menu: + * @manager : the #XfdesktopIconViewManager instance + * @drop_icon : the #XfdesktopIcon to which is being dropped. + * @context : the #GdkDragContext of the icons being dropped. + * @row : the row on the desktop to drop to. + * @col : the col on the desktop to drop to. + * @ time_ : the starting time of the drag event. + * Pops up a menu that asks the user to choose one of the + * actions or to cancel the drop. Sets context->action to + * the new action the user selected or 0 on cancel. + * Portions of this code was copied from thunar-dnd.c + * Copyright (c) 2005-2006 Benedikt Meurer <be...@xfce.org> + * Copyright (c) 2009-2011 Jannis Pohlmann <jan...@xfce.org> + **/ +static void xfdesktop_dnd_menu (XfdesktopIconViewManager *manager, + XfdesktopIcon *drop_icon, + GdkDragContext *context, + guint16 row, + guint16 col, + guint time_) +{ + static GdkDragAction actions[] = { GDK_ACTION_COPY, GDK_ACTION_MOVE, GDK_ACTION_LINK }; + static const gchar *action_names[] = { N_ ("Copy _Here") , N_ ("_Move Here") , N_ ("_Link Here") }; + static const gchar *action_icons[] = { "stock_folder-copy", "stock_folder-move", NULL }; + GtkWidget *menu; + GtkWidget *item; + GtkWidget *image; + guint menu_item, signal_id; + GMainLoop *loop; + gint response; + menu = gtk_menu_new(); + + /* This adds the Copy, Move, & Link options */ + for(menu_item = 0; menu_item < G_N_ELEMENTS(actions); menu_item++) { + item = gtk_image_menu_item_new_with_mnemonic(_(action_names[menu_item])); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(xfdesktop_dnd_item), &response); + g_object_set_data(G_OBJECT(item), "action", GUINT_TO_POINTER(actions[menu_item])); + /* add image to the menu item */ + if(G_LIKELY(action_icons[menu_item] != NULL)) { + image = gtk_image_new_from_icon_name(action_icons[menu_item], GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image); + gtk_widget_show(image); + } + + gtk_widget_show(item); + } + + /* Add a seperator */ + item = gtk_separator_menu_item_new(); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + gtk_widget_show(item); + + /* Cancel option */ + item = gtk_image_menu_item_new_from_stock(GTK_STOCK_CANCEL, NULL); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(xfdesktop_dnd_item_cancel), &response); + gtk_widget_show(item); + + gtk_widget_show(menu); + g_object_ref_sink(G_OBJECT(menu)); + + /* Loop until we get a user response */ + loop = g_main_loop_new(NULL, FALSE); + signal_id = g_signal_connect_swapped(G_OBJECT(menu), "deactivate", G_CALLBACK(g_main_loop_quit), loop); + gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 3, time_); + g_main_loop_run(loop); + g_signal_handler_disconnect(G_OBJECT(menu), signal_id); + g_main_loop_unref(loop); + + context->action = response; + + g_object_unref(G_OBJECT(menu)); +} + static void xfdesktop_file_icon_manager_drag_data_received(XfdesktopIconViewManager *manager, XfdesktopIcon *drop_icon, @@ -2794,6 +2880,20 @@ xfdesktop_file_icon_manager_drag_data_received(XfdesktopIconViewManager *manager GFile *tfile = NULL; gboolean copy_only = TRUE, drop_ok = FALSE; GList *file_list; + gboolean user_selected_action = FALSE; + + TRACE("entering"); + + if(context->action == GDK_ACTION_ASK) { + xfdesktop_dnd_menu(manager, drop_icon, context, row, col, time_); + + if(context->action == 0) { + gtk_drag_finish(context, FALSE, FALSE, time_); + return; + } + /* The user picked whether to move or copy the files */ + user_selected_action = TRUE; + } if(info == TARGET_XDND_DIRECT_SAVE0) { /* we don't suppose XdndDirectSave stage 3, result F, i.e., the app @@ -2866,7 +2966,7 @@ xfdesktop_file_icon_manager_drag_data_received(XfdesktopIconViewManager *manager tinfo = xfdesktop_file_icon_peek_file_info(file_icon); } - copy_only = (context->action != GDK_ACTION_MOVE); + copy_only = (context->action == GDK_ACTION_COPY); if(tfile && g_file_has_uri_scheme(tfile, "trash") && copy_only) { gtk_drag_finish(context, FALSE, FALSE, time_); @@ -2907,12 +3007,48 @@ xfdesktop_file_icon_manager_drag_data_received(XfdesktopIconViewManager *manager base_dest_file = g_object_ref(fmanager->priv->folder); } + /* If the user didn't pick whether to copy or move via + * a GDK_ACTION_ASK then determine if we should move/copy + * by checking if the files are on the same file system. + */ + if(user_selected_action == FALSE) { + GFileInfo *src_info, *dest_info; + const gchar *src_name, *dest_name; + dest_info = g_file_query_info(base_dest_file, + G_FILE_ATTRIBUTE_ID_FILESYSTEM, + G_FILE_QUERY_INFO_NONE, + NULL, + NULL); + src_info = g_file_query_info(file_list->data, + G_FILE_ATTRIBUTE_ID_FILESYSTEM, + G_FILE_QUERY_INFO_NONE, + NULL, + NULL); + + if(dest_info != NULL && src_info != NULL) { + dest_name = g_file_info_get_attribute_string(dest_info, + G_FILE_ATTRIBUTE_ID_FILESYSTEM); + src_name = g_file_info_get_attribute_string(src_info, + G_FILE_ATTRIBUTE_ID_FILESYSTEM); + + if(g_strcmp0(src_name, dest_name) == 0) { + copy_only = FALSE; + context->action = GDK_ACTION_MOVE; + } + } + + if(dest_info != NULL) + g_object_unref(dest_info); + if(src_info != NULL) + g_object_unref(src_info); + } + for (l = file_list; l; l = l->next) { gchar *dest_basename = g_file_get_basename(l->data); if(dest_basename && *dest_basename != '\0') { /* If we copy a file, we need to use the new absolute filename - * as the destination. If we move, we need to use the destination + * as the destination. If we move or link, we need to use the destination * directory. */ if(copy_only) { GFile *dest_file = g_file_get_child(base_dest_file, dest_basename); @@ -2936,7 +3072,11 @@ xfdesktop_file_icon_manager_drag_data_received(XfdesktopIconViewManager *manager fmanager->priv->gscreen); } - xfdesktop_file_utils_file_list_free(dest_file_list); + if(copy_only) { + xfdesktop_file_utils_file_list_free(dest_file_list); + } else { + g_list_free(dest_file_list); + } } } } diff --git a/src/xfdesktop-icon-view.c b/src/xfdesktop-icon-view.c index 0736006..e1c918a 100644 --- a/src/xfdesktop-icon-view.c +++ b/src/xfdesktop-icon-view.c @@ -48,6 +48,7 @@ #include "xfdesktop-icon-view.h" #include "xfdesktop-marshal.h" +#include "xfce-desktop.h" #include <libwnck/libwnck.h> #include <libxfce4ui/libxfce4ui.h> @@ -744,7 +745,7 @@ xfdesktop_icon_view_button_press(GtkWidget *widget, xfdesktop_icon_view_select_item(icon_view, icon); } - if(evt->button == 1) { + if(evt->button == 1 || evt->button == 3) { /* we might be the start of a drag */ DBG("setting stuff"); icon_view->priv->maybe_begin_drag = TRUE; @@ -752,10 +753,6 @@ xfdesktop_icon_view_button_press(GtkWidget *widget, icon_view->priv->definitely_rubber_banding = FALSE; icon_view->priv->press_start_x = evt->x; icon_view->priv->press_start_y = evt->y; - } else if(evt->button == 3) { - /* XfceDesktop will handle signalling the icon view manager - * to show the context menu */ - return FALSE; } return TRUE; @@ -809,8 +806,11 @@ xfdesktop_icon_view_button_release(GtkWidget *widget, XfdesktopIconView *icon_view = XFDESKTOP_ICON_VIEW(user_data); TRACE("entering btn=%d", evt->button); - - if(evt->button == 1) { + + if(evt->button == 3 && !icon_view->priv->definitely_dragging && !icon_view->priv->definitely_rubber_banding) + xfce_desktop_popup_root_menu(XFCE_DESKTOP(widget), evt->button, evt->time); + + if(evt->button == 1 || evt->button == 3) { DBG("unsetting stuff"); icon_view->priv->definitely_dragging = FALSE; icon_view->priv->maybe_begin_drag = FALSE; @@ -897,9 +897,15 @@ xfdesktop_icon_view_maybe_begin_drag(XfdesktopIconView *icon_view, actions = GDK_ACTION_MOVE | (icon_view->priv->drag_source_set ? icon_view->priv->foreign_source_actions : 0); + if(evt->state != GDK_BUTTON3_MASK) { gtk_drag_begin(GTK_WIDGET(icon_view), icon_view->priv->source_targets, actions, 1, (GdkEvent *)evt); + } else { + gtk_drag_begin(GTK_WIDGET(icon_view), + icon_view->priv->source_targets, + actions | GDK_ACTION_ASK, 3, (GdkEvent *)evt); + } DBG("DRAG BEGIN!"); _______________________________________________ Xfce4-commits mailing list Xfce4-commits@xfce.org https://mail.xfce.org/mailman/listinfo/xfce4-commits