static gboolean panel_check_drop_forbidden (PanelWidget *panel, GdkDragContext *context, guint info, guint time_) { if (!panel) return FALSE; if (panel_lockdown_get_panels_locked_down_s ()) return FALSE; if (info == TARGET_ICON_INTERNAL || info == TARGET_APPLET_INTERNAL) { if (gdk_drag_context_get_actions (context) & GDK_ACTION_MOVE) gdk_drag_status (context, GDK_ACTION_MOVE, time_); else gdk_drag_status (context, gdk_drag_context_get_suggested_action (context), time_); } else if (gdk_drag_context_get_actions (context) & GDK_ACTION_COPY) gdk_drag_status (context, GDK_ACTION_COPY, time_); else gdk_drag_status (context, gdk_drag_context_get_suggested_action (context), time_); return TRUE; }
gboolean panel_check_dnd_target_data (GtkWidget *widget, GdkDragContext *context, guint *ret_info, GdkAtom *ret_atom) { GList *l; g_return_val_if_fail (widget, FALSE); if (!PANEL_IS_TOPLEVEL (widget) && !BUTTON_IS_WIDGET (widget)) return FALSE; if (!(gdk_drag_context_get_actions (context) & (GDK_ACTION_COPY|GDK_ACTION_MOVE))) return FALSE; for (l = gdk_drag_context_list_targets (context); l; l = l->next) { GdkAtom atom; guint info; atom = GDK_POINTER_TO_ATOM (l->data); if (gtk_target_list_find (get_target_list (), atom, &info)) { if (ret_info) *ret_info = info; if (ret_atom) *ret_atom = atom; break; } } return l ? TRUE : FALSE; }
static gboolean is_this_drop_ok (GtkWidget *widget, GdkDragContext *context) { static GdkAtom text_uri_list = GDK_NONE; GList *l; GtkWidget *source; source = gtk_drag_get_source_widget (context); if (source == widget) return FALSE; if (!(gdk_drag_context_get_actions (context) & GDK_ACTION_COPY)) return FALSE; if (!text_uri_list) text_uri_list = gdk_atom_intern_static_string ("text/uri-list"); for (l = gdk_drag_context_list_targets (context); l; l = l->next) { if (GDK_POINTER_TO_ATOM (l->data) == text_uri_list) break; } return l ? TRUE : FALSE; }
gboolean panel_check_drop_forbidden (PanelWidget *panel, GdkDragContext *context, guint info, guint time_) { if (!panel) return FALSE; if (panel_lockdown_get_locked_down ()) return FALSE; if (info == TARGET_APPLET_INTERNAL) { GtkWidget *source_widget; source_widget = gtk_drag_get_source_widget (context); if (BUTTON_IS_WIDGET (source_widget)) { GSList *forb; forb = g_object_get_data (G_OBJECT (source_widget), MATE_PANEL_APPLET_FORBIDDEN_PANELS); if (g_slist_find (forb, panel)) return FALSE; } } if (info == TARGET_ICON_INTERNAL || info == TARGET_APPLET_INTERNAL) { if (gdk_drag_context_get_actions (context) & GDK_ACTION_MOVE) gdk_drag_status (context, GDK_ACTION_MOVE, time_); else gdk_drag_status (context, gdk_drag_context_get_suggested_action (context), time_); } else if (gdk_drag_context_get_actions (context) & GDK_ACTION_COPY) gdk_drag_status (context, GDK_ACTION_COPY, time_); else gdk_drag_status (context, gdk_drag_context_get_suggested_action (context), time_); return TRUE; }
wxDragResult wxDropTarget::GTKFigureOutSuggestedAction() { if (!m_dragContext) return wxDragError; // GTK+ always supposes that we want to copy the data by default while we // might want to move it, so examine not only suggested_action - which is // only good if we don't have our own preferences - but also the actions // field wxDragResult suggested_action = wxDragNone; const GdkDragAction actions = gdk_drag_context_get_actions(m_dragContext); if (GetDefaultAction() == wxDragNone) { // use default action set by wxDropSource::DoDragDrop() if ( (gs_flagsForDrag & wxDrag_DefaultMove) == wxDrag_DefaultMove && (actions & GDK_ACTION_MOVE)) { // move is requested by the program and allowed by GTK+ - do it, even // though suggested_action may be currently wxDragCopy suggested_action = wxDragMove; } else // use whatever GTK+ says we should { suggested_action = ConvertFromGTK(gdk_drag_context_get_suggested_action(m_dragContext)); #if 0 // RR: I don't understand the code below: if the drag comes from // a different app, the gs_flagsForDrag is invalid; if it // comes from the same wx app, then GTK+ hopefully won't // suggest something we didn't allow in the frist place // in DoDrop() if ( (suggested_action == wxDragMove) && !(gs_flagsForDrag & wxDrag_AllowMove) ) { // we're requested to move but we can't suggested_action = wxDragCopy; } #endif } } else if (GetDefaultAction() == wxDragMove && (actions & GDK_ACTION_MOVE)) { suggested_action = wxDragMove; } else { if (actions & GDK_ACTION_COPY) suggested_action = wxDragCopy; else if (actions & GDK_ACTION_MOVE) suggested_action = wxDragMove; else if (actions & GDK_ACTION_LINK) suggested_action = wxDragLink; else suggested_action = wxDragNone; } return suggested_action; }
GdkDragAction athena_drag_default_drop_action_for_uri_list (GdkDragContext *context, const char *target_uri_string) { if (eel_uri_is_trash (target_uri_string) && (gdk_drag_context_get_actions (context) & GDK_ACTION_MOVE)) { /* Only move to Trash */ return GDK_ACTION_MOVE; } else { return gdk_drag_context_get_suggested_action (context); } }
GdkDragAction athena_drag_default_drop_action_for_netscape_url (GdkDragContext *context) { /* Mozilla defaults to copy, but unless thats the only allowed thing (enforced by ctrl) we want to LINK */ if (gdk_drag_context_get_suggested_action (context) == GDK_ACTION_COPY && gdk_drag_context_get_actions (context) != GDK_ACTION_COPY) { return GDK_ACTION_LINK; } else if (gdk_drag_context_get_suggested_action (context) == GDK_ACTION_MOVE) { /* Don't support move */ return GDK_ACTION_COPY; } return gdk_drag_context_get_suggested_action (context); }
static gboolean gstyle_color_widget_on_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time) { GstyleColorWidget *self = (GstyleColorWidget *)widget; GstylePaletteWidgetDndLockFlags dnd_lock; GdkAtom target; GdkDragAction drag_action; g_assert (GSTYLE_IS_COLOR_WIDGET (self)); g_assert (GDK_IS_DRAG_CONTEXT (context)); target = gtk_drag_dest_find_target (widget, context, NULL); dnd_lock = get_palette_widget_dnd_lock (self); if ((dnd_lock & GSTYLE_PALETTE_WIDGET_DND_LOCK_FLAGS_DRAG) != 0) { gdk_drag_status (context, 0, time); return FALSE; } if ((target == gdk_atom_intern_static_string ("GSTYLE_COLOR_WIDGET") || target == gdk_atom_intern_static_string ("application/x-color") || gtk_targets_include_text (&target, 1)) && (dnd_lock & GSTYLE_PALETTE_WIDGET_DND_LOCK_FLAGS_DROP) == 0 && is_in_drop_zone (self, x, y)) { gtk_drag_highlight (widget); drag_action = gdk_drag_context_get_actions (context); if ((drag_action | GDK_ACTION_COPY) != 0) { gdk_drag_status (context, GDK_ACTION_COPY, time); return TRUE; } } gdk_drag_status (context, 0, time); return FALSE; }
static void dispatchEvent(GdkEvent* event) { webkit_web_frame_layout(mainFrame); WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); if (!view) { gdk_event_free(event); return; } gtk_main_do_event(event); if (!currentDragSourceContext) { gdk_event_free(event); return; } if (event->type == GDK_MOTION_NOTIFY) { // WebKit has called gtk_drag_start(), but because the main loop isn't // running GDK internals don't know that the drag has started yet. Pump // the main loop a little bit so that GDK is in the correct state. while (gtk_events_pending()) gtk_main_iteration(); // Simulate a drag motion on the top-level GDK window. GtkWidget* parentWidget = gtk_widget_get_parent(GTK_WIDGET(view)); GdkWindow* parentWidgetWindow = gtk_widget_get_window(parentWidget); gdk_drag_motion(currentDragSourceContext, parentWidgetWindow, GDK_DRAG_PROTO_XDND, event->motion.x_root, event->motion.y_root, gdk_drag_context_get_selected_action(currentDragSourceContext), gdk_drag_context_get_actions(currentDragSourceContext), GDK_CURRENT_TIME); } else if (currentDragSourceContext && event->type == GDK_BUTTON_RELEASE) { // We've released the mouse button, we should just be able to spin the // event loop here and have GTK+ send the appropriate notifications for // the end of the drag. while (gtk_events_pending()) gtk_main_iteration(); } gdk_event_free(event); }
static void gth_file_list_drag_data_received (GtkWidget *file_view, GdkDragContext *context, int x, int y, GtkSelectionData *selection_data, guint info, guint time, gpointer user_data) { GthBrowser *browser = user_data; gboolean success = FALSE; char **uris; GList *selected_files; GdkDragAction action; g_signal_stop_emission_by_name (file_view, "drag-data-received"); action = gdk_drag_context_get_suggested_action (context); if (action == GDK_ACTION_COPY || action == GDK_ACTION_MOVE) { success = TRUE; } if (action == GDK_ACTION_ASK) { GdkDragAction actions = _gtk_menu_ask_drag_drop_action (file_view, gdk_drag_context_get_actions (context), time); gdk_drag_status (context, actions, time); success = gdk_drag_context_get_selected_action (context) != 0; } if (gtk_selection_data_get_data_type (selection_data) == XDND_ACTION_DIRECT_SAVE_ATOM) { const guchar *data; int format; int length; data = gtk_selection_data_get_data (selection_data); format = gtk_selection_data_get_format (selection_data); length = gtk_selection_data_get_length (selection_data); if ((format == 8) && (length == 1) && (data[0] == 'S')) { success = TRUE; } else { gdk_property_change (gdk_drag_context_get_dest_window (context), XDND_ACTION_DIRECT_SAVE_ATOM, TEXT_PLAIN_ATOM, 8, GDK_PROP_MODE_REPLACE, (const guchar *) "", 0); success = FALSE; } gtk_drag_finish (context, success, FALSE, time); return; } gtk_drag_finish (context, success, FALSE, time); if (! success) return; uris = gtk_selection_data_get_uris (selection_data); selected_files = _g_file_list_new_from_uriv (uris); if (selected_files != NULL) { if (gtk_drag_get_source_widget (context) == file_view) { GList *file_data_list; GList *visible_files; BrowserData *data; GthTask *task; file_data_list = gth_file_store_get_visibles (gth_browser_get_file_store (browser)); visible_files = gth_file_data_list_to_file_list (file_data_list); data = g_object_get_data (G_OBJECT (browser), BROWSER_DATA_KEY); task = gth_reorder_task_new (gth_browser_get_location_source (browser), gth_browser_get_location_data (browser), visible_files, selected_files, data->drop_pos); gth_browser_exec_task (browser, task, FALSE); g_object_unref (task); _g_object_list_unref (visible_files); _g_object_list_unref (file_data_list); } else { GthFileSource *file_source; gboolean cancel = FALSE; gboolean move; file_source = gth_browser_get_location_source (browser); move = gdk_drag_context_get_selected_action (context) == GDK_ACTION_MOVE; if (move && ! gth_file_source_can_cut (file_source, (GFile *) selected_files->data)) { GtkWidget *dialog; int response; dialog = _gtk_message_dialog_new (GTK_WINDOW (browser), GTK_DIALOG_MODAL, GTK_STOCK_DIALOG_QUESTION, _("Could not move the files"), _("Files cannot be moved to the current location, as alternative you can choose to copy them."), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_COPY, GTK_RESPONSE_OK, NULL); response = gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); if (response == GTK_RESPONSE_CANCEL) cancel = TRUE; move = FALSE; } if (! cancel) { GthFileSource *location_source; BrowserData *data; GthTask *task; location_source = gth_main_get_file_source (gth_browser_get_location (browser)); data = g_object_get_data (G_OBJECT (browser), BROWSER_DATA_KEY); task = gth_copy_task_new (location_source, gth_browser_get_location_data (browser), move, selected_files, data->drop_pos); gth_browser_exec_task (browser, task, FALSE); g_object_unref (task); g_object_unref (location_source); } } } _g_object_list_unref (selected_files); g_strfreev (uris); }
bool DragAndDropHandler::drop(GdkDragContext* context, const IntPoint& position, unsigned time) { DroppingContext* droppingContext = m_droppingContexts.get(context); if (!droppingContext) return false; droppingContext->dropHappened = true; DataObjectGtk* dataObject = droppingContext->dataObject.get(); if (!dataObject) return false; DragData dragData(dataObject, position, convertWidgetPointToScreenPoint(m_page.viewWidget(), position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context))); SandboxExtension::Handle handle; SandboxExtension::HandleArray sandboxExtensionForUpload; m_page.performDragOperation(dragData, String(), handle, sandboxExtensionForUpload); gtk_drag_finish(context, TRUE, FALSE, time); return true; }
void DragAndDropHandler::dragMotion(GdkDragContext* context, const IntPoint& position, unsigned time) { DataObjectGtk* dataObject = requestDragData(context, position, time); if (!dataObject) return; DragData dragData(dataObject, position, convertWidgetPointToScreenPoint(m_page.viewWidget(), position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context))); m_page.dragUpdated(dragData); DragOperation operation = m_page.currentDragOperation(); gdk_drag_status(context, dragOperationToSingleGdkDragAction(operation), time); }
void DragAndDropHandler::dragEntered(GdkDragContext* context, GtkSelectionData* selectionData, unsigned info, unsigned time) { IntPoint position; DataObjectGtk* dataObject = dataObjectForDropData(context, selectionData, info, position); if (!dataObject) return; DragData dragData(dataObject, position, convertWidgetPointToScreenPoint(m_page.viewWidget(), position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context))); m_page.resetCurrentDragInformation(); m_page.dragEntered(dragData); DragOperation operation = m_page.currentDragOperation(); gdk_drag_status(context, dragOperationToSingleGdkDragAction(operation), time); }
static gboolean target_drag_motion( GtkWidget *WXUNUSED(widget), GdkDragContext *context, gint x, gint y, guint time, wxDropTarget *drop_target ) { /* Owen Taylor: "if the coordinates not in a drop zone, return FALSE, otherwise call gtk_drag_status() and return TRUE" */ #if 0 wxPrintf( "motion\n" ); GList *tmp_list; for (tmp_list = context->targets; tmp_list; tmp_list = tmp_list->next) { wxString atom = wxString::FromAscii( gdk_atom_name (GDK_POINTER_TO_ATOM (tmp_list->data)) ); wxPrintf( "Atom: %s\n", atom ); } #endif // Inform the wxDropTarget about the current GdkDragContext. // This is only valid for the duration of this call. drop_target->GTKSetDragContext( context ); // Does the source actually accept the data type? if (drop_target->GTKGetMatchingPair() == (GdkAtom) 0) { drop_target->GTKSetDragContext( NULL ); return FALSE; } wxDragResult suggested_action = drop_target->GTKFigureOutSuggestedAction(); wxDragResult result = wxDragNone; if (drop_target->m_firstMotion) { // the first "drag_motion" event substitutes a "drag_enter" event result = drop_target->OnEnter( x, y, suggested_action ); } else { // give program a chance to react (i.e. to say no by returning FALSE) result = drop_target->OnDragOver( x, y, suggested_action ); } GdkDragAction result_action = GDK_ACTION_DEFAULT; if (result == wxDragCopy) result_action = GDK_ACTION_COPY; else if (result == wxDragLink) result_action = GDK_ACTION_LINK; else result_action = GDK_ACTION_MOVE; // is result action actually supported bool ret = (result_action != GDK_ACTION_DEFAULT) && (gdk_drag_context_get_actions(context) & result_action); if (ret) gdk_drag_status( context, result_action, time ); // after this, invalidate the drop_target's GdkDragContext drop_target->GTKSetDragContext( NULL ); // this has to be done because GDK has no "drag_enter" event drop_target->m_firstMotion = false; return ret; }
void athena_drag_default_drop_action_for_icons (GdkDragContext *context, const char *target_uri_string, const GList *items, int *action) { gboolean same_fs; gboolean target_is_source_parent; gboolean source_deletable; const char *dropped_uri; GFile *target, *dropped, *dropped_directory; GdkDragAction actions; AthenaFile *dropped_file, *target_file; if (target_uri_string == NULL) { *action = 0; return; } actions = gdk_drag_context_get_actions (context) & (GDK_ACTION_MOVE | GDK_ACTION_COPY); if (actions == 0) { /* We can't use copy or move, just go with the suggested action. */ *action = gdk_drag_context_get_suggested_action (context); return; } if (gdk_drag_context_get_suggested_action (context) == GDK_ACTION_ASK) { /* Don't override ask */ *action = gdk_drag_context_get_suggested_action (context); return; } dropped_uri = ((AthenaDragSelectionItem *)items->data)->uri; dropped_file = athena_file_get_existing_by_uri (dropped_uri); target_file = athena_file_get_existing_by_uri (target_uri_string); /* * Check for trash URI. We do a find_directory for any Trash directory. * Passing 0 permissions as gnome-vfs would override the permissions * passed with 700 while creating .Trash directory */ if (eel_uri_is_trash (target_uri_string)) { /* Only move to Trash */ if (actions & GDK_ACTION_MOVE) { *action = GDK_ACTION_MOVE; } athena_file_unref (dropped_file); athena_file_unref (target_file); return; } else if (dropped_file != NULL && athena_file_is_launcher (dropped_file)) { if (actions & GDK_ACTION_MOVE) { *action = GDK_ACTION_MOVE; } athena_file_unref (dropped_file); athena_file_unref (target_file); return; } else if (eel_uri_is_desktop (target_uri_string)) { target = athena_get_desktop_location (); athena_file_unref (target_file); target_file = athena_file_get (target); if (eel_uri_is_desktop (dropped_uri)) { /* Only move to Desktop icons */ if (actions & GDK_ACTION_MOVE) { *action = GDK_ACTION_MOVE; } g_object_unref (target); athena_file_unref (dropped_file); athena_file_unref (target_file); return; } } else if (target_file != NULL && athena_file_is_archive (target_file)) { *action = GDK_ACTION_COPY; athena_file_unref (dropped_file); athena_file_unref (target_file); return; } else { target = g_file_new_for_uri (target_uri_string); } same_fs = check_same_fs (target_file, dropped_file); athena_file_unref (dropped_file); athena_file_unref (target_file); /* Compare the first dropped uri with the target uri for same fs match. */ dropped = g_file_new_for_uri (dropped_uri); dropped_directory = g_file_get_parent (dropped); target_is_source_parent = FALSE; if (dropped_directory != NULL) { /* If the dropped file is already in the same directory but is in another filesystem we still want to move, not copy as this is then just a move of a mountpoint to another position in the dir */ target_is_source_parent = g_file_equal (dropped_directory, target); g_object_unref (dropped_directory); } source_deletable = source_is_deletable (dropped); if ((same_fs && source_deletable) || target_is_source_parent || g_file_has_uri_scheme (dropped, "trash")) { if (actions & GDK_ACTION_MOVE) { *action = GDK_ACTION_MOVE; } else { *action = gdk_drag_context_get_suggested_action (context); } } else { if (actions & GDK_ACTION_COPY) { *action = GDK_ACTION_COPY; } else { *action = gdk_drag_context_get_suggested_action (context); } } g_object_unref (target); g_object_unref (dropped); }
gboolean on_dir_tree_view_drag_motion ( GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y, guint time, PtkFileBrowser* file_browser ) //MOD added { GdkDragAction suggested_action; GdkAtom target; GtkTargetList* target_list; target_list = gtk_target_list_new( drag_targets, G_N_ELEMENTS(drag_targets) ); target = gtk_drag_dest_find_target( widget, drag_context, target_list ); gtk_target_list_unref( target_list ); if (target == GDK_NONE) gdk_drag_status( drag_context, 0, time); else { // Need to set suggested_action because default handler assumes copy /* Only 'move' is available. The user force move action by pressing Shift key */ if( (gdk_drag_context_get_actions ( drag_context ) & GDK_ACTION_ALL) == GDK_ACTION_MOVE ) suggested_action = GDK_ACTION_MOVE; /* Only 'copy' is available. The user force copy action by pressing Ctrl key */ else if( (gdk_drag_context_get_actions ( drag_context ) & GDK_ACTION_ALL) == GDK_ACTION_COPY ) suggested_action = GDK_ACTION_COPY; /* Only 'link' is available. The user force link action by pressing Shift+Ctrl key */ else if( (gdk_drag_context_get_actions ( drag_context ) & GDK_ACTION_ALL) == GDK_ACTION_LINK ) suggested_action = GDK_ACTION_LINK; /* Several different actions are available. We have to figure out a good default action. */ else { int drag_action = xset_get_int( "drag_action", "x" ); if ( drag_action == 1 ) suggested_action = GDK_ACTION_COPY; else if ( drag_action == 2 ) suggested_action = GDK_ACTION_MOVE; else if ( drag_action == 3 ) suggested_action = GDK_ACTION_LINK; else { // automatic file_browser->pending_drag_status_tree = 1; gtk_drag_get_data (widget, drag_context, target, time); suggested_action = gdk_drag_context_get_selected_action( drag_context ); } } #if GTK_CHECK_VERSION (3, 0, 0) /* hack to be able to call the default handler with the correct suggested_action */ struct _GdkDragContext { GObject parent_instance; /*< private >*/ GdkDragProtocol protocol; #if GTK_CHECK_VERSION (3, 22, 0) /* 1.0.6 per Teklad: _GdkDragContext appears to change between * different versions of GTK3 which causes the crash. It appears they * added/removed some variables from that struct. * https://github.com/IgnorantGuru/spacefm/issues/670 */ GdkDisplay *display; #endif gboolean is_source; GdkWindow *source_window; GdkWindow *dest_window; GList *targets; GdkDragAction actions; GdkDragAction suggested_action; GdkDragAction action; guint32 start_time; GdkDevice *device; #if GTK_CHECK_VERSION (3, 22, 0) /* 1.0.6 per Teklad: _GdkDragContext appears to change between * different versions of GTK3 which causes the crash. It appears they * added/removed some variables from that struct. * https://github.com/IgnorantGuru/spacefm/issues/670 */ guint drop_done : 1; /* Whether gdk_drag_drop_done() was performed */ #endif }; ((struct _GdkDragContext *)drag_context)->suggested_action = suggested_action; #else drag_context->suggested_action = suggested_action; // needed for default handler #endif gdk_drag_status( drag_context, suggested_action, gtk_get_current_event_time() ); } return FALSE; }