+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
+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
+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
+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
+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
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);
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
private = (GdkWindowObject*) window;
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
switch (GDK_WINDOW_TYPE (window))
{
case GDK_WINDOW_TOPLEVEL:
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;
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);
}
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
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)
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
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));
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;