int clip_GDK_DRAGDROP(ClipMachine * cm) { C_object *ccontext = _fetch_co_arg(cm); guint32 time = _clip_parni(cm, 2); if (!ccontext || ccontext->type != GDK_TYPE_DRAG_CONTEXT) goto err; CHECKARG(2, NUMERIC_t); gdk_drag_drop((GdkDragContext*)ccontext->object, time); return 0; err: return 1; }
gboolean gwy_remote_open_files(GwyRemote *remote, int argc, char **argv) { GdkNativeWindow xid; GdkDragContext *context; GdkDragProtocol protocol; GtkWidget *source; GdkAtom sel_type, sel_id; GString *file_list; GList *targetlist; gchar *cwd; gint i; if (!remote) return FALSE; xid = gdk_drag_get_protocol_for_display(remote->display, remote->winid, &protocol); /* FIXME: Here we may need some platform-dependent protocol check. * protocol should be GDK_DRAG_PROTO_XDND on X11, but on win32 * gdk_drag_get_protocol_for_display returns 0, which means there * is no DnD support for target window. */ if (!xid) { g_printerr("Gwyddion window doesn't support DnD.\n"); return FALSE; } /* Now we have the toolbox, it seems to support DnD and we have some files * to send to it. So build the list. */ cwd = g_get_current_dir(); file_list = g_string_sized_new(32*argc); for (i = 0; i < argc; i++) { gchar *s, *t; if (i) g_string_append_c(file_list, '\n'); if (g_path_is_absolute(argv[i])) s = g_filename_to_uri(argv[i], NULL, NULL); else { t = g_build_filename(cwd, argv[i], NULL); s = g_filename_to_uri(t, NULL, NULL); g_free(t); } g_string_append(file_list, s); g_free(s); } /* Don't hang when the toolbox is non-responsive. * This may not be necessary in Gwyddion, but it does not hurt either. */ g_timeout_add(2000, toolbox_timeout, NULL); /* Set up an DnD-source. */ source = gtk_window_new(GTK_WINDOW_TOPLEVEL); g_signal_connect(source, "selection-get", G_CALLBACK(source_selection_get), file_list->str); gtk_widget_realize(source); /* Specify the id and the content-type of the selection used to * pass the URIs to Gwyddion toolbox. */ sel_id = gdk_atom_intern("XdndSelection", FALSE); sel_type = gdk_atom_intern("text/plain", FALSE); targetlist = g_list_prepend(NULL, GUINT_TO_POINTER(sel_type)); /* Assign the selection to our DnD-source. */ gtk_selection_owner_set(source, sel_id, GDK_CURRENT_TIME); gtk_selection_add_target(source, sel_id, sel_type, 0); /* Drag_begin/motion/drop. */ context = gdk_drag_begin(source->window, targetlist); gdk_drag_motion(context, remote->toolbox, protocol, 0, 0, GDK_ACTION_COPY, GDK_ACTION_COPY, GDK_CURRENT_TIME); gdk_drag_drop(context, GDK_CURRENT_TIME); /* Finally enter the mainloop to handle the events. */ gtk_main(); gdk_notify_startup_complete(); return TRUE; }
static VALUE rg_drag_drop(VALUE self, VALUE time) { gdk_drag_drop(_SELF(self), NUM2UINT(time)); return self; }
gboolean gimp_remote_drop_files (GdkDisplay *display, GdkWindow *window, GString *file_list) { GdkDragContext *context; GdkDragProtocol protocol; GtkWidget *source; GdkAtom sel_type; GdkAtom sel_id; GList *targetlist; guint timeout; gdk_drag_get_protocol_for_display (display, GDK_WINDOW_XID (window), &protocol); if (protocol != GDK_DRAG_PROTO_XDND) { g_printerr ("GIMP Window doesnt use Xdnd-Protocol - huh?\n"); return FALSE; } /* Problem: If the Toolbox is hidden via Tab (gtk_widget_hide) * it does not accept DnD-Operations and gtk_main() will not be * terminated. If the Toolbox is simply unmapped (by the WM) * DnD works. But in both cases gdk_window_is_visible() returns * FALSE. To work around this we add a timeout and abort after * 5 seconds. */ timeout = g_timeout_add (5000, toolbox_hidden, NULL); /* set up an DND-source */ source = gtk_window_new (GTK_WINDOW_TOPLEVEL); g_signal_connect (source, "selection-get", G_CALLBACK (source_selection_get), file_list->str); gtk_widget_realize (source); /* specify the id and the content-type of the selection used to * pass the URIs to GIMP. */ sel_id = gdk_atom_intern ("XdndSelection", FALSE); sel_type = gdk_atom_intern ("text/uri-list", FALSE); targetlist = g_list_prepend (NULL, GUINT_TO_POINTER (sel_type)); /* assign the selection to our DnD-source */ gtk_selection_owner_set (source, sel_id, GDK_CURRENT_TIME); gtk_selection_add_target (source, sel_id, sel_type, 0); /* drag_begin/motion/drop */ context = gdk_drag_begin (gtk_widget_get_window (source), targetlist); gdk_drag_motion (context, window, protocol, 0, 0, GDK_ACTION_COPY, GDK_ACTION_COPY, GDK_CURRENT_TIME); gdk_drag_drop (context, GDK_CURRENT_TIME); /* finally enter the mainloop to handle the events */ gtk_main (); g_source_remove (timeout); return TRUE; }
static void process_dnd_source_mouse_release(GdkWindow *window, GdkEventButton *event) { glass_gdk_master_pointer_ungrab(); if (GLASS_GDK_DRAG_CONTEXT_GET_SELECTED_ACTION(get_drag_context())) { gdk_drag_drop(get_drag_context(), GDK_CURRENT_TIME); } else { gdk_drag_abort(get_drag_context(), GDK_CURRENT_TIME); /* let the gdk_drag_abort messages handled before finish */ gdk_threads_add_idle((GSourceFunc) dnd_finish_callback, NULL); } }