mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 15:23:51 +00:00
b=522635 destroy child nsWindows when destroying the parent r=roc
--HG-- extra : rebase_source : 53b4061a728721db67c9b253e0454ee815a0fad9
This commit is contained in:
parent
80f6afa68a
commit
41b65db823
@ -652,9 +652,7 @@ CheckDestroyInvisibleContainer()
|
||||
|
||||
// Change the containing GtkWidget on a sub-hierarchy of GdkWindows belonging
|
||||
// to aOldWidget and rooted at aWindow, and reparent any child GtkWidgets of
|
||||
// the GdkWindow hierarchy. If aNewWidget is NULL, the reference to
|
||||
// aOldWidget is removed from its GdkWindows, and child GtkWidgets are
|
||||
// destroyed.
|
||||
// the GdkWindow hierarchy to aNewWidget.
|
||||
static void
|
||||
SetWidgetForHierarchy(GdkWindow *aWindow,
|
||||
GtkWidget *aOldWidget,
|
||||
@ -673,13 +671,7 @@ SetWidgetForHierarchy(GdkWindow *aWindow,
|
||||
|
||||
// This window belongs to a child widget, which will no longer be a
|
||||
// child of aOldWidget.
|
||||
if (aNewWidget) {
|
||||
gtk_widget_reparent(widget, aNewWidget);
|
||||
} else {
|
||||
// aNewWidget == NULL indicates that the window is about to be
|
||||
// destroyed.
|
||||
gtk_widget_destroy(widget);
|
||||
}
|
||||
gtk_widget_reparent(widget, aNewWidget);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -693,6 +685,34 @@ SetWidgetForHierarchy(GdkWindow *aWindow,
|
||||
gdk_window_set_user_data(aWindow, aNewWidget);
|
||||
}
|
||||
|
||||
// Walk the list of child windows and call destroy on them.
|
||||
void
|
||||
nsWindow::DestroyChildWindows()
|
||||
{
|
||||
if (!mGdkWindow)
|
||||
return;
|
||||
|
||||
GList *children = gdk_window_get_children(mGdkWindow);
|
||||
|
||||
for(GList *list = children; list; list = list->next) {
|
||||
GdkWindow *child = GDK_WINDOW(children->data);
|
||||
nsWindow *kid = get_window_for_gdk_window(child);
|
||||
if (kid) {
|
||||
kid->Destroy();
|
||||
} else {
|
||||
// This child is not an nsWindow.
|
||||
// Destroy the child GtkWidget.
|
||||
gpointer data;
|
||||
gdk_window_get_user_data(child, &data);
|
||||
if (GTK_IS_WIDGET(data)) {
|
||||
gtk_widget_destroy(static_cast<GtkWidget*>(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free(children);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::Destroy(void)
|
||||
{
|
||||
@ -730,15 +750,6 @@ nsWindow::Destroy(void)
|
||||
|
||||
NativeShow(PR_FALSE);
|
||||
|
||||
// walk the list of children and call destroy on them. Have to be
|
||||
// careful, though -- calling destroy on a kid may actually remove
|
||||
// it from our child list, losing its sibling links.
|
||||
for (nsIWidget* kid = mFirstChild; kid; ) {
|
||||
nsIWidget* next = kid->GetNextSibling();
|
||||
kid->Destroy();
|
||||
kid = next;
|
||||
}
|
||||
|
||||
#ifdef USE_XIM
|
||||
IMEDestroyContext();
|
||||
#endif
|
||||
@ -790,16 +801,13 @@ nsWindow::Destroy(void)
|
||||
"mGdkWindow should be NULL when mContainer is destroyed");
|
||||
}
|
||||
else if (mGdkWindow) {
|
||||
// Remove references from GdkWindows back to their container
|
||||
// widget while the GdkWindow hierarchy is still available.
|
||||
// (OnContainerUnrealize does this when the MozContainer widget is
|
||||
// destroyed.)
|
||||
if (owningWidget) {
|
||||
SetWidgetForHierarchy(mGdkWindow, owningWidget, NULL);
|
||||
}
|
||||
NS_ASSERTION(!get_gtk_widget_for_gdk_window(mGdkWindow),
|
||||
"widget reference not removed");
|
||||
// Destroy child windows to ensure that their mThebesSurfaces are
|
||||
// released and to remove references from GdkWindows back to their
|
||||
// container widget. (OnContainerUnrealize() does this when the
|
||||
// MozContainer widget is destroyed.)
|
||||
DestroyChildWindows();
|
||||
|
||||
gdk_window_set_user_data(mGdkWindow, NULL);
|
||||
g_object_set_data(G_OBJECT(mGdkWindow), "nsWindow", NULL);
|
||||
gdk_window_destroy(mGdkWindow);
|
||||
mGdkWindow = nsnull;
|
||||
@ -2384,7 +2392,7 @@ nsWindow::OnContainerUnrealize(GtkWidget *aWidget)
|
||||
"unexpected \"unrealize\" signal");
|
||||
|
||||
if (mGdkWindow) {
|
||||
SetWidgetForHierarchy(mGdkWindow, aWidget, NULL);
|
||||
DestroyChildWindows();
|
||||
|
||||
g_object_set_data(G_OBJECT(mGdkWindow), "nsWindow", NULL);
|
||||
mGdkWindow = NULL;
|
||||
@ -7211,6 +7219,9 @@ nsWindow::GetSurfaceForGdkDrawable(GdkDrawable* aDrawable,
|
||||
gfxASurface*
|
||||
nsWindow::GetThebesSurface()
|
||||
{
|
||||
if (!mGdkWindow)
|
||||
return nsnull;
|
||||
|
||||
GdkDrawable* d;
|
||||
gint x_offset, y_offset;
|
||||
gdk_window_get_internal_paint_info(mGdkWindow, &d, &x_offset, &y_offset);
|
||||
|
@ -432,6 +432,7 @@ protected:
|
||||
PRPackedBool mPlaced;
|
||||
|
||||
private:
|
||||
void DestroyChildWindows();
|
||||
void GetToplevelWidget(GtkWidget **aWidget);
|
||||
GtkWidget *GetMozContainerWidget();
|
||||
nsWindow *GetContainerWindow();
|
||||
|
Loading…
Reference in New Issue
Block a user