Re: Updated unexpected window destruction patch.



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]