зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1760276 [Wayland] When we check for popup resize workaround, consider toplevel window instead of parent one, r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D141600
This commit is contained in:
Родитель
79c266123a
Коммит
ba683562a8
|
@ -2006,36 +2006,31 @@ void nsWindow::WaylandPopupSetDirectPosition() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsWindow::WaylandPopupFitsParentWindow(const GdkRectangle& aSize) {
|
bool nsWindow::WaylandPopupFitsToplevelWindow() {
|
||||||
GtkWindow* parentGtkWindow = gtk_window_get_transient_for(GTK_WINDOW(mShell));
|
LOG("nsWindow::WaylandPopupFitsToplevelWindow()");
|
||||||
nsWindow* parentWindow =
|
|
||||||
get_window_for_gtk_widget(GTK_WIDGET(parentGtkWindow));
|
|
||||||
|
|
||||||
// Don't try to fiddle with popup position when our parent is also popup.
|
GtkWindow* parent = gtk_window_get_transient_for(GTK_WINDOW(mShell));
|
||||||
// Use layout setup in such case.
|
GtkWindow* tmp = parent;
|
||||||
if (parentWindow->IsPopup()) {
|
while (tmp = gtk_window_get_transient_for(GTK_WINDOW(parent))) {
|
||||||
|
parent = tmp;
|
||||||
|
}
|
||||||
|
GdkWindow* toplevelGdkWindow = gtk_widget_get_window(GTK_WIDGET(parent));
|
||||||
|
|
||||||
|
if (!toplevelGdkWindow) {
|
||||||
|
NS_WARNING("Toplevel widget without GdkWindow?");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use MozContainer to get visible area without decorations.
|
int parentWidth = gdk_window_get_width(toplevelGdkWindow);
|
||||||
GdkWindow* parentGdkWindow =
|
int parentHeight = gdk_window_get_height(toplevelGdkWindow);
|
||||||
gtk_widget_get_window(GTK_WIDGET(parentWindow->GetMozContainer()));
|
LOG(" parent size %d x %d", parentWidth, parentHeight);
|
||||||
|
|
||||||
// x,y are offsets of mozcontainer, i.e. size of CSD decorations size.
|
GdkRectangle rect = DevicePixelsToGdkRectRoundOut(mBounds);
|
||||||
int x, y;
|
int fits = rect.x >= 0 && rect.y >= 0 && rect.x + rect.width <= parentWidth &&
|
||||||
gdk_window_get_position(parentGdkWindow, &x, &y);
|
rect.y + rect.height <= parentHeight;
|
||||||
|
|
||||||
// We use parent mozcontainer size plus left/top CSD decorations sizes as
|
LOG(" fits %d", fits);
|
||||||
// this coordinates are used by mBounds.
|
return fits;
|
||||||
int parentWidth = gdk_window_get_width(parentGdkWindow) + x;
|
|
||||||
int parentHeight = gdk_window_get_height(parentGdkWindow) + y;
|
|
||||||
int popupWidth = aSize.width;
|
|
||||||
int popupHeight = aSize.height;
|
|
||||||
|
|
||||||
auto popupBounds = DevicePixelsToGdkRectRoundOut(mBounds);
|
|
||||||
return popupBounds.x >= 0 && popupBounds.y >= 0 &&
|
|
||||||
popupBounds.x + popupWidth <= parentWidth &&
|
|
||||||
popupBounds.y + popupHeight <= parentHeight;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsWindow::NativeMoveResizeWaylandPopup(bool aMove, bool aResize) {
|
void nsWindow::NativeMoveResizeWaylandPopup(bool aMove, bool aResize) {
|
||||||
|
@ -2089,7 +2084,7 @@ void nsWindow::NativeMoveResizeWaylandPopup(bool aMove, bool aResize) {
|
||||||
gtk_window_resize(GTK_WINDOW(mShell), rect.width, rect.height);
|
gtk_window_resize(GTK_WINDOW(mShell), rect.width, rect.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aMove && WaylandPopupFitsParentWindow(rect)) {
|
if (!aMove && WaylandPopupFitsToplevelWindow()) {
|
||||||
// Popup position has not been changed and its position/size fits
|
// Popup position has not been changed and its position/size fits
|
||||||
// parent window so no need to reposition the window.
|
// parent window so no need to reposition the window.
|
||||||
LOG(" fits parent window size, just resize\n");
|
LOG(" fits parent window size, just resize\n");
|
||||||
|
@ -2362,6 +2357,8 @@ void nsWindow::WaylandPopupMove() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See https://gitlab.gnome.org/GNOME/gtk/-/issues/1986
|
||||||
|
// We're likely fail to reposition already visible widget.
|
||||||
if (gtk_widget_is_visible(mShell)) {
|
if (gtk_widget_is_visible(mShell)) {
|
||||||
NS_WARNING(
|
NS_WARNING(
|
||||||
"Positioning visible popup under Wayland, position may be wrong!");
|
"Positioning visible popup under Wayland, position may be wrong!");
|
||||||
|
|
|
@ -793,7 +793,7 @@ class nsWindow final : public nsBaseWidget {
|
||||||
void WaylandPopupMarkAsClosed();
|
void WaylandPopupMarkAsClosed();
|
||||||
void WaylandPopupRemoveClosedPopups();
|
void WaylandPopupRemoveClosedPopups();
|
||||||
void WaylandPopupSetDirectPosition();
|
void WaylandPopupSetDirectPosition();
|
||||||
bool WaylandPopupFitsParentWindow(const GdkRectangle& aSize);
|
bool WaylandPopupFitsToplevelWindow();
|
||||||
const WaylandPopupMoveToRectParams WaylandPopupGetPositionFromLayout();
|
const WaylandPopupMoveToRectParams WaylandPopupGetPositionFromLayout();
|
||||||
nsWindow* WaylandPopupFindLast(nsWindow* aPopup);
|
nsWindow* WaylandPopupFindLast(nsWindow* aPopup);
|
||||||
GtkWindow* GetCurrentTopmostWindow();
|
GtkWindow* GetCurrentTopmostWindow();
|
||||||
|
@ -807,9 +807,11 @@ class nsWindow final : public nsBaseWidget {
|
||||||
|
|
||||||
// mPopupPosition is the original popup position from layout, set by
|
// mPopupPosition is the original popup position from layout, set by
|
||||||
// nsWindow::Move() or nsWindow::Resize().
|
// nsWindow::Move() or nsWindow::Resize().
|
||||||
|
// Popup position is relative to main (toplevel) window.
|
||||||
GdkPoint mPopupPosition{};
|
GdkPoint mPopupPosition{};
|
||||||
|
|
||||||
// mRelativePopupPosition is popup position calculated against parent window.
|
// mRelativePopupPosition is popup position calculated against
|
||||||
|
// recent popup parent window.
|
||||||
GdkPoint mRelativePopupPosition{};
|
GdkPoint mRelativePopupPosition{};
|
||||||
|
|
||||||
// Toplevel window (first element) of linked list of Wayland popups. It's null
|
// Toplevel window (first element) of linked list of Wayland popups. It's null
|
||||||
|
|
Загрузка…
Ссылка в новой задаче