forked from AuroraMiddleware/gtk
Make this a total no-op when the new or old parent is destroyed. (#134230,
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)
This commit is contained in:
parent
fadaa65145
commit
ef5915da35
19
ChangeLog
19
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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
@ -1503,6 +1504,12 @@ gdk_window_reparent (GdkWindow *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;
|
||||
|
Loading…
Reference in New Issue
Block a user