зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1562827 - [Linux] Merge nsWindow::ReparentNativeWidgetInternal() to nsWindow::SetParent() and use nsWindow::ReparentNativeWidget() for toplevel windows only, r=karlt
- Use former ReparentNativeWidgetInternal() code in nsWindow::SetParent(). Also update mToplevelParentWindow for Wayland to hold default toplevel window. - Make nsWindow::ReparentNativeWidget() to work on toplevel windows only and use only gtk_window_set_transient_for() to reparent a toplevel window. Also update mToplevelParentWindow for Wayland. Differential Revision: https://phabricator.services.mozilla.com/D43600 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
52b58160a7
Коммит
1cf5fdd9b6
|
@ -821,7 +821,6 @@ void nsWindow::SetParent(nsIWidget* aNewParent) {
|
|||
if (mParent) {
|
||||
mParent->RemoveChild(this);
|
||||
}
|
||||
|
||||
mParent = aNewParent;
|
||||
|
||||
GtkWidget* oldContainer = GetMozContainerWidget();
|
||||
|
@ -833,18 +832,47 @@ void nsWindow::SetParent(nsIWidget* aNewParent) {
|
|||
return;
|
||||
}
|
||||
|
||||
nsWindow* newParent = static_cast<nsWindow*>(aNewParent);
|
||||
GdkWindow* newParentWindow = nullptr;
|
||||
GtkWidget* newContainer = nullptr;
|
||||
if (aNewParent) {
|
||||
aNewParent->AddChild(this);
|
||||
ReparentNativeWidget(aNewParent);
|
||||
newParentWindow = newParent->mGdkWindow;
|
||||
newContainer = newParent->GetMozContainerWidget();
|
||||
} else {
|
||||
// aNewParent is nullptr, but reparent to a hidden window to avoid
|
||||
// destroying the GdkWindow and its descendants.
|
||||
// An invisible container widget is needed to hold descendant
|
||||
// GtkWidgets.
|
||||
GtkWidget* newContainer = EnsureInvisibleContainer();
|
||||
GdkWindow* newParentWindow = gtk_widget_get_window(newContainer);
|
||||
ReparentNativeWidgetInternal(aNewParent, newContainer, newParentWindow,
|
||||
oldContainer);
|
||||
newContainer = EnsureInvisibleContainer();
|
||||
newParentWindow = gtk_widget_get_window(newContainer);
|
||||
}
|
||||
|
||||
if (!newContainer) {
|
||||
// The new parent GdkWindow has been destroyed.
|
||||
MOZ_ASSERT(!newParentWindow || gdk_window_is_destroyed(newParentWindow),
|
||||
"live GdkWindow with no widget");
|
||||
Destroy();
|
||||
} else {
|
||||
if (newContainer != oldContainer) {
|
||||
MOZ_ASSERT(!gdk_window_is_destroyed(newParentWindow),
|
||||
"destroyed GdkWindow with widget");
|
||||
SetWidgetForHierarchy(mGdkWindow, oldContainer, newContainer);
|
||||
|
||||
if (oldContainer == gInvisibleContainer) {
|
||||
CheckDestroyInvisibleContainer();
|
||||
}
|
||||
}
|
||||
|
||||
gdk_window_reparent(mGdkWindow, newParentWindow,
|
||||
DevicePixelsToGdkCoordRoundDown(mBounds.x),
|
||||
DevicePixelsToGdkCoordRoundDown(mBounds.y));
|
||||
mToplevelParentWindow = GTK_WINDOW(gtk_widget_get_toplevel(newContainer));
|
||||
}
|
||||
|
||||
bool parentHasMappedToplevel = newParent && newParent->mHasMappedToplevel;
|
||||
if (mHasMappedToplevel != parentHasMappedToplevel) {
|
||||
SetHasMappedToplevel(parentHasMappedToplevel);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -852,66 +880,22 @@ bool nsWindow::WidgetTypeSupportsAcceleration() { return !IsSmallPopup(); }
|
|||
|
||||
void nsWindow::ReparentNativeWidget(nsIWidget* aNewParent) {
|
||||
MOZ_ASSERT(aNewParent, "null widget");
|
||||
NS_ASSERTION(!mIsDestroyed, "");
|
||||
NS_ASSERTION(!static_cast<nsWindow*>(aNewParent)->mIsDestroyed, "");
|
||||
|
||||
GtkWidget* oldContainer = GetMozContainerWidget();
|
||||
if (!oldContainer) {
|
||||
// The GdkWindows have been destroyed so there is nothing else to
|
||||
// reparent.
|
||||
MOZ_ASSERT(gdk_window_is_destroyed(mGdkWindow),
|
||||
"live GdkWindow with no widget");
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(!mIsDestroyed, "");
|
||||
MOZ_ASSERT(!static_cast<nsWindow*>(aNewParent)->mIsDestroyed, "");
|
||||
MOZ_ASSERT(!gdk_window_is_destroyed(mGdkWindow),
|
||||
"destroyed GdkWindow with widget");
|
||||
|
||||
MOZ_ASSERT(
|
||||
!mParent,
|
||||
"nsWindow::ReparentNativeWidget() works on toplevel windows only.");
|
||||
|
||||
auto* newParent = static_cast<nsWindow*>(aNewParent);
|
||||
GdkWindow* newParentWindow = newParent->mGdkWindow;
|
||||
GtkWidget* newContainer = newParent->GetMozContainerWidget();
|
||||
GtkWindow* newParentWidget = GTK_WINDOW(newParent->GetGtkWidget());
|
||||
GtkWindow* shell = GTK_WINDOW(mShell);
|
||||
|
||||
if (shell && gtk_window_get_transient_for(shell)) {
|
||||
GtkWindow* topLevelParent =
|
||||
GTK_WINDOW(gtk_widget_get_toplevel(newContainer));
|
||||
gtk_window_set_transient_for(shell, topLevelParent);
|
||||
}
|
||||
|
||||
ReparentNativeWidgetInternal(aNewParent, newContainer, newParentWindow,
|
||||
oldContainer);
|
||||
}
|
||||
|
||||
void nsWindow::ReparentNativeWidgetInternal(nsIWidget* aNewParent,
|
||||
GtkWidget* aNewContainer,
|
||||
GdkWindow* aNewParentWindow,
|
||||
GtkWidget* aOldContainer) {
|
||||
if (!aNewContainer) {
|
||||
// The new parent GdkWindow has been destroyed.
|
||||
MOZ_ASSERT(!aNewParentWindow || gdk_window_is_destroyed(aNewParentWindow),
|
||||
"live GdkWindow with no widget");
|
||||
Destroy();
|
||||
} else {
|
||||
if (aNewContainer != aOldContainer) {
|
||||
MOZ_ASSERT(!gdk_window_is_destroyed(aNewParentWindow),
|
||||
"destroyed GdkWindow with widget");
|
||||
SetWidgetForHierarchy(mGdkWindow, aOldContainer, aNewContainer);
|
||||
|
||||
if (aOldContainer == gInvisibleContainer) {
|
||||
CheckDestroyInvisibleContainer();
|
||||
}
|
||||
}
|
||||
|
||||
if (!mIsTopLevel) {
|
||||
gdk_window_reparent(mGdkWindow, aNewParentWindow,
|
||||
DevicePixelsToGdkCoordRoundDown(mBounds.x),
|
||||
DevicePixelsToGdkCoordRoundDown(mBounds.y));
|
||||
}
|
||||
}
|
||||
|
||||
auto* newParent = static_cast<nsWindow*>(aNewParent);
|
||||
bool parentHasMappedToplevel = newParent && newParent->mHasMappedToplevel;
|
||||
if (mHasMappedToplevel != parentHasMappedToplevel) {
|
||||
SetHasMappedToplevel(parentHasMappedToplevel);
|
||||
gtk_window_set_transient_for(shell, newParentWidget);
|
||||
mToplevelParentWindow = newParentWidget;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -402,12 +402,6 @@ class nsWindow final : public nsBaseWidget {
|
|||
void DispatchResized();
|
||||
void MaybeDispatchResized();
|
||||
|
||||
// Helper for SetParent and ReparentNativeWidget.
|
||||
void ReparentNativeWidgetInternal(nsIWidget* aNewParent,
|
||||
GtkWidget* aNewContainer,
|
||||
GdkWindow* aNewParentWindow,
|
||||
GtkWidget* aOldContainer);
|
||||
|
||||
virtual void RegisterTouchWindow() override;
|
||||
virtual bool CompositorInitiallyPaused() override {
|
||||
#ifdef MOZ_WAYLAND
|
||||
|
|
Загрузка…
Ссылка в новой задаче