Bug 1351783 part 10 - Create and sync the current FocusTarget on each layer transaction. r?kats,botond
This commit modifies PresShell and nsDisplayList to send a FocusTarget update on
every layer transaction. Ideally we would like to send updates as often as possible,
but this seems like it works well. This can be iterated on later, if necessary.
MozReview-Commit-ID: 8PFqIOhzH77
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -92,16 +92,17 @@ class CompositorAnimations;
class CompositorBridgeChild;
class TextLayer;
class CanvasLayer;
class BorderLayer;
class ReadbackLayer;
class ReadbackProcessor;
class RefLayer;
class HostLayer;
+class FocusTarget;
class KnowsCompositor;
class ShadowableLayer;
class ShadowLayerForwarder;
class LayerManagerComposite;
class SpecificLayerAttributes;
class TransactionIdAllocator;
class Compositor;
class FrameUniformityData;
@@ -595,16 +596,21 @@ public:
virtual void ClearCachedResources(Layer* aSubtree = nullptr) {}
/**
* Flag the next paint as the first for a document.
*/
virtual void SetIsFirstPaint() {}
/**
+ * Set the current focus target to be sent with the next paint.
+ */
+ virtual void SetFocusTarget(const FocusTarget& aFocusTarget) {}
+
+ /**
* Make sure that the previous transaction has been entirely
* completed.
*
* Note: This may sychronously wait on a remote compositor
* to complete rendering.
*/
virtual void FlushRendering() { }
--- a/gfx/layers/apz/src/FocusTarget.cpp
+++ b/gfx/layers/apz/src/FocusTarget.cpp
@@ -124,10 +124,27 @@ FocusTarget::FocusTarget(nsIPresShell* a
// the horizontal and vertical scroll targets of this element.
mType = FocusTarget::eScrollLayer;
mData.mScrollTargets.mHorizontal =
nsLayoutUtils::FindIDForScrollableFrame(horizontal);
mData.mScrollTargets.mVertical =
nsLayoutUtils::FindIDForScrollableFrame(vertical);
}
+bool
+FocusTarget::operator==(const FocusTarget& aRhs) const
+{
+ if (mFocusHasKeyEventListeners != aRhs.mFocusHasKeyEventListeners ||
+ mType != aRhs.mType) {
+ return false;
+ }
+
+ if (mType == FocusTarget::eRefLayer) {
+ return mData.mRefLayerId == aRhs.mData.mRefLayerId;
+ } else if (mType == FocusTarget::eScrollLayer) {
+ return mData.mScrollTargets.mHorizontal == aRhs.mData.mScrollTargets.mHorizontal &&
+ mData.mScrollTargets.mVertical == aRhs.mData.mScrollTargets.mVertical;
+ }
+ return true;
+}
+
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/apz/src/FocusTarget.h
+++ b/gfx/layers/apz/src/FocusTarget.h
@@ -47,16 +47,18 @@ public:
FocusTarget();
/**
* Construct a focus target for the specified top level PresShell
*/
FocusTarget(nsIPresShell* aRootPresShell);
+ bool operator==(const FocusTarget& aRhs) const;
+
public:
// Whether there are keydown, keypress, or keyup event listeners
// in the event target chain of the focused element
bool mFocusHasKeyEventListeners;
FocusTargetType mType;
FocusTargetData mData;
};
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -808,16 +808,22 @@ ClientLayerManager::SupportsBackdropCopy
void
ClientLayerManager::SetIsFirstPaint()
{
mForwarder->SetIsFirstPaint();
}
void
+ClientLayerManager::SetFocusTarget(const FocusTarget& aFocusTarget)
+{
+ mForwarder->SetFocusTarget(aFocusTarget);
+}
+
+void
ClientLayerManager::ClearCachedResources(Layer* aSubtree)
{
if (mDestroyed) {
// ClearCachedResource was already called by ClientLayerManager::Destroy
return;
}
MOZ_ASSERT(!HasShadowManager() || !aSubtree);
mForwarder->ClearCachedResources();
--- a/gfx/layers/client/ClientLayerManager.h
+++ b/gfx/layers/client/ClientLayerManager.h
@@ -9,16 +9,17 @@
#include <stdint.h> // for int32_t
#include "Layers.h"
#include "gfxContext.h" // for gfxContext
#include "mozilla/Attributes.h" // for override
#include "mozilla/LinkedList.h" // For LinkedList
#include "mozilla/WidgetUtils.h" // for ScreenRotation
#include "mozilla/gfx/Rect.h" // for Rect
#include "mozilla/layers/CompositorTypes.h"
+#include "mozilla/layers/FocusTarget.h" // for FocusTarget
#include "mozilla/layers/LayersTypes.h" // for BufferMode, LayersBackend, etc
#include "mozilla/layers/ShadowLayers.h" // for ShadowLayerForwarder, etc
#include "mozilla/layers/APZTestData.h" // for APZTestData
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsIObserver.h" // for nsIObserver
#include "nsISupportsImpl.h" // for Layer::Release, etc
#include "nsRect.h" // for mozilla::gfx::IntRect
#include "nsTArray.h" // for nsTArray
@@ -128,16 +129,18 @@ public:
bool HasShadowManager() const { return mForwarder->HasShadowManager(); }
virtual bool IsCompositingCheap() override;
virtual bool HasShadowManagerInternal() const override { return HasShadowManager(); }
virtual void SetIsFirstPaint() override;
+ virtual void SetFocusTarget(const FocusTarget& aFocusTarget) override;
+
/**
* Pass through call to the forwarder for nsPresContext's
* CollectPluginGeometryUpdates. Passes widget configuration information
* to the compositor for transmission to the chrome process. This
* configuration gets set when the window paints.
*/
void StorePluginWidgetConfigurations(const nsTArray<nsIWidget::Configuration>&
aConfigurations) override;
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -833,16 +833,17 @@ CompositorBridgeParent::UpdatePaintTime(
return;
}
mLayerManager->SetPaintTime(aPaintTime);
}
void
CompositorBridgeParent::NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstPaint,
+ const FocusTarget& aFocusTarget,
bool aScheduleComposite, uint32_t aPaintSequenceNumber,
bool aIsRepeatTransaction, bool aHitTestUpdate)
{
if (!aIsRepeatTransaction &&
mLayerManager &&
mLayerManager->GetRoot()) {
// Process plugin data here to give time for them to update before the next
// composition.
@@ -853,19 +854,23 @@ CompositorBridgeParent::NotifyShadowTree
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
// If plugins haven't been updated, stop waiting.
if (!pluginsUpdatedFlag) {
mWaitForPluginsUntil = TimeStamp();
mHaveBlockedForPlugins = false;
}
#endif
- if (mApzcTreeManager && aHitTestUpdate) {
- mApzcTreeManager->UpdateHitTestingTree(mRootLayerTreeID,
- mLayerManager->GetRoot(), aIsFirstPaint, aId, aPaintSequenceNumber);
+ if (mApzcTreeManager) {
+ mApzcTreeManager->UpdateFocusState(mRootLayerTreeID, aId,
+ aFocusTarget);
+ if (aHitTestUpdate) {
+ mApzcTreeManager->UpdateHitTestingTree(mRootLayerTreeID,
+ mLayerManager->GetRoot(), aIsFirstPaint, aId, aPaintSequenceNumber);
+ }
}
mLayerManager->NotifyShadowTreeTransaction();
}
if (aScheduleComposite) {
ScheduleComposition();
}
}
@@ -1206,22 +1211,28 @@ CompositorBridgeParent::ShadowLayersUpda
if (mLayerManager->GetCompositor()) {
mLayerManager->GetCompositor()->SetScreenRotation(targetConfig.rotation());
}
mCompositionManager->Updated(aInfo.isFirstPaint(), targetConfig);
Layer* root = aLayerTree->GetRoot();
mLayerManager->SetRoot(root);
- if (mApzcTreeManager && !aInfo.isRepeatTransaction() && aHitTestUpdate) {
- AutoResolveRefLayers resolve(mCompositionManager);
+ if (mApzcTreeManager && !aInfo.isRepeatTransaction()) {
+ mApzcTreeManager->UpdateFocusState(mRootLayerTreeID,
+ mRootLayerTreeID,
+ aInfo.focusTarget());
- mApzcTreeManager->UpdateHitTestingTree(
- mRootLayerTreeID, root, aInfo.isFirstPaint(),
- mRootLayerTreeID, aInfo.paintSequenceNumber());
+ if (aHitTestUpdate) {
+ AutoResolveRefLayers resolve(mCompositionManager);
+
+ mApzcTreeManager->UpdateHitTestingTree(
+ mRootLayerTreeID, root, aInfo.isFirstPaint(),
+ mRootLayerTreeID, aInfo.paintSequenceNumber());
+ }
}
// The transaction ID might get reset to 1 if the page gets reloaded, see
// https://bugzilla.mozilla.org/show_bug.cgi?id=1145295#c41
// Otherwise, it should be continually increasing.
MOZ_ASSERT(aInfo.id() == 1 || aInfo.id() > mPendingTransaction);
mPendingTransaction = aInfo.id();
--- a/gfx/layers/ipc/CompositorBridgeParent.h
+++ b/gfx/layers/ipc/CompositorBridgeParent.h
@@ -25,16 +25,17 @@
#include "mozilla/TimeStamp.h" // for TimeStamp
#include "mozilla/dom/ipc/IdType.h"
#include "mozilla/gfx/Point.h" // for IntSize
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/ipc/SharedMemory.h"
#include "mozilla/layers/CompositorController.h"
#include "mozilla/layers/CompositorOptions.h"
#include "mozilla/layers/CompositorVsyncSchedulerOwner.h"
+#include "mozilla/layers/FocusState.h"
#include "mozilla/layers/GeckoContentController.h"
#include "mozilla/layers/ISurfaceAllocator.h" // for ShmemAllocator
#include "mozilla/layers/LayersMessages.h" // for TargetConfig
#include "mozilla/layers/MetricsSharingController.h"
#include "mozilla/layers/PCompositorBridgeParent.h"
#include "mozilla/layers/APZTestData.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "mozilla/widget/CompositorWidget.h"
@@ -298,16 +299,17 @@ public:
* Returns true if a surface was obtained and the resume succeeded; false
* otherwise.
*/
bool ScheduleResumeOnCompositorThread();
bool ScheduleResumeOnCompositorThread(int width, int height);
virtual void ScheduleComposition();
void NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstPaint,
+ const FocusTarget& aFocusTarget,
bool aScheduleComposite, uint32_t aPaintSequenceNumber,
bool aIsRepeatTransaction, bool aHitTestUpdate);
void UpdatePaintTime(LayerTransactionParent* aLayerTree,
const TimeDuration& aPaintTime) override;
/**
* Check rotation info and schedule a rendering task if needed.
--- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
@@ -291,16 +291,17 @@ CrossProcessCompositorBridgeParent::Shad
// Cache the plugin data for this remote layer tree
state->mPluginData = aInfo.plugins();
state->mUpdatedPluginDataAvailable = true;
state->mParent->NotifyShadowTreeTransaction(
id,
aInfo.isFirstPaint(),
+ aInfo.focusTarget(),
aInfo.scheduleComposite(),
aInfo.paintSequenceNumber(),
aInfo.isRepeatTransaction(),
aHitTestUpdate);
// Send the 'remote paint ready' message to the content thread if it has already asked.
if(mNotifyAfterRemotePaint) {
Unused << SendRemotePaintIsReady();
--- a/gfx/layers/ipc/LayersMessageUtils.h
+++ b/gfx/layers/ipc/LayersMessageUtils.h
@@ -12,16 +12,17 @@
#include "chrome/common/ipc_message_utils.h"
#include "gfxTelemetry.h"
#include "ipc/IPCMessageUtils.h"
#include "ipc/nsGUIEventIPC.h"
#include "mozilla/GfxMessageUtils.h"
#include "mozilla/layers/AsyncDragMetrics.h"
#include "mozilla/layers/CompositorOptions.h"
#include "mozilla/layers/CompositorTypes.h"
+#include "mozilla/layers/FocusTarget.h"
#include "mozilla/layers/GeckoContentController.h"
#include "mozilla/layers/Keyboard.h"
#include "mozilla/layers/LayerAttributes.h"
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/Move.h"
#include <stdint.h>
@@ -414,16 +415,75 @@ struct ParamTraits<mozilla::layers::Even
ReadParam(aMsg, aIter, &aResult->mDispatchToContentHitRegion) &&
ReadParam(aMsg, aIter, &aResult->mNoActionRegion) &&
ReadParam(aMsg, aIter, &aResult->mHorizontalPanRegion) &&
ReadParam(aMsg, aIter, &aResult->mVerticalPanRegion));
}
};
template <>
+struct ParamTraits<mozilla::layers::FocusTarget::ScrollTargets>
+{
+ typedef mozilla::layers::FocusTarget::ScrollTargets paramType;
+
+ static void Write(Message* aMsg, const paramType& aParam)
+ {
+ WriteParam(aMsg, aParam.mHorizontal);
+ WriteParam(aMsg, aParam.mVertical);
+ }
+
+ static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
+ {
+ return ReadParam(aMsg, aIter, &aResult->mHorizontal) &&
+ ReadParam(aMsg, aIter, &aResult->mVertical);
+ }
+};
+
+template <>
+struct ParamTraits<mozilla::layers::FocusTarget::FocusTargetType>
+ : public ContiguousEnumSerializer<
+ mozilla::layers::FocusTarget::FocusTargetType,
+ mozilla::layers::FocusTarget::eNone,
+ mozilla::layers::FocusTarget::eSentinel>
+{};
+
+template <>
+struct ParamTraits<mozilla::layers::FocusTarget>
+{
+ typedef mozilla::layers::FocusTarget paramType;
+
+ static void Write(Message* aMsg, const paramType& aParam)
+ {
+ WriteParam(aMsg, aParam.mFocusHasKeyEventListeners);
+ WriteParam(aMsg, aParam.mType);
+ if (aParam.mType == mozilla::layers::FocusTarget::eRefLayer) {
+ WriteParam(aMsg, aParam.mData.mRefLayerId);
+ } else if (aParam.mType == mozilla::layers::FocusTarget::eScrollLayer) {
+ WriteParam(aMsg, aParam.mData.mScrollTargets);
+ }
+ }
+
+ static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
+ {
+ if (!ReadParam(aMsg, aIter, &aResult->mFocusHasKeyEventListeners) ||
+ !ReadParam(aMsg, aIter, &aResult->mType)) {
+ return false;
+ }
+
+ if (aResult->mType == mozilla::layers::FocusTarget::eRefLayer) {
+ return ReadParam(aMsg, aIter, &aResult->mData.mRefLayerId);
+ } else if (aResult->mType == mozilla::layers::FocusTarget::eScrollLayer) {
+ return ReadParam(aMsg, aIter, &aResult->mData.mScrollTargets);
+ }
+
+ return true;
+ }
+};
+
+template <>
struct ParamTraits<mozilla::layers::KeyboardScrollAction::KeyboardScrollActionType>
: public ContiguousEnumSerializer<
mozilla::layers::KeyboardScrollAction::KeyboardScrollActionType,
mozilla::layers::KeyboardScrollAction::KeyboardScrollActionType::eScrollCharacter,
mozilla::layers::KeyboardScrollAction::KeyboardScrollActionType::eSentinel>
{};
template <>
--- a/gfx/layers/ipc/LayersMessages.ipdlh
+++ b/gfx/layers/ipc/LayersMessages.ipdlh
@@ -35,16 +35,17 @@ using mozilla::LayerSize from "Units.h";
using mozilla::LayerRect from "Units.h";
using mozilla::LayerIntRegion from "Units.h";
using mozilla::ParentLayerIntRect from "Units.h";
using mozilla::LayoutDeviceIntRect from "Units.h";
using mozilla::layers::ScaleMode from "mozilla/layers/LayersTypes.h";
using mozilla::layers::EventRegions from "mozilla/layers/LayersTypes.h";
using mozilla::layers::EventRegionsOverride from "mozilla/layers/LayersTypes.h";
using mozilla::layers::DiagnosticTypes from "mozilla/layers/CompositorTypes.h";
+using mozilla::layers::FocusTarget from "mozilla/layers/FocusTarget.h";
using struct mozilla::layers::ScrollMetadata from "FrameMetrics.h";
using mozilla::layers::FrameMetrics::ViewID from "FrameMetrics.h";
using mozilla::layers::LayersBackend from "mozilla/layers/LayersTypes.h";
using mozilla::layers::MaybeLayerClip from "FrameMetrics.h";
using mozilla::gfx::Glyph from "Layers.h";
using mozilla::layers::BorderColors from "mozilla/layers/LayersTypes.h";
using mozilla::layers::BorderCorners from "mozilla/layers/LayersTypes.h";
using mozilla::layers::BorderWidths from "mozilla/layers/LayersTypes.h";
@@ -564,16 +565,17 @@ struct TransactionInfo
OpSetLayerAttributes[] setAttrs;
CompositableOperation[] paints;
OpDestroy[] toDestroy;
uint64_t fwdTransactionId;
uint64_t id;
TargetConfig targetConfig;
PluginWindowData[] plugins;
bool isFirstPaint;
+ FocusTarget focusTarget;
bool scheduleComposite;
uint32_t paintSequenceNumber;
bool isRepeatTransaction;
TimeStamp transactionStart;
};
} // namespace
} // namespace
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -726,16 +726,17 @@ ShadowLayerForwarder::EndTransaction(con
info.setSimpleAttrs() = Move(setSimpleAttrs);
info.setAttrs() = Move(setAttrs);
info.paints() = Move(mTxn->mPaints);
info.toDestroy() = mTxn->mDestroyedActors;
info.fwdTransactionId() = GetFwdTransactionId();
info.id() = aId;
info.plugins() = mPluginWindowData;
info.isFirstPaint() = mIsFirstPaint;
+ info.focusTarget() = mFocusTarget;
info.scheduleComposite() = aScheduleComposite;
info.paintSequenceNumber() = aPaintSequenceNumber;
info.isRepeatTransaction() = aIsRepeatTransaction;
info.transactionStart() = aTransactionStart;
TargetConfig targetConfig(mTxn->mTargetBounds,
mTxn->mTargetRotation,
mTxn->mTargetOrientation,
@@ -770,16 +771,17 @@ ShadowLayerForwarder::EndTransaction(con
if (startTime) {
mPaintTiming.sendMs() = (TimeStamp::Now() - startTime.value()).ToMilliseconds();
mShadowManager->SendRecordPaintTimes(mPaintTiming);
}
*aSent = true;
mIsFirstPaint = false;
+ mFocusTarget = FocusTarget();
MOZ_LAYERS_LOG(("[LayersForwarder] ... done"));
return true;
}
RefPtr<CompositableClient>
ShadowLayerForwarder::FindCompositable(const CompositableHandle& aHandle)
{
CompositableClient* client = nullptr;
--- a/gfx/layers/ipc/ShadowLayers.h
+++ b/gfx/layers/ipc/ShadowLayers.h
@@ -12,16 +12,17 @@
#include <stdint.h> // for uint64_t
#include "gfxTypes.h"
#include "mozilla/Attributes.h" // for override
#include "mozilla/gfx/Rect.h"
#include "mozilla/WidgetUtils.h" // for ScreenRotation
#include "mozilla/dom/ScreenOrientation.h" // for ScreenOrientation
#include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc
#include "mozilla/layers/CompositableForwarder.h"
+#include "mozilla/layers/FocusTarget.h"
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/layers/TextureForwarder.h"
#include "mozilla/layers/CompositorTypes.h" // for OpenMode, etc
#include "mozilla/layers/CompositorBridgeChild.h"
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsRegion.h" // for nsIntRegion
#include "nsTArrayForwardDeclare.h" // for InfallibleTArray
#include "nsIWidget.h"
@@ -366,16 +367,21 @@ public:
*/
LayerHandle ConstructShadowFor(ShadowableLayer* aLayer);
/**
* Flag the next paint as the first for a document.
*/
void SetIsFirstPaint() { mIsFirstPaint = true; }
+ /**
+ * Set the current focus target to be sent with the next paint.
+ */
+ void SetFocusTarget(const FocusTarget& aFocusTarget) { mFocusTarget = aFocusTarget; }
+
void SetLayerObserverEpoch(uint64_t aLayerObserverEpoch);
static void PlatformSyncBeforeUpdate();
virtual bool AllocSurfaceDescriptor(const gfx::IntSize& aSize,
gfxContentType aContent,
SurfaceDescriptor* aBuffer) override;
@@ -443,16 +449,17 @@ protected:
private:
ClientLayerManager* mClientLayerManager;
Transaction* mTxn;
MessageLoop* mMessageLoop;
DiagnosticTypes mDiagnosticTypes;
bool mIsFirstPaint;
+ FocusTarget mFocusTarget;
bool mWindowOverlayChanged;
InfallibleTArray<PluginWindowData> mPluginWindowData;
UniquePtr<ActiveResourceTracker> mActiveResourceTracker;
uint64_t mNextLayerHandle;
nsDataHashtable<nsUint64HashKey, CompositableClient*> mCompositables;
PaintTiming mPaintTiming;
/**
* ShadowLayerForwarder might dispatch tasks to main while puppet widget and
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -186,16 +186,17 @@
#include "nsIDragSession.h"
#include "nsIFrameInlines.h"
#include "mozilla/gfx/2D.h"
#include "nsSubDocumentFrame.h"
#include "nsQueryObject.h"
#include "nsLayoutStylesheetCache.h"
#include "mozilla/layers/InputAPZContext.h"
#include "mozilla/layers/ScrollInputMethods.h"
+#include "mozilla/layers/FocusTarget.h"
#include "nsStyleSet.h"
#include "mozilla/StyleSetHandle.h"
#include "mozilla/StyleSetHandleInlines.h"
#include "mozilla/StyleSheet.h"
#include "mozilla/StyleSheetInlines.h"
#include "mozilla/dom/ImageTracker.h"
#include "nsIDocShellTreeOwner.h"
@@ -6332,16 +6333,21 @@ PresShell::Paint(nsView* aViewTo
NS_ASSERTION(aViewToPaint, "null view");
MOZ_ASSERT(!mApproximateFrameVisibilityVisited, "Should have been cleared");
if (!mIsActive) {
return;
}
+ // Update the focus target for async keyboard scrolling. This will be forwarded
+ // to APZ by nsDisplayList::PaintRoot. We need to to do this before we enter
+ // the paint phase because dispatching eVoid events can cause layout to happen.
+ mAPZFocusTarget = FocusTarget(this);
+
nsPresContext* presContext = GetPresContext();
AUTO_LAYOUT_PHASE_ENTRY_POINT(presContext, Paint);
nsIFrame* frame = aViewToPaint->GetFrame();
LayerManager* layerManager =
aViewToPaint->GetWidget()->GetLayerManager();
NS_ASSERTION(layerManager, "Must be in paint event");
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -18,16 +18,17 @@
/* a presentation of a document, part 2 */
#ifndef nsIPresShell_h___
#define nsIPresShell_h___
#include "mozilla/ArenaObjectID.h"
#include "mozilla/EventForwards.h"
#include "mozilla/FlushType.h"
+#include "mozilla/layers/FocusTarget.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/StyleSetHandle.h"
#include "mozilla/StyleSheet.h"
#include "mozilla/WeakPtr.h"
#include "gfxPoint.h"
#include "nsTHashtable.h"
#include "nsHashKeys.h"
@@ -175,16 +176,17 @@ enum nsRectVisibility {
*/
class nsIPresShell : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPRESSHELL_IID)
protected:
+ typedef mozilla::layers::FocusTarget FocusTarget;
typedef mozilla::layers::LayerManager LayerManager;
typedef mozilla::gfx::SourceSurface SourceSurface;
enum eRenderFlag {
STATE_IGNORING_VIEWPORT_SCROLLING = 0x1,
STATE_DRAWWINDOW_NOT_FLUSHING = 0x2
};
typedef uint8_t RenderFlags; // for storing the above flags
@@ -1522,16 +1524,21 @@ public:
/**
* Get the isFirstPaint flag.
*/
bool GetIsFirstPaint() const { return mIsFirstPaint; }
uint32_t GetPresShellId() { return mPresShellId; }
/**
+ * Get the APZ FocusTarget used for async keyboard scrolling.
+ */
+ const FocusTarget& GetAPZFocusTarget() const { return mAPZFocusTarget; }
+
+ /**
* Dispatch a mouse move event based on the most recent mouse position if
* this PresShell is visible. This is used when the contents of the page
* moved (aFromScroll is false) or scrolled (aFromScroll is true).
*/
virtual void SynthesizeMouseMove(bool aFromScroll) = 0;
enum PaintFlags {
/* Update the layer tree and paint PaintedLayers. If this is not specified,
@@ -1831,17 +1838,16 @@ protected:
#ifdef DEBUG
nsIFrame* mDrawEventTargetFrame;
// We track allocated pointers in a debug-only hashtable to assert against
// missing/double frees.
nsTHashtable<nsPtrHashKey<void>> mAllocatedPointers;
#endif
-
// Count of the number of times this presshell has been painted to a window.
uint64_t mPaintCount;
nsSize mScrollPositionClampingScrollPortSize;
// A list of stack weak frames. This is a pointer to the last item in the list.
AutoWeakFrame* mAutoWeakFrames;
@@ -1894,16 +1900,19 @@ protected:
bool mObservingLayoutFlushes: 1;
// True if there are throttled animations that would be processed when
// performing a flush with mFlushAnimations == true.
bool mNeedThrottledAnimationFlush : 1;
uint32_t mPresShellId;
+ // The focus information needed for async keyboard scrolling
+ FocusTarget mAPZFocusTarget;
+
static nsIContent* gKeyDownTarget;
// Cached font inflation values. This is done to prevent changing of font
// inflation until a page is reloaded.
uint32_t mFontSizeInflationEmPerLine;
uint32_t mFontSizeInflationMinTwips;
uint32_t mFontSizeInflationLineThreshold;
bool mFontSizeInflationForceEnabled;
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -2202,17 +2202,16 @@ already_AddRefed<LayerManager> nsDisplay
} else {
// If there is no root scroll frame, pick the document element instead.
// The only case we don't want to do this is in non-APZ fennec, where
// we want the root xul document to get a null scroll id so that the root
// content document gets the first non-null scroll id.
content = document->GetDocumentElement();
}
-
if (ensureMetricsForRootId && content) {
ViewID scrollId = nsLayoutUtils::FindOrCreateIDFor(content);
if (nsLayoutUtils::ContainsMetricsWithId(root, scrollId)) {
ensureMetricsForRootId = false;
}
}
if (addMetrics || ensureMetricsForRootId) {
@@ -2223,16 +2222,19 @@ already_AddRefed<LayerManager> nsDisplay
root->SetScrollMetadata(
nsLayoutUtils::ComputeScrollMetadata(frame,
rootScrollFrame, content,
aBuilder->FindReferenceFrameFor(frame),
root, FrameMetrics::NULL_SCROLL_ID, viewport, Nothing(),
isRootContent, containerParameters));
}
+ // Send an updated focus target with this transaction
+ layerManager->SetFocusTarget(presShell->GetAPZFocusTarget());
+
// NS_WARNING is debug-only, so don't even bother checking the conditions in
// a release build.
#ifdef DEBUG
bool usingDisplayport = false;
if (nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame()) {
nsIContent* content = rootScrollFrame->GetContent();
if (content) {
usingDisplayport = nsLayoutUtils::HasDisplayPort(content);