Diff
Modified: trunk/Source/WTF/ChangeLog (259164 => 259165)
--- trunk/Source/WTF/ChangeLog 2020-03-28 22:13:37 UTC (rev 259164)
+++ trunk/Source/WTF/ChangeLog 2020-03-29 00:59:22 UTC (rev 259165)
@@ -1,3 +1,14 @@
+2020-03-28 Simon Fraser <[email protected]>
+
+ Add a ScrollLatching log channel and improve some logging functionality
+ https://bugs.webkit.org/show_bug.cgi?id=209706
+
+ Reviewed by Darin Adler, David Kilzer.
+
+ * wtf/text/TextStream.h:
+ (WTF::ValueOrNull::ValueOrNull):
+ (WTF::operator<<):
+
2020-03-27 Simon Fraser <[email protected]>
Define ENABLE_WHEEL_EVENT_LATCHING and use it to wrap wheel event latching code
Modified: trunk/Source/WTF/wtf/text/TextStream.h (259164 => 259165)
--- trunk/Source/WTF/wtf/text/TextStream.h 2020-03-28 22:13:37 UTC (rev 259164)
+++ trunk/Source/WTF/wtf/text/TextStream.h 2020-03-29 00:59:22 UTC (rev 259165)
@@ -28,6 +28,7 @@
#include <wtf/Forward.h>
#include <wtf/Markable.h>
#include <wtf/Optional.h>
+#include <wtf/WeakPtr.h>
#include <wtf/text/StringBuilder.h>
namespace WTF {
@@ -176,6 +177,24 @@
return ts;
}
+template<typename T>
+struct ValueOrNull {
+ explicit ValueOrNull(T* inValue)
+ : value(inValue)
+ { }
+ T* value;
+};
+
+template<typename T>
+TextStream& operator<<(TextStream& ts, ValueOrNull<T> item)
+{
+ if (item.value)
+ ts << *item.value;
+ else
+ ts << "null";
+ return ts;
+}
+
template<typename Item>
TextStream& operator<<(TextStream& ts, const Optional<Item>& item)
{
@@ -209,6 +228,15 @@
return ts << "]";
}
+template<typename T>
+TextStream& operator<<(TextStream& ts, const WeakPtr<T>& item)
+{
+ if (item)
+ return ts << *item;
+
+ return ts << "null";
+}
+
template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg>
TextStream& operator<<(TextStream& ts, const HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>& map)
{
@@ -261,4 +289,5 @@
} // namespace WTF
using WTF::TextStream;
+using WTF::ValueOrNull;
using WTF::indent;
Modified: trunk/Source/WebCore/ChangeLog (259164 => 259165)
--- trunk/Source/WebCore/ChangeLog 2020-03-28 22:13:37 UTC (rev 259164)
+++ trunk/Source/WebCore/ChangeLog 2020-03-29 00:59:22 UTC (rev 259165)
@@ -1,3 +1,44 @@
+2020-03-28 Simon Fraser <[email protected]>
+
+ Add a ScrollLatching log channel and improve some logging functionality
+ https://bugs.webkit.org/show_bug.cgi?id=209706
+
+ Reviewed by Darin Adler, David Kilzer.
+
+ Add a "ScrollLatching" log channel. Make ScrollLatchingState and Node loggable.
+ Make a convenience template class ValueOrNull<> which makes logging a pointer type convenient.
+
+ Also change Page::pushNewLatchingState() to take the new latching state.
+
+ * dom/Node.cpp:
+ (WebCore::operator<<):
+ * dom/Node.h:
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::clearLatchedState):
+ * page/Page.cpp:
+ (WebCore::Page::pushNewLatchingState):
+ (WebCore::Page::popLatchingState):
+ (WebCore::Page::removeLatchingStateForTarget):
+ * page/Page.h:
+ (WebCore::Page::latchingStateStack const):
+ * page/mac/EventHandlerMac.mm:
+ (WebCore::EventHandler::clearOrScheduleClearingLatchedStateIfNeeded):
+ (WebCore::EventHandler::platformPrepareForWheelEvents):
+ (WebCore::frameViewForLatchingState):
+ (WebCore::EventHandler::platformCompleteWheelEvent):
+ (WebCore::EventHandler::platformCompletePlatformWidgetWheelEvent):
+ * page/scrolling/ScrollLatchingState.cpp:
+ (WebCore::operator<<):
+ * page/scrolling/ScrollLatchingState.h:
+ (WebCore::ScrollLatchingState::wheelEventElement const):
+ (WebCore::ScrollLatchingState::frame const):
+ (WebCore::ScrollLatchingState::previousWheelScrolledElement const):
+ (WebCore::ScrollLatchingState::scrollableContainer const):
+ * page/scrolling/ScrollingTree.cpp:
+ (WebCore::ScrollingTree::setOrClearLatchedNode):
+ (WebCore::ScrollingTree::handleWheelEvent):
+ * platform/Logging.h:
+
2020-03-28 Fujii Hironori <[email protected]>
[WinCairo] Unreviewed build fix for WinCairo Debug builds
Modified: trunk/Source/WebCore/dom/Node.cpp (259164 => 259165)
--- trunk/Source/WebCore/dom/Node.cpp 2020-03-28 22:13:37 UTC (rev 259164)
+++ trunk/Source/WebCore/dom/Node.cpp 2020-03-29 00:59:22 UTC (rev 259165)
@@ -83,6 +83,7 @@
#include <wtf/Variant.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>
+#include <wtf/text/TextStream.h>
namespace WebCore {
@@ -2612,6 +2613,20 @@
return const_cast<void*>(static_cast<const void*>(node));
}
+TextStream& operator<<(TextStream& ts, const Node& node)
+{
+#if ENABLE(TREE_DEBUGGING)
+ const size_t FormatBufferSize = 512;
+ char s[FormatBufferSize];
+ node.formatForDebugger(s, FormatBufferSize);
+ ts << "node " << &node << " " << s;
+#else
+ ts << "node " << &node << " " << node.nodeName();
+#endif
+
+ return ts;
+}
+
} // namespace WebCore
#if ENABLE(TREE_DEBUGGING)
Modified: trunk/Source/WebCore/dom/Node.h (259164 => 259165)
--- trunk/Source/WebCore/dom/Node.h 2020-03-28 22:13:37 UTC (rev 259164)
+++ trunk/Source/WebCore/dom/Node.h 2020-03-29 00:59:22 UTC (rev 259165)
@@ -41,6 +41,10 @@
// This needs to be here because Document.h also depends on it.
#define DUMP_NODE_STATISTICS 0
+namespace WTF {
+class TextStream;
+}
+
namespace WebCore {
class ContainerNode;
@@ -789,6 +793,8 @@
bool areNodesConnectedInSameTreeScope(const Node*, const Node*);
+WTF::TextStream& operator<<(WTF::TextStream&, const Node&);
+
} // namespace WebCore
#if ENABLE(TREE_DEBUGGING)
Modified: trunk/Source/WebCore/page/EventHandler.cpp (259164 => 259165)
--- trunk/Source/WebCore/page/EventHandler.cpp 2020-03-28 22:13:37 UTC (rev 259164)
+++ trunk/Source/WebCore/page/EventHandler.cpp 2020-03-29 00:59:22 UTC (rev 259165)
@@ -2896,6 +2896,7 @@
return;
#if ENABLE(WHEEL_EVENT_LATCHING)
+ LOG_WITH_STREAM(ScrollLatching, stream << "EventHandler::clearLatchedState()");
page->resetLatchingState();
#endif
if (auto filter = page->wheelEventDeltaFilter())
Modified: trunk/Source/WebCore/page/Page.cpp (259164 => 259165)
--- trunk/Source/WebCore/page/Page.cpp 2020-03-28 22:13:37 UTC (rev 259164)
+++ trunk/Source/WebCore/page/Page.cpp 2020-03-29 00:59:22 UTC (rev 259165)
@@ -2950,9 +2950,9 @@
return &m_latchingState.last();
}
-void Page::pushNewLatchingState()
+void Page::pushNewLatchingState(ScrollLatchingState&& state)
{
- m_latchingState.append(ScrollLatchingState());
+ m_latchingState.append(WTFMove(state));
}
void Page::resetLatchingState()
@@ -2963,6 +2963,7 @@
void Page::popLatchingState()
{
m_latchingState.removeLast();
+ LOG_WITH_STREAM(ScrollLatching, stream << "Page::popLatchingState() - new state " << m_latchingState);
}
void Page::removeLatchingStateForTarget(Element& targetNode)
@@ -2977,6 +2978,7 @@
return targetNode.isEqualNode(wheelElement);
});
+ LOG_WITH_STREAM(ScrollLatching, stream << "Page::removeLatchingStateForTarget() - new state " << m_latchingState);
}
#endif // ENABLE(WHEEL_EVENT_LATCHING)
Modified: trunk/Source/WebCore/page/Page.h (259164 => 259165)
--- trunk/Source/WebCore/page/Page.h 2020-03-28 22:13:37 UTC (rev 259164)
+++ trunk/Source/WebCore/page/Page.h 2020-03-29 00:59:22 UTC (rev 259165)
@@ -430,7 +430,8 @@
#if ENABLE(WHEEL_EVENT_LATCHING)
ScrollLatchingState* latchingState();
- void pushNewLatchingState();
+ const Vector<ScrollLatchingState>& latchingStateStack() const { return m_latchingState; }
+ void pushNewLatchingState(ScrollLatchingState&&);
void popLatchingState();
void resetLatchingState();
void removeLatchingStateForTarget(Element&);
Modified: trunk/Source/WebCore/page/mac/EventHandlerMac.mm (259164 => 259165)
--- trunk/Source/WebCore/page/mac/EventHandlerMac.mm 2020-03-28 22:13:37 UTC (rev 259164)
+++ trunk/Source/WebCore/page/mac/EventHandlerMac.mm 2020-03-29 00:59:22 UTC (rev 259165)
@@ -72,6 +72,7 @@
#include <wtf/NeverDestroyed.h>
#include <wtf/ObjCRuntimeExtras.h>
#include <wtf/ProcessPrivilege.h>
+#include <wtf/text/TextStream.h>
#if ENABLE(MAC_GESTURE_EVENTS)
#import <WebKitAdditions/EventHandlerMacGesture.cpp>
@@ -927,16 +928,19 @@
// Logic below installs a timer when non-momentum scrolling ends. If momentum scroll does not start within that interval,
// reset the latched state. If it does, stop the timer, leaving the latched state untouched.
if (!m_pendingMomentumWheelEventsTimer.isActive()) {
- if (event.isEndOfNonMomentumScroll())
+ if (event.isEndOfNonMomentumScroll()) {
+ LOG_WITH_STREAM(ScrollLatching, stream << "EventHandler::clearOrScheduleClearingLatchedStateIfNeeded() - event" << event << ", scheduling clear timer");
m_pendingMomentumWheelEventsTimer.startOneShot(resetLatchedStateTimeout);
+ }
} else {
// If another wheel event scrolling starts, stop the timer manually, and reset the latched state immediately.
if (event.shouldConsiderLatching()) {
+ LOG_WITH_STREAM(ScrollLatching, stream << "EventHandler::clearOrScheduleClearingLatchedStateIfNeeded() - event" << event << ", timer pending, another scroll starting");
if (auto* page = m_frame.page())
page->resetLatchingState();
m_pendingMomentumWheelEventsTimer.stop();
} else if (event.isTransitioningToMomentumScroll()) {
- // Wheel events machinary is transitioning to momenthum scrolling, so no need to reset latched state. Stop the timer.
+ // Wheel events machinary is transitioning to momentum scrolling, so no need to reset latched state. Stop the timer.
m_pendingMomentumWheelEventsTimer.stop();
}
}
@@ -962,6 +966,8 @@
scrollableContainer = view->frame().document()->bodyOrFrameset();
scrollableArea = makeWeakPtr(static_cast<ScrollableArea&>(*view));
}
+
+ LOG_WITH_STREAM(ScrollLatching, stream << "EventHandler::platformPrepareForWheelEvents() - event" << wheelEvent << " found scrollableContainer" << ValueOrNull(scrollableContainer.get()) << " scrollableArea " << (scrollableArea ? scrollableArea.get() : nullptr));
}
}
@@ -974,19 +980,24 @@
if (scrollableContainer && scrollableArea && page) {
bool startingAtScrollLimit = scrolledToEdgeInDominantDirection(*scrollableContainer, *scrollableArea.get(), wheelEvent.deltaX(), wheelEvent.deltaY());
if (!startingAtScrollLimit) {
- page->pushNewLatchingState();
- latchingState = page->latchingState();
- latchingState->setStartedGestureAtScrollLimit(false);
- latchingState->setWheelEventElement(wheelEventTarget.get());
- latchingState->setFrame(&m_frame);
- latchingState->setScrollableContainer(scrollableContainer.copyRef());
- latchingState->setWidgetIsLatched(result.isOverWidget());
- isOverWidget = latchingState->widgetIsLatched();
+ ScrollLatchingState latchingState;
+ latchingState.setStartedGestureAtScrollLimit(false);
+ latchingState.setWheelEventElement(wheelEventTarget.get());
+ latchingState.setFrame(&m_frame);
+ latchingState.setScrollableContainer(scrollableContainer.copyRef());
+ latchingState.setWidgetIsLatched(result.isOverWidget());
+ page->pushNewLatchingState(WTFMove(latchingState));
+
page->wheelEventDeltaFilter()->beginFilteringDeltas();
+ isOverWidget = result.isOverWidget();
}
+
+ LOG_WITH_STREAM(ScrollLatching, stream << "EventHandler::platformPrepareForWheelEvents() - considering latching for " << wheelEvent << ", at scroll limit " << startingAtScrollLimit << ", latching state " << page->latchingStateStack());
}
- } else if (wheelEvent.shouldResetLatching())
+ } else if (wheelEvent.shouldResetLatching()) {
clearLatchedState();
+ LOG_WITH_STREAM(ScrollLatching, stream << "EventHandler::platformPrepareForWheelEvents() - reset latching for event " << wheelEvent << " latching state " << page->latchingStateStack());
+ }
if (!wheelEvent.shouldResetLatching() && latchingState && latchingState->wheelEventElement()) {
if (latchingIsLockedToPlatformFrame(m_frame))
@@ -1025,17 +1036,17 @@
page->wheelEventDeltaFilter()->updateFromDelta(FloatSize(wheelEvent.deltaX(), wheelEvent.deltaY()));
}
-static FrameView* frameViewForLatchingState(Frame& frame, ScrollLatchingState* latchingState)
+static FrameView* frameViewForLatchingState(Frame& frame, const ScrollLatchingState& latchingState)
{
if (latchingIsLockedToPlatformFrame(frame))
return frame.view();
- return latchingState->frame() ? latchingState->frame()->view() : frame.view();
+ return latchingState.frame() ? latchingState.frame()->view() : frame.view();
}
bool EventHandler::platformCompleteWheelEvent(const PlatformWheelEvent& wheelEvent, ContainerNode* scrollableContainer, const WeakPtr<ScrollableArea>& scrollableArea)
{
- LOG_WITH_STREAM(Scrolling, stream << "EventHandler::platformCompleteWheelEvent " << wheelEvent << " - scrollableContainer " << scrollableContainer << " scrollableArea " << scrollableArea.get() << " use latched element " << wheelEvent.useLatchedEventElement());
+ LOG_WITH_STREAM(ScrollLatching, stream << "EventHandler::platformCompleteWheelEvent " << wheelEvent << " - scrollableContainer " << scrollableContainer << " scrollableArea " << scrollableArea.get() << " use latched element " << wheelEvent.useLatchedEventElement());
Ref<Frame> protectedFrame(m_frame);
@@ -1044,10 +1055,13 @@
if (!view)
return false;
- ScrollLatchingState* latchingState = m_frame.page() ? m_frame.page()->latchingState() : nullptr;
+ const auto* latchingState = m_frame.page() ? m_frame.page()->latchingState() : nullptr;
+
if (wheelEvent.useLatchedEventElement() && !latchingIsLockedToAncestorOfThisFrame(m_frame) && latchingState && latchingState->scrollableContainer()) {
m_isHandlingWheelEvent = false;
+ LOG_WITH_STREAM(ScrollLatching, stream << " latching state " << *latchingState);
+
// WebKit2 code path
if (!frameHasPlatformWidget(m_frame) && !latchingState->startedGestureAtScrollLimit() && scrollableContainer == latchingState->scrollableContainer() && scrollableArea && view != scrollableArea) {
// If we did not start at the scroll limit, do not pass the event on to be handled by enclosing scrollable regions.
@@ -1056,7 +1070,7 @@
}
if (!latchingState->startedGestureAtScrollLimit())
- view = frameViewForLatchingState(m_frame, latchingState);
+ view = frameViewForLatchingState(m_frame, *latchingState);
ASSERT(view);
@@ -1085,7 +1099,7 @@
if (frameHasPlatformWidget(m_frame) && widget.isFrameView())
return true;
- ScrollLatchingState* latchingState = m_frame.page() ? m_frame.page()->latchingState() : nullptr;
+ const auto* latchingState = m_frame.page() ? m_frame.page()->latchingState() : nullptr;
if (!latchingState)
return false;
Modified: trunk/Source/WebCore/page/scrolling/ScrollLatchingState.cpp (259164 => 259165)
--- trunk/Source/WebCore/page/scrolling/ScrollLatchingState.cpp 2020-03-28 22:13:37 UTC (rev 259164)
+++ trunk/Source/WebCore/page/scrolling/ScrollLatchingState.cpp 2020-03-29 00:59:22 UTC (rev 259165)
@@ -27,6 +27,7 @@
#include "ScrollLatchingState.h"
#include "Element.h"
+#include <wtf/text/TextStream.h>
namespace WebCore {
@@ -63,4 +64,20 @@
m_scrollableContainer = WTFMove(container);
}
+TextStream& operator<<(TextStream& ts, const ScrollLatchingState& state)
+{
+ TextStream multilineStream;
+ multilineStream.setIndent(ts.indent() + 2);
+
+ multilineStream.dumpProperty("element", state.wheelEventElement());
+ multilineStream.dumpProperty("previousElement", state.previousWheelScrolledElement());
+ multilineStream.dumpProperty("scrollable container", state.scrollableContainer());
+ multilineStream.dumpProperty("widgetIsLatched", state.widgetIsLatched());
+ multilineStream.dumpProperty("started at limit", state.startedGestureAtScrollLimit());
+
+ ts << "ScrollLatchingState " << multilineStream.release();
+
+ return ts;
}
+
+}
Modified: trunk/Source/WebCore/page/scrolling/ScrollLatchingState.h (259164 => 259165)
--- trunk/Source/WebCore/page/scrolling/ScrollLatchingState.h 2020-03-28 22:13:37 UTC (rev 259164)
+++ trunk/Source/WebCore/page/scrolling/ScrollLatchingState.h 2020-03-29 00:59:22 UTC (rev 259165)
@@ -27,6 +27,10 @@
#include <wtf/RefPtr.h>
+namespace WTF {
+class TextStream;
+}
+
namespace WebCore {
class ContainerNode;
@@ -40,18 +44,18 @@
void clear();
- Element* wheelEventElement() { return m_wheelEventElement.get(); }
+ Element* wheelEventElement() const { return m_wheelEventElement.get(); }
void setWheelEventElement(RefPtr<Element>&&);
- Frame* frame() { return m_frame; }
+ Frame* frame() const { return m_frame; }
void setFrame(Frame* frame) { m_frame = frame; }
bool widgetIsLatched() const { return m_widgetIsLatched; }
void setWidgetIsLatched(bool isOverWidget);
- Element* previousWheelScrolledElement() { return m_previousWheelScrolledElement.get(); }
+ Element* previousWheelScrolledElement() const { return m_previousWheelScrolledElement.get(); }
void setPreviousWheelScrolledElement(RefPtr<Element>&&);
- ContainerNode* scrollableContainer() { return m_scrollableContainer.get(); }
+ ContainerNode* scrollableContainer() const { return m_scrollableContainer.get(); }
void setScrollableContainer(RefPtr<ContainerNode>&&);
bool startedGestureAtScrollLimit() const { return m_startedGestureAtScrollLimit; }
void setStartedGestureAtScrollLimit(bool startedAtLimit) { m_startedGestureAtScrollLimit = startedAtLimit; }
@@ -66,5 +70,7 @@
bool m_widgetIsLatched { false };
bool m_startedGestureAtScrollLimit { false };
};
-
+
+WTF::TextStream& operator<<(WTF::TextStream&, const ScrollLatchingState&);
+
} // namespace WebCore
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp (259164 => 259165)
--- trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2020-03-28 22:13:37 UTC (rev 259164)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2020-03-29 00:59:22 UTC (rev 259165)
@@ -82,10 +82,10 @@
void ScrollingTree::setOrClearLatchedNode(const PlatformWheelEvent& wheelEvent, ScrollingNodeID nodeID)
{
if (wheelEvent.shouldConsiderLatching()) {
- LOG_WITH_STREAM(Scrolling, stream << "ScrollingTree " << this << " setOrClearLatchedNode: setting latched node " << nodeID);
+ LOG_WITH_STREAM(ScrollLatching, stream << "ScrollingTree " << this << " setOrClearLatchedNode: setting latched node " << nodeID);
setLatchedNode(nodeID);
} else if (wheelEvent.shouldResetLatching()) {
- LOG_WITH_STREAM(Scrolling, stream << "ScrollingTree " << this << " setOrClearLatchedNode: clearing latched node (was " << latchedNode() << ")");
+ LOG_WITH_STREAM(ScrollLatching, stream << "ScrollingTree " << this << " setOrClearLatchedNode: clearing latched node (was " << latchedNode() << ")");
clearLatchedNode();
}
}
@@ -106,7 +106,7 @@
}
if (hasLatchedNode()) {
- LOG_WITH_STREAM(Scrolling, stream << " has latched node " << latchedNode());
+ LOG_WITH_STREAM(ScrollLatching, stream << "ScrollingTree::handleWheelEvent: has latched node " << latchedNode());
auto* node = nodeForID(latchedNode());
if (is<ScrollingTreeScrollingNode>(node))
return downcast<ScrollingTreeScrollingNode>(*node).handleWheelEvent(wheelEvent);
Modified: trunk/Source/WebCore/platform/Logging.h (259164 => 259165)
--- trunk/Source/WebCore/platform/Logging.h 2020-03-28 22:13:37 UTC (rev 259164)
+++ trunk/Source/WebCore/platform/Logging.h 2020-03-29 00:59:22 UTC (rev 259165)
@@ -93,6 +93,7 @@
M(ResourceLoadObserver) \
M(ResourceLoadStatistics) \
M(Scrolling) \
+ M(ScrollLatching) \
M(Services) \
M(ServiceWorker) \
M(SpellingAndGrammar) \