Re: Updated unexpected window destruction patch.
- From: Tim Janik <timj gtk org>
- To: gtk-devel-list redhat com
- cc: Nat Friedman <nat nat org>, Owen Taylor <otaylor redhat com>, Miguel de Icaza <miguel nuclecu unam mx>
- Subject: Re: Updated unexpected window destruction patch.
- Date: Wed, 25 Aug 1999 00:02:36 +0200 (CEST)
On 24 Aug 1999, Nat Friedman wrote:
(i'm leaving the issues alone that owen already pointed out)
> private = (GdkWindowPrivate*) window;
> @@ -701,12 +700,50 @@
> {
> if (private->window_type == GDK_WINDOW_FOREIGN)
> gdk_window_internal_destroy (window, FALSE, FALSE);
> - else
> + else {
> + GdkWindowPrivate *parent;
> +
> g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
> +
> + gdk_window_internal_destroy (window, FALSE, FALSE);
> +
> + /*
> + * A window has been unexpectedly destroyed by the X server.
> + *
> + * In the case where a foreign, reparented window (such as is
> + * used by GtkPlug) is destroyed by the death of the client
> + * which created it, the X server will recursively destroy all
> + * of that window's subwindows. In what is effectively a
> + * random order. So what we do here is to walk up the window
> + * tree until we encounter the first foreign window, and
> + * rewrite the event to occur on that window. That way, the
> + * first widget to be destroyed will be the GtkPlug, and its
> + * subwidgets can be killed politely.
> + *
> + * If there is no foreign ancestral window, we don't rewrite
> + * the event.
> + */
you should wrap this into
if (event)
{
> + parent = private;
> + while (parent != NULL && parent->window_type != GDK_WINDOW_FOREIGN)
> + parent = (GdkWindowPrivate *) parent->parent;
> +
> + if (parent != NULL)
> + event->any.window = (GdkWindow *) parent;
> + }
}
since event can validly be NULL, and we don't want to segfault in that case.
> }
>
> gdk_xid_table_remove (private->xwindow);
> gdk_window_unref (window);
> +}
> +
> +
> +static void
> +gtk_plug_unrealize (GtkWidget *widget)
> +{
> + GtkPlug *plug;
> +
> + g_return_if_fail (widget != NULL);
> + g_return_if_fail (GTK_IS_PLUG (widget));
> +
> + plug = GTK_PLUG (widget);
> +
> + if (plug->socket_window != NULL)
> + {
> + gdk_window_set_user_data (plug->socket_window, NULL);
> + gdk_window_destroy (plug->socket_window);
plug->socket = NULL;
> +
> + gdk_window_set_user_data (widget->window, NULL);
> + gdk_window_destroy (widget->window);
widget->window = NULL; though this destruction can be left out,
sicne you are chaning the parent class handler below. however,
i wonder that you don't get gdk warnings with your code, since
you don't reset widget->window to NULL, and
> + }
> +
> + if (GTK_WIDGET_CLASS (parent_class)->unrealize)
> + (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
here you call gtk_widget_real_unrealize() which actually does:
gdk_window_unref (widget->window);
widget->window = NULL;
> }
>
> static void
>
>
---
ciaoTJ
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]