int clip_GDK_DRAGMOTION(ClipMachine * cm) { C_object *ccontext = _fetch_co_arg(cm); C_object *cgdk_win = _fetch_cobject(cm, _clip_spar(cm, 2)); GdkDragProtocol protocol = _clip_parni(cm, 3); gint x_root = _clip_parni(cm, 4); gint y_root = _clip_parni(cm, 5); GdkDragAction suggested_action = _clip_parni(cm, 6); GdkDragAction possible_actions = _clip_parni(cm, 7); guint32 time = _clip_parni(cm, 8); if (!ccontext || ccontext->type != GDK_TYPE_DRAG_CONTEXT) goto err; CHECKCOBJ(cgdk_win, GDK_IS_WINDOW(cgdk_win->object)); CHECKARG(3, NUMERIC_t); CHECKARG(4, NUMERIC_t); CHECKARG(5, NUMERIC_t); CHECKARG(6, NUMERIC_t); CHECKARG(7, NUMERIC_t); CHECKARG(8, NUMERIC_t); gdk_drag_motion((GdkDragContext*)ccontext->object, GDK_WINDOW(cgdk_win->object), protocol, x_root, y_root, suggested_action, possible_actions, time); return 0; err: return 1; }
static VALUE rg_drag_motion(VALUE self, VALUE dest_window, VALUE protocol, VALUE x_root, VALUE y_root, VALUE suggested_action, VALUE possible_actions, VALUE time) { gboolean ret = gdk_drag_motion(_SELF(self), GDK_WINDOW(RVAL2GOBJ(dest_window)), RVAL2GENUM(protocol, GDK_TYPE_DRAG_PROTOCOL), NUM2INT(x_root), NUM2INT(y_root), RVAL2GFLAGS(suggested_action, GDK_TYPE_DRAG_ACTION), RVAL2GFLAGS(possible_actions, GDK_TYPE_DRAG_ACTION), NUM2UINT(time)); return CBOOL2RVAL(ret); }
static void process_drag_motion(gint x_root, gint y_root, guint state) { GdkWindow *dest_window; GdkDragProtocol prot; gdk_drag_find_window_for_screen(get_drag_context(), NULL, gdk_screen_get_default(), x_root, y_root, &dest_window, &prot); if (prot != GDK_DRAG_PROTO_NONE) { GdkDragAction action, possible_actions; determine_actions(state, &action, &possible_actions); gdk_drag_motion(get_drag_context(), dest_window, prot, x_root, y_root, action, possible_actions, GDK_CURRENT_TIME); } }
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); }
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; }
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; }