зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1798213 - For widget-less pages keep defaulting to primary screen scale factor. r=tnikkel,layout-reviewers,extension-reviewers,robwu
This restores the previous behavior in a somewhat more principled way. The extensions code is still broken in multi-monitor cases, but that's a more complicated fix. Differential Revision: https://phabricator.services.mozilla.com/D161997
This commit is contained in:
Родитель
06ebad6fd8
Коммит
a8a5c8fe6a
|
@ -473,10 +473,10 @@ ParentShowInfo BrowserParent::GetShowInfo() {
|
|||
TryCacheDPIAndScale();
|
||||
if (mFrameElement) {
|
||||
nsAutoString name;
|
||||
mFrameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
|
||||
mFrameElement->GetAttr(nsGkAtoms::name, name);
|
||||
bool isTransparent =
|
||||
nsContentUtils::IsChromeDoc(mFrameElement->OwnerDoc()) &&
|
||||
mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::transparent);
|
||||
mFrameElement->HasAttr(nsGkAtoms::transparent);
|
||||
return ParentShowInfo(name, false, isTransparent, mDPI, mRounding,
|
||||
mDefaultScale.scale);
|
||||
}
|
||||
|
@ -546,6 +546,10 @@ void BrowserParent::SetOwnerElement(Element* aElement) {
|
|||
#endif
|
||||
|
||||
AddWindowListeners();
|
||||
|
||||
// The DPI depends on our frame element's widget, so invalidate now in case
|
||||
// we've tried to cache it already.
|
||||
mDPI = -1;
|
||||
TryCacheDPIAndScale();
|
||||
|
||||
if (mRemoteLayerTreeOwner.IsInitialized()) {
|
||||
|
@ -3427,17 +3431,17 @@ void BrowserParent::TryCacheDPIAndScale() {
|
|||
return;
|
||||
}
|
||||
|
||||
const auto oldDefaultScale = mDefaultScale;
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
mDPI = widget ? widget->GetDPI() : nsIWidget::GetFallbackDPI();
|
||||
mRounding = widget ? widget->RoundsWidgetCoordinatesTo() : 1;
|
||||
mDefaultScale =
|
||||
widget ? widget->GetDefaultScale() : nsIWidget::GetFallbackDefaultScale();
|
||||
|
||||
if (widget) {
|
||||
mDPI = widget->GetDPI();
|
||||
mRounding = widget->RoundsWidgetCoordinatesTo();
|
||||
if (mDefaultScale != widget->GetDefaultScale()) {
|
||||
// The change of the default scale factor will affect the child dimensions
|
||||
// so we need to invalidate it.
|
||||
mUpdatedDimensions = false;
|
||||
}
|
||||
mDefaultScale = widget->GetDefaultScale();
|
||||
if (mDefaultScale != oldDefaultScale) {
|
||||
// The change of the default scale factor will affect the child dimensions
|
||||
// so we need to invalidate it.
|
||||
mUpdatedDimensions = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3582,18 +3586,19 @@ void BrowserParent::PreserveLayers(bool aPreserveLayers) {
|
|||
}
|
||||
|
||||
void BrowserParent::NotifyResolutionChanged() {
|
||||
if (!mIsDestroyed) {
|
||||
// TryCacheDPIAndScale()'s cache is keyed off of
|
||||
// mDPI being greater than 0, so this invalidates it.
|
||||
mDPI = -1;
|
||||
TryCacheDPIAndScale();
|
||||
// If mDPI was set to -1 to invalidate it and then TryCacheDPIAndScale
|
||||
// fails to cache the values, then mDefaultScale.scale might be invalid.
|
||||
// We don't want to send that value to content. Just send -1 for it too in
|
||||
// that case.
|
||||
Unused << SendUIResolutionChanged(mDPI, mRounding,
|
||||
mDPI < 0 ? -1.0 : mDefaultScale.scale);
|
||||
if (mIsDestroyed) {
|
||||
return;
|
||||
}
|
||||
// TryCacheDPIAndScale()'s cache is keyed off of
|
||||
// mDPI being greater than 0, so this invalidates it.
|
||||
mDPI = -1;
|
||||
TryCacheDPIAndScale();
|
||||
// If mDPI was set to -1 to invalidate it and then TryCacheDPIAndScale
|
||||
// fails to cache the values, then mDefaultScale.scale might be invalid.
|
||||
// We don't want to send that value to content. Just send -1 for it too in
|
||||
// that case.
|
||||
Unused << SendUIResolutionChanged(mDPI, mRounding,
|
||||
mDPI < 0 ? -1.0 : mDefaultScale.scale);
|
||||
}
|
||||
|
||||
bool BrowserParent::CanCancelContentJS(
|
||||
|
|
|
@ -87,6 +87,7 @@ skip-if = toolkit == 'android' || tsan # near-permafail after landing bug 127005
|
|||
[test_ext_background_canvas.html]
|
||||
[test_ext_background_page.html]
|
||||
skip-if = (toolkit == 'android') # android doesn't have devtools
|
||||
[test_ext_background_page_dpi.html]
|
||||
[test_ext_browserAction_openPopup.html]
|
||||
[test_ext_browserAction_openPopup_incognito_window.html]
|
||||
skip-if = os == "android" # cannot open private windows - bug 1372178
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
<!DOCTYPE HTML>
|
||||
<meta charset="utf-8">
|
||||
<title>DPI of background page</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
|
||||
<script src="head.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
async function testDPIMatches(description) {
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
background: function() {
|
||||
browser.test.sendMessage("dpi", window.devicePixelRatio);
|
||||
},
|
||||
});
|
||||
await extension.startup();
|
||||
let dpi = await extension.awaitMessage("dpi");
|
||||
await extension.unload();
|
||||
|
||||
// This assumes that the window is loaded in a device DPI.
|
||||
is(
|
||||
dpi,
|
||||
window.devicePixelRatio,
|
||||
`DPI in a background page should match DPI in primary chrome page ${description}`
|
||||
);
|
||||
}
|
||||
|
||||
add_task(async function test_dpi_simple() {
|
||||
await testDPIMatches("by default");
|
||||
});
|
||||
|
||||
add_task(async function test_dpi_devPixelsPerPx() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["layout.css.devPixelsPerPx", 1.5]],
|
||||
});
|
||||
await testDPIMatches("with devPixelsPerPx");
|
||||
await SpecialPowers.popPrefEnv();
|
||||
});
|
||||
|
||||
add_task(async function test_dpi_os_zoom() {
|
||||
await SpecialPowers.pushPrefEnv({ set: [["ui.textScaleFactor", 200]] });
|
||||
await testDPIMatches("with OS zoom");
|
||||
await SpecialPowers.popPrefEnv();
|
||||
});
|
||||
</script>
|
|
@ -382,9 +382,9 @@ class PuppetWidget : public nsBaseWidget,
|
|||
ContentCacheInChild mContentCache;
|
||||
|
||||
// The DPI of the parent widget containing this widget.
|
||||
float mDPI = 96;
|
||||
float mDPI = GetFallbackDPI();
|
||||
int32_t mRounding = 1;
|
||||
double mDefaultScale = 1.0f;
|
||||
double mDefaultScale = GetFallbackDefaultScale().scale;
|
||||
|
||||
ScreenIntMargin mSafeAreaInsets;
|
||||
|
||||
|
|
|
@ -129,15 +129,21 @@ Screen::GetContentsScaleFactor(double* aOutScale) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
CSSToLayoutDeviceScale Screen::GetCSSToLayoutDeviceScale(
|
||||
IncludeOSZoom aIncludeOSZoom) const {
|
||||
auto scale = CSSToLayoutDeviceScale(StaticPrefs::layout_css_devPixelsPerPx());
|
||||
if (scale.scale <= 0.0) {
|
||||
scale = mDefaultCssScale;
|
||||
}
|
||||
if (bool(aIncludeOSZoom)) {
|
||||
scale.scale *= LookAndFeel::SystemZoomSettings().mFullZoom;
|
||||
}
|
||||
return scale;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Screen::GetDefaultCSSScaleFactor(double* aOutScale) {
|
||||
double scale = StaticPrefs::layout_css_devPixelsPerPx();
|
||||
if (scale > 0.0) {
|
||||
*aOutScale = scale;
|
||||
} else {
|
||||
*aOutScale = mDefaultCssScale.scale;
|
||||
}
|
||||
*aOutScale *= LookAndFeel::SystemZoomSettings().mFullZoom;
|
||||
*aOutScale = GetCSSToLayoutDeviceScale(IncludeOSZoom::Yes).scale;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,9 @@ class Screen final : public nsIScreen {
|
|||
return mContentsScale;
|
||||
}
|
||||
|
||||
enum class IncludeOSZoom : bool { No, Yes };
|
||||
CSSToLayoutDeviceScale GetCSSToLayoutDeviceScale(IncludeOSZoom) const;
|
||||
|
||||
private:
|
||||
virtual ~Screen() = default;
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
#include "mozilla/layers/InputAPZContext.h"
|
||||
#include "mozilla/layers/WebRenderLayerManager.h"
|
||||
#include "mozilla/webrender/WebRenderTypes.h"
|
||||
#include "mozilla/widget/ScreenManager.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
@ -2105,6 +2106,17 @@ void nsIWidget::OnLongTapTimerCallback(nsITimer* aTimer, void* aClosure) {
|
|||
self->mLongTapTouchPoint = nullptr;
|
||||
}
|
||||
|
||||
float nsIWidget::GetFallbackDPI() {
|
||||
RefPtr<const Screen> primaryScreen =
|
||||
ScreenManager::GetSingleton().GetPrimaryScreen();
|
||||
return primaryScreen->GetDPI();
|
||||
}
|
||||
|
||||
CSSToLayoutDeviceScale nsIWidget::GetFallbackDefaultScale() {
|
||||
RefPtr<const Screen> s = ScreenManager::GetSingleton().GetPrimaryScreen();
|
||||
return s->GetCSSToLayoutDeviceScale(Screen::IncludeOSZoom::No);
|
||||
}
|
||||
|
||||
nsresult nsIWidget::ClearNativeTouchSequence(nsIObserver* aObserver) {
|
||||
AutoObserverNotifier notifier(aObserver, "cleartouch");
|
||||
|
||||
|
|
|
@ -594,6 +594,11 @@ class nsIWidget : public nsISupports {
|
|||
*/
|
||||
virtual float GetDPI() = 0;
|
||||
|
||||
/**
|
||||
* Fallback DPI for when there's no widget available.
|
||||
*/
|
||||
static float GetFallbackDPI();
|
||||
|
||||
/**
|
||||
* Return the scaling factor between device pixels and the platform-
|
||||
* dependent "desktop pixels" used to manage window positions on a
|
||||
|
@ -618,6 +623,11 @@ class nsIWidget : public nsISupports {
|
|||
*/
|
||||
mozilla::CSSToLayoutDeviceScale GetDefaultScale();
|
||||
|
||||
/**
|
||||
* Fallback default scale for when there's no widget available.
|
||||
*/
|
||||
static mozilla::CSSToLayoutDeviceScale GetFallbackDefaultScale();
|
||||
|
||||
/**
|
||||
* Return the first child of this widget. Will return null if
|
||||
* there are no children.
|
||||
|
|
Загрузка…
Ссылка в новой задаче