diff options
author | Martin Negyokru <negyokru@inf.u-szeged.hu> | 2022-12-14 10:37:23 +0100 |
---|---|---|
committer | Martin Negyokru <negyokru@inf.u-szeged.hu> | 2023-01-17 19:01:42 +0100 |
commit | e70f53df4d189fa832e3cd6bb729a00c5b6d52ea (patch) | |
tree | 289c8a9fe21219f1f2728118b7b6e0f14a062dee /src | |
parent | e8137c729afbbb5c1549cad863ecbfd8c95b94a5 (diff) |
Add InputEventObserver to child frames
RenderWidgetHostViewChildFrame does not Ack mouse wheel events.
RenderWidgetHostViewQt::handleWheelEvent expects Ack on every event.
Origin-Agent-Cluster is a HTTP response header that instructs
the browser to prevent synchronous scripting between same-site
cross-origin pages. Chromium also uses this header as a hint
that an origin should get its own separate resources, such as a
dedicated process. That's where child frames are created.
This feature is implemented in chromium 88.
Add observer to child frames that responds to wheel events.
Add test for wheel/scroll events on child frames.
Pick-to: 6.5
Fixes: QTBUG-109348
Change-Id: I20439a9068c5c2f8416a350891a6cf8830e1a5d6
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/extensions/extension_web_contents_observer_qt.cpp | 13 | ||||
-rw-r--r-- | src/core/render_widget_host_view_qt.cpp | 54 | ||||
-rw-r--r-- | src/core/render_widget_host_view_qt.h | 14 | ||||
-rw-r--r-- | src/core/web_contents_delegate_qt.cpp | 4 |
4 files changed, 46 insertions, 39 deletions
diff --git a/src/core/extensions/extension_web_contents_observer_qt.cpp b/src/core/extensions/extension_web_contents_observer_qt.cpp index 22092be30..a33954a20 100644 --- a/src/core/extensions/extension_web_contents_observer_qt.cpp +++ b/src/core/extensions/extension_web_contents_observer_qt.cpp @@ -41,17 +41,8 @@ void ExtensionWebContentsObserverQt::CreateForWebContents(content::WebContents * void ExtensionWebContentsObserverQt::RenderFrameCreated(content::RenderFrameHost *render_frame_host) { ExtensionWebContentsObserver::RenderFrameCreated(render_frame_host); - - if (web_contents()->IsInnerWebContentsForGuest() && static_cast<content::RenderFrameHostImpl *>(render_frame_host)->is_local_root_subframe()) { - content::WebContents *parent = web_contents()->GetOutermostWebContents(); - QtWebEngineCore::RenderWidgetHostViewQt *main_rwhv = static_cast<QtWebEngineCore::RenderWidgetHostViewQt *>(parent->GetRenderWidgetHostView()); - // Main frame of guest WebContents - content::RenderWidgetHost *guest_render_widget_host = web_contents()->GetRenderViewHost()->GetWidget(); - main_rwhv->addGuest(guest_render_widget_host); - // The frame which holds the actual PDF content inside the guest - content::RenderWidgetHost *pdf_render_widget_host = render_frame_host->GetRenderWidgetHost(); - main_rwhv->addGuest(pdf_render_widget_host); - } + QtWebEngineCore::RenderWidgetHostViewQt::registerInputEventObserver(web_contents(), + render_frame_host); const Extension *extension = GetExtensionFromFrame(render_frame_host, false); if (!extension) diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 19b9f462c..3d4e5bbc2 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -18,6 +18,7 @@ #include "components/viz/common/surfaces/frame_sink_id_allocator.h" #include "components/viz/host/host_frame_sink_manager.h" #include "content/browser/compositor/image_transport_factory.h" +#include "content/browser/renderer_host/render_frame_host_impl.h" #include "content/browser/renderer_host/frame_tree.h" #include "content/browser/renderer_host/frame_tree_node.h" #include "content/browser/renderer_host/cursor_manager.h" @@ -29,6 +30,7 @@ #include "content/browser/renderer_host/ui_events_helper.h" #include "content/common/content_switches_internal.h" #include "content/common/cursors/webcursor.h" +#include "content/public/browser/web_contents.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/base/cursor/cursor.h" #include "ui/base/resource/resource_bundle.h" @@ -141,33 +143,10 @@ public: } }; -class GuestInputEventObserverQt : public content::RenderWidgetHost::InputEventObserver -{ -public: - GuestInputEventObserverQt(RenderWidgetHostViewQt *rwhv) - : m_rwhv(rwhv) - { - } - ~GuestInputEventObserverQt() {} - - void OnInputEvent(const blink::WebInputEvent&) override {} - void OnInputEventAck(blink::mojom::InputEventResultSource, - blink::mojom::InputEventResultState state, - const blink::WebInputEvent &event) override - { - if (event.GetType() == blink::WebInputEvent::Type::kMouseWheel) - m_rwhv->WheelEventAck(static_cast<const blink::WebMouseWheelEvent &>(event), state); - } - -private: - RenderWidgetHostViewQt *m_rwhv; -}; - RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget) : content::RenderWidgetHostViewBase::RenderWidgetHostViewBase(widget) , m_taskRunner(base::ThreadTaskRunnerHandle::Get()) , m_gestureProvider(QtGestureProviderConfig(), this) - , m_guestInputEventObserver(new GuestInputEventObserverQt(this)) , m_frameSinkId(host()->GetFrameSinkId()) , m_delegateClient(new RenderWidgetHostViewQtDelegateClient(this)) { @@ -247,9 +226,34 @@ void RenderWidgetHostViewQt::setAdapterClient(WebContentsAdapterClient *adapterC m_adapterClient = nullptr; }); } -void RenderWidgetHostViewQt::addGuest(content::RenderWidgetHost *rwh) +void RenderWidgetHostViewQt::OnInputEventAck(blink::mojom::InputEventResultSource, + blink::mojom::InputEventResultState state, + const blink::WebInputEvent &event) { - rwh->AddInputEventObserver(m_guestInputEventObserver.get()); + if (event.GetType() == blink::WebInputEvent::Type::kMouseWheel) + WheelEventAck(static_cast<const blink::WebMouseWheelEvent &>(event), state); +} + +// static +// Called when new child/guest renderframes created. +void RenderWidgetHostViewQt::registerInputEventObserver(content::WebContents *webContents, + content::RenderFrameHost *rfh) +{ + if (static_cast<content::RenderFrameHostImpl *>(rfh)->is_local_root_subframe()) { + content::WebContents *parent = webContents->GetOutermostWebContents(); + QtWebEngineCore::RenderWidgetHostViewQt *mainRwhv = + static_cast<QtWebEngineCore::RenderWidgetHostViewQt *>( + parent->GetRenderWidgetHostView()); + // Child (originAgentCluster) or guest (pdf) frame that is embedded into the main frame + content::RenderWidgetHost *childFrame = rfh->GetRenderWidgetHost(); + childFrame->AddInputEventObserver(mainRwhv); + + if (webContents->IsInnerWebContentsForGuest()) { + // The frame which holds the actual PDF content inside the guest + content::RenderWidgetHost *guestFrame = webContents->GetRenderViewHost()->GetWidget(); + guestFrame->AddInputEventObserver(mainRwhv); + } + } } void RenderWidgetHostViewQt::InitAsChild(gfx::NativeView) diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h index aebf59ddb..25fd20115 100644 --- a/src/core/render_widget_host_view_qt.h +++ b/src/core/render_widget_host_view_qt.h @@ -21,6 +21,7 @@ namespace content { class RenderFrameHost; class RenderWidgetHostImpl; +class WebContents; } namespace ui { @@ -30,7 +31,7 @@ class TouchSelectionController; namespace QtWebEngineCore { class RenderWidgetHostViewQtDelegateClient; -class GuestInputEventObserverQt; +class InputEventObserverQt; class TouchSelectionControllerClientQt; class WebContentsAccessibilityQt; class WebContentsAdapterClient; @@ -41,6 +42,7 @@ class RenderWidgetHostViewQt , public base::SupportsWeakPtr<RenderWidgetHostViewQt> , public content::TextInputManager::Observer , public content::RenderFrameMetadataProvider::Observer + , public content::RenderWidgetHost::InputEventObserver { public: RenderWidgetHostViewQt(content::RenderWidgetHost* widget); @@ -51,7 +53,6 @@ public: WebContentsAdapterClient *adapterClient() { return m_adapterClient; } void setAdapterClient(WebContentsAdapterClient *adapterClient); RenderWidgetHostViewQtDelegateClient *delegateClient() const { return m_delegateClient.get(); } - void addGuest(content::RenderWidgetHost *); // Overridden from RenderWidgetHostView: void InitAsChild(gfx::NativeView) override; @@ -149,6 +150,14 @@ public: void OnRenderFrameSubmission() override {} void OnLocalSurfaceIdChanged(const cc::RenderFrameMetadata &) override {} + // Overridden from content::RenderWidgetHost::InputEventObserver + void OnInputEvent(const blink::WebInputEvent &) override { } + void OnInputEventAck(blink::mojom::InputEventResultSource, + blink::mojom::InputEventResultState state, + const blink::WebInputEvent &event) override; + + static void registerInputEventObserver(content::WebContents *, content::RenderFrameHost *); + // Called from RenderWidgetHostViewQtDelegateClient. Compositor::Id compositorId(); void notifyShown(); @@ -185,7 +194,6 @@ private: std::unique_ptr<content::CursorManager> m_cursorManager; ui::FilteredGestureProvider m_gestureProvider; - std::unique_ptr<GuestInputEventObserverQt> m_guestInputEventObserver; viz::FrameSinkId m_frameSinkId; std::unique_ptr<RenderWidgetHostViewQtDelegateClient> m_delegateClient; diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index fd445f88a..b58b56500 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -255,6 +255,10 @@ void WebContentsDelegateQt::RenderFrameCreated(content::RenderFrameHost *render_ { content::FrameTreeNode *node = static_cast<content::RenderFrameHostImpl *>(render_frame_host)->frame_tree_node(); m_frameFocusedObserver.addNode(node); + + // If it's a child frame (render_widget_host_view_child_frame) install an InputEventObserver on + // it. Note that it is only needed for WheelEventAck. + RenderWidgetHostViewQt::registerInputEventObserver(web_contents(), render_frame_host); } void WebContentsDelegateQt::PrimaryMainFrameRenderProcessGone(base::TerminationStatus status) |