Skip to content

Commit

Permalink
[UnifiedPDF] Can't click-drag the scrollbar
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=271115
rdar://124785551

Reviewed by Abrar Rahman Protyasha.

For mouse interaction with the PDFPlugin's scrollbars to work, `EventHandler::enclosingScrollableArea()`
has to be able to find the plugin node's ScrollableArea. Add an easy way to get to the ScrollableArea
from RenderEmbeddedObject, which calls through the PluginView. Replace the odd code in `startKeyboardScrollAnimationOnPlugin()`
with this cleaner code.

Oddly that broke keyboard scrolling, which is fixed by implementing `scrollAnimatorEnabled()` in
PDFPluginBase to return true.

Also implement `PDFPluginBase::enclosingScrollableArea()`; this isn't called on macOS at this point, but
is implemented for completeness.

* Source/WebCore/page/EventHandler.cpp:
(WebCore::EventHandler::enclosingScrollableArea):
(WebCore::EventHandler::startKeyboardScrollAnimationOnPlugin):
* Source/WebCore/plugins/PluginViewBase.h:
(WebCore::PluginViewBase::scrollableArea const):
* Source/WebCore/rendering/RenderEmbeddedObject.cpp:
(WebCore::RenderEmbeddedObject::scrollableArea const):
(WebCore::RenderEmbeddedObject::usesAsyncScrolling const):
(WebCore::RenderEmbeddedObject::scrollingNodeID const):
(WebCore::RenderEmbeddedObject::willAttachScrollingNode):
(WebCore::RenderEmbeddedObject::didAttachScrollingNode):
* Source/WebCore/rendering/RenderEmbeddedObject.h:
* Source/WebKit/WebProcess/Plugins/PDF/PDFPluginBase.h:
* Source/WebKit/WebProcess/Plugins/PDF/PDFPluginBase.mm:
(WebKit::PDFPluginBase::enclosingScrollableArea const):
* Source/WebKit/WebProcess/Plugins/PluginView.cpp:
(WebKit::PluginView::scrollableArea const):
* Source/WebKit/WebProcess/Plugins/PluginView.h:

Canonical link: https://commits.webkit.org/276244@main
  • Loading branch information
smfr committed Mar 16, 2024
1 parent a4e05b2 commit 5dce176
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 12 deletions.
14 changes: 9 additions & 5 deletions Source/WebCore/page/EventHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2009,6 +2009,11 @@ ScrollableArea* EventHandler::enclosingScrollableArea(Node* node)
return scrollableArea;
}

if (RefPtr plugin = dynamicDowncast<RenderEmbeddedObject>(renderer)) {
if (auto* scrollableArea = plugin->scrollableArea())
return scrollableArea;
}

auto* layer = renderer->enclosingLayer();
if (!layer)
return nullptr;
Expand Down Expand Up @@ -4614,17 +4619,16 @@ bool EventHandler::startKeyboardScrollAnimationOnRenderBoxAndItsAncestors(Scroll
return false;
}

bool EventHandler::startKeyboardScrollAnimationOnPlugin(ScrollDirection direction, ScrollGranularity granularity, RenderEmbeddedObject& plugin, bool isKeyRepeat)
bool EventHandler::startKeyboardScrollAnimationOnPlugin(ScrollDirection direction, ScrollGranularity granularity, RenderEmbeddedObject& pluginRenderer, bool isKeyRepeat)
{
if (!plugin.usesAsyncScrolling())
return false;
ScrollingNodeID scroller = plugin.scrollingNodeID();
ScrollableArea* scrollableArea = m_frame->view()->scrollableAreaForScrollingNodeID(scroller);
auto* scrollableArea = pluginRenderer.scrollableArea();
if (!scrollableArea)
return false;

auto* animator = scrollableArea->scrollAnimator().keyboardScrollingAnimator();
if (!animator)
return false;

return beginKeyboardScrollGesture(animator, direction, granularity, isKeyRepeat);
}

Expand Down
2 changes: 2 additions & 0 deletions Source/WebCore/plugins/PluginViewBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ namespace WebCore {

class Element;
class GraphicsLayer;
class ScrollableArea;
class Scrollbar;
class VoidCallback;

Expand Down Expand Up @@ -64,6 +65,7 @@ class PluginViewBase : public Widget {
virtual bool shouldAllowNavigationFromDrags() const { return false; }
virtual void willDetachRenderer() { }

virtual ScrollableArea* scrollableArea() const { return nullptr; }
virtual bool usesAsyncScrolling() const { return false; }
virtual ScrollingNodeID scrollingNodeID() const { return { }; }
virtual void willAttachScrollingNode() { }
Expand Down
17 changes: 13 additions & 4 deletions Source/WebCore/rendering/RenderEmbeddedObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,33 +111,42 @@ bool RenderEmbeddedObject::requiresAcceleratedCompositing() const
return pluginViewBase->layerHostingStrategy() != PluginLayerHostingStrategy::None;
}

ScrollableArea* RenderEmbeddedObject::scrollableArea() const
{
RefPtr pluginViewBase = dynamicDowncast<PluginViewBase>(widget());
if (!pluginViewBase)
return nullptr;

return pluginViewBase->scrollableArea();
}

bool RenderEmbeddedObject::usesAsyncScrolling() const
{
auto* pluginViewBase = dynamicDowncast<PluginViewBase>(widget());
RefPtr pluginViewBase = dynamicDowncast<PluginViewBase>(widget());
if (!pluginViewBase)
return false;
return pluginViewBase->usesAsyncScrolling();
}

ScrollingNodeID RenderEmbeddedObject::scrollingNodeID() const
{
auto* pluginViewBase = dynamicDowncast<PluginViewBase>(widget());
RefPtr pluginViewBase = dynamicDowncast<PluginViewBase>(widget());
if (!pluginViewBase)
return { };
return pluginViewBase->scrollingNodeID();
}

void RenderEmbeddedObject::willAttachScrollingNode()
{
auto* pluginViewBase = dynamicDowncast<PluginViewBase>(widget());
RefPtr pluginViewBase = dynamicDowncast<PluginViewBase>(widget());
if (!pluginViewBase)
return;
pluginViewBase->willAttachScrollingNode();
}

void RenderEmbeddedObject::didAttachScrollingNode()
{
auto* pluginViewBase = dynamicDowncast<PluginViewBase>(widget());
RefPtr pluginViewBase = dynamicDowncast<PluginViewBase>(widget());
if (!pluginViewBase)
return;
pluginViewBase->didAttachScrollingNode();
Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/rendering/RenderEmbeddedObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class RenderEmbeddedObject final : public RenderWidget {

const String& pluginReplacementTextIfUnavailable() const { return m_unavailablePluginReplacementText; }

ScrollableArea* scrollableArea() const;
bool usesAsyncScrolling() const;
ScrollingNodeID scrollingNodeID() const;
void willAttachScrollingNode();
Expand Down
1 change: 1 addition & 0 deletions Source/WebKit/WebProcess/Plugins/PDF/PDFPluginBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ class PDFPluginBase : public ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr<PDF
// ScrollableArea functions.
WebCore::IntRect scrollCornerRect() const final;
WebCore::ScrollableArea* enclosingScrollableArea() const final;
bool scrollAnimatorEnabled() const final { return true; }
bool isScrollableOrRubberbandable() final { return true; }
bool hasScrollableOrRubberbandableAncestor() final { return true; }
WebCore::IntRect scrollableAreaBoundingBox(bool* = nullptr) const final;
Expand Down
21 changes: 19 additions & 2 deletions Source/WebKit/WebProcess/Plugins/PDF/PDFPluginBase.mm
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@
#import <WebCore/LocalizedStrings.h>
#import <WebCore/MouseEvent.h>
#import <WebCore/PluginDocument.h>
#import <WebCore/RenderEmbeddedObject.h>
#import <WebCore/RenderLayer.h>
#import <WebCore/RenderLayerScrollableArea.h>
#import <WebCore/ResourceResponse.h>
#import <WebCore/ScrollAnimator.h>
#import <WebCore/SharedBuffer.h>
Expand Down Expand Up @@ -663,8 +666,22 @@

ScrollableArea* PDFPluginBase::enclosingScrollableArea() const
{
// FIXME: Walk up the frame tree and look for a scrollable parent frame or RenderLayer.
return nullptr;
if (!m_element)
return nullptr;

RefPtr renderer = dynamicDowncast<RenderEmbeddedObject>(m_element->renderer());
if (!renderer)
return nullptr;

CheckedPtr layer = renderer->enclosingLayer();
if (!layer)
return nullptr;

CheckedPtr enclosingScrollableLayer = layer->enclosingScrollableLayer(IncludeSelfOrNot::ExcludeSelf, CrossFrameBoundaries::No);
if (!enclosingScrollableLayer)
return nullptr;

return enclosingScrollableLayer->scrollableArea();
}

IntRect PDFPluginBase::scrollableAreaBoundingBox(bool*) const
Expand Down
9 changes: 8 additions & 1 deletion Source/WebKit/WebProcess/Plugins/PluginView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,14 @@ void PluginView::willDetachRenderer()
protectedPlugin()->willDetachRenderer();
}

ScrollableArea* PluginView::scrollableArea() const
{
if (!m_isInitialized)
return nullptr;

return m_plugin.ptr();
}

bool PluginView::usesAsyncScrolling() const
{
if (!m_isInitialized)
Expand All @@ -722,7 +730,6 @@ bool PluginView::usesAsyncScrolling() const
return protectedPlugin()->usesAsyncScrolling();
}


ScrollingNodeID PluginView::scrollingNodeID() const
{
if (!m_isInitialized)
Expand Down
1 change: 1 addition & 0 deletions Source/WebKit/WebProcess/Plugins/PluginView.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ class PluginView final : public WebCore::PluginViewBase {
bool shouldAllowNavigationFromDrags() const final;
void willDetachRenderer() final;

WebCore::ScrollableArea* scrollableArea() const final;
bool usesAsyncScrolling() const final;
WebCore::ScrollingNodeID scrollingNodeID() const final;
void willAttachScrollingNode() final;
Expand Down

0 comments on commit 5dce176

Please sign in to comment.