]> Pileus Git - ~andy/gtk/commitdiff
Make this a total no-op when the new or old parent is destroyed. (#134230,
authorOwen Taylor <otaylor@redhat.com>
Sat, 13 Mar 2004 18:27:56 +0000 (18:27 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Sat, 13 Mar 2004 18:27:56 +0000 (18:27 +0000)
Sat Mar 13 12:17:16 2004  Owen Taylor  <otaylor@redhat.com>

        * gdk/x11/gdkwindow-x11.c (gdk_window_reparent): Make
        this a total no-op when the new or old parent is
        destroyed. (#134230, patch from Soeren Sandmann)

        * gdk/gdkwindow.c (_gdk_window_destroy_hierarchy):
        For foreign windows in our heirarchy, call
        _gdk_windowing_window_destroy_foreign (window) and skip
        all the normal destruction logic.

        * gdk/x11/gdkwindow-x11.c gdk/win32/gdkwindow-win32.c:
        Move code to request destruction of a foreign window
        code into a separate _gdk_windowing_window_destroy_foreign().

        * gdk/x11/gdkwindow-x11.c (gdk_window_impl_x11_finalize):
        Call GDK_WINDOW_DISPLAY() on the wrapper not on the
        impl. (Also from Soeren's patch)

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gdk/gdkinternals.h
gdk/gdkwindow.c
gdk/win32/gdkwindow-win32.c
gdk/x11/gdkwindow-x11.c

index a339e04bbc29d0646eb1bf7885d0ac2f4f3cacf1..55bb85671ab9fa221bb3e61d947217622e52a169 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+Sat Mar 13 12:17:16 2004  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_reparent): Make
+       this a total no-op when the new or old parent is
+       destroyed. (#134230, patch from Soeren Sandmann)
+
+       * gdk/gdkwindow.c (_gdk_window_destroy_hierarchy):
+       For foreign windows in our heirarchy, call
+       _gdk_windowing_window_destroy_foreign (window) and skip
+       all the normal destruction logic.
+
+       * gdk/x11/gdkwindow-x11.c gdk/win32/gdkwindow-win32.c:
+       Move code to request destruction of a foreign window
+       code into a separate _gdk_windowing_window_destroy_foreign().
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_impl_x11_finalize):
+       Call GDK_WINDOW_DISPLAY() on the wrapper not on the
+       impl. (Also from Soeren's patch)
+
 Sat Mar 13 10:49:46 2004  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkdnd.c (_gtk_drag_dest_handle_event): For
index a339e04bbc29d0646eb1bf7885d0ac2f4f3cacf1..55bb85671ab9fa221bb3e61d947217622e52a169 100644 (file)
@@ -1,3 +1,22 @@
+Sat Mar 13 12:17:16 2004  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_reparent): Make
+       this a total no-op when the new or old parent is
+       destroyed. (#134230, patch from Soeren Sandmann)
+
+       * gdk/gdkwindow.c (_gdk_window_destroy_hierarchy):
+       For foreign windows in our heirarchy, call
+       _gdk_windowing_window_destroy_foreign (window) and skip
+       all the normal destruction logic.
+
+       * gdk/x11/gdkwindow-x11.c gdk/win32/gdkwindow-win32.c:
+       Move code to request destruction of a foreign window
+       code into a separate _gdk_windowing_window_destroy_foreign().
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_impl_x11_finalize):
+       Call GDK_WINDOW_DISPLAY() on the wrapper not on the
+       impl. (Also from Soeren's patch)
+
 Sat Mar 13 10:49:46 2004  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkdnd.c (_gtk_drag_dest_handle_event): For
index a339e04bbc29d0646eb1bf7885d0ac2f4f3cacf1..55bb85671ab9fa221bb3e61d947217622e52a169 100644 (file)
@@ -1,3 +1,22 @@
+Sat Mar 13 12:17:16 2004  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_reparent): Make
+       this a total no-op when the new or old parent is
+       destroyed. (#134230, patch from Soeren Sandmann)
+
+       * gdk/gdkwindow.c (_gdk_window_destroy_hierarchy):
+       For foreign windows in our heirarchy, call
+       _gdk_windowing_window_destroy_foreign (window) and skip
+       all the normal destruction logic.
+
+       * gdk/x11/gdkwindow-x11.c gdk/win32/gdkwindow-win32.c:
+       Move code to request destruction of a foreign window
+       code into a separate _gdk_windowing_window_destroy_foreign().
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_impl_x11_finalize):
+       Call GDK_WINDOW_DISPLAY() on the wrapper not on the
+       impl. (Also from Soeren's patch)
+
 Sat Mar 13 10:49:46 2004  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkdnd.c (_gtk_drag_dest_handle_event): For
index a339e04bbc29d0646eb1bf7885d0ac2f4f3cacf1..55bb85671ab9fa221bb3e61d947217622e52a169 100644 (file)
@@ -1,3 +1,22 @@
+Sat Mar 13 12:17:16 2004  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_reparent): Make
+       this a total no-op when the new or old parent is
+       destroyed. (#134230, patch from Soeren Sandmann)
+
+       * gdk/gdkwindow.c (_gdk_window_destroy_hierarchy):
+       For foreign windows in our heirarchy, call
+       _gdk_windowing_window_destroy_foreign (window) and skip
+       all the normal destruction logic.
+
+       * gdk/x11/gdkwindow-x11.c gdk/win32/gdkwindow-win32.c:
+       Move code to request destruction of a foreign window
+       code into a separate _gdk_windowing_window_destroy_foreign().
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_impl_x11_finalize):
+       Call GDK_WINDOW_DISPLAY() on the wrapper not on the
+       impl. (Also from Soeren's patch)
+
 Sat Mar 13 10:49:46 2004  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkdnd.c (_gtk_drag_dest_handle_event): For
index a339e04bbc29d0646eb1bf7885d0ac2f4f3cacf1..55bb85671ab9fa221bb3e61d947217622e52a169 100644 (file)
@@ -1,3 +1,22 @@
+Sat Mar 13 12:17:16 2004  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_reparent): Make
+       this a total no-op when the new or old parent is
+       destroyed. (#134230, patch from Soeren Sandmann)
+
+       * gdk/gdkwindow.c (_gdk_window_destroy_hierarchy):
+       For foreign windows in our heirarchy, call
+       _gdk_windowing_window_destroy_foreign (window) and skip
+       all the normal destruction logic.
+
+       * gdk/x11/gdkwindow-x11.c gdk/win32/gdkwindow-win32.c:
+       Move code to request destruction of a foreign window
+       code into a separate _gdk_windowing_window_destroy_foreign().
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_impl_x11_finalize):
+       Call GDK_WINDOW_DISPLAY() on the wrapper not on the
+       impl. (Also from Soeren's patch)
+
 Sat Mar 13 10:49:46 2004  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkdnd.c (_gtk_drag_dest_handle_event): For
index 6f4c5394243862a6546d2952b813263065a45231..f9d3c02798c8664dac5edee758aba6d8575a7c5c 100644 (file)
@@ -306,6 +306,13 @@ void _gdk_windowing_window_destroy (GdkWindow *window,
                                    gboolean   recursing,
                                    gboolean   foreign_destroy);
 
+/* Called when gdk_window_destroy() is called on a foreign window
+ * or an ancestor of the foreign window. It should generally reparent
+ * the window out of it's current heirarchy, hide it, and then
+ * send a message to the owner requesting that the window be destroyed.
+ */
+void _gdk_windowing_window_destroy_foreign (GdkWindow *window);
+
 void _gdk_windowing_display_set_sm_client_id (GdkDisplay  *display,
                                              const gchar *sm_client_id);
 
index 4df74dd6df3eea0bda3c11fc5a7361c5d93e08bd..7987e650a385f38a48e71b44ea6f7a1c070fe795 100644 (file)
@@ -278,6 +278,23 @@ gdk_window_finalize (GObject *object)
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
+static void
+window_remove_filters (GdkWindow *window)
+{
+  GdkWindowObject *obj = (GdkWindowObject*) window;
+
+  if (obj->filters)
+    {
+      GList *tmp_list;
+      
+      for (tmp_list = obj->filters; tmp_list; tmp_list = tmp_list->next)
+       g_free (tmp_list->data);
+    
+      g_list_free (obj->filters);
+      obj->filters = NULL;
+    }
+}
+
 /**
  * _gdk_window_destroy_hierarchy:
  * @window: a #GdkWindow
@@ -309,6 +326,9 @@ _gdk_window_destroy_hierarchy (GdkWindow *window,
   
   private = (GdkWindowObject*) window;
   
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+    
   switch (GDK_WINDOW_TYPE (window))
     {
     case GDK_WINDOW_TOPLEVEL:
@@ -316,7 +336,25 @@ _gdk_window_destroy_hierarchy (GdkWindow *window,
     case GDK_WINDOW_DIALOG:
     case GDK_WINDOW_TEMP:
     case GDK_WINDOW_FOREIGN:
-      if (!GDK_WINDOW_DESTROYED (window))
+      if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_FOREIGN && !foreign_destroy)
+       {
+         /* Logically, it probably makes more sense to send
+          * a "destroy yourself" message to the foreign window
+          * whether or not it's in our heirarchy; but for historical
+          * reasons, we only send "destroy yourself" messages to
+          * foreign windows in our heirarchy.
+          */
+         if (private->parent)
+           _gdk_windowing_window_destroy_foreign (window);
+
+         /* Also for historical reasons, we remove any filters
+          * on a foreign window when it or a parent is destroyed;
+          * this likely causes problems if two separate portions
+          * of code are maintaining filter lists on a foreign window.
+          */
+         window_remove_filters (window);
+       }
+      else
        {
          private->state |= GDK_WINDOW_STATE_WITHDRAWN;
          
@@ -363,19 +401,7 @@ _gdk_window_destroy_hierarchy (GdkWindow *window,
          private->parent = NULL;
          private->destroyed = TRUE;
 
-         if (private->filters)
-           {
-             tmp = private->filters;
-             
-             while (tmp)
-               {
-                 g_free (tmp->data);
-                 tmp = tmp->next;
-               }
-             
-             g_list_free (private->filters);
-             private->filters = NULL;
-           }
+         window_remove_filters (window);
 
           gdk_drawable_set_colormap (GDK_DRAWABLE (window), NULL);
        }
index 424a5433131927070e9c1d8a94a946785657eac2..958df71c91017eb98d4740cc5eca5bf82f0040c2 100644 (file)
@@ -810,32 +810,32 @@ _gdk_windowing_window_destroy (GdkWindow *window,
   if (private->extension_events != 0)
     _gdk_input_window_destroy (window);
 
-  if (private->window_type == GDK_WINDOW_FOREIGN)
-    {
-      if (!foreign_destroy && (private->parent != NULL))
-       {
-         /* It's somebody else's window, but in our hierarchy,
-          * so reparent it to the root window, and then call
-          * DestroyWindow() on it.
-          */
-         gdk_window_hide (window);
-         gdk_window_reparent (window, NULL, 0, 0);
-         
-         /* Is this too drastic? Many (most?) applications
-          * quit if any window receives WM_QUIT I think.
-          * OTOH, I don't think foreign windows are much
-          * used, so the question is maybe academic.
-          */
-         PostMessage (GDK_WINDOW_HWND (window), WM_QUIT, 0, 0);
-       }
-    }
-  else if (!recursing && !foreign_destroy)
+
+  if (!recursing && !foreign_destroy)
     {
       private->destroyed = TRUE;
       DestroyWindow (GDK_WINDOW_HWND (window));
     }
 }
 
+void
+_gdk_windowing_window_destroy_foreign (GdkWindow *window)
+{
+  /* It's somebody else's window, but in our hierarchy,
+   * so reparent it to the root window, and then call
+   * DestroyWindow() on it.
+   */
+  gdk_window_hide (window);
+  gdk_window_reparent (window, NULL, 0, 0);
+  
+  /* Is this too drastic? Many (most?) applications
+   * quit if any window receives WM_QUIT I think.
+   * OTOH, I don't think foreign windows are much
+   * used, so the question is maybe academic.
+   */
+  PostMessage (GDK_WINDOW_HWND (window), WM_QUIT, 0, 0);
+}
+
 /* This function is called when the window really gone.
  */
 void
index a4a26d14b688a303976bc6f4f3bc05d1ad1e9879..c594444845b1a0c99da95dc14bafb5b653d9b864 100644 (file)
@@ -204,9 +204,11 @@ gdk_window_impl_x11_finalize (GObject *object)
 
   if (!GDK_WINDOW_DESTROYED (wrapper))
     {
-      _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (object), draw_impl->xid);
+      GdkDisplay *display = GDK_WINDOW_DISPLAY (wrapper);
+      
+      _gdk_xid_table_remove (display, draw_impl->xid);
       if (window_impl->toplevel && window_impl->toplevel->focus_window)
-       _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (object), window_impl->toplevel->focus_window);
+       _gdk_xid_table_remove (display, window_impl->toplevel->focus_window);
     }
 
   if (window_impl->toplevel)
@@ -937,45 +939,44 @@ _gdk_windowing_window_destroy (GdkWindow *window,
   if (draw_impl->xft_draw)
     XftDrawDestroy (draw_impl->xft_draw);
 
-  if (private->window_type == GDK_WINDOW_FOREIGN)
-    {
-      if (!foreign_destroy && (private->parent != NULL))
-       {
-         /* It's somebody else's window, but in our heirarchy,
-          * so reparent it to the root window, and then send
-          * it a delete event, as if we were a WM
-          */
-         XClientMessageEvent xevent;
-         
-         gdk_error_trap_push ();
-         gdk_window_hide (window);
-         gdk_window_reparent (window, NULL, 0, 0);
-         
-         xevent.type = ClientMessage;
-         xevent.window = GDK_WINDOW_XID (window);
-         xevent.message_type = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
-                                                                      "WM_PROTOCOLS");
-         xevent.format = 32;
-         xevent.data.l[0] = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
-                                                                   "WM_DELETE_WINDOW");
-         xevent.data.l[1] = CurrentTime;
-         xevent.data.l[2] = 0;
-         xevent.data.l[3] = 0;
-         xevent.data.l[4] = 0;
-         
-         XSendEvent (GDK_WINDOW_XDISPLAY (window),
-                     GDK_WINDOW_XID (window),
-                     False, 0, (XEvent *)&xevent);
-         gdk_display_sync (GDK_WINDOW_DISPLAY (window));
-         gdk_error_trap_pop ();
-       }
-    }
-  else if (!recursing && !foreign_destroy)
+  if (!recursing && !foreign_destroy)
     {
       XDestroyWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
     }
 }
 
+void
+_gdk_windowing_window_destroy_foreign (GdkWindow *window)
+{
+  /* It's somebody else's window, but in our heirarchy,
+   * so reparent it to the root window, and then send
+   * it a delete event, as if we were a WM
+   */
+  XClientMessageEvent xevent;
+  
+  gdk_error_trap_push ();
+  gdk_window_hide (window);
+  gdk_window_reparent (window, NULL, 0, 0);
+  
+  xevent.type = ClientMessage;
+  xevent.window = GDK_WINDOW_XID (window);
+  xevent.message_type = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
+                                                              "WM_PROTOCOLS");
+  xevent.format = 32;
+  xevent.data.l[0] = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
+                                                           "WM_DELETE_WINDOW");
+  xevent.data.l[1] = CurrentTime;
+  xevent.data.l[2] = 0;
+  xevent.data.l[3] = 0;
+  xevent.data.l[4] = 0;
+  
+  XSendEvent (GDK_WINDOW_XDISPLAY (window),
+             GDK_WINDOW_XID (window),
+             False, 0, (XEvent *)&xevent);
+  gdk_display_sync (GDK_WINDOW_DISPLAY (window));
+  gdk_error_trap_pop ();
+}
+
 /* This function is called when the XWindow is really gone.
  */
 void
@@ -1502,6 +1503,12 @@ gdk_window_reparent (GdkWindow *window,
   g_return_if_fail (GDK_IS_WINDOW (window));
   g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
   g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
+
+  if (GDK_WINDOW_DESTROYED (window) ||
+      (new_parent && GDK_WINDOW_DESTROYED (new_parent)))
+    {
+      return;
+    }
   
   if (!new_parent)
     new_parent = gdk_screen_get_root_window (GDK_WINDOW_SCREEN (window));
@@ -1513,11 +1520,10 @@ gdk_window_reparent (GdkWindow *window,
   parent_private = (GdkWindowObject*) new_parent;
   impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
   
-  if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (new_parent))
-    XReparentWindow (GDK_WINDOW_XDISPLAY (window),
-                    GDK_WINDOW_XID (window),
-                    GDK_WINDOW_XID (new_parent),
-                    x, y);
+  XReparentWindow (GDK_WINDOW_XDISPLAY (window),
+                  GDK_WINDOW_XID (window),
+                  GDK_WINDOW_XID (new_parent),
+                  x, y);
 
   window_private->x = x;
   window_private->y = y;