Bug 1753836 - Fix callers of screenForRect to pass desktop pixels. r=jfkthame,Gijs

Device pixels and desktop pixels are not the same on macOS and Win7.
Expose the desktop-to-device scale to JS and use it appropriately.

Depends on D138038

Differential Revision: https://phabricator.services.mozilla.com/D138039
This commit is contained in:
Emilio Cobos Álvarez 2022-02-16 12:18:12 +00:00
Родитель c31d70c2b8
Коммит a8883d1cfc
6 изменённых файлов: 51 добавлений и 32 удалений

Просмотреть файл

@ -870,14 +870,11 @@
// screen.availLeft et. al. only check the screen that this window is on,
// but we want to look at the screen the tab is being dropped onto.
let cssToDesktopScale =
window.devicePixelRatio / window.desktopToDeviceScale;
var screen = Cc["@mozilla.org/gfx/screenmanager;1"]
.getService(Ci.nsIScreenManager)
.screenForRect(
eX * window.devicePixelRatio,
eY * window.devicePixelRatio,
1,
1
);
.screenForRect(eX * cssToDesktopScale, eY * cssToDesktopScale, 1, 1);
var fullX = {},
fullY = {},
fullWidth = {},

Просмотреть файл

@ -1170,13 +1170,16 @@ var PanelMultiView = class extends AssociatedToNode {
// Screen manager uses screen coordinates, while screenX/Y and anchorRect
// are in CSS pixels, so need to convert to the right coordinate space.
let devicePixelRatio = this.window.devicePixelRatio;
let cssToDesktopPixels =
this.window.devicePixelRatio / this.window.desktopToDeviceScale;
let screen = this._screenManager.screenForRect(
anchor.screenX * devicePixelRatio,
anchor.screenY * devicePixelRatio,
anchorRect.width * devicePixelRatio,
anchorRect.height * devicePixelRatio
anchor.screenX * cssToDesktopPixels,
anchor.screenY * cssToDesktopPixels,
anchorRect.width * cssToDesktopPixels,
anchorRect.height * cssToDesktopPixels
);
// GetAvailRect returns screen-device pixels, which we can convert to CSS
// pixels here.
let availTop = {},
availHeight = {};
screen.GetAvailRect({}, availTop, {}, availHeight);

Просмотреть файл

@ -4876,13 +4876,13 @@ var SessionStoreInternal = {
/**
* Restore a window's dimensions
* @param aWidth
* Window width
* Window width in desktop pixels
* @param aHeight
* Window height
* Window height in desktop pixels
* @param aLeft
* Window left
* Window left in desktop pixels
* @param aTop
* Window top
* Window top in desktop pixels
* @param aSizeMode
* Window size mode (eg: maximized)
* @param aSizeModeBeforeMinimized

Просмотреть файл

@ -211,6 +211,7 @@
#include "nsDOMNavigationTiming.h"
#include "nsDOMOfflineResourceList.h"
#include "nsDebug.h"
#include "nsDeviceContext.h"
#include "nsDocShell.h"
#include "nsFocusManager.h"
#include "nsFrameMessageManager.h"
@ -3516,28 +3517,31 @@ float nsGlobalWindowInner::GetMozInnerScreenY(CallerType aCallerType,
FORWARD_TO_OUTER_OR_THROW(GetMozInnerScreenYOuter, (aCallerType), aError, 0);
}
static nsPresContext* GetPresContextForRatio(Document* aDoc) {
if (nsPresContext* presContext = aDoc->GetPresContext()) {
return presContext;
}
// We're in an undisplayed subdocument... There's not really an awesome way
// to tell what the right DPI is from here, so we try to walk up our parent
// document chain to the extent that the docs can observe each other.
Document* doc = aDoc;
while (doc->StyleOrLayoutObservablyDependsOnParentDocumentLayout()) {
doc = doc->GetInProcessParentDocument();
if (nsPresContext* presContext = doc->GetPresContext()) {
return presContext;
}
}
return nullptr;
}
double nsGlobalWindowInner::GetDevicePixelRatio(CallerType aCallerType,
ErrorResult& aError) {
ENSURE_ACTIVE_DOCUMENT(aError, 0.0);
RefPtr<nsPresContext> presContext = mDoc->GetPresContext();
RefPtr<nsPresContext> presContext = GetPresContextForRatio(mDoc);
if (NS_WARN_IF(!presContext)) {
// We're in an undisplayed subdocument... There's not really an awesome way
// to tell what the right DPI is from here, so we try to walk up our parent
// document chain to the extent that the docs can observe each other.
Document* doc = mDoc;
while (doc->StyleOrLayoutObservablyDependsOnParentDocumentLayout()) {
doc = doc->GetInProcessParentDocument();
presContext = doc->GetPresContext();
if (presContext) {
break;
}
}
if (!presContext) {
// Still nothing, oh well.
return 1.0;
}
// Still nothing, oh well.
return 1.0;
}
if (nsContentUtils::ResistFingerprinting(aCallerType)) {
@ -3564,6 +3568,15 @@ double nsGlobalWindowInner::GetDevicePixelRatio(CallerType aCallerType,
double(presContext->AppUnitsPerDevPixel());
}
double nsGlobalWindowInner::GetDesktopToDeviceScale(ErrorResult& aError) {
ENSURE_ACTIVE_DOCUMENT(aError, 0.0);
nsPresContext* presContext = GetPresContextForRatio(mDoc);
if (!presContext) {
return 1.0;
}
return presContext->DeviceContext()->GetDesktopToDeviceScale().scale;
}
uint64_t nsGlobalWindowInner::GetMozPaintCount(ErrorResult& aError) {
FORWARD_TO_OUTER_OR_THROW(GetMozPaintCountOuter, (), aError, 0);
}

Просмотреть файл

@ -869,6 +869,7 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
mozilla::ErrorResult& aError);
double GetDevicePixelRatio(mozilla::dom::CallerType aCallerType,
mozilla::ErrorResult& aError);
double GetDesktopToDeviceScale(mozilla::ErrorResult& aError);
int32_t GetScrollMinX(mozilla::ErrorResult& aError);
int32_t GetScrollMinY(mozilla::ErrorResult& aError);
int32_t GetScrollMaxX(mozilla::ErrorResult& aError);

Просмотреть файл

@ -448,6 +448,11 @@ partial interface Window {
[Replaceable, Throws, NeedsCallerType]
readonly attribute double devicePixelRatio;
// Allows chrome code to convert desktop pixels to device pixels and vice
// versa. Useful for interacting with the screen manager.
[ChromeOnly, Throws]
readonly attribute double desktopToDeviceScale;
/* The maximum offset that the window can be scrolled to
(i.e., the document width/height minus the scrollport width/height) */
[ChromeOnly, Throws] readonly attribute long scrollMinX;