#include "gtkimage.h"
#include "gtkinvisible.h"
#include "gtkmain.h"
-#include "gtksignal.h"
#include "gtkstock.h"
#include "gtkwindow.h"
-static GSList *drag_widgets = NULL;
static GSList *source_widgets = NULL;
typedef struct _GtkDragSourceSite GtkDragSourceSite;
GdkDragAction possible_actions; /* Actions allowed by source */
GdkDragContext *context; /* drag context */
GtkWidget *icon_window; /* Window for drag */
+ GtkWidget *fallback_icon; /* Window for drag used on other screens */
GtkWidget *ipc_widget; /* GtkInvisible for grab, message passing */
GdkCursor *cursor; /* Cursor for drag */
gint hot_x, hot_y; /* Hot spot for drag */
gint start_x, start_y; /* Initial position */
gint cur_x, cur_y; /* Current Position */
+ GdkScreen *cur_screen; /* Current screen for pointer */
+ guint32 grab_time; /* timestamp for initial grab */
GList *selections; /* selections we've claimed */
GtkDragDestInfo *proxy_dest; /* Set if this is a proxy drag */
guint drop_timeout; /* Timeout for aborting drop */
guint destroy_icon : 1; /* If true, destroy icon_window
- */
+ */
+ guint have_grab : 1; /* Do we still have the pointer grab
+ */
};
struct _GtkDragDestSite
GdkDragAction actions,
GdkDragAction *suggested_action,
GdkDragAction *possible_actions);
-static GdkCursor * gtk_drag_get_cursor (GdkDragAction action);
-static GtkWidget *gtk_drag_get_ipc_widget (void);
+static GdkCursor * gtk_drag_get_cursor (GdkDisplay *display,
+ GdkDragAction action);
+static GtkWidget *gtk_drag_get_ipc_widget (GdkScreen *screen);
static void gtk_drag_release_ipc_widget (GtkWidget *widget);
static gboolean gtk_drag_highlight_expose (GtkWidget *widget,
static void gtk_drag_drop_finished (GtkDragSourceInfo *info,
gboolean success,
guint time);
+static void gtk_drag_cancel (GtkDragSourceInfo *info,
+ guint32 time);
static gint gtk_drag_source_event_cb (GtkWidget *widget,
GdkEvent *event,
static void gtk_drag_remove_icon (GtkDragSourceInfo *info);
static void gtk_drag_source_info_destroy (GtkDragSourceInfo *info);
static void gtk_drag_update (GtkDragSourceInfo *info,
+ GdkScreen *screen,
gint x_root,
gint y_root,
GdkEvent *event);
static struct {
GdkDragAction action;
- const char *bits;
- const char *mask;
+ const guchar *bits;
+ const guchar *mask;
GdkCursor *cursor;
} drag_cursors[] = {
{ GDK_ACTION_DEFAULT, 0 },
* Utility functions *
*********************/
+static void
+set_can_change_screen (GtkWidget *widget,
+ gboolean can_change_screen)
+{
+ can_change_screen = can_change_screen != FALSE;
+
+ g_object_set_data (G_OBJECT (widget), "gtk-dnd-can-change-screen",
+ GUINT_TO_POINTER (can_change_screen));
+}
+
+static gboolean
+get_can_change_screen (GtkWidget *widget)
+{
+ return g_object_get_data (G_OBJECT (widget), "gtk-dnd-can-change-screen") != NULL;
+
+}
+
/*************************************************************
* gtk_drag_get_ipc_widget:
* Return a invisible, off-screen, override-redirect
*************************************************************/
static GtkWidget *
-gtk_drag_get_ipc_widget (void)
+gtk_drag_get_ipc_widget (GdkScreen *screen)
{
GtkWidget *result;
+ GSList *drag_widgets = g_object_get_data (G_OBJECT (screen),
+ "gtk-dnd-ipc-widgets");
if (drag_widgets)
{
GSList *tmp = drag_widgets;
result = drag_widgets->data;
drag_widgets = drag_widgets->next;
+ g_object_set_data (G_OBJECT (screen),
+ "gtk-dnd-ipc-widgets",
+ drag_widgets);
g_slist_free_1 (tmp);
}
else
{
- result = gtk_invisible_new ();
+ result = gtk_invisible_new_for_screen (screen);
gtk_widget_show (result);
}
static void
gtk_drag_release_ipc_widget (GtkWidget *widget)
{
+ GdkScreen *screen = gtk_widget_get_screen (widget);
+ GSList *drag_widgets = g_object_get_data (G_OBJECT (screen),
+ "gtk-dnd-ipc-widgets");
drag_widgets = g_slist_prepend (drag_widgets, widget);
+ g_object_set_data (G_OBJECT (screen),
+ "gtk-dnd-ipc-widgets",
+ drag_widgets);
}
static guint32
}
static GdkCursor *
-gtk_drag_get_cursor (GdkDragAction action)
+gtk_drag_get_cursor (GdkDisplay *display,
+ GdkDragAction action)
{
gint i;
for (i = 0 ; i < n_drag_cursors - 1; i++)
if (drag_cursors[i].action == action)
break;
+ if (drag_cursors[i].cursor != NULL)
+ {
+ if (display != gdk_cursor_get_display (drag_cursors[i].cursor))
+ {
+ gdk_cursor_unref (drag_cursors[i].cursor);
+ drag_cursors[i].cursor = NULL;
+ }
+ }
if (drag_cursors[i].cursor == NULL)
{
- GdkColor fg, bg;
+ GdkColor bg = { 0, 0xffff, 0xffff, 0xffff };
+ GdkColor fg = { 0, 0x0000, 0x0000, 0x0000 };
+ GdkScreen *screen = gdk_display_get_default_screen (display);
+ GdkWindow *window = gdk_screen_get_root_window (screen);
GdkPixmap *pixmap =
- gdk_bitmap_create_from_data (NULL,
- drag_cursors[i].bits,
- CURSOR_WIDTH, CURSOR_HEIGHT);
+ gdk_bitmap_create_from_data (window, (gchar *)drag_cursors[i].bits, CURSOR_WIDTH, CURSOR_HEIGHT);
+
GdkPixmap *mask =
- gdk_bitmap_create_from_data (NULL,
- drag_cursors[i].mask,
- CURSOR_WIDTH, CURSOR_HEIGHT);
+ gdk_bitmap_create_from_data (window, (gchar *)drag_cursors[i].mask, CURSOR_WIDTH, CURSOR_HEIGHT);
- gdk_color_white (gdk_colormap_get_system (), &bg);
- gdk_color_black (gdk_colormap_get_system (), &fg);
-
drag_cursors[i].cursor = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg, 0, 0);
- gdk_pixmap_unref (pixmap);
- gdk_pixmap_unref (mask);
+ g_object_unref (pixmap);
+ g_object_unref (mask);
}
return drag_cursors[i].cursor;
{
GtkWidget *selection_widget;
- g_return_if_fail (widget != NULL);
- g_return_if_fail (context != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
+ g_return_if_fail (!context->is_source);
- selection_widget = gtk_drag_get_ipc_widget ();
+ selection_widget = gtk_drag_get_ipc_widget (gtk_widget_get_screen (widget));
- gdk_drag_context_ref (context);
- gtk_widget_ref (widget);
+ g_object_ref (context);
+ g_object_ref (widget);
- gtk_signal_connect (GTK_OBJECT (selection_widget), "selection_received",
- GTK_SIGNAL_FUNC (gtk_drag_selection_received), widget);
+ g_signal_connect (selection_widget, "selection_received",
+ G_CALLBACK (gtk_drag_selection_received), widget);
- gtk_object_set_data (GTK_OBJECT (selection_widget), "drag-context", context);
+ g_object_set_data (G_OBJECT (selection_widget), "drag-context", context);
gtk_selection_convert (selection_widget,
gdk_drag_get_selection (context),
{
GSList *tmp_list;
+ g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
+ g_return_val_if_fail (!context->is_source, NULL);
+
tmp_list = source_widgets;
while (tmp_list)
{
if (ipc_widget->window == context->source_window)
{
GtkDragSourceInfo *info;
- info = gtk_object_get_data (GTK_OBJECT (ipc_widget), "gtk-info");
+ info = g_object_get_data (G_OBJECT (ipc_widget), "gtk-info");
return info ? info->widget : NULL;
}
{
GdkAtom target = GDK_NONE;
- g_return_if_fail (context != NULL);
+ g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
+ g_return_if_fail (!context->is_source);
if (success && del)
{
if (target != GDK_NONE)
{
- GtkWidget *selection_widget = gtk_drag_get_ipc_widget ();
+ GtkWidget *selection_widget = gtk_drag_get_ipc_widget (gdk_drawable_get_screen (context->source_window));
- gdk_drag_context_ref (context);
+ g_object_ref (context);
- gtk_object_set_data (GTK_OBJECT (selection_widget), "drag-context", context);
- gtk_signal_connect (GTK_OBJECT (selection_widget), "selection_received",
- GTK_SIGNAL_FUNC (gtk_drag_selection_received),
- NULL);
+ g_object_set_data (G_OBJECT (selection_widget), "drag-context", context);
+ g_signal_connect (selection_widget, "selection_received",
+ G_CALLBACK (gtk_drag_selection_received),
+ NULL);
gtk_selection_convert (selection_widget,
gdk_drag_get_selection (context),
{
x = 0;
y = 0;
- gdk_window_get_size (widget->window, &width, &height);
+ gdk_drawable_get_size (widget->window, &width, &height);
}
- gtk_draw_shadow (widget->style, widget->window,
- GTK_STATE_NORMAL, GTK_SHADOW_OUT,
- x, y, width, height);
+ gtk_paint_shadow (widget->style, widget->window,
+ GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+ NULL, widget, "dnd",
+ x, y, width, height);
gdk_draw_rectangle (widget->window,
widget->style->black_gc,
void
gtk_drag_highlight (GtkWidget *widget)
{
- gtk_signal_connect_after (GTK_OBJECT (widget), "expose_event",
- GTK_SIGNAL_FUNC (gtk_drag_highlight_expose),
- NULL);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ g_signal_connect_after (widget, "expose_event",
+ G_CALLBACK (gtk_drag_highlight_expose),
+ NULL);
gtk_widget_queue_draw (widget);
}
void
gtk_drag_unhighlight (GtkWidget *widget)
{
- g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
- gtk_signal_disconnect_by_func (GTK_OBJECT (widget),
- GTK_SIGNAL_FUNC (gtk_drag_highlight_expose),
- NULL);
+ g_signal_handlers_disconnect_by_func (widget,
+ gtk_drag_highlight_expose,
+ NULL);
- gtk_widget_queue_clear (widget);
+ gtk_widget_queue_draw (widget);
}
static void
g_return_if_fail (widget != NULL);
/* HACK, do this in the destroy */
- old_site = gtk_object_get_data (GTK_OBJECT (widget), "gtk-drag-dest");
+ old_site = g_object_get_data (G_OBJECT (widget), "gtk-drag-dest");
if (old_site)
- gtk_signal_disconnect_by_data (GTK_OBJECT (widget), old_site);
+ {
+ g_signal_handlers_disconnect_by_func (widget,
+ gtk_drag_dest_realized,
+ old_site);
+ g_signal_handlers_disconnect_by_func (widget,
+ gtk_drag_dest_hierarchy_changed,
+ old_site);
+ }
if (GTK_WIDGET_REALIZED (widget))
gtk_drag_dest_realized (widget);
- gtk_signal_connect (GTK_OBJECT (widget), "realize",
- GTK_SIGNAL_FUNC (gtk_drag_dest_realized), site);
- gtk_signal_connect (GTK_OBJECT (widget), "hierarchy_changed",
- GTK_SIGNAL_FUNC (gtk_drag_dest_hierarchy_changed), site);
+ g_signal_connect (widget, "realize",
+ G_CALLBACK (gtk_drag_dest_realized), site);
+ g_signal_connect (widget, "hierarchy_changed",
+ G_CALLBACK (gtk_drag_dest_hierarchy_changed), site);
- gtk_object_set_data_full (GTK_OBJECT (widget), "gtk-drag-dest",
- site, gtk_drag_dest_site_destroy);
+ g_object_set_data_full (G_OBJECT (widget), "gtk-drag-dest",
+ site, gtk_drag_dest_site_destroy);
}
{
GtkDragDestSite *site;
- g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
site = g_new (GtkDragDestSite, 1);
site->target_list = gtk_target_list_new (targets, n_targets);
else
site->target_list = NULL;
-
site->actions = actions;
site->do_proxy = FALSE;
+ site->proxy_window = NULL;
gtk_drag_dest_set_internal (widget, site);
}
{
GtkDragDestSite *site;
- g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (!proxy_window || GDK_IS_WINDOW (proxy_window));
site = g_new (GtkDragDestSite, 1);
site->actions = 0;
site->proxy_window = proxy_window;
if (proxy_window)
- gdk_window_ref (proxy_window);
+ g_object_ref (proxy_window);
site->do_proxy = TRUE;
site->proxy_protocol = protocol;
site->proxy_coords = use_coordinates;
void
gtk_drag_dest_unset (GtkWidget *widget)
{
- g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
- gtk_object_set_data (GTK_OBJECT (widget), "gtk-drag-dest", NULL);
+ g_object_set_data (G_OBJECT (widget), "gtk-drag-dest", NULL);
}
/**
gtk_drag_dest_get_target_list (GtkWidget *widget)
{
GtkDragDestSite *site;
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
- site = gtk_object_get_data (GTK_OBJECT (widget), "gtk-drag-dest");
+ site = g_object_get_data (G_OBJECT (widget), "gtk-drag-dest");
return site ? site->target_list : NULL;
}
GtkTargetList *target_list)
{
GtkDragDestSite *site;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
- site = gtk_object_get_data (GTK_OBJECT (widget), "gtk-drag-dest");
+ site = g_object_get_data (G_OBJECT (widget), "gtk-drag-dest");
if (site == NULL)
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), GDK_NONE);
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), GDK_NONE);
+ g_return_val_if_fail (!context->is_source, GDK_NONE);
+
source_widget = gtk_drag_get_source_widget (context);
drop_widget = data;
- context = gtk_object_get_data (GTK_OBJECT (widget), "drag-context");
+ context = g_object_get_data (G_OBJECT (widget), "drag-context");
info = gtk_drag_get_dest_info (context, FALSE);
if (info->proxy_data &&
{
GtkDragDestSite *site;
- site = gtk_object_get_data (GTK_OBJECT (drop_widget), "gtk-drag-dest");
+ site = g_object_get_data (G_OBJECT (drop_widget), "gtk-drag-dest");
if (site && site->target_list)
{
{
if (!(site->flags & GTK_DEST_DEFAULT_DROP) ||
selection_data->length >= 0)
- gtk_signal_emit_by_name (GTK_OBJECT (drop_widget),
- "drag_data_received",
- context, info->drop_x, info->drop_y,
- selection_data,
- target_info, time);
+ g_signal_emit_by_name (drop_widget,
+ "drag_data_received",
+ context, info->drop_x, info->drop_y,
+ selection_data,
+ target_info, time);
}
}
else
{
- gtk_signal_emit_by_name (GTK_OBJECT (drop_widget),
- "drag_data_received",
- context, info->drop_x, info->drop_y,
- selection_data, 0, time);
+ g_signal_emit_by_name (drop_widget,
+ "drag_data_received",
+ context, info->drop_x, info->drop_y,
+ selection_data,
+ 0, time);
}
if (site && site->flags & GTK_DEST_DEFAULT_DROP)
time);
}
- gtk_widget_unref (drop_widget);
+ g_object_unref (drop_widget);
}
- gtk_signal_disconnect_by_func (GTK_OBJECT (widget),
- GTK_SIGNAL_FUNC (gtk_drag_selection_received),
- data);
+ g_signal_handlers_disconnect_by_func (widget,
+ gtk_drag_selection_received,
+ data);
- gtk_object_set_data (GTK_OBJECT (widget), "drag-context", NULL);
- gdk_drag_context_unref (context);
+ g_object_set_data (G_OBJECT (widget), "drag-context", NULL);
+ g_object_unref (context);
gtk_drag_release_ipc_widget (widget);
}
GtkDragFindData *data)
{
GtkAllocation new_allocation;
+ gint allocation_to_window_x = 0;
+ gint allocation_to_window_y = 0;
gint x_offset = 0;
gint y_offset = 0;
- if (data->found || !GTK_WIDGET_MAPPED (widget))
+ if (data->found || !GTK_WIDGET_MAPPED (widget) || !GTK_WIDGET_SENSITIVE (widget))
return;
/* Note that in the following code, we only count the
if (widget->parent)
{
- gint tx, ty, twidth, theight;
+ gint tx, ty;
GdkWindow *window = widget->window;
- /* Correct for the fact that the allocation is relative
- * to the parent window for window widgets, not to widget->window.
+ /* Compute the offset from allocation-relative to
+ * window-relative coordinates.
*/
+ allocation_to_window_x = widget->allocation.x;
+ allocation_to_window_y = widget->allocation.y;
+
if (!GTK_WIDGET_NO_WINDOW (widget))
{
+ /* The allocation is relative to the parent window for
+ * window widgets, not to widget->window.
+ */
gdk_window_get_position (window, &tx, &ty);
- new_allocation.x -= tx;
- new_allocation.y -= ty;
+ allocation_to_window_x -= tx;
+ allocation_to_window_y -= ty;
}
+
+ new_allocation.x = 0 + allocation_to_window_x;
+ new_allocation.y = 0 + allocation_to_window_y;
while (window && window != widget->parent->window)
- {
- gdk_window_get_size (window, &twidth, &theight);
+ {
+ GdkRectangle window_rect = { 0, 0, 0, 0 };
+
+ gdk_drawable_get_size (window, &window_rect.width, &window_rect.height);
- if (new_allocation.x < 0)
- {
- new_allocation.width += new_allocation.x;
- new_allocation.x = 0;
- }
- if (new_allocation.y < 0)
- {
- new_allocation.height += new_allocation.y;
- new_allocation.y = 0;
- }
- if (new_allocation.x + new_allocation.width > twidth)
- new_allocation.width = twidth - new_allocation.x;
- if (new_allocation.y + new_allocation.height > theight)
- new_allocation.height = theight - new_allocation.y;
+ gdk_rectangle_intersect (&new_allocation, &window_rect, &new_allocation);
gdk_window_get_position (window, &tx, &ty);
new_allocation.x += tx;
{
if (!new_data.found && GTK_WIDGET_DRAWABLE (tmp_list->data))
gtk_drag_find_widget (tmp_list->data, &new_data);
- gtk_widget_unref (tmp_list->data);
+ g_object_unref (tmp_list->data);
}
g_slist_free (children);
* a drop site.
*/
if (!data->found &&
- gtk_object_get_data (GTK_OBJECT (widget), "gtk-drag-dest"))
+ g_object_get_data (G_OBJECT (widget), "gtk-drag-dest"))
{
data->found = data->callback (widget,
data->context,
- data->x - new_allocation.x,
- data->y - new_allocation.y,
+ data->x - x_offset - allocation_to_window_x,
+ data->y - y_offset - allocation_to_window_y,
data->time);
/* If so, send a "drag_leave" to the last widget */
if (data->found)
dest_info->proxy_source = NULL;
}
- ipc_widget = gtk_drag_get_ipc_widget ();
+ ipc_widget = gtk_drag_get_ipc_widget (gtk_widget_get_screen (widget));
context = gdk_drag_begin (ipc_widget->window,
dest_info->context->targets);
source_info->proxy_dest = dest_info;
- gtk_signal_connect (GTK_OBJECT (ipc_widget),
- "selection_get",
- GTK_SIGNAL_FUNC (gtk_drag_selection_get),
- source_info);
+ g_signal_connect (ipc_widget,
+ "selection_get",
+ G_CALLBACK (gtk_drag_selection_get),
+ source_info);
dest_info->proxy_source = source_info;
}
{
GtkDragDestSite *site = data;
+ if (site->proxy_window)
+ g_object_unref (site->proxy_window);
+
if (site->target_list)
gtk_target_list_unref (site->target_list);
{
GtkDragDestSite *site;
- site = gtk_object_get_data (GTK_OBJECT (widget), "gtk-drag-dest");
+ site = g_object_get_data (G_OBJECT (widget), "gtk-drag-dest");
g_return_if_fail (site != NULL);
if (site->do_proxy)
gtk_drag_unhighlight (widget);
if (!(site->flags & GTK_DEST_DEFAULT_MOTION) || site->have_drag)
- gtk_signal_emit_by_name (GTK_OBJECT (widget), "drag_leave",
- context, time);
+ g_signal_emit_by_name (widget, "drag_leave",
+ context, time);
site->have_drag = FALSE;
}
GdkDragAction action = 0;
gboolean retval;
- site = gtk_object_get_data (GTK_OBJECT (widget), "gtk-drag-dest");
+ site = g_object_get_data (G_OBJECT (widget), "gtk-drag-dest");
g_return_val_if_fail (site != NULL, FALSE);
if (site->do_proxy)
}
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_find_window_for_screen (info->proxy_source->context,
+ NULL,
+ gdk_drawable_get_screen (current_event->dnd.window),
+ current_event->dnd.x_root,
+ current_event->dnd.y_root,
+ &dest_window, &proto);
}
gdk_drag_motion (info->proxy_source->context,
context->actions, time);
if (!site->proxy_window && dest_window)
- gdk_window_unref (dest_window);
+ g_object_unref (dest_window);
selection = gdk_drag_get_selection (info->proxy_source->context);
if (selection &&
}
}
- gtk_signal_emit_by_name (GTK_OBJECT (widget), "drag_motion",
- context, x, y, time, &retval);
+ g_signal_emit_by_name (widget, "drag_motion",
+ context, x, y, time, &retval);
return (site->flags & GTK_DEST_DEFAULT_MOTION) ? TRUE : retval;
}
GtkDragDestSite *site;
GtkDragDestInfo *info;
- site = gtk_object_get_data (GTK_OBJECT (widget), "gtk-drag-dest");
+ site = g_object_get_data (G_OBJECT (widget), "gtk-drag-dest");
g_return_val_if_fail (site != NULL, FALSE);
info = gtk_drag_get_dest_info (context, FALSE);
}
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_find_window_for_screen (info->proxy_source->context,
+ NULL,
+ gdk_drawable_get_screen (current_event->dnd.window),
+ current_event->dnd.x_root,
+ current_event->dnd.y_root,
+ &dest_window, &proto);
}
gdk_drag_motion (info->proxy_source->context,
context->actions, time);
if (!site->proxy_window && dest_window)
- gdk_window_unref (dest_window);
+ g_object_unref (dest_window);
selection = gdk_drag_get_selection (info->proxy_source->context);
if (selection &&
gtk_drag_get_data (widget, context, target, time);
}
- gtk_signal_emit_by_name (GTK_OBJECT (widget), "drag_drop",
- context, x, y, time, &retval);
+ g_signal_emit_by_name (widget, "drag_drop",
+ context, x, y, time, &retval);
return (site->flags & GTK_DEST_DEFAULT_DROP) ? TRUE : retval;
}
GdkDragContext *context;
GtkWidget *ipc_widget;
- g_return_val_if_fail (widget != NULL, NULL);
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
g_return_val_if_fail (GTK_WIDGET_REALIZED (widget), NULL);
g_return_val_if_fail (target_list != NULL, NULL);
tmp_list = tmp_list->prev;
}
- ipc_widget = gtk_drag_get_ipc_widget ();
+ ipc_widget = gtk_drag_get_ipc_widget (gtk_widget_get_screen (widget));
source_widgets = g_slist_prepend (source_widgets, ipc_widget);
context = gdk_drag_begin (ipc_widget->window, targets);
info = gtk_drag_get_source_info (context, TRUE);
info->ipc_widget = ipc_widget;
- gtk_object_set_data (GTK_OBJECT (info->ipc_widget), "gtk-info", info);
+ g_object_set_data (G_OBJECT (info->ipc_widget), "gtk-info", info);
info->widget = gtk_widget_ref (widget);
-
info->button = button;
info->target_list = target_list;
gtk_drag_get_event_actions (event, info->button, actions,
&suggested_action, &possible_actions);
- info->cursor = gtk_drag_get_cursor (suggested_action);
+ info->cursor = gtk_drag_get_cursor (gtk_widget_get_display (widget), 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 && event->type == GDK_MOTION_NOTIFY)
{
+ info->cur_screen = gtk_widget_get_screen (widget);
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;
+ gdk_display_get_pointer (gtk_widget_get_display (widget),
+ &info->cur_screen, &info->cur_x, &info->cur_y, NULL);
}
- gtk_signal_emit_by_name (GTK_OBJECT (widget), "drag_begin",
- info->context);
+ g_signal_emit_by_name (widget, "drag_begin",
+ info->context);
if (event && 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);
+ g_signal_connect (info->ipc_widget, "button_release_event",
+ G_CALLBACK (gtk_drag_button_release_cb), info);
+ g_signal_connect (info->ipc_widget, "motion_notify_event",
+ G_CALLBACK (gtk_drag_motion_cb), info);
+ g_signal_connect (info->ipc_widget, "key_press_event",
+ G_CALLBACK (gtk_drag_key_cb), info);
+ g_signal_connect (info->ipc_widget, "key_release_event",
+ G_CALLBACK (gtk_drag_key_cb), info);
+ g_signal_connect (info->ipc_widget, "selection_get",
+ G_CALLBACK (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
{
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);
-
+ gtk_drag_cancel (info, time);
return NULL;
}
}
+ info->have_grab = TRUE;
+ info->grab_time = time;
+
return info->context;
}
{
GtkDragSourceSite *site;
- g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
- site = gtk_object_get_data (GTK_OBJECT (widget), "gtk-site-data");
+ site = g_object_get_data (G_OBJECT (widget), "gtk-site-data");
gtk_widget_add_events (widget,
gtk_widget_get_events (widget) |
site->icon_type = GTK_IMAGE_EMPTY;
- 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);
+ g_signal_connect (widget, "button_press_event",
+ G_CALLBACK (gtk_drag_source_event_cb),
+ site);
+ g_signal_connect (widget, "motion_notify_event",
+ G_CALLBACK (gtk_drag_source_event_cb),
+ site);
- gtk_object_set_data_full (GTK_OBJECT (widget),
- "gtk-site-data",
- site, gtk_drag_source_site_destroy);
+ g_object_set_data_full (G_OBJECT (widget),
+ "gtk-site-data",
+ site, gtk_drag_source_site_destroy);
}
site->start_button_mask = start_button_mask;
{
GtkDragSourceSite *site;
- g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
- site = gtk_object_get_data (GTK_OBJECT (widget), "gtk-site-data");
+ site = g_object_get_data (G_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);
+ g_signal_handlers_disconnect_by_func (widget,
+ gtk_drag_source_event_cb,
+ site);
+ g_signal_handlers_disconnect_by_func (widget,
+ gtk_drag_source_event_cb,
+ site);
+ g_object_set_data (G_OBJECT (widget), "gtk-site-data", NULL);
}
}
break;
case GTK_IMAGE_PIXMAP:
if (site->icon_data.pixmap.pixmap)
- gdk_pixmap_unref (site->icon_data.pixmap.pixmap);
+ g_object_unref (site->icon_data.pixmap.pixmap);
if (site->icon_mask)
- gdk_pixmap_unref (site->icon_mask);
+ g_object_unref (site->icon_mask);
break;
case GTK_IMAGE_PIXBUF:
- g_object_unref (G_OBJECT (site->icon_data.pixbuf.pixbuf));
+ g_object_unref (site->icon_data.pixbuf.pixbuf);
break;
case GTK_IMAGE_STOCK:
g_free (G_OBJECT (site->icon_data.stock.stock_id));
site->icon_type = GTK_IMAGE_EMPTY;
if (site->colormap)
- gdk_colormap_unref (site->colormap);
+ g_object_unref (site->colormap);
site->colormap = NULL;
}
{
GtkDragSourceSite *site;
- g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (GDK_IS_COLORMAP (colormap));
g_return_if_fail (GDK_IS_PIXMAP (pixmap));
g_return_if_fail (!mask || GDK_IS_PIXMAP (mask));
- site = gtk_object_get_data (GTK_OBJECT (widget), "gtk-site-data");
+ site = g_object_get_data (G_OBJECT (widget), "gtk-site-data");
g_return_if_fail (site != NULL);
- gdk_colormap_ref (colormap);
- gdk_pixmap_ref (pixmap);
+ g_object_ref (colormap);
+ g_object_ref (pixmap);
if (mask)
- gdk_pixmap_ref (mask);
+ g_object_ref (mask);
gtk_drag_source_unset_icon (site);
{
GtkDragSourceSite *site;
- g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
- site = gtk_object_get_data (GTK_OBJECT (widget), "gtk-site-data");
+ site = g_object_get_data (G_OBJECT (widget), "gtk-site-data");
g_return_if_fail (site != NULL);
- gdk_pixbuf_ref (pixbuf);
+ g_object_ref (pixbuf);
gtk_drag_source_unset_icon (site);
{
GtkDragSourceSite *site;
- g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (stock_id != NULL);
- site = gtk_object_get_data (GTK_OBJECT (widget), "gtk-site-data");
+ site = g_object_get_data (G_OBJECT (widget), "gtk-site-data");
g_return_if_fail (site != NULL);
gtk_drag_source_unset_icon (site);
site->icon_data.stock.stock_id = g_strdup (stock_id);
}
+static void
+gtk_drag_get_icon (GtkDragSourceInfo *info,
+ GtkWidget **icon_window,
+ gint *hot_x,
+ gint *hot_y)
+{
+ if (get_can_change_screen (info->icon_window))
+ gtk_window_set_screen (GTK_WINDOW (info->icon_window),
+ info->cur_screen);
+
+ if (gtk_widget_get_screen (info->icon_window) != info->cur_screen)
+ {
+ if (!info->fallback_icon)
+ {
+ gint save_hot_x, save_hot_y;
+ gboolean save_destroy_icon;
+ GtkWidget *save_icon_window;
+
+ /* HACK to get the appropriate icon
+ */
+ save_icon_window = info->icon_window;
+ save_hot_x = info->hot_x;
+ save_hot_y = info->hot_x;
+ save_destroy_icon = info->destroy_icon;
+
+ info->icon_window = NULL;
+ gtk_drag_set_icon_default (info->context);
+ info->fallback_icon = info->icon_window;
+
+ info->icon_window = save_icon_window;
+ info->hot_x = save_hot_x;
+ info->hot_y = save_hot_y;
+ info->destroy_icon = save_destroy_icon;
+ }
+
+ gtk_widget_hide (info->icon_window);
+
+ *icon_window = info->fallback_icon;
+ gtk_window_set_screen (GTK_WINDOW (*icon_window), info->cur_screen);
+
+ if (!default_icon_pixmap)
+ {
+ *hot_x = -2;
+ *hot_y = -2;
+ }
+ else
+ {
+ *hot_x = default_icon_hot_x;
+ *hot_y = default_icon_hot_y;
+ }
+ }
+ else
+ {
+ if (info->fallback_icon)
+ gtk_widget_hide (info->fallback_icon);
+
+ *icon_window = info->icon_window;
+ *hot_x = info->hot_x;
+ *hot_y = info->hot_y;
+ }
+}
+
+static void
+gtk_drag_update_icon (GtkDragSourceInfo *info)
+{
+ if (info->icon_window)
+ {
+ GtkWidget *icon_window;
+ gint hot_x, hot_y;
+
+ gtk_drag_get_icon (info, &icon_window, &hot_x, &hot_y);
+
+ gtk_window_move (GTK_WINDOW (icon_window),
+ info->cur_x - hot_x,
+ info->cur_y - hot_y);
+
+ if (GTK_WIDGET_VISIBLE (icon_window))
+ gdk_window_raise (icon_window->window);
+ else
+ gtk_widget_show (icon_window);
+ }
+}
+
static void
gtk_drag_set_icon_window (GdkDragContext *context,
GtkWidget *widget,
{
GtkDragSourceInfo *info;
- g_return_if_fail (context != NULL);
- g_return_if_fail (widget != NULL);
-
info = gtk_drag_get_source_info (context, FALSE);
gtk_drag_remove_icon (info);
+ if (widget)
+ gtk_widget_ref (widget);
+
info->icon_window = widget;
info->hot_x = hot_x;
info->hot_y = hot_y;
-
- if (widget)
- {
- gtk_widget_set_uposition (widget,
- info->cur_x - info->hot_x,
- info->cur_y - info->hot_y);
- gtk_widget_ref (widget);
- gdk_window_raise (widget->window);
- gtk_widget_show (widget);
- }
-
info->destroy_icon = destroy_on_release;
+
+ gtk_drag_update_icon (info);
}
/**
gint hot_x,
gint hot_y)
{
- g_return_if_fail (context != NULL);
- g_return_if_fail (widget != NULL);
+ g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
+ g_return_if_fail (context->is_source);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
gtk_drag_set_icon_window (context, widget, hot_x, hot_y, FALSE);
}
+static void
+icon_window_realize (GtkWidget *window,
+ GdkPixbuf *pixbuf)
+{
+ GdkPixmap *pixmap;
+ GdkPixmap *mask;
+
+ gdk_pixbuf_render_pixmap_and_mask_for_colormap (pixbuf,
+ gtk_widget_get_colormap (window),
+ &pixmap, &mask, 128);
+
+ gdk_window_set_back_pixmap (window->window, pixmap, FALSE);
+
+ if (mask)
+ gtk_widget_shape_combine_mask (window, mask, 0, 0);
+
+ g_object_unref (G_OBJECT (pixmap));
+
+ if (mask)
+ g_object_unref (G_OBJECT (mask));
+}
+
static void
set_icon_stock_pixbuf (GdkDragContext *context,
const gchar *stock_id,
{
GtkWidget *window;
gint width, height;
- GdkPixmap *pixmap;
- GdkPixmap *mask;
-
+ GdkScreen *screen;
+
g_return_if_fail (context != NULL);
g_return_if_fail (pixbuf != NULL || stock_id != NULL);
g_return_if_fail (pixbuf == NULL || stock_id == NULL);
+
+ screen = gdk_drawable_get_screen (context->source_window);
- gtk_widget_push_colormap (gdk_rgb_get_colormap ());
+ /* Push a NULL colormap to guard against gtk_widget_push_colormap() */
+ gtk_widget_push_colormap (NULL);
window = gtk_window_new (GTK_WINDOW_POPUP);
+ gtk_window_set_screen (GTK_WINDOW (window), screen);
+ set_can_change_screen (window, TRUE);
gtk_widget_pop_colormap ();
gtk_widget_set_events (window, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
}
}
+ else
+ g_object_ref (pixbuf);
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_width (pixbuf);
- gtk_widget_set_usize (window,
- gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf));
- gtk_widget_realize (window);
-
- gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &mask, 128);
-
- gdk_window_set_back_pixmap (window->window, pixmap, FALSE);
-
- if (mask)
- gtk_widget_shape_combine_mask (window, mask, 0, 0);
-
- g_object_unref (G_OBJECT (pixmap));
-
- if (mask)
- g_object_unref (G_OBJECT (mask));
+ gtk_widget_set_size_request (window,
+ gdk_pixbuf_get_width (pixbuf),
+ gdk_pixbuf_get_height (pixbuf));
+ g_signal_connect_closure (window, "realize",
+ g_cclosure_new (G_CALLBACK (icon_window_realize),
+ pixbuf,
+ (GClosureNotify)g_object_unref),
+ FALSE);
+
gtk_drag_set_icon_window (context, window, hot_x, hot_y, TRUE);
}
gint hot_y)
{
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
+ g_return_if_fail (context->is_source);
g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
set_icon_stock_pixbuf (context, NULL, pixbuf, hot_x, hot_y);
gint hot_y)
{
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
+ g_return_if_fail (context->is_source);
g_return_if_fail (stock_id != NULL);
set_icon_stock_pixbuf (context, stock_id, NULL, hot_x, hot_y);
gint hot_y)
{
GtkWidget *window;
+ GdkScreen *screen;
gint width, height;
- g_return_if_fail (context != NULL);
- g_return_if_fail (colormap != NULL);
- g_return_if_fail (pixmap != NULL);
+ g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
+ g_return_if_fail (context->is_source);
+ g_return_if_fail (GDK_IS_COLORMAP (colormap));
+ g_return_if_fail (GDK_IS_PIXMAP (pixmap));
+ g_return_if_fail (!mask || GDK_IS_PIXMAP (mask));
- gdk_window_get_size (pixmap, &width, &height);
+ screen = gdk_colormap_get_screen (colormap);
+
+ g_return_if_fail (gdk_drawable_get_screen (pixmap) == screen);
+ g_return_if_fail (!mask || gdk_drawable_get_screen (mask) == screen);
+
+ gdk_drawable_get_size (pixmap, &width, &height);
gtk_widget_push_colormap (colormap);
window = gtk_window_new (GTK_WINDOW_POPUP);
+ gtk_window_set_screen (GTK_WINDOW (window), screen);
+ set_can_change_screen (window, FALSE);
gtk_widget_set_events (window, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
gtk_widget_pop_colormap ();
- gtk_widget_set_usize (window, width, height);
+ gtk_widget_set_size_request (window, width, height);
gtk_widget_realize (window);
gdk_window_set_back_pixmap (window->window, pixmap, FALSE);
void
gtk_drag_set_icon_default (GdkDragContext *context)
{
- g_return_if_fail (context != NULL);
+ g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
+ g_return_if_fail (context->is_source);
if (!default_icon_pixmap)
gtk_drag_set_icon_stock (context, GTK_STOCK_DND, -2, -2);
* Changes the default drag icon. GTK+ retains references for the
* arguments, and will release them when they are no longer needed.
* This function is obsolete. The default icon should now be changed
- * via the stock system by changing the stock pixbuf for %GTK_STOCK_DND.
+ * via the stock system by changing the stock pixbuf for #GTK_STOCK_DND.
**/
void
gtk_drag_set_default_icon (GdkColormap *colormap,
gint hot_x,
gint hot_y)
{
- g_return_if_fail (colormap != NULL);
- g_return_if_fail (pixmap != NULL);
+ g_return_if_fail (GDK_IS_COLORMAP (colormap));
+ g_return_if_fail (GDK_IS_PIXMAP (pixmap));
+ g_return_if_fail (!mask || GDK_IS_PIXMAP (mask));
if (default_icon_colormap)
- gdk_colormap_unref (default_icon_colormap);
+ g_object_unref (default_icon_colormap);
if (default_icon_pixmap)
- gdk_pixmap_unref (default_icon_pixmap);
+ g_object_unref (default_icon_pixmap);
if (default_icon_mask)
- gdk_pixmap_unref (default_icon_mask);
+ g_object_unref (default_icon_mask);
default_icon_colormap = colormap;
- gdk_colormap_ref (colormap);
+ g_object_ref (colormap);
default_icon_pixmap = pixmap;
- gdk_pixmap_ref (pixmap);
+ g_object_ref (pixmap);
default_icon_mask = mask;
if (mask)
- gdk_pixmap_ref (mask);
+ g_object_ref (mask);
default_icon_hot_x = hot_x;
default_icon_hot_y = hot_y;
}
}
}
- else
+ else if (info->have_grab)
{
- cursor = gtk_drag_get_cursor (event->dnd.context->action);
+ cursor = gtk_drag_get_cursor (gtk_widget_get_display (widget),
+ event->dnd.context->action);
if (info->cursor != cursor)
{
gdk_pointer_grab (widget->window, FALSE,
GDK_POINTER_MOTION_HINT_MASK |
GDK_BUTTON_RELEASE_MASK,
NULL,
- cursor, event->dnd.time);
+ cursor, info->grab_time);
info->cursor = cursor;
}
if (info->last_event)
{
gtk_drag_update (info,
- info->cur_x, info->cur_y,
+ info->cur_screen, info->cur_x, info->cur_y,
info->last_event);
info->last_event = NULL;
}
tmp_list = tmp_list->next;
}
- gtk_selection_owner_set (info->ipc_widget, selection, time);
+ gtk_selection_owner_set_for_display (gtk_widget_get_display (info->widget),
+ info->ipc_widget,
+ selection,
+ time);
info->selections = g_list_prepend (info->selections,
GUINT_TO_POINTER (selection));
anim->n_steps = MAX (info->cur_x - info->start_x,
info->cur_y - info->start_y) / ANIM_STEP_LENGTH;
anim->n_steps = CLAMP (anim->n_steps, ANIM_MIN_STEPS, ANIM_MAX_STEPS);
- if (info->icon_window)
- {
- gtk_widget_show (info->icon_window);
- gdk_window_raise (info->icon_window->window);
- }
+
+ info->cur_screen = gtk_widget_get_screen (info->widget);
+ gtk_drag_update_icon (info);
/* Mark the context as dead, so if the destination decides
* to respond really late, we still are OK.
gtk_drag_source_release_selections (GtkDragSourceInfo *info,
guint32 time)
{
+ GdkDisplay *display = gtk_widget_get_display (info->widget);
GList *tmp_list = info->selections;
+
while (tmp_list)
{
GdkAtom selection = GDK_POINTER_TO_ATOM (tmp_list->data);
- if (gdk_selection_owner_get (selection) == info->ipc_widget->window)
- gtk_selection_owner_set (NULL, selection, time);
+ if (gdk_selection_owner_get_for_display (display, selection) == info->ipc_widget->window)
+ gtk_selection_owner_set_for_display (display, NULL, selection, time);
+
tmp_list = tmp_list->next;
}
selection_data.data = NULL;
selection_data.length = -1;
- gtk_signal_emit_by_name (GTK_OBJECT (info->widget), "drag_data_get",
- info->context, &selection_data,
- pair->info,
- time);
+ g_signal_emit_by_name (info->widget, "drag_data_get",
+ info->context, &selection_data,
+ pair->info,
+ time);
/* FIXME: Should we check for length >= 0 here? */
gtk_drag_drop_finished (info, TRUE, time);
switch (sel_info)
{
case TARGET_DELETE:
- gtk_signal_emit_by_name (GTK_OBJECT (info->widget),
- "drag_data_delete",
- info->context);
+ g_signal_emit_by_name (info->widget,
+ "drag_data_delete",
+ info->context);
gtk_selection_data_set (selection_data, null_atom, 8, NULL, 0);
break;
case TARGET_MOTIF_SUCCESS:
selection_data->target,
&target_info))
{
- gtk_signal_emit_by_name (GTK_OBJECT (info->widget), "drag_data_get",
- info->context,
- selection_data,
- target_info,
- time);
+ g_signal_emit_by_name (info->widget, "drag_data_get",
+ info->context,
+ selection_data,
+ target_info,
+ time);
}
}
break;
y = (anim->info->start_y * (anim->step + 1) +
anim->info->cur_y * (anim->n_steps - anim->step - 1)) / anim->n_steps;
if (anim->info->icon_window)
- gtk_widget_set_uposition (anim->info->icon_window,
- x - anim->info->hot_x,
- y - anim->info->hot_y);
+ {
+ GtkWidget *icon_window;
+ gint hot_x, hot_y;
+
+ gtk_drag_get_icon (anim->info, &icon_window, &hot_x, &hot_y);
+
+ gtk_window_move (GTK_WINDOW (icon_window),
+ x - hot_x,
+ y - hot_y);
+ }
anim->step++;
if (info->destroy_icon)
gtk_widget_destroy (info->icon_window);
- gtk_widget_unref (info->icon_window);
+ if (info->fallback_icon)
+ {
+ gtk_widget_destroy (info->fallback_icon);
+ info->fallback_icon = NULL;
+ }
+
+ g_object_unref (info->icon_window);
info->icon_window = NULL;
}
}
gtk_drag_remove_icon (info);
if (!info->proxy_dest)
- gtk_signal_emit_by_name (GTK_OBJECT (info->widget), "drag_end",
- info->context);
+ g_signal_emit_by_name (info->widget, "drag_end",
+ info->context);
if (info->widget)
- gtk_widget_unref (info->widget);
+ g_object_unref (info->widget);
+
+
+ g_signal_handlers_disconnect_by_func (info->ipc_widget,
+ gtk_drag_button_release_cb,
+ info);
+ g_signal_handlers_disconnect_by_func (info->ipc_widget,
+ gtk_drag_motion_cb,
+ info);
+ g_signal_handlers_disconnect_by_func (info->ipc_widget,
+ gtk_drag_key_cb,
+ info);
+ g_signal_handlers_disconnect_by_func (info->ipc_widget,
+ gtk_drag_selection_get,
+ info);
- gtk_signal_disconnect_by_data (GTK_OBJECT (info->ipc_widget), info);
gtk_selection_remove_all (info->ipc_widget);
- gtk_object_set_data (GTK_OBJECT (info->ipc_widget), "gtk-info", NULL);
+ g_object_set_data (G_OBJECT (info->ipc_widget), "gtk-info", NULL);
source_widgets = g_slist_remove (source_widgets, info->ipc_widget);
gtk_drag_release_ipc_widget (info->ipc_widget);
gtk_target_list_unref (info->target_list);
gtk_drag_clear_source_info (info->context);
- gdk_drag_context_unref (info->context);
+ g_object_unref (info->context);
if (info->drop_timeout)
gtk_timeout_remove (info->drop_timeout);
static void
gtk_drag_update (GtkDragSourceInfo *info,
+ GdkScreen *screen,
gint x_root,
gint y_root,
GdkEvent *event)
{
GdkDragAction action;
GdkDragAction possible_actions;
- GdkWindow *window = NULL;
GdkWindow *dest_window;
GdkDragProtocol protocol;
GdkAtom selection;
info->button,
info->possible_actions,
&action, &possible_actions);
+ info->cur_screen = screen;
info->cur_x = x_root;
info->cur_y = y_root;
- if (info->icon_window)
- {
- gdk_window_raise (info->icon_window->window);
- gtk_widget_set_uposition (info->icon_window,
- info->cur_x - info->hot_x,
- info->cur_y - info->hot_y);
- window = info->icon_window->window;
- }
-
- gdk_drag_find_window (info->context,
- window, x_root, y_root,
- &dest_window, &protocol);
+ gtk_drag_update_icon (info);
+ gdk_drag_find_window_for_screen (info->context,
+ info->icon_window ? info->icon_window->window : NULL,
+ screen, x_root, y_root,
+ &dest_window, &protocol);
if (gdk_drag_motion (info->context, dest_window, protocol,
x_root, y_root, action,
}
if (dest_window)
- gdk_window_unref (dest_window);
+ g_object_unref (dest_window);
selection = gdk_drag_get_selection (info->context);
if (selection)
* Called when the user finishes to drag, either by
* releasing the mouse, or by pressing Esc.
* arguments:
- * widget: GtkInvisible widget for this drag
- * info:
+ * info: Source info for the drag
+ * time: Timestamp for ending the drag
* results:
*************************************************************/
static void
gtk_drag_end (GtkDragSourceInfo *info, guint32 time)
{
- GdkEvent send_event;
+ GdkEvent *send_event;
GtkWidget *source_widget = info->widget;
+ GdkDisplay *display = gtk_widget_get_display (source_widget);
- gdk_pointer_ungrab (time);
- gdk_keyboard_ungrab (time);
-
+ info->have_grab = FALSE;
+
+ gdk_display_pointer_ungrab (display, time);
+ gdk_display_keyboard_ungrab (display, time);
gtk_grab_remove (info->ipc_widget);
- gtk_signal_disconnect_by_func (GTK_OBJECT (info->ipc_widget),
- GTK_SIGNAL_FUNC (gtk_drag_button_release_cb),
- info);
- gtk_signal_disconnect_by_func (GTK_OBJECT (info->ipc_widget),
- GTK_SIGNAL_FUNC (gtk_drag_motion_cb),
- info);
+ g_signal_handlers_disconnect_by_func (info->ipc_widget,
+ gtk_drag_button_release_cb,
+ info);
+ g_signal_handlers_disconnect_by_func (info->ipc_widget,
+ gtk_drag_motion_cb,
+ info);
+ g_signal_handlers_disconnect_by_func (info->ipc_widget,
+ gtk_drag_key_cb,
+ info);
/* Send on a release pair to the the original
* widget to convince it to release its grab. We need to
* expect propagation.
*/
- send_event.button.type = GDK_BUTTON_RELEASE;
- send_event.button.window = GDK_ROOT_PARENT ();
- send_event.button.send_event = TRUE;
- send_event.button.time = time;
- send_event.button.x = 0;
- send_event.button.y = 0;
- send_event.button.axes = NULL;
- send_event.button.state = 0;
- send_event.button.button = info->button;
- send_event.button.device = gdk_device_get_core_pointer ();
- send_event.button.x_root = 0;
- send_event.button.y_root = 0;
+ send_event = gdk_event_new (GDK_BUTTON_RELEASE);
+ send_event->button.window = g_object_ref (gtk_widget_get_root_window (source_widget));
+ send_event->button.send_event = TRUE;
+ send_event->button.time = time;
+ send_event->button.x = 0;
+ send_event->button.y = 0;
+ send_event->button.axes = NULL;
+ send_event->button.state = 0;
+ send_event->button.button = info->button;
+ send_event->button.device = gdk_display_get_core_pointer (display);
+ send_event->button.x_root = 0;
+ send_event->button.y_root = 0;
+
+ gtk_propagate_event (source_widget, send_event);
+ gdk_event_free (send_event);
+}
+
+/*************************************************************
+ * gtk_drag_cancel:
+ * Called on cancellation of a drag, either by the user
+ * or programmatically.
+ * arguments:
+ * info: Source info for the drag
+ * time: Timestamp for ending the drag
+ * results:
+ *************************************************************/
- gtk_propagate_event (source_widget, &send_event);
+static void
+gtk_drag_cancel (GtkDragSourceInfo *info, guint32 time)
+{
+ gtk_drag_end (info, time);
+ gdk_drag_abort (info->context, time);
+ gtk_drag_drop_finished (info, FALSE, time);
}
/*************************************************************
gpointer data)
{
GtkDragSourceInfo *info = (GtkDragSourceInfo *)data;
+ GdkScreen *screen;
gint x_root, y_root;
if (event->is_hint)
{
- gdk_window_get_pointer (GDK_ROOT_PARENT(), &x_root, &y_root, NULL);
+ GdkDisplay *display = gtk_widget_get_display (widget);
+
+ gdk_display_get_pointer (display, &screen, &x_root, &y_root, NULL);
event->x_root = x_root;
event->y_root = y_root;
}
+ else
+ screen = gdk_event_get_screen ((GdkEvent *)event);
- gtk_drag_update (info, event->x_root, event->y_root, (GdkEvent *)event);
+ gtk_drag_update (info, screen, event->x_root, event->y_root, (GdkEvent *)event);
return TRUE;
}
{
GtkDragSourceInfo *info = (GtkDragSourceInfo *)data;
GdkModifierType state;
+ GdkWindow *root_window;
if (event->type == GDK_KEY_PRESS)
{
if (event->keyval == GDK_Escape)
{
- gtk_drag_end (info, event->time);
- gdk_drag_abort (info->context, event->time);
- gtk_drag_drop_finished (info, FALSE, event->time);
+ gtk_drag_cancel (info, event->time);
return TRUE;
}
* to query it here. We could use XGetModifierMapping, but
* that would be overkill.
*/
- gdk_window_get_pointer (GDK_ROOT_PARENT(), NULL, NULL, &state);
+ root_window = gtk_widget_get_root_window (widget);
+ gdk_window_get_pointer (root_window, NULL, NULL, &state);
event->state = state;
- gtk_drag_update (info, info->cur_x, info->cur_y, (GdkEvent *)event);
+ gtk_drag_update (info, info->cur_screen, info->cur_x, info->cur_y, (GdkEvent *)event);
return TRUE;
}
if (event->button != info->button)
return FALSE;
- gtk_drag_end (info, event->time);
-
if ((info->context->action != 0) && (info->context->dest_window != NULL))
{
+ gtk_drag_end (info, event->time);
gtk_drag_drop (info, event->time);
}
else
{
- gdk_drag_abort (info->context, event->time);
- gtk_drag_drop_finished (info, FALSE, event->time);
+ gtk_drag_cancel (info, event->time);
}
return TRUE;
* @current_x: current X coordinate
* @current_y: current Y coordinate
*
- * Checks to see if a mouse drag starting at (start_x, start_y) and ending
- * at (current_x, current_y) has passed the GTK drag threshhold, and thus
+ * Checks to see if a mouse drag starting at (@start_x, @start_y) and ending
+ * at (@current_x, @current_y) has passed the GTK+ drag threshhold, and thus
* should trigger the beginning of a drag-and-drop operation.
*
- * Return Value: If the drag threshold has been passed.
+ * Return Value: %TRUE if the drag threshold has been passed.
**/
gboolean
gtk_drag_check_threshold (GtkWidget *widget,
{
gint drag_threshold;
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+
g_object_get (gtk_widget_get_settings (widget),
"gtk-dnd-drag-threshold", &drag_threshold,
NULL);