📄 gtkdnd.c
字号:
current_event = gtk_get_current_event (); if (site->proxy_window) { dest_window = site->proxy_window; proto = site->proxy_protocol; } else { gdk_drag_find_window (info->proxy_source->context, NULL, current_event->dnd.x_root, current_event->dnd.y_root, &dest_window, &proto); } gdk_drag_motion (info->proxy_source->context, dest_window, proto, current_event->dnd.x_root, current_event->dnd.y_root, context->suggested_action, context->actions, time); if (!site->proxy_window && dest_window) gdk_window_unref (dest_window); selection = gdk_drag_get_selection (info->proxy_source->context); if (selection && selection != gdk_drag_get_selection (info->context)) gtk_drag_source_check_selection (info->proxy_source, selection, time); gdk_event_free (current_event); return TRUE; } if (site->flags & GTK_DEST_DEFAULT_MOTION) { if (context->suggested_action & site->actions) action = context->suggested_action; else { gint i; for (i=0; i<8; i++) { if ((site->actions & (1 << i)) && (context->actions & (1 << i))) { action = (1 << i); break; } } } if (action && gtk_drag_dest_find_target (widget, site, context)) { if (!site->have_drag) { site->have_drag = TRUE; if (site->flags & GTK_DEST_DEFAULT_HIGHLIGHT) gtk_drag_highlight (widget); } gdk_drag_status (context, action, time); } else { gdk_drag_status (context, 0, time); return TRUE; } } gtk_signal_emit_by_name (GTK_OBJECT (widget), "drag_motion", context, x, y, time, &retval); return (site->flags & GTK_DEST_DEFAULT_MOTION) ? TRUE : retval;}static gbooleangtk_drag_dest_drop (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time){ GtkDragDestSite *site; GtkDragDestInfo *info; site = gtk_object_get_data (GTK_OBJECT (widget), "gtk-drag-dest"); g_return_val_if_fail (site != NULL, FALSE); info = g_dataset_get_data (context, "gtk-info"); g_return_val_if_fail (info != NULL, FALSE); info->drop_x = x; info->drop_y = y; if (site->do_proxy) { if (info->proxy_source || (info->context->protocol == GDK_DRAG_PROTO_ROOTWIN)) { gtk_drag_drop (info->proxy_source, time); } else { /* We need to synthesize a motion event, wait for a status, * and, if we get a good one, do a drop. */ GdkEvent *current_event; GdkAtom selection; GdkWindow *dest_window; GdkDragProtocol proto; gtk_drag_proxy_begin (widget, info); info->proxy_drop_wait = TRUE; info->proxy_drop_time = time; current_event = gtk_get_current_event (); if (site->proxy_window) { dest_window = site->proxy_window; proto = site->proxy_protocol; } else { gdk_drag_find_window (info->proxy_source->context, NULL, current_event->dnd.x_root, current_event->dnd.y_root, &dest_window, &proto); } gdk_drag_motion (info->proxy_source->context, dest_window, proto, current_event->dnd.x_root, current_event->dnd.y_root, context->suggested_action, context->actions, time); if (!site->proxy_window && dest_window) gdk_window_unref (dest_window); selection = gdk_drag_get_selection (info->proxy_source->context); if (selection && selection != gdk_drag_get_selection (info->context)) gtk_drag_source_check_selection (info->proxy_source, selection, time); gdk_event_free (current_event); } return TRUE; } else { gboolean retval; if (site->flags & GTK_DEST_DEFAULT_DROP) { GdkAtom target = gtk_drag_dest_find_target (widget, site, context); if (target == GDK_NONE) return FALSE; gtk_drag_get_data (widget, context, target, time); } gtk_signal_emit_by_name (GTK_OBJECT (widget), "drag_drop", context, x, y, time, &retval); return (site->flags & GTK_DEST_DEFAULT_DROP) ? TRUE : retval; }}/*************** * Source side * ***************//************************************************************* * gtk_drag_begin: Start a drag operation * * arguments: * widget: Widget from which drag starts * handlers: List of handlers to supply the data for the drag * button: Button user used to start drag * time: Time of event starting drag * * results: *************************************************************/GdkDragContext *gtk_drag_begin (GtkWidget *widget, GtkTargetList *target_list, GdkDragAction actions, gint button, GdkEvent *event){ GtkDragSourceInfo *info; GList *targets = NULL; GList *tmp_list; guint32 time = GDK_CURRENT_TIME; GdkDragAction possible_actions, suggested_action; g_return_val_if_fail (widget != NULL, NULL); g_return_val_if_fail (GTK_WIDGET_REALIZED (widget), NULL); g_return_val_if_fail (target_list != NULL, NULL); if (event) time = gdk_event_get_time (event); info = g_new0 (GtkDragSourceInfo, 1); info->ipc_widget = gtk_drag_get_ipc_widget (); source_widgets = g_slist_prepend (source_widgets, info->ipc_widget); gtk_object_set_data (GTK_OBJECT (info->ipc_widget), "gtk-info", info); tmp_list = g_list_last (target_list->list); while (tmp_list) { GtkTargetPair *pair = tmp_list->data; targets = g_list_prepend (targets, GINT_TO_POINTER (pair->target)); tmp_list = tmp_list->prev; } info->widget = widget; gtk_widget_ref (info->widget); info->context = gdk_drag_begin (info->ipc_widget->window, targets); g_list_free (targets); g_dataset_set_data (info->context, "gtk-info", info); info->button = button; info->target_list = target_list; gtk_target_list_ref (target_list); info->possible_actions = actions; info->cursor = NULL; info->status = GTK_DRAG_STATUS_DRAG; info->last_event = NULL; info->selections = NULL; info->icon_window = NULL; info->destroy_icon = FALSE; gtk_drag_get_event_actions (event, info->button, actions, &suggested_action, &possible_actions); if (event) info->cursor = gtk_drag_get_cursor (suggested_action); /* Set cur_x, cur_y here so if the "drag_begin" signal shows * the drag icon, it will be in the right place */ if (event->type == GDK_MOTION_NOTIFY) { info->cur_x = event->motion.x_root; info->cur_y = event->motion.y_root; } else { gint x, y; gdk_window_get_pointer (GDK_ROOT_PARENT (), &x, &y, NULL); info->cur_x = x; info->cur_y = y; } gtk_signal_emit_by_name (GTK_OBJECT (widget), "drag_begin", info->context); if (event->type == GDK_MOTION_NOTIFY) gtk_drag_motion_cb (info->ipc_widget, (GdkEventMotion *)event, info); info->start_x = info->cur_x; info->start_y = info->cur_y; gtk_signal_connect (GTK_OBJECT (info->ipc_widget), "button_release_event", GTK_SIGNAL_FUNC (gtk_drag_button_release_cb), info); gtk_signal_connect (GTK_OBJECT (info->ipc_widget), "motion_notify_event", GTK_SIGNAL_FUNC (gtk_drag_motion_cb), info); gtk_signal_connect (GTK_OBJECT (info->ipc_widget), "key_press_event", GTK_SIGNAL_FUNC (gtk_drag_key_cb), info); gtk_signal_connect (GTK_OBJECT (info->ipc_widget), "key_release_event", GTK_SIGNAL_FUNC (gtk_drag_key_cb), info); gtk_signal_connect (GTK_OBJECT (info->ipc_widget), "selection_get", GTK_SIGNAL_FUNC (gtk_drag_selection_get), info); /* We use a GTK grab here to override any grabs that the widget * we are dragging from might have held */ gtk_grab_add (info->ipc_widget); if (gdk_pointer_grab (info->ipc_widget->window, FALSE, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_RELEASE_MASK, NULL, info->cursor, time) == 0) { if (gdk_keyboard_grab (info->ipc_widget->window, FALSE, time) != 0) { /* FIXME: This should be cleaned up... */ GdkEventButton ev; ev.time = time; ev.type = GDK_BUTTON_RELEASE; ev.button = info->button; gtk_drag_button_release_cb (widget, &ev, info); return NULL; } } return info->context;}/************************************************************* * gtk_drag_source_set: * Register a drop site, and possibly add default behaviors. * arguments: * widget: * start_button_mask: Mask of allowed buttons to start drag * targets: Table of targets for this source * n_targets: * actions: Actions allowed for this source * results: *************************************************************/void gtk_drag_source_set (GtkWidget *widget, GdkModifierType start_button_mask, const GtkTargetEntry *targets, gint n_targets, GdkDragAction actions){ GtkDragSourceSite *site; g_return_if_fail (widget != NULL); site = gtk_object_get_data (GTK_OBJECT (widget), "gtk-site-data"); gtk_widget_add_events (widget, gtk_widget_get_events (widget) | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_MOTION_MASK); if (site) { if (site->target_list) gtk_target_list_unref (site->target_list); } else { site = g_new0 (GtkDragSourceSite, 1); gtk_signal_connect (GTK_OBJECT (widget), "button_press_event", GTK_SIGNAL_FUNC (gtk_drag_source_event_cb), site); gtk_signal_connect (GTK_OBJECT (widget), "motion_notify_event", GTK_SIGNAL_FUNC (gtk_drag_source_event_cb), site); gtk_object_set_data_full (GTK_OBJECT (widget), "gtk-site-data", site, gtk_drag_source_site_destroy); } site->start_button_mask = start_button_mask; if (targets) site->target_list = gtk_target_list_new (targets, n_targets); else site->target_list = NULL; site->actions = actions;}/************************************************************* * gtk_drag_source_unset * Unregister this widget as a drag source. * arguments: * widget: * results: *************************************************************/void gtk_drag_source_unset (GtkWidget *widget){ GtkDragSourceSite *site; g_return_if_fail (widget != NULL); site = gtk_object_get_data (GTK_OBJECT (widget), "gtk-site-data"); if (site) { gtk_signal_disconnect_by_data (GTK_OBJECT (widget), site); gtk_object_set_data (GTK_OBJECT (widget), "gtk-site-data", NULL); }}/************************************************************* * gtk_drag_source_set_icon: * Set an icon for drags from this source. * arguments: * colormap: Colormap for this icon * pixmap: * mask * results: *************************************************************/void gtk_drag_source_set_icon (GtkWidget *widget, GdkColormap *colormap, GdkPixmap *pixmap, GdkBitmap *mask){ GtkDragSourceSite *site; g_return_if_fail (widget != NULL); site = gtk_object_get_data (GTK_OBJECT (widget), "gtk-site-data"); g_return_if_fail (site != NULL); if (site->colormap) gdk_colormap_unref (site->colormap); if (site->pixmap) gdk_pixmap_unref (site->pixmap); if (site->mask) gdk_pixmap_unref (site->mask); site->colormap = colormap; if (colormap) gdk_colormap_ref (colormap); site->pixmap = pixmap; if (pixmap) gdk_pixmap_ref (pixmap); site->mask = mask; if (mask) gdk_pixmap_ref (mask);}/************************************************************* * gtk_drag_set_icon_window: * Set a widget as the icon for a drag. * arguments: * context: * widget: * hot_x: Hot spot * hot_y: * results: *************************************************************/static void gtk_drag_set_icon_window (GdkDragContext *context, GtkWidget *widget, gint hot_x, gint hot_y, gboolean destroy_on_release){ GtkDragSourceInfo *info; g_return_if_fail (context != NULL); g_return_if_fail (widget != NULL); info = g_dataset_get_data (context, "gtk-info"); gtk_drag_remove_icon (info);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -