Bug 1788910 [Wayland] Look for parents recursively at nsWindow::WaylandGetParentPosition() r=emilio

Right now we look for first parent only at nsWindow::WaylandGetParentPosition() and that's wrong.
WaylandGetParentPosition() is expected to return popup position in root coordinates regardless of popup parent nembers.

In this patch we calc popup position according to whole popup chain.

Differential Revision: https://phabricator.services.mozilla.com/D156673
This commit is contained in:
stransky 2022-09-08 08:55:17 +00:00
parent 9eee1bc1e3
commit feb00b8d6d
2 changed files with 18 additions and 12 deletions

View File

@ -1559,24 +1559,29 @@ bool nsWindow::WaylandPopupIsFirst() {
return !mWaylandPopupPrev || !mWaylandPopupPrev->mWaylandToplevel;
}
nsWindow* nsWindow::GetEffectiveParent() {
GtkWindow* parentGtkWindow = gtk_window_get_transient_for(GTK_WINDOW(mShell));
if (!parentGtkWindow || !GTK_IS_WIDGET(parentGtkWindow)) {
return nullptr;
}
return get_window_for_gtk_widget(GTK_WIDGET(parentGtkWindow));
}
GdkPoint nsWindow::WaylandGetParentPosition() {
// Don't call WaylandGetParentPosition on X11 as it causes X11 roundtrips.
// gdk_window_get_origin is very fast on Wayland as the
// window position is cached by Gtk.
MOZ_DIAGNOSTIC_ASSERT(GdkIsWaylandDisplay());
GtkWindow* parentGtkWindow = gtk_window_get_transient_for(GTK_WINDOW(mShell));
if (!parentGtkWindow || !GTK_IS_WIDGET(parentGtkWindow)) {
NS_WARNING("Popup has no parent!");
return {0, 0};
}
GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(parentGtkWindow));
if (!window) {
NS_WARNING("Popup parent is not mapped!");
return {0, 0};
}
gint x = 0, y = 0;
gdk_window_get_origin(window, &x, &y);
for (nsWindow* window = GetEffectiveParent(); window;
window = window->GetEffectiveParent()) {
// Get relative position of window
gint dx, dy;
gdk_window_get_origin(gtk_widget_get_window(window->GetGtkWidget()), &dx,
&dy);
x += dx;
y += dy;
}
return {x, y};
}

View File

@ -280,6 +280,7 @@ class nsWindow final : public nsBaseWidget {
GdkWindow* GetToplevelGdkWindow() const;
GtkWidget* GetGtkWidget() const { return mShell; }
nsIFrame* GetFrame() const;
nsWindow* GetEffectiveParent();
bool IsDestroyed() const { return mIsDestroyed; }
bool IsPopup() const;
bool IsWaylandPopup() const;