Bug 2056581 - Have autoscroll take DPI into account. r=botond

Differential Revision: https://phabricator.services.mozilla.com/D317166
This commit is contained in:
Eugeniusz Lewandowski
2026-09-12 02:11:34 +00:00
committed by bballo@mozilla.com
parent 0c89c90077
commit 9ae0afd977
5 changed files with 40 additions and 12 deletions
+9 -2
View File
@@ -275,6 +275,7 @@ class MOZ_RAII AutoFocusSequenceNumberSetter {
};
APZCTreeManager::APZCTreeManager(LayersId aRootLayersId,
CSSToLayoutDeviceScale aWidgetScale,
UniquePtr<IAPZHitTester> aHitTester)
: mTestSampleTime(Nothing(), "APZCTreeManager::mTestSampleTime"),
mInputQueue(new InputQueue()),
@@ -290,6 +291,7 @@ APZCTreeManager::APZCTreeManager(LayersId aRootLayersId,
mApzcTreeLog("apzctree"),
mTestDataLock("APZTestDataLock"),
mDPI(160.0),
mWidgetScale(aWidgetScale),
mHitTester(std::move(aHitTester)),
mScrollGenerationLock("APZScrollGenerationLock"),
mInteractiveWidget(
@@ -315,9 +317,10 @@ void APZCTreeManager::Init() {
}
already_AddRefed<APZCTreeManager> APZCTreeManager::Create(
LayersId aRootLayersId, UniquePtr<IAPZHitTester> aHitTester) {
LayersId aRootLayersId, CSSToLayoutDeviceScale aWidgetScale,
UniquePtr<IAPZHitTester> aHitTester) {
RefPtr<APZCTreeManager> manager =
new APZCTreeManager(aRootLayersId, std::move(aHitTester));
new APZCTreeManager(aRootLayersId, aWidgetScale, std::move(aHitTester));
manager->Init();
return manager.forget();
}
@@ -4079,6 +4082,10 @@ float APZCTreeManager::GetDPI() const {
return mDPI;
}
CSSToLayoutDeviceScale APZCTreeManager::GetWidgetScale() const {
return mWidgetScale;
}
void APZCTreeManager::EndWheelTransaction(
PWebRenderBridgeParent::EndWheelTransactionResolver&& aResolver) {
RefPtr<nsISerialEventTarget> controllerThread =
+12 -2
View File
@@ -10,6 +10,7 @@
#include "FocusState.h" // for FocusState
#include "HitTestingTreeNode.h" // for HitTestingTreeNodeAutoLock
#include "IAPZHitTester.h" // for IAPZHitTester::HitTestResult
#include "Units.h"
#include "VsyncSource.h"
#include "gfxPoint.h" // for gfxPoint
#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
@@ -137,7 +138,8 @@ class APZCTreeManager : public IAPZCTreeManager, public APZInputBridge {
static mozilla::LazyLogModule sLog;
static already_AddRefed<APZCTreeManager> Create(
LayersId aRootLayersId, UniquePtr<IAPZHitTester> aHitTester = nullptr);
LayersId aRootLayersId, CSSToLayoutDeviceScale aWidgetScale = {},
UniquePtr<IAPZHitTester> aHitTester = nullptr);
void SetSampler(APZSampler* aSampler);
void SetUpdater(APZUpdater* aUpdater);
@@ -290,6 +292,11 @@ class APZCTreeManager : public IAPZCTreeManager, public APZInputBridge {
*/
float GetDPI() const;
/**
* Returns the Widget scale value in use.
*/
CSSToLayoutDeviceScale GetWidgetScale() const;
/**
* Find the hit testing node for the scrollbar thumb that matches these
* drag metrics. Initializes aOutThumbNode with the node, if there is one.
@@ -532,7 +539,8 @@ class APZCTreeManager : public IAPZCTreeManager, public APZInputBridge {
already_AddRefed<wr::WebRenderAPI> GetWebRenderAPI() const;
protected:
APZCTreeManager(LayersId aRootLayersId, UniquePtr<IAPZHitTester> aHitTester);
APZCTreeManager(LayersId aRootLayersId, CSSToLayoutDeviceScale aScale,
UniquePtr<IAPZHitTester> aHitTester);
void Init();
@@ -1164,6 +1172,8 @@ class APZCTreeManager : public IAPZCTreeManager, public APZInputBridge {
// This must only be touched on the controller thread.
float mDPI;
CSSToLayoutDeviceScale mWidgetScale;
friend class IAPZHitTester;
UniquePtr<IAPZHitTester> mHitTester;
+15 -6
View File
@@ -10,22 +10,26 @@
#include "APZCTreeManager.h"
#include "AsyncPanZoomController.h"
#include "FrameMetrics.h"
#include "Units.h"
#include "mozilla/StaticPrefs_general.h"
namespace mozilla {
namespace layers {
// Helper function for AutoscrollAnimation::DoSample().
// Basically copied as-is from toolkit/actors/AutoScrollChild.sys.mjs.
static float Accelerate(ScreenCoord curr, ScreenCoord start) {
// Basically copied as-is from toolkit/actors/AutoScrollChild.sys.mjs, the only
// addition is adjusting for DPI.
static float Accelerate(ScreenCoord curr, ScreenCoord start,
const CSSToLayoutDeviceScale& widgetScale) {
// |speed| is the divisor in |val| below, so a higher multiplier must make
// |speed| smaller to produce a faster autoscroll. The multiplier is a
// percentage (100 = default). Clamp to avoid a zero divisor.
static const float baseSpeed = 12.0f;
constexpr float baseSpeed = 12.0f;
int multiplier =
std::max(1, int(StaticPrefs::general_autoscroll_speed_multiplier()));
float speed = std::max(1.0f, baseSpeed * 100 / multiplier);
float val = (curr - start) / speed;
float val = (curr - start) / (speed * widgetScale.scale);
if (val > 1) {
return val * sqrtf(val) - 1;
}
@@ -48,6 +52,9 @@ bool AutoscrollAnimation::DoSample(FrameMetrics& aFrameMetrics,
ScreenPoint mouseLocation = treeManager->GetCurrentMousePosition();
// Get the dpi so accelerate can scale to screen dpi.
const auto widgetScale = treeManager->GetWidgetScale();
// The implementation of this function closely mirrors that of its main-
// thread equivalent, the autoscrollLoop() function in
// toolkit/actors/AutoScrollChild.sys.mjs.
@@ -69,8 +76,10 @@ bool AutoscrollAnimation::DoSample(FrameMetrics& aFrameMetrics,
// its output is interpreted as CSS coordinates. This is intentional,
// insofar as autoscrollLoop() does the same thing.
CSSPoint scrollDelta{
Accelerate(mouseLocation.x, mAnchorLocation.x) * timeCompensation,
Accelerate(mouseLocation.y, mAnchorLocation.y) * timeCompensation};
Accelerate(mouseLocation.x, mAnchorLocation.x, widgetScale) *
timeCompensation,
Accelerate(mouseLocation.y, mAnchorLocation.y, widgetScale) *
timeCompensation};
mApzc.ScrollByAndClamp(scrollDelta);
+3 -1
View File
@@ -237,7 +237,9 @@ class TestAPZCTreeManager : public APZCTreeManager {
public:
explicit TestAPZCTreeManager(MockContentControllerDelayed* aMcc,
UniquePtr<IAPZHitTester> aHitTester = nullptr)
: APZCTreeManager(LayersId{0}, std::move(aHitTester)), mcc(aMcc) {
: APZCTreeManager(LayersId{0}, CSSToLayoutDeviceScale{1},
std::move(aHitTester)),
mcc(aMcc) {
Init();
}
+1 -1
View File
@@ -274,7 +274,7 @@ void CompositorBridgeParent::Initialize() {
MOZ_ASSERT(!mApzcTreeManager);
MOZ_ASSERT(!mApzSampler);
MOZ_ASSERT(!mApzUpdater);
mApzcTreeManager = APZCTreeManager::Create(mRootLayerTreeID);
mApzcTreeManager = APZCTreeManager::Create(mRootLayerTreeID, mScale);
mApzSampler = new APZSampler(mApzcTreeManager, true);
mApzUpdater = new APZUpdater(mApzcTreeManager, true);
}