From 582ea4cda5c424143d456b2e6020ef810a9ab786 Mon Sep 17 00:00:00 2001 From: Jan Horak Date: Tue, 19 May 2020 15:34:18 +0000 Subject: [PATCH] Bug 1637948 Don't resize popup on hidpi when not needed r=stransky We have to compare new width and height multiplied by scale because mBounds is in real pixels while gdk_window_move_to_rect returns the size without multiplying by scale factor. Also to fix overflow popups we need to use NativeMoveResize in nsWindow::ResizeInt when size of the popup has changed. Differential Revision: https://phabricator.services.mozilla.com/D75298 --- layout/xul/nsMenuPopupFrame.cpp | 2 +- widget/gtk/nsWindow.cpp | 15 +++++++++++++-- widget/gtk/nsWindow.h | 2 ++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/layout/xul/nsMenuPopupFrame.cpp b/layout/xul/nsMenuPopupFrame.cpp index 11e8c9db40a6..e5813709c37a 100644 --- a/layout/xul/nsMenuPopupFrame.cpp +++ b/layout/xul/nsMenuPopupFrame.cpp @@ -550,7 +550,7 @@ void nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState, mPrefSize = prefSize; #if MOZ_WAYLAND nsIWidget* widget = GetWidget(); - if (widget) { + if (widget && mPopupState != ePopupShown) { // When the popup size changed in the DOM, we need to flush widget // preferred popup rect to avoid showing it in wrong size. widget->FlushPreferredPopupRect(); diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index fe4f6b40225d..78ee9c2d2aaa 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -1090,7 +1090,8 @@ void nsWindow::ResizeInt(int aX, int aY, int aWidth, int aHeight, bool aMove, if (!mCreated) return; - if (aMove) { + if (aMove || mPreferredPopupRectFlushed) { + LOG((" Need also to move, flushed? %d\n", mPreferredPopupRectFlushed)); NativeMoveResize(); } else { NativeResize(); @@ -1445,10 +1446,15 @@ void nsWindow::NativeMoveResizeWaylandPopupCB(const GdkRectangle* aFinalSize, LOG((" new mBounds x=%d y=%d width=%d height=%d\n", newBounds.x, newBounds.y, newBounds.width, newBounds.height)); + double scale = + BoundsUseDesktopPixels() ? GetDesktopToDeviceScale().scale : 1.0; + int32_t newWidth = NSToIntRound(scale * newBounds.width); + int32_t newHeight = NSToIntRound(scale * newBounds.height); + bool needsPositionUpdate = (newBounds.x != mBounds.x || newBounds.y != mBounds.y); bool needsSizeUpdate = - (newBounds.width != mBounds.width || newBounds.height != mBounds.height); + (newWidth != mBounds.width || newHeight != mBounds.height); // Update view if (needsSizeUpdate) { @@ -1457,6 +1463,7 @@ void nsWindow::NativeMoveResizeWaylandPopupCB(const GdkRectangle* aFinalSize, NSIntPixelsToAppUnits(newBounds.y, p2a), NSIntPixelsToAppUnits(newBounds.width, p2a), NSIntPixelsToAppUnits(newBounds.height, p2a)); + mPreferredPopupRectFlushed = false; Resize(newBounds.width, newBounds.height, true); DispatchResized(); @@ -4125,6 +4132,9 @@ nsresult nsWindow::Create(nsIWidget* aParent, nsNativeWidget aNativeParent, // save our bounds mBounds = aRect; + + mPreferredPopupRectFlushed = false; + ConstrainSize(&mBounds.width, &mBounds.height); GtkWidget* eventWidget = nullptr; @@ -4982,6 +4992,7 @@ void nsWindow::NativeShow(bool aAction) { // There's a chance that when the popup will be shown again it might be // resized because parent could be moved meanwhile. mPreferredPopupRect = nsRect(0, 0, 0, 0); + mPreferredPopupRectFlushed = false; if (!mIsX11Display) { WaylandStopVsync(); if (IsWaylandPopup() && IsMainMenuWindow()) { diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index 24e8e9632d35..0d107d3c74d7 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -432,6 +432,7 @@ class nsWindow final : public nsBaseWidget { }; virtual void FlushPreferredPopupRect() override { mPreferredPopupRect = nsRect(0, 0, 0, 0); + mPreferredPopupRectFlushed = true; }; #endif bool IsRemoteContent() { return HasRemoteContent(); } @@ -701,6 +702,7 @@ class nsWindow final : public nsBaseWidget { GtkWindow* GetTopmostWindow(); bool IsWidgetOverflowWindow(); nsRect mPreferredPopupRect; + bool mPreferredPopupRectFlushed; bool mWaitingForMoveToRectCB; LayoutDeviceIntRect mPendingSizeRect;