From b2015798aa2018a44158105751d6553383a58c59 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Fri, 4 Jan 2002 18:28:18 +0000 Subject: [PATCH] At least don't infinite loop if the widget and window heirarchies don't Fri Jan 4 13:05:15 2002 Owen Taylor * gtk/gtkdnd.c (gtk_drag_find_widget): At least don't infinite loop if the widget and window heirarchies don't correspond. * gtk/gtkdnd.c (gtk_drag_find_widget): Handle changes in heirarchy in ::drag_motion, ::drag_drop callbacks by referencing child widget lists. (Patch from Tim) * gtk/gtkdnd.c (gtk_drag_find_widget): Fix a problem with widgets where window.x != widget->allocation. --- ChangeLog | 13 ++++++++++ ChangeLog.pre-2-0 | 13 ++++++++++ ChangeLog.pre-2-10 | 13 ++++++++++ ChangeLog.pre-2-2 | 13 ++++++++++ ChangeLog.pre-2-4 | 13 ++++++++++ ChangeLog.pre-2-6 | 13 ++++++++++ ChangeLog.pre-2-8 | 13 ++++++++++ gtk/gtkdnd.c | 64 ++++++++++++++++++++++++++++++++++++---------- 8 files changed, 141 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 15cf3d1d94..70eb1b3d1b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +Fri Jan 4 13:05:15 2002 Owen Taylor + + * gtk/gtkdnd.c (gtk_drag_find_widget): At least + don't infinite loop if the widget and window heirarchies + don't correspond. + + * gtk/gtkdnd.c (gtk_drag_find_widget): Handle changes + in heirarchy in ::drag_motion, ::drag_drop callbacks + by referencing child widget lists. (Patch from Tim) + + * gtk/gtkdnd.c (gtk_drag_find_widget): Fix a problem + with widgets where window.x != widget->allocation.x + Fri Jan 4 01:36:48 2002 Owen Taylor * gdk/x11/gdkdrawable-x11.c (convert_to_format): Optimize diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 15cf3d1d94..70eb1b3d1b 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,16 @@ +Fri Jan 4 13:05:15 2002 Owen Taylor + + * gtk/gtkdnd.c (gtk_drag_find_widget): At least + don't infinite loop if the widget and window heirarchies + don't correspond. + + * gtk/gtkdnd.c (gtk_drag_find_widget): Handle changes + in heirarchy in ::drag_motion, ::drag_drop callbacks + by referencing child widget lists. (Patch from Tim) + + * gtk/gtkdnd.c (gtk_drag_find_widget): Fix a problem + with widgets where window.x != widget->allocation.x + Fri Jan 4 01:36:48 2002 Owen Taylor * gdk/x11/gdkdrawable-x11.c (convert_to_format): Optimize diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 15cf3d1d94..70eb1b3d1b 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,16 @@ +Fri Jan 4 13:05:15 2002 Owen Taylor + + * gtk/gtkdnd.c (gtk_drag_find_widget): At least + don't infinite loop if the widget and window heirarchies + don't correspond. + + * gtk/gtkdnd.c (gtk_drag_find_widget): Handle changes + in heirarchy in ::drag_motion, ::drag_drop callbacks + by referencing child widget lists. (Patch from Tim) + + * gtk/gtkdnd.c (gtk_drag_find_widget): Fix a problem + with widgets where window.x != widget->allocation.x + Fri Jan 4 01:36:48 2002 Owen Taylor * gdk/x11/gdkdrawable-x11.c (convert_to_format): Optimize diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 15cf3d1d94..70eb1b3d1b 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,16 @@ +Fri Jan 4 13:05:15 2002 Owen Taylor + + * gtk/gtkdnd.c (gtk_drag_find_widget): At least + don't infinite loop if the widget and window heirarchies + don't correspond. + + * gtk/gtkdnd.c (gtk_drag_find_widget): Handle changes + in heirarchy in ::drag_motion, ::drag_drop callbacks + by referencing child widget lists. (Patch from Tim) + + * gtk/gtkdnd.c (gtk_drag_find_widget): Fix a problem + with widgets where window.x != widget->allocation.x + Fri Jan 4 01:36:48 2002 Owen Taylor * gdk/x11/gdkdrawable-x11.c (convert_to_format): Optimize diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 15cf3d1d94..70eb1b3d1b 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,16 @@ +Fri Jan 4 13:05:15 2002 Owen Taylor + + * gtk/gtkdnd.c (gtk_drag_find_widget): At least + don't infinite loop if the widget and window heirarchies + don't correspond. + + * gtk/gtkdnd.c (gtk_drag_find_widget): Handle changes + in heirarchy in ::drag_motion, ::drag_drop callbacks + by referencing child widget lists. (Patch from Tim) + + * gtk/gtkdnd.c (gtk_drag_find_widget): Fix a problem + with widgets where window.x != widget->allocation.x + Fri Jan 4 01:36:48 2002 Owen Taylor * gdk/x11/gdkdrawable-x11.c (convert_to_format): Optimize diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 15cf3d1d94..70eb1b3d1b 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,16 @@ +Fri Jan 4 13:05:15 2002 Owen Taylor + + * gtk/gtkdnd.c (gtk_drag_find_widget): At least + don't infinite loop if the widget and window heirarchies + don't correspond. + + * gtk/gtkdnd.c (gtk_drag_find_widget): Handle changes + in heirarchy in ::drag_motion, ::drag_drop callbacks + by referencing child widget lists. (Patch from Tim) + + * gtk/gtkdnd.c (gtk_drag_find_widget): Fix a problem + with widgets where window.x != widget->allocation.x + Fri Jan 4 01:36:48 2002 Owen Taylor * gdk/x11/gdkdrawable-x11.c (convert_to_format): Optimize diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 15cf3d1d94..70eb1b3d1b 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,16 @@ +Fri Jan 4 13:05:15 2002 Owen Taylor + + * gtk/gtkdnd.c (gtk_drag_find_widget): At least + don't infinite loop if the widget and window heirarchies + don't correspond. + + * gtk/gtkdnd.c (gtk_drag_find_widget): Handle changes + in heirarchy in ::drag_motion, ::drag_drop callbacks + by referencing child widget lists. (Patch from Tim) + + * gtk/gtkdnd.c (gtk_drag_find_widget): Fix a problem + with widgets where window.x != widget->allocation.x + Fri Jan 4 01:36:48 2002 Owen Taylor * gdk/x11/gdkdrawable-x11.c (convert_to_format): Optimize diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c index 83b79ef460..44b7e821aa 100644 --- a/gtk/gtkdnd.c +++ b/gtk/gtkdnd.c @@ -1206,6 +1206,15 @@ gtk_drag_selection_received (GtkWidget *widget, gtk_drag_release_ipc_widget (widget); } +static void +prepend_and_ref_widget (GtkWidget *widget, + gpointer data) +{ + GSList **slist_p = data; + + *slist_p = g_slist_prepend (*slist_p, g_object_ref (widget)); +} + /************************************************************* * gtk_drag_find_widget: * Recursive callback used to locate widgets for @@ -1223,8 +1232,6 @@ gtk_drag_find_widget (GtkWidget *widget, gint x_offset = 0; gint y_offset = 0; - new_allocation = widget->allocation; - if (data->found || !GTK_WIDGET_MAPPED (widget)) return; @@ -1233,19 +1240,35 @@ gtk_drag_find_widget (GtkWidget *widget, * widget->window; points that are outside of widget->window * but within the allocation are not counted. This is consistent * with the way we highlight drag targets. - */ - if (!GTK_WIDGET_NO_WINDOW (widget)) - { - new_allocation.x = 0; - new_allocation.y = 0; - } - + * + * data->x,y are relative to widget->parent->window (if + * widget is not a toplevel, widget->window otherwise). + * We compute the allocation of widget in the same coordinates, + * clipping to widget->window, and all intermediate + * windows. If data->x,y is inside that, then we translate + * our coordinates to be relative to widget->window and + * recurse. + */ + new_allocation = widget->allocation; + if (widget->parent) { + gint tx, ty, twidth, theight; GdkWindow *window = widget->window; - while (window != widget->parent->window) + + /* Correct for the fact that the allocation is relative + * to the parent window for window widgets, not to widget->window. + */ + if (!GTK_WIDGET_NO_WINDOW (widget)) { - gint tx, ty, twidth, theight; + gdk_window_get_position (window, &tx, &ty); + + new_allocation.x -= tx; + new_allocation.y -= ty; + } + + while (window && window != widget->parent->window) + { gdk_window_get_size (window, &twidth, &theight); if (new_allocation.x < 0) @@ -1271,6 +1294,9 @@ gtk_drag_find_widget (GtkWidget *widget, window = gdk_window_get_parent (window); } + + if (!window) /* Window and widget heirarchies didn't match. */ + return; } if (data->toplevel || @@ -1284,15 +1310,25 @@ gtk_drag_find_widget (GtkWidget *widget, if (GTK_IS_CONTAINER (widget)) { GtkDragFindData new_data = *data; + GSList *children = NULL; + GSList *tmp_list; new_data.x -= x_offset; new_data.y -= y_offset; new_data.found = FALSE; new_data.toplevel = FALSE; - gtk_container_forall (GTK_CONTAINER (widget), - (GtkCallback)gtk_drag_find_widget, - &new_data); + /* need to reference children temporarily in case the + * ::drag_motion/::drag_drop callbacks change the widget heirarchy. + */ + gtk_container_forall (GTK_CONTAINER (widget), prepend_and_ref_widget, &children); + for (tmp_list = children; tmp_list; tmp_list = tmp_list->next) + { + 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_slist_free (children); data->found = new_data.found; }