Bug 1493081 - Added nsIWidget::GetDesktopToDeviceScaleByScreen for scale factor lookup by window position; r=mattwoodrow

We've added nsIWidget::GetDesktopToDeviceScaleByScreen which will return scale factor of the newly placed window
according to its position on the display. This change is to move implementation to the nsIWidget derived classes.
We need that for GTK Wayland, because on the Wayland we cannot determine absolute position of the window, we
need to use parent's window scale factor. For other platforms the GetDesktopToDeviceScaleByScreen is implemented
in nsBaseWidget.

Differential Revision: https://phabricator.services.mozilla.com/D7290

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jan Horak 2018-10-09 11:00:47 +00:00
parent 2150b8be21
commit 697b7b3f5d
5 changed files with 48 additions and 2 deletions

View File

@ -320,7 +320,6 @@ void nsView::DoResetWidgetBounds(bool aMoveOnly,
// Stash a copy of these and use them so we can handle this being deleted (say
// from sync painting/flushing from Show/Move/Resize on the widget).
LayoutDeviceIntRect newBounds;
RefPtr<nsDeviceContext> dx = mViewManager->GetDeviceContext();
nsWindowType type = widget->WindowType();
@ -360,7 +359,8 @@ void nsView::DoResetWidgetBounds(bool aMoveOnly,
// because of the potential for device-pixel coordinate spaces for mixed
// hidpi/lodpi screens to overlap each other and result in bad placement
// (bug 814434).
DesktopToLayoutDeviceScale scale = dx->GetDesktopToDeviceScale();
DesktopToLayoutDeviceScale scale = widget->GetDesktopToDeviceScaleByScreen();
DesktopRect deskRect = newBounds / scale;
if (changedPos) {

View File

@ -57,6 +57,7 @@
#if defined(MOZ_WAYLAND)
#include <gdk/gdkwayland.h>
#include "nsView.h"
#endif
#include "nsGkAtoms.h"
@ -841,6 +842,37 @@ nsWindow::GetDesktopToDeviceScale()
return DesktopToLayoutDeviceScale(1.0);
}
DesktopToLayoutDeviceScale
nsWindow::GetDesktopToDeviceScaleByScreen()
{
#ifdef MOZ_WAYLAND
GdkDisplay* gdkDisplay = gdk_display_get_default();
// In Wayland there's no way to get absolute position of the window and use it to
// determine the screen factor of the monitor on which the window is placed.
// The window is notified of the current scale factor but not at this point,
// so the GdkScaleFactor can return wrong value which can lead to wrong popup
// placement.
// We need to use parent's window scale factor for the new one.
if (GDK_IS_WAYLAND_DISPLAY(gdkDisplay)) {
nsView* view = nsView::GetViewFor(this);
if (view) {
nsView* parentView = view->GetParent();
if (parentView) {
nsIWidget* parentWidget = parentView->GetNearestWidget(nullptr);
if (parentWidget) {
return DesktopToLayoutDeviceScale(parentWidget->RoundsWidgetCoordinatesTo());
} else {
NS_WARNING("Widget has no parent");
}
}
} else {
NS_WARNING("Cannot find widget view");
}
}
#endif
return nsBaseWidget::GetDesktopToDeviceScale();
}
void
nsWindow::SetParent(nsIWidget *aNewParent)
{

View File

@ -125,6 +125,7 @@ public:
virtual float GetDPI() override;
virtual double GetDefaultScaleInternal() override;
mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() override;
mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScaleByScreen() override;
virtual void SetParent(nsIWidget* aNewParent) override;
virtual void SetModal(bool aModal) override;
virtual bool IsVisible() const override;

View File

@ -24,6 +24,8 @@
#include "nsIWidgetListener.h"
#include "nsPIDOMWindow.h"
#include "nsWeakReference.h"
#include "nsView.h"
#include "nsViewManager.h"
#include <algorithm>
#if defined(XP_WIN)
@ -238,6 +240,10 @@ public:
mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() override {
return mozilla::DesktopToLayoutDeviceScale(1.0);
}
mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScaleByScreen() override {
return (nsView::GetViewFor(this)->GetViewManager()->GetDeviceContext())->GetDesktopToDeviceScale();
}
virtual void ConstrainPosition(bool aAllowSlop,
int32_t *aX,
int32_t *aY) override {}

View File

@ -577,6 +577,13 @@ class nsIWidget : public nsISupports
*/
virtual mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() = 0;
/**
* Return the scaling factor between device pixels and the platform-
* dependent "desktop pixels" by looking up the screen by the position
* of the widget.
*/
virtual mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScaleByScreen() = 0;
/**
* Return the default scale factor for the window. This is the
* default number of device pixels per CSS pixel to use. This should