зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1669588 - Factor out a OneShotPostRefreshObserver utility class. r=kats
Differential Revision: https://phabricator.services.mozilla.com/D93897
This commit is contained in:
Родитель
63198ca57a
Коммит
944a3748f5
|
@ -649,7 +649,7 @@ static bool PrepareForSetTargetAPZCNotification(
|
|||
|
||||
static void SendLayersDependentApzcTargetConfirmation(
|
||||
PresShell* aPresShell, uint64_t aInputBlockId,
|
||||
const nsTArray<ScrollableLayerGuid>& aTargets) {
|
||||
nsTArray<ScrollableLayerGuid>&& aTargets) {
|
||||
LayerManager* lm = aPresShell->GetLayerManager();
|
||||
if (!lm) {
|
||||
return;
|
||||
|
@ -679,11 +679,13 @@ static void SendLayersDependentApzcTargetConfirmation(
|
|||
|
||||
DisplayportSetListener::DisplayportSetListener(
|
||||
nsIWidget* aWidget, PresShell* aPresShell, const uint64_t& aInputBlockId,
|
||||
const nsTArray<ScrollableLayerGuid>& aTargets)
|
||||
: mWidget(aWidget),
|
||||
mPresShell(aPresShell),
|
||||
nsTArray<ScrollableLayerGuid>&& aTargets)
|
||||
: OneShotPostRefreshObserver(
|
||||
aPresShell,
|
||||
[this](PresShell* aPresShell) { OnPostRefresh(this, aPresShell); }),
|
||||
mWidget(aWidget),
|
||||
mInputBlockId(aInputBlockId),
|
||||
mTargets(aTargets.Clone()) {}
|
||||
mTargets(std::move(aTargets)) {}
|
||||
|
||||
DisplayportSetListener::~DisplayportSetListener() = default;
|
||||
|
||||
|
@ -699,29 +701,13 @@ bool DisplayportSetListener::Register() {
|
|||
return false;
|
||||
}
|
||||
|
||||
void DisplayportSetListener::DidRefresh() {
|
||||
if (!mPresShell) {
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
"Post-refresh observer fired again after failed attempt at "
|
||||
"unregistering it");
|
||||
return;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void DisplayportSetListener::OnPostRefresh(DisplayportSetListener* aListener,
|
||||
PresShell* aPresShell) {
|
||||
APZCCH_LOG("Got refresh, sending target APZCs for input block %" PRIu64 "\n",
|
||||
mInputBlockId);
|
||||
SendLayersDependentApzcTargetConfirmation(mPresShell, mInputBlockId,
|
||||
std::move(mTargets));
|
||||
|
||||
if (!mPresShell->RemovePostRefreshObserver(this)) {
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
"Unable to unregister post-refresh observer! Leaking it instead of "
|
||||
"leaving garbage registered");
|
||||
// Graceful handling, just in case...
|
||||
mPresShell = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
delete this;
|
||||
aListener->mInputBlockId);
|
||||
SendLayersDependentApzcTargetConfirmation(
|
||||
aPresShell, aListener->mInputBlockId, std::move(aListener->mTargets));
|
||||
}
|
||||
|
||||
UniquePtr<DisplayportSetListener>
|
||||
|
|
|
@ -35,20 +35,21 @@ typedef std::function<void(uint64_t, const nsTArray<TouchBehaviorFlags>&)>
|
|||
SetAllowedTouchBehaviorCallback;
|
||||
|
||||
/* Refer to documentation on SendSetTargetAPZCNotification for this class */
|
||||
class DisplayportSetListener : public nsAPostRefreshObserver {
|
||||
class DisplayportSetListener : public OneShotPostRefreshObserver {
|
||||
public:
|
||||
DisplayportSetListener(nsIWidget* aWidget, PresShell* aPresShell,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsTArray<ScrollableLayerGuid>& aTargets);
|
||||
nsTArray<ScrollableLayerGuid>&& aTargets);
|
||||
virtual ~DisplayportSetListener();
|
||||
bool Register();
|
||||
void DidRefresh() override;
|
||||
|
||||
private:
|
||||
RefPtr<nsIWidget> mWidget;
|
||||
RefPtr<PresShell> mPresShell;
|
||||
uint64_t mInputBlockId;
|
||||
nsTArray<ScrollableLayerGuid> mTargets;
|
||||
|
||||
static void OnPostRefresh(DisplayportSetListener* aListener,
|
||||
PresShell* aPresShell);
|
||||
};
|
||||
|
||||
/* This class contains some helper methods that facilitate implementing the
|
||||
|
|
|
@ -125,6 +125,7 @@ UNIFIED_SOURCES += [
|
|||
"nsPresArena.cpp",
|
||||
"nsPresContext.cpp",
|
||||
"nsQuoteList.cpp",
|
||||
"nsRefreshObservers.cpp",
|
||||
"nsStyleChangeList.cpp",
|
||||
"nsStyleSheetService.cpp",
|
||||
"PositionedEventTargeting.cpp",
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsRefreshObservers.h"
|
||||
#include "PresShell.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
OneShotPostRefreshObserver::OneShotPostRefreshObserver(PresShell* aPresShell,
|
||||
Action&& aAction)
|
||||
: mPresShell(aPresShell), mAction(std::move(aAction)) {}
|
||||
|
||||
OneShotPostRefreshObserver::~OneShotPostRefreshObserver() = default;
|
||||
|
||||
void OneShotPostRefreshObserver::DidRefresh() {
|
||||
if (!mPresShell) {
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
"Post-refresh observer fired again after failed attempt at "
|
||||
"unregistering it");
|
||||
return;
|
||||
}
|
||||
|
||||
mAction(mPresShell);
|
||||
|
||||
if (!mPresShell->RemovePostRefreshObserver(this)) {
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
"Unable to unregister post-refresh observer! Leaking it instead of "
|
||||
"leaving garbage registered");
|
||||
// Graceful handling, just in case...
|
||||
mPresShell = nullptr;
|
||||
mAction = Action();
|
||||
return;
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
|
@ -19,6 +19,7 @@
|
|||
namespace mozilla {
|
||||
class AnimationEventDispatcher;
|
||||
class PendingFullscreenEvent;
|
||||
class PresShell;
|
||||
class RefreshDriverTimer;
|
||||
namespace layout {
|
||||
class VsyncChild;
|
||||
|
@ -64,4 +65,28 @@ class nsAPostRefreshObserver {
|
|||
virtual void DidRefresh() = 0;
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/**
|
||||
* A wrapper for nsAPostRefreshObserver that's one-shot (unregisters itself
|
||||
* after firing once) and can be used without writing a derived class by passing
|
||||
* in the action in the form of a lambda (or other function object).
|
||||
*
|
||||
* Note, while the observer unregisters itself, the registering still needs to
|
||||
* be done by the caller.
|
||||
*/
|
||||
class OneShotPostRefreshObserver : public nsAPostRefreshObserver {
|
||||
public:
|
||||
using Action = std::function<void(mozilla::PresShell*)>;
|
||||
OneShotPostRefreshObserver(mozilla::PresShell* aPresShell, Action&& aAction);
|
||||
virtual ~OneShotPostRefreshObserver();
|
||||
void DidRefresh() override;
|
||||
|
||||
protected:
|
||||
RefPtr<mozilla::PresShell> mPresShell;
|
||||
Action mAction;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
|
@ -894,42 +894,6 @@ nsresult nsSliderMediator::HandleEvent(dom::Event* aEvent) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
class AsyncScrollbarDragStarter final : public nsAPostRefreshObserver {
|
||||
public:
|
||||
AsyncScrollbarDragStarter(mozilla::PresShell* aPresShell, nsIWidget* aWidget,
|
||||
const AsyncDragMetrics& aDragMetrics)
|
||||
: mPresShell(aPresShell), mWidget(aWidget), mDragMetrics(aDragMetrics) {}
|
||||
virtual ~AsyncScrollbarDragStarter() = default;
|
||||
|
||||
void DidRefresh() override {
|
||||
if (!mPresShell) {
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
"Post-refresh observer fired again after failed attempt at "
|
||||
"unregistering it");
|
||||
return;
|
||||
}
|
||||
|
||||
mWidget->StartAsyncScrollbarDrag(mDragMetrics);
|
||||
|
||||
if (!mPresShell->RemovePostRefreshObserver(this)) {
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
"Unable to unregister post-refresh observer! Leaking it instead of "
|
||||
"leaving garbage registered");
|
||||
// Graceful handling, just in case...
|
||||
mPresShell = nullptr;
|
||||
mWidget = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<mozilla::PresShell> mPresShell;
|
||||
RefPtr<nsIWidget> mWidget;
|
||||
AsyncDragMetrics mDragMetrics;
|
||||
};
|
||||
|
||||
static bool ScrollFrameWillBuildScrollInfoLayer(nsIFrame* aScrollFrame) {
|
||||
/*
|
||||
* Note: if changing the conditions in this function, make a corresponding
|
||||
|
@ -1026,8 +990,12 @@ void nsSliderFrame::StartAPZDrag(WidgetGUIEvent* aEvent) {
|
|||
bool waitForRefresh = InputAPZContext::HavePendingLayerization();
|
||||
nsIWidget* widget = this->GetNearestWidget();
|
||||
if (waitForRefresh) {
|
||||
waitForRefresh = presShell->AddPostRefreshObserver(
|
||||
new AsyncScrollbarDragStarter(presShell, widget, dragMetrics));
|
||||
waitForRefresh =
|
||||
presShell->AddPostRefreshObserver(new OneShotPostRefreshObserver(
|
||||
presShell, [widget = RefPtr<nsIWidget>(widget),
|
||||
dragMetrics](mozilla::PresShell*) {
|
||||
widget->StartAsyncScrollbarDrag(dragMetrics);
|
||||
}));
|
||||
}
|
||||
if (!waitForRefresh) {
|
||||
widget->StartAsyncScrollbarDrag(dragMetrics);
|
||||
|
|
Загрузка…
Ссылка в новой задаче