diff options
Diffstat (limited to 'gtk/gtkdnd.c')
-rw-r--r-- | gtk/gtkdnd.c | 112 |
1 files changed, 74 insertions, 38 deletions
diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c index ca209fade0..ab7b35ef46 100644 --- a/gtk/gtkdnd.c +++ b/gtk/gtkdnd.c @@ -36,7 +36,6 @@ #include "gtkstock.h" #include "gtkwindow.h" -static GSList *drag_widgets = NULL; static GSList *source_widgets = NULL; typedef struct _GtkDragSourceSite GtkDragSourceSite; @@ -180,8 +179,9 @@ static void gtk_drag_get_event_actions (GdkEvent *event, 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 (GdkScreen *screen, + 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, @@ -366,20 +366,25 @@ static const gint n_drag_cursors = sizeof (drag_cursors) / sizeof (drag_cursors[ *************************************************************/ 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); } @@ -397,7 +402,13 @@ gtk_drag_get_ipc_widget (void) 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 @@ -538,29 +549,39 @@ gtk_drag_get_event_actions (GdkEvent *event, } static GdkCursor * -gtk_drag_get_cursor (GdkDragAction action) +gtk_drag_get_cursor (GdkScreen *screen, + 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 (screen != gdk_cursor_get_screen (drag_cursors[i].cursor)) + { + gdk_cursor_unref (drag_cursors[i].cursor); + drag_cursors[i].cursor = NULL; + } + } if (drag_cursors[i].cursor == NULL) { + GdkColormap *colormap; GdkColor fg, bg; GdkPixmap *pixmap = - gdk_bitmap_create_from_data (NULL, - drag_cursors[i].bits, - CURSOR_WIDTH, CURSOR_HEIGHT); + gdk_bitmap_create_from_data (gdk_screen_get_root_window (screen), + 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 (gdk_screen_get_root_window (screen), + drag_cursors[i].mask, CURSOR_WIDTH, CURSOR_HEIGHT); - gdk_color_white (gdk_colormap_get_system (), &bg); - gdk_color_black (gdk_colormap_get_system (), &fg); + colormap = gdk_screen_get_system_colormap (screen); + gdk_color_white (colormap, &bg); + gdk_color_black (colormap, &fg); drag_cursors[i].cursor = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg, 0, 0); @@ -597,7 +618,7 @@ gtk_drag_get_data (GtkWidget *widget, g_return_if_fail (widget != NULL); g_return_if_fail (context != NULL); - 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); @@ -684,7 +705,7 @@ gtk_drag_finish (GdkDragContext *context, 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); @@ -1375,7 +1396,7 @@ gtk_drag_proxy_begin (GtkWidget *widget, 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); @@ -1786,7 +1807,7 @@ gtk_drag_begin (GtkWidget *widget, 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); @@ -1816,7 +1837,7 @@ gtk_drag_begin (GtkWidget *widget, 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_screen (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 @@ -1828,11 +1849,8 @@ gtk_drag_begin (GtkWidget *widget, } else { - gint x, y; - gdk_window_get_pointer (GDK_ROOT_PARENT (), &x, &y, NULL); - - info->cur_x = x; - info->cur_y = y; + gdk_window_get_pointer (gtk_widget_get_root_window (widget), + &info->cur_x, &info->cur_y, NULL); } gtk_signal_emit_by_name (GTK_OBJECT (widget), "drag_begin", @@ -2163,13 +2181,19 @@ set_icon_stock_pixbuf (GdkDragContext *context, gint width, height; GdkPixmap *pixmap; GdkPixmap *mask; - + GdkScreen *screen; + GdkColormap *colormap; + g_return_if_fail (context != NULL); g_return_if_fail (pixbuf != NULL || stock_id != NULL); g_return_if_fail (pixbuf == NULL || stock_id == NULL); - - gtk_widget_push_colormap (gdk_rgb_get_colormap ()); + + screen = gdk_drawable_get_screen (context->source_window); + colormap = gdk_screen_get_rgb_colormap (screen); + + gtk_widget_push_colormap (colormap); window = gtk_window_new (GTK_WINDOW_POPUP); + gtk_window_set_screen (GTK_WINDOW (window), screen); gtk_widget_pop_colormap (); gtk_widget_set_events (window, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); @@ -2197,7 +2221,7 @@ set_icon_stock_pixbuf (GdkDragContext *context, gdk_pixbuf_get_height (pixbuf)); gtk_widget_realize (window); - gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &mask, 128); + gdk_pixbuf_render_pixmap_and_mask_for_colormap (pixbuf, colormap, &pixmap, &mask, 128); gdk_window_set_back_pixmap (window->window, pixmap, FALSE); @@ -2291,6 +2315,7 @@ gtk_drag_set_icon_pixmap (GdkDragContext *context, gtk_widget_push_colormap (colormap); window = gtk_window_new (GTK_WINDOW_POPUP); + gtk_window_set_screen (GTK_WINDOW (window), gdk_drawable_get_screen (context->source_window)); gtk_widget_set_events (window, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE); @@ -2433,7 +2458,8 @@ _gtk_drag_source_handle_event (GtkWidget *widget, } else { - cursor = gtk_drag_get_cursor (event->dnd.context->action); + cursor = gtk_drag_get_cursor (gtk_widget_get_screen (widget), + event->dnd.context->action); if (info->cursor != cursor) { gdk_pointer_grab (widget->window, FALSE, @@ -2488,7 +2514,10 @@ gtk_drag_source_check_selection (GtkDragSourceInfo *info, 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)); @@ -2580,12 +2609,15 @@ static void 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; } @@ -2988,10 +3020,10 @@ gtk_drag_end (GtkDragSourceInfo *info, guint32 time) { GdkEvent send_event; GtkWidget *source_widget = info->widget; + GdkDisplay *display = gtk_widget_get_display (source_widget); - gdk_pointer_ungrab (time); - gdk_keyboard_ungrab (time); - + 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), @@ -3009,7 +3041,7 @@ gtk_drag_end (GtkDragSourceInfo *info, guint32 time) */ send_event.button.type = GDK_BUTTON_RELEASE; - send_event.button.window = GDK_ROOT_PARENT (); + send_event.button.window = gtk_widget_get_root_window (source_widget); send_event.button.send_event = TRUE; send_event.button.time = time; send_event.button.x = 0; @@ -3042,7 +3074,9 @@ gtk_drag_motion_cb (GtkWidget *widget, if (event->is_hint) { - gdk_window_get_pointer (GDK_ROOT_PARENT(), &x_root, &y_root, NULL); + GdkWindow *root_window = gtk_widget_get_root_window (widget); + + gdk_window_get_pointer (root_window, &x_root, &y_root, NULL); event->x_root = x_root; event->y_root = y_root; } @@ -3067,6 +3101,7 @@ gtk_drag_key_cb (GtkWidget *widget, { GtkDragSourceInfo *info = (GtkDragSourceInfo *)data; GdkModifierType state; + GdkWindow *root_window; if (event->type == GDK_KEY_PRESS) { @@ -3086,7 +3121,8 @@ gtk_drag_key_cb (GtkWidget *widget, * 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); |