diff options
author | Christian Strømme <christian.stromme@qt.io> | 2021-05-05 14:46:06 +0200 |
---|---|---|
committer | Christian Strømme <christian.stromme@qt.io> | 2022-10-27 14:44:35 +0000 |
commit | c77a7d8140d2212f347be34dc5c54d93349084ec (patch) | |
tree | 1a80419bf9bafd1b3ae7d4e565880366922e8374 /src | |
parent | ba547a3db3907377ca6b1cfee5845c0ae8314d26 (diff) |
Fix assert when WebView is used in combination with QQuickWidget
Using the WebView with QQuickWidget is not really a use-case the
WebView is well suited for, due to the native WebView being an overlay,
however it should not crash or trigger an assert, so this change tries
to avoid some of the caveats when mixing with QQuickWidget. For example,
we cannot under any circumstances call winId() before the window the
QQuickWidget lives under, is backed by a platform window. The native
WebView is therefore not added before the platform window is created.
Fixes: QTBUG-46084
Change-Id: I815d37cdd0328b3a258ef60294b5ea282f41cfc6
Reviewed-by: Christian Strømme <christian.stromme@qt.io>
(cherry picked from commit d7a1d393989eda6bc0207515dce0b8b4aac4b0ff)
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/darwin/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/plugins/darwin/qdarwinwebview.mm | 28 | ||||
-rw-r--r-- | src/plugins/darwin/qdarwinwebview_p.h | 1 | ||||
-rw-r--r-- | src/quick/qquickviewcontroller.cpp | 3 | ||||
-rw-r--r-- | src/webview/qnativeviewcontroller_p.h | 1 | ||||
-rw-r--r-- | src/webview/qwebview.cpp | 5 | ||||
-rw-r--r-- | src/webview/qwebview_p.h | 1 |
7 files changed, 39 insertions, 1 deletions
diff --git a/src/plugins/darwin/CMakeLists.txt b/src/plugins/darwin/CMakeLists.txt index 10b5847..59c47fe 100644 --- a/src/plugins/darwin/CMakeLists.txt +++ b/src/plugins/darwin/CMakeLists.txt @@ -18,6 +18,7 @@ qt_internal_add_plugin(QDarwinWebViewPlugin ${FWWebKit} Qt::Core Qt::Gui + Qt::Quick Qt::WebViewPrivate ) diff --git a/src/plugins/darwin/qdarwinwebview.mm b/src/plugins/darwin/qdarwinwebview.mm index 45151d4..1cc2e72 100644 --- a/src/plugins/darwin/qdarwinwebview.mm +++ b/src/plugins/darwin/qdarwinwebview.mm @@ -11,6 +11,9 @@ #include <QtCore/qmap.h> #include <QtCore/qvariant.h> +#include <QtQuick/qquickrendercontrol.h> +#include <QtQuick/qquickwindow.h> + #include <CoreFoundation/CoreFoundation.h> #include <WebKit/WebKit.h> @@ -326,8 +329,11 @@ void QDarwinWebViewPrivate::setParentView(QObject *view) if (!wkWebView) return; + // NOTE: We delay adding the uiView to the scene + // if the window is not backed by a platform window + // see: updateParent(). QWindow *w = qobject_cast<QWindow *>(view); - if (w) { + if (w && w->handle()) { UIView *parentView = reinterpret_cast<UIView *>(w->winId()); [parentView addSubview:wkWebView]; } else { @@ -363,6 +369,26 @@ void QDarwinWebViewPrivate::setFocus(bool focus) Q_EMIT requestFocus(focus); } +void QDarwinWebViewPrivate::updatePolish() +{ + // This is a special case for when the WebView is inside a QQuickWidget... + // We delay adding the view until we can verify that we have a non-hidden platform window. + if (m_parentView && wkWebView.superview == nullptr) { + if (auto window = qobject_cast<QWindow *>(m_parentView)) { + if (window->visibility() != QWindow::Hidden) { + UIView *parentView = nullptr; + if (window->handle()) + parentView = reinterpret_cast<UIView *>(window->winId()); + else if (auto rw = QQuickRenderControl::renderWindowFor(qobject_cast<QQuickWindow *>(window))) + parentView = reinterpret_cast<UIView *>(rw->winId()); + + if (parentView) + [parentView addSubview:wkWebView]; + } + } + } +} + void QDarwinWebViewPrivate::goBack() { [wkWebView goBack]; diff --git a/src/plugins/darwin/qdarwinwebview_p.h b/src/plugins/darwin/qdarwinwebview_p.h index d22a60f..8013945 100644 --- a/src/plugins/darwin/qdarwinwebview_p.h +++ b/src/plugins/darwin/qdarwinwebview_p.h @@ -65,6 +65,7 @@ public: void setVisibility(QWindow::Visibility visibility) override; void setVisible(bool visible) override; void setFocus(bool focus) override; + void updatePolish() override; public Q_SLOTS: void goBack() override; diff --git a/src/quick/qquickviewcontroller.cpp b/src/quick/qquickviewcontroller.cpp index b08626e..4315514 100644 --- a/src/quick/qquickviewcontroller.cpp +++ b/src/quick/qquickviewcontroller.cpp @@ -176,6 +176,7 @@ void QQuickViewController::updatePolish() m_view->setGeometry(rw ? QRect(rw->mapFromGlobal(tl), itemSize) : itemGeometry); m_view->setVisible(isVisible()); + m_view->updatePolish(); } void QQuickViewController::setView(QNativeViewController *view) @@ -221,6 +222,7 @@ void QQuickViewController::onWindowChanged(QQuickWindow *window) &QQuickViewController::scheduleUpdatePolish); connect(window, &QQuickWindow::sceneGraphInvalidated, this, &QQuickViewController::onSceneGraphInvalidated); + connect(rw, &QWindow::visibilityChanged, this, &QQuickViewController::scheduleUpdatePolish); m_view->setParentView(rw); } else { connect(window, &QWindow::widthChanged, this, &QQuickViewController::scheduleUpdatePolish); @@ -234,6 +236,7 @@ void QQuickViewController::onWindowChanged(QQuickWindow *window) connect(window, &QWindow::visibilityChanged, this, [this](QWindow::Visibility visibility) { m_view->setVisible(visibility != QWindow::Hidden); }); + connect(window, &QWindow::visibilityChanged, this, &QQuickViewController::scheduleUpdatePolish); m_view->setVisible(window->visibility() != QWindow::Hidden); m_view->setParentView(window); } diff --git a/src/webview/qnativeviewcontroller_p.h b/src/webview/qnativeviewcontroller_p.h index 782bfd4..37a8f45 100644 --- a/src/webview/qnativeviewcontroller_p.h +++ b/src/webview/qnativeviewcontroller_p.h @@ -34,6 +34,7 @@ public: virtual void setVisible(bool visible) = 0; virtual void init() { } virtual void setFocus(bool focus) { Q_UNUSED(focus); } + virtual void updatePolish() { } }; QT_END_NAMESPACE diff --git a/src/webview/qwebview.cpp b/src/webview/qwebview.cpp index 090a920..6ef0aeb 100644 --- a/src/webview/qwebview.cpp +++ b/src/webview/qwebview.cpp @@ -131,6 +131,11 @@ void QWebView::setFocus(bool focus) d->setFocus(focus); } +void QWebView::updatePolish() +{ + d->updatePolish(); +} + void QWebView::loadHtml(const QString &html, const QUrl &baseUrl) { d->loadHtml(html, baseUrl); diff --git a/src/webview/qwebview_p.h b/src/webview/qwebview_p.h index 47a10c0..36230d8 100644 --- a/src/webview/qwebview_p.h +++ b/src/webview/qwebview_p.h @@ -60,6 +60,7 @@ public: void setVisibility(QWindow::Visibility visibility) override; void setVisible(bool visible) override; void setFocus(bool focus) override; + void updatePolish() override; public Q_SLOTS: void goBack() override; |