From 2fbe10a115fb0f5f50efe192d554fb7d1c988884 Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Fri, 16 Oct 2020 12:15:51 +0200 Subject: Drop dependency on QWebEngineView in page Introduce temporarily PageView interface and DummyDelegate. Change-Id: I3a3d57435c98b31a15fb6d777045e141d007486f Reviewed-by: Allan Sandfeld Jensen --- src/webenginewidgets/api/qwebenginepage.cpp | 94 +++++++++++++++++++---------- src/webenginewidgets/api/qwebenginepage.h | 2 +- src/webenginewidgets/api/qwebenginepage_p.h | 31 +++++++++- src/webenginewidgets/api/qwebengineview.cpp | 83 +++++++++++++++++++++++-- src/webenginewidgets/api/qwebengineview_p.h | 34 ++++++++--- 5 files changed, 197 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index cc8e00796..8307977ee 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -63,14 +63,13 @@ #include "qwebengineregisterprotocolhandlerrequest.h" #include "qwebenginescriptcollection_p.h" #include "qwebenginesettings.h" -#include "qwebengineview.h" -#include "qwebengineview_p.h" #include "user_notification_controller.h" #include "render_widget_host_view_qt_delegate_widget.h" #include "web_contents_adapter.h" #include "web_engine_settings.h" #include "qwebenginescript.h" - +#include "render_view_context_menu_qt.h" +#include "render_widget_host_view_qt_delegate_client.h" #include #include #include @@ -93,6 +92,49 @@ using namespace QtWebEngineCore; static const int MaxTooltipLength = 1024; +// add temporary dummy code to cover the case when page is loading and there is no view +class DummyDelegate : public QObject, public QtWebEngineCore::RenderWidgetHostViewQtDelegate +{ +public: + DummyDelegate(RenderWidgetHostViewQtDelegateClient *client) : m_delegateClient(client) {}; + ~DummyDelegate() = default; + void initAsPopup(const QRect &) override { Q_UNREACHABLE(); } + QRectF viewGeometry() const override { return QRectF(m_pos, m_size); } + void setKeyboardFocus() override { } + bool hasKeyboardFocus() override { return false; } + void lockMouse() override { Q_UNREACHABLE(); } + void unlockMouse() override { Q_UNREACHABLE(); } + void show() override { m_delegateClient->notifyShown(); } + void hide() override { m_delegateClient->notifyHidden(); } + bool isVisible() const override { Q_UNREACHABLE(); } + QWindow *window() const override { return nullptr; } + void updateCursor(const QCursor &cursor) override + { /*setCursor(cursor);*/ + } + void resize(int width, int height) override + { + m_size = QSize(width, height); + m_delegateClient->visualPropertiesChanged(); + } + void move(const QPoint &) override { Q_UNREACHABLE(); } + void inputMethodStateChanged(bool, bool) override { } + void setInputMethodHints(Qt::InputMethodHints) override { } + void setClearColor(const QColor &) override { } + void adapterClientChanged(WebContentsAdapterClient *client) override { } + bool copySurface(const QRect &rect, const QSize &size, QImage &image) + { + Q_UNREACHABLE(); + return false; + } + QRect windowGeometry() const override { return QRect(m_pos, m_size); } + bool forwardEvent(QEvent *ev) { return m_delegateClient->forwardEvent(ev); } + +private: + RenderWidgetHostViewQtDelegateClient *m_delegateClient; + QPoint m_pos; + QSize m_size; +}; + static QWebEnginePage::WebWindowType toWindowType(WebContentsAdapterClient::WindowOpenDisposition disposition) { switch (disposition) { @@ -159,7 +201,7 @@ RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostVie // The new delegate will not be deleted by the parent view though, because we unset the parent // when the parent is destroyed. The delegate will be destroyed by Chromium when the popup is // dismissed. - return new RenderWidgetHostViewQtDelegateWidget(client, this->view); + return view ? view->CreateRenderWidgetHostViewQtDelegate(client) : new DummyDelegate(client); } void QWebEnginePagePrivate::initializationFinished() @@ -243,7 +285,7 @@ void QWebEnginePagePrivate::renderProcessPidChanged(qint64 pid) QRectF QWebEnginePagePrivate::viewportRect() const { - return view ? view->rect() : QRectF(); + return view ? view->viewportRect() : QRectF(); } QColor QWebEnginePagePrivate::backgroundColor() const @@ -298,15 +340,15 @@ void QWebEnginePagePrivate::didPrintPageToPdf(const QString &filePath, bool succ void QWebEnginePagePrivate::focusContainer() { if (view) { - view->activateWindow(); - view->setFocus(); + view->focusContainer(); } } void QWebEnginePagePrivate::unhandledKeyEvent(QKeyEvent *event) { - if (view && view->parentWidget()) - QGuiApplication::sendEvent(view->parentWidget(), event); + if (view) { + view->unhandledKeyEvent(event); + } } QSharedPointer @@ -415,9 +457,7 @@ void QWebEnginePagePrivate::didPrintPage(quint64 requestId, QSharedPointerfocusNextPrevChild(!reverse); - return false; + return view ? view->passOnFocus(reverse) : false; } void QWebEnginePagePrivate::authenticationRequired(QSharedPointer controller) @@ -450,7 +490,7 @@ void QWebEnginePagePrivate::releaseProfile() void QWebEnginePagePrivate::showColorDialog(QSharedPointer controller) { if (view) - view->d_func()->showColorDialog(controller); + view->showColorDialog(controller); } void QWebEnginePagePrivate::runMediaAccessPermissionRequest(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags requestFlags) @@ -512,7 +552,7 @@ void QWebEnginePagePrivate::runRegisterProtocolHandlerRequest(QWebEngineRegister QObject *QWebEnginePagePrivate::accessibilityParentObject() { - return view; + return view ? view->accessibilityParentObject() : nullptr; } void QWebEnginePagePrivate::updateAction(QWebEnginePage::WebAction action) const @@ -1522,7 +1562,7 @@ bool QWebEnginePage::event(QEvent *e) void QWebEnginePagePrivate::contextMenuRequested(QWebEngineContextMenuRequest *data) { if (view) - view->d_ptr->contextMenuRequested(data); + view->contextMenuRequested(data); } void QWebEnginePagePrivate::navigationRequested(int navigationType, const QUrl &url, int &navigationRequestAction, bool isMainFrame) @@ -1568,8 +1608,7 @@ void QWebEnginePagePrivate::javascriptDialog(QSharedPointerjavaScriptConfirm(controller->securityOrigin(), QCoreApplication::translate("QWebEnginePage", "Are you sure you want to leave this page? Changes that you made may not be saved.")); break; case InternalAuthorizationDialog: - accepted = view ? view->d_func()->showAuthorizationDialog(controller->title(), - controller->message()) + accepted = view ? view->showAuthorizationDialog(controller->title(), controller->message()) : false; break; } @@ -1641,9 +1680,8 @@ QObject *QWebEnginePagePrivate::dragSource() const bool QWebEnginePagePrivate::isEnabled() const { - const QWidget *widget = view; - if (widget) - return widget->isEnabled(); + if (view) + return view->isEnabled(); return true; } @@ -2003,12 +2041,7 @@ QWebEngineScriptCollection &QWebEnginePage::scripts() QWebEnginePage *QWebEnginePage::createWindow(WebWindowType type) { Q_D(QWebEnginePage); - if (d->view) { - QWebEngineView *newView = d->view->createWindow(type); - if (newView) - return newView->page(); - } - return 0; + return d->view ? d->view->createPageForWindow(type) : nullptr; } /*! @@ -2107,8 +2140,7 @@ ASSERT_ENUMS_MATCH(FilePickerController::OpenMultiple, QWebEnginePage::FileSelec QStringList QWebEnginePage::chooseFiles(FileSelectionMode mode, const QStringList &oldFiles, const QStringList &acceptedMimeTypes) { Q_D(const QWebEnginePage); - return d->view ? d->view->d_func()->chooseFiles(mode, oldFiles, acceptedMimeTypes) - : QStringList(); + return d->view ? d->view->chooseFiles(mode, oldFiles, acceptedMimeTypes) : QStringList(); } void QWebEnginePage::javaScriptAlert(const QUrl &securityOrigin, const QString &msg) @@ -2116,21 +2148,21 @@ void QWebEnginePage::javaScriptAlert(const QUrl &securityOrigin, const QString & Q_UNUSED(securityOrigin); Q_D(const QWebEnginePage); if (d->view) - d->view->d_func()->javaScriptAlert(url(), msg); + d->view->javaScriptAlert(url(), msg); } bool QWebEnginePage::javaScriptConfirm(const QUrl &securityOrigin, const QString &msg) { Q_UNUSED(securityOrigin); Q_D(const QWebEnginePage); - return d->view ? d->view->d_func()->javaScriptConfirm(url(), msg) : false; + return d->view ? d->view->javaScriptConfirm(url(), msg) : false; } bool QWebEnginePage::javaScriptPrompt(const QUrl &securityOrigin, const QString &msg, const QString &defaultValue, QString *result) { Q_UNUSED(securityOrigin); Q_D(const QWebEnginePage); - return d->view ? d->view->d_func()->javaScriptPrompt(url(), msg, defaultValue, result) : false; + return d->view ? d->view->javaScriptPrompt(url(), msg, defaultValue, result) : false; } void QWebEnginePage::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID) diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h index 250b809bd..ab4b7af0f 100644 --- a/src/webenginewidgets/api/qwebenginepage.h +++ b/src/webenginewidgets/api/qwebenginepage.h @@ -50,8 +50,8 @@ #include #include #include +#include #include -#include QT_BEGIN_NAMESPACE class QMenu; diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h index 2ed8fd936..cce8e90f5 100644 --- a/src/webenginewidgets/api/qwebenginepage_p.h +++ b/src/webenginewidgets/api/qwebenginepage_p.h @@ -64,6 +64,7 @@ namespace QtWebEngineCore { class RenderWidgetHostViewQtDelegate; class RenderWidgetHostViewQtDelegateWidget; +class RenderWidgetHostViewQtDelegateClient; class TouchHandleDrawableClient; class TouchSelectionMenuController; class WebContentsAdapter; @@ -77,6 +78,34 @@ class QWebEngineProfile; class QWebEngineSettings; class QWebEngineView; +class PageView +{ +public: + virtual void contextMenuRequested(QWebEngineContextMenuRequest *request) = 0; + virtual QStringList chooseFiles(QWebEnginePage::FileSelectionMode mode, + const QStringList &oldFiles, + const QStringList &acceptedMimeTypes) = 0; + virtual void + showColorDialog(QSharedPointer controller) = 0; + virtual bool showAuthorizationDialog(const QString &title, const QString &message) = 0; + virtual void javaScriptAlert(const QUrl &url, const QString &msg) = 0; + virtual bool javaScriptConfirm(const QUrl &url, const QString &msg) = 0; + virtual bool javaScriptPrompt(const QUrl &url, const QString &msg, const QString &defaultValue, + QString *result) = 0; + virtual void setToolTip(const QString &toolTipText) = 0; + virtual QtWebEngineCore::RenderWidgetHostViewQtDelegate *CreateRenderWidgetHostViewQtDelegate( + QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) = 0; + virtual QWebEngineContextMenuRequest *lastContextMenuRequest() const = 0; + virtual QWebEnginePage *createPageForWindow(QWebEnginePage::WebWindowType type) = 0; + virtual bool isEnabled() const = 0; + virtual bool isVisible() const = 0; + virtual QRect viewportRect() const = 0; + virtual void focusContainer() = 0; + virtual void unhandledKeyEvent(QKeyEvent *event) = 0; + virtual bool passOnFocus(bool reverse) = 0; + virtual QObject *accessibilityParentObject() = 0; +}; + class QWebEnginePagePrivate : public QtWebEngineCore::WebContentsAdapterClient { public: @@ -174,7 +203,7 @@ public: QWebEngineHistory *history; QWebEngineProfile *profile; QWebEngineSettings *settings; - QWebEngineView *view; + PageView *view; QUrl url; bool isLoading; QWebEngineScriptCollection scriptCollection; diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp index 934991cbe..2b5b2414c 100644 --- a/src/webenginewidgets/api/qwebengineview.cpp +++ b/src/webenginewidgets/api/qwebengineview.cpp @@ -78,6 +78,7 @@ # include #endif #include +#include QT_BEGIN_NAMESPACE @@ -306,6 +307,26 @@ bool QWebEngineViewPrivate::javaScriptPrompt(const QUrl &url, const QString &msg #endif // QT_CONFIG(inputdialog) } +void QWebEngineViewPrivate::focusContainer() +{ + Q_Q(QWebEngineView); + q->activateWindow(); + q->setFocus(); +} + +void QWebEngineViewPrivate::unhandledKeyEvent(QKeyEvent *event) +{ + Q_Q(QWebEngineView); + if (q->parentWidget()) + QGuiApplication::sendEvent(q->parentWidget(), event); +} + +bool QWebEngineViewPrivate::passOnFocus(bool reverse) +{ + Q_Q(QWebEngineView); + return q->focusNextPrevChild(!reverse); +} + #ifndef QT_NO_ACCESSIBILITY static QAccessibleInterface *webAccessibleFactory(const QString &, QObject *object) { @@ -323,9 +344,13 @@ QWebEngineViewPrivate::QWebEngineViewPrivate() #endif // QT_NO_ACCESSIBILITY } +QWebEngineViewPrivate::~QWebEngineViewPrivate() = default; + void QWebEngineViewPrivate::bindPageAndView(QWebEnginePage *page, QWebEngineView *view) { - auto oldView = page ? page->d_func()->view : nullptr; + QWebEngineViewPrivate *v = + page ? static_cast(page->d_func()->view) : nullptr; + auto oldView = v ? v->q_func() : nullptr; auto oldPage = view ? view->d_func()->page : nullptr; bool ownNewPage = false; @@ -339,7 +364,7 @@ void QWebEngineViewPrivate::bindPageAndView(QWebEnginePage *page, QWebEngineView oldView->d_func()->page = nullptr; oldView->d_func()->m_ownsPage = false; } - page->d_func()->view = view; + page->d_func()->view = view ? view->d_func() : nullptr; } if (view && oldPage != page) { @@ -399,12 +424,12 @@ void QWebEngineViewPrivate::bindPageAndWidget( if (widget && oldPage != page && oldPage && oldPage->d_func()) { if (auto oldView = oldPage->d_func()->view) - oldView->d_func()->widgetChanged(widget, nullptr); + static_cast(oldView)->widgetChanged(widget, nullptr); } if (page && oldWidget != widget) { if (auto view = page->d_func()->view) - view->d_func()->widgetChanged(oldWidget, widget); + static_cast(view)->widgetChanged(oldWidget, widget); } } @@ -435,6 +460,56 @@ QIcon QWebEngineViewPrivate::webActionIcon(QWebEnginePage::WebAction action) } return icon; } + +QWebEnginePage *QWebEngineViewPrivate::createPageForWindow(QWebEnginePage::WebWindowType type) +{ + Q_Q(QWebEngineView); + QWebEngineView *newView = q->createWindow(type); + if (newView) + return newView->page(); + return nullptr; +} + +void QWebEngineViewPrivate::setToolTip(const QString &toolTipText) +{ + Q_Q(QWebEngineView); + q->setToolTip(toolTipText); +} + +bool QWebEngineViewPrivate::isEnabled() const +{ + Q_Q(const QWebEngineView); + return q->isEnabled(); +} + +QObject *QWebEngineViewPrivate::accessibilityParentObject() +{ + Q_Q(QWebEngineView); + return q; +} + +bool QWebEngineViewPrivate::isVisible() const +{ + Q_Q(const QWebEngineView); + return q->isVisible(); +} +QRect QWebEngineViewPrivate::viewportRect() const +{ + Q_Q(const QWebEngineView); + return q->rect(); +} +QtWebEngineCore::RenderWidgetHostViewQtDelegate * +QWebEngineViewPrivate::CreateRenderWidgetHostViewQtDelegate( + QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) +{ + Q_Q(QWebEngineView); + return new QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget(client, q); +} + +QWebEngineContextMenuRequest *QWebEngineViewPrivate::lastContextMenuRequest() const +{ + return m_contextRequest; +} /*! \fn QWebEngineView::renderProcessTerminated(QWebEnginePage::RenderProcessTerminationStatus terminationStatus, int exitCode) \since 5.6 diff --git a/src/webenginewidgets/api/qwebengineview_p.h b/src/webenginewidgets/api/qwebengineview_p.h index ddd4506e2..47694ab24 100644 --- a/src/webenginewidgets/api/qwebengineview_p.h +++ b/src/webenginewidgets/api/qwebengineview_p.h @@ -54,17 +54,19 @@ #include #include "qwebenginecontextmenurequest.h" #include "render_view_context_menu_qt.h" +#include "qwebenginepage_p.h" #include namespace QtWebEngineCore { class RenderWidgetHostViewQtDelegateWidget; +class RenderWidgetHostViewQtDelegate; } QT_BEGIN_NAMESPACE class QWebEngineView; -class QWebEngineViewPrivate +class QWebEngineViewPrivate : public PageView { public: Q_DECLARE_PUBLIC(QWebEngineView) @@ -74,22 +76,34 @@ public: void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *oldWidget, QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *newWidget); - void contextMenuRequested(QWebEngineContextMenuRequest *request); + void contextMenuRequested(QWebEngineContextMenuRequest *request) override; QStringList chooseFiles(QWebEnginePage::FileSelectionMode mode, const QStringList &oldFiles, - const QStringList &acceptedMimeTypes); - void showColorDialog(QSharedPointer controller); - bool showAuthorizationDialog(const QString &title, const QString &message); - void javaScriptAlert(const QUrl &url, const QString &msg); - bool javaScriptConfirm(const QUrl &url, const QString &msg); + const QStringList &acceptedMimeTypes) override; + void + showColorDialog(QSharedPointer controller) override; + bool showAuthorizationDialog(const QString &title, const QString &message) override; + void javaScriptAlert(const QUrl &url, const QString &msg) override; + bool javaScriptConfirm(const QUrl &url, const QString &msg) override; bool javaScriptPrompt(const QUrl &url, const QString &msg, const QString &defaultValue, - QString *result); - void setToolTip(const QString &toolTipText); + QString *result) override; + void setToolTip(const QString &toolTipText) override; + QtWebEngineCore::RenderWidgetHostViewQtDelegate *CreateRenderWidgetHostViewQtDelegate( + QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override; + QWebEngineContextMenuRequest *lastContextMenuRequest() const override; + QWebEnginePage *createPageForWindow(QWebEnginePage::WebWindowType type) override; + QObject *accessibilityParentObject() override; QWebEngineViewPrivate(); + virtual ~QWebEngineViewPrivate(); static void bindPageAndView(QWebEnginePage *page, QWebEngineView *view); static void bindPageAndWidget(QWebEnginePage *page, QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *widget); QIcon webActionIcon(QWebEnginePage::WebAction action); - + void unhandledKeyEvent(QKeyEvent *event) override; + void focusContainer() override; + bool passOnFocus(bool reverse) override; + bool isEnabled() const override; + bool isVisible() const override; + QRect viewportRect() const override; QWebEnginePage *page; bool m_dragEntered; mutable bool m_ownsPage; -- cgit v1.2.3