summaryrefslogtreecommitdiffstats
path: root/src/webengine/api
diff options
context:
space:
mode:
authorMichal Klocek <michal.klocek@qt.io>2018-08-31 10:29:07 +0200
committerMichal Klocek <michal.klocek@qt.io>2018-09-12 10:22:28 +0000
commita5e680c2ef404693870aedfb10f22ffc83cd38e7 (patch)
treedcaf1c152848cb5cc0b710e241661b87e83bafa1 /src/webengine/api
parent5b5b7d9a5f922ef5fa99cfac41da348e23970032 (diff)
Fix issues with qml bindings accessing non-existing adapter
We have currently two levels of initialization for WebEngineView: the profile initialization and the adapter initialization. The adapter initialization is delayed to first navigation request to pick the right initial site instance and avoid creating dummy/blank WebContents, which in turn would start unnecessary render process. Profile initialization is delayed to make sure we avoid unnecessary default profile creations. Created profiles use filestorage. Unfortunately qml will call QQuickItem::componentComplete() only when the root element is completed and the bindings can be already in use by that time. Profile initialization has to take place before adapter initialization. Construct adapter together with WebEngineView, but create and initialize profile before adapter initialization. Go through WebEngineView and fix emitting signals based on adapter initialization. Most of the signals are emitted on initializationFinished(). Task-number: QTBUG-70248 Change-Id: I2acd8bff761c692a360733cbf537de53e1295695 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/webengine/api')
-rw-r--r--src/webengine/api/qquickwebengineprofile.h1
-rw-r--r--src/webengine/api/qquickwebengineprofile_p.h2
-rw-r--r--src/webengine/api/qquickwebenginesettings_p.h2
-rw-r--r--src/webengine/api/qquickwebengineview.cpp155
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h6
5 files changed, 90 insertions, 76 deletions
diff --git a/src/webengine/api/qquickwebengineprofile.h b/src/webengine/api/qquickwebengineprofile.h
index 4f1053924..9fc4f9eca 100644
--- a/src/webengine/api/qquickwebengineprofile.h
+++ b/src/webengine/api/qquickwebengineprofile.h
@@ -168,6 +168,7 @@ private:
friend class QQuickWebEngineViewPrivate;
friend class QQuickWebEngineDownloadItem;
friend class QQuickWebEngineDownloadItemPrivate;
+ friend class QQuickWebEngineView;
QScopedPointer<QQuickWebEngineProfilePrivate> d_ptr;
};
diff --git a/src/webengine/api/qquickwebengineprofile_p.h b/src/webengine/api/qquickwebengineprofile_p.h
index 9ed8b89de..d31ded0ec 100644
--- a/src/webengine/api/qquickwebengineprofile_p.h
+++ b/src/webengine/api/qquickwebengineprofile_p.h
@@ -90,7 +90,7 @@ public:
static void userScripts_clear(QQmlListProperty<QQuickWebEngineScript> *p);
private:
- friend class QQuickWebEngineViewPrivate;
+ friend class QQuickWebEngineView;
QQuickWebEngineProfile *q_ptr;
QScopedPointer<QQuickWebEngineSettings> m_settings;
QPointer<QtWebEngineCore::ProfileAdapter> m_profileAdapter;
diff --git a/src/webengine/api/qquickwebenginesettings_p.h b/src/webengine/api/qquickwebenginesettings_p.h
index 179416b54..6e1aaca39 100644
--- a/src/webengine/api/qquickwebenginesettings_p.h
+++ b/src/webengine/api/qquickwebenginesettings_p.h
@@ -204,7 +204,7 @@ private:
Q_DISABLE_COPY(QQuickWebEngineSettings)
friend class QQuickWebEngineProfilePrivate;
friend class QQuickWebEngineViewPrivate;
-
+ friend class QQuickWebEngineView;
void setParentSettings(QQuickWebEngineSettings *parentSettings);
QScopedPointer<QtWebEngineCore::WebEngineSettings> d_ptr;
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index bdd3bfe26..6bf23ea7b 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -107,8 +107,11 @@ static QAccessibleInterface *webAccessibleFactory(const QString &, QObject *obje
}
#endif // QT_NO_ACCESSIBILITY
+static QLatin1String defaultMimeType("text/html;charset=UTF-8");
+
QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
: m_profile(nullptr)
+ , adapter(QSharedPointer<WebContentsAdapter>::create())
, m_history(new QQuickWebEngineHistory(this))
#if QT_CONFIG(webengine_testsupport)
, m_testSupport(0)
@@ -125,7 +128,7 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
, m_isBeingAdopted(false)
, m_dpiScale(1.0)
, m_backgroundColor(Qt::white)
- , m_defaultZoomFactor(1.0)
+ , m_zoomFactor(1.0)
, m_ui2Enabled(false)
, m_profileInitialized(false)
{
@@ -168,16 +171,13 @@ QQuickWebEngineViewPrivate::~QQuickWebEngineViewPrivate()
void QQuickWebEngineViewPrivate::initializeProfile()
{
if (!m_profileInitialized) {
+ Q_ASSERT(!adapter->isInitialized());
m_profileInitialized = true;
if (!m_profile)
m_profile = QQuickWebEngineProfile::defaultProfile();
m_profile->d_ptr->addWebContentsAdapterClient(this);
- adapter = QSharedPointer<WebContentsAdapter>::create();
m_settings.reset(new QQuickWebEngineSettings(m_profile->settings()));
-#if QT_CONFIG(webengine_webchannel)
- if (m_webChannel)
- adapter->setWebChannel(m_webChannel, m_webChannelWorld);
-#endif
+ adapter->setClient(this);
}
}
@@ -348,7 +348,6 @@ void QQuickWebEngineViewPrivate::urlChanged(const QUrl &url)
{
Q_Q(QQuickWebEngineView);
Q_UNUSED(url);
- explicitUrl = QUrl();
Q_EMIT q->urlChanged();
}
@@ -473,7 +472,6 @@ void QQuickWebEngineViewPrivate::loadFinished(bool success, const QUrl &url, boo
return;
}
if (success) {
- explicitUrl = QUrl();
QTimer::singleShot(0, q, [q, url, errorDescription, errorCode]() {
QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus, errorDescription, errorCode);
emit q->loadingChanged(&loadRequest);
@@ -784,9 +782,12 @@ QQuickWebEngineView::~QQuickWebEngineView()
void QQuickWebEngineViewPrivate::ensureContentsAdapter()
{
+ initializeProfile();
if (!adapter->isInitialized()) {
- if (explicitUrl.isValid())
- adapter->load(explicitUrl);
+ if (!m_html.isEmpty())
+ adapter->setContent(m_html.toUtf8(), defaultMimeType, m_url);
+ else if (m_url.isValid())
+ adapter->load(m_url);
else
adapter->loadDefault();
}
@@ -796,14 +797,21 @@ void QQuickWebEngineViewPrivate::initializationFinished()
{
Q_Q(QQuickWebEngineView);
- if (m_backgroundColor != Qt::white)
- adapter->backgroundColorChanged();
+ Q_ASSERT(m_profileInitialized);
+ if (m_backgroundColor != Qt::white) {
+ adapter->setBackgroundColor(m_backgroundColor);
+ emit q->backgroundColorChanged();
+ }
+
+ if (!qFuzzyCompare(adapter->currentZoomFactor(), m_zoomFactor)) {
+ adapter->setZoomFactor(m_zoomFactor);
+ emit q->zoomFactorChanged(m_zoomFactor);
+ }
+
#if QT_CONFIG(webengine_webchannel)
if (m_webChannel)
adapter->setWebChannel(m_webChannel, m_webChannelWorld);
#endif
- if (!qFuzzyCompare(adapter->currentZoomFactor(), m_defaultZoomFactor))
- q->setZoomFactor(m_defaultZoomFactor);
if (devToolsView && devToolsView->d_ptr->adapter)
adapter->openDevToolsFrontend(devToolsView->d_ptr->adapter);
@@ -874,20 +882,25 @@ void QQuickWebEngineViewPrivate::updateAction(QQuickWebEngineView::WebAction act
QUrl QQuickWebEngineView::url() const
{
Q_D(const QQuickWebEngineView);
- return d->explicitUrl.isValid() ? d->explicitUrl : d->adapter->activeUrl();
+ if (d->adapter->isInitialized())
+ return d->adapter->activeUrl();
+ else
+ return d->m_url;
}
void QQuickWebEngineView::setUrl(const QUrl& url)
{
+ Q_D(QQuickWebEngineView);
if (url.isEmpty())
return;
- Q_D(QQuickWebEngineView);
- d->explicitUrl = url;
- if (d->profileInitialized() && d->adapter->isInitialized())
+ if (d->adapter->isInitialized()) {
d->adapter->load(url);
- if (!qmlEngine(this) || isComponentComplete())
- d->ensureContentsAdapter();
+ return;
+ }
+
+ d->m_url = url;
+ d->m_html.clear();
}
QUrl QQuickWebEngineView::icon() const
@@ -899,11 +912,12 @@ QUrl QQuickWebEngineView::icon() const
void QQuickWebEngineView::loadHtml(const QString &html, const QUrl &baseUrl)
{
Q_D(QQuickWebEngineView);
- d->explicitUrl = QUrl();
- if (!qmlEngine(this) || isComponentComplete())
- d->ensureContentsAdapter();
- if (d->adapter->isInitialized())
- d->adapter->setContent(html.toUtf8(), QStringLiteral("text/html;charset=UTF-8"), baseUrl);
+ d->m_url = baseUrl;
+ d->m_html = html;
+ if (d->adapter->isInitialized()) {
+ d->adapter->setContent(html.toUtf8(), defaultMimeType, baseUrl);
+ return;
+ }
}
void QQuickWebEngineView::goBack()
@@ -939,20 +953,17 @@ void QQuickWebEngineView::stop()
void QQuickWebEngineView::setZoomFactor(qreal arg)
{
Q_D(QQuickWebEngineView);
- d->m_defaultZoomFactor = arg;
-
- qreal oldFactor = d->adapter->currentZoomFactor();
- d->adapter->setZoomFactor(arg);
- if (qFuzzyCompare(oldFactor, d->adapter->currentZoomFactor()))
- return;
-
- emit zoomFactorChanged(arg);
+ if (d->adapter->isInitialized() && !qFuzzyCompare(d->m_zoomFactor, d->adapter->currentZoomFactor())) {
+ d->adapter->setZoomFactor(arg);
+ emit zoomFactorChanged(arg);
+ } else {
+ d->m_zoomFactor = arg;
+ }
}
QQuickWebEngineProfile *QQuickWebEngineView::profile()
{
Q_D(QQuickWebEngineView);
- // this can be called before onComplete for group properties
d->initializeProfile();
return d->m_profile;
}
@@ -960,7 +971,24 @@ QQuickWebEngineProfile *QQuickWebEngineView::profile()
void QQuickWebEngineView::setProfile(QQuickWebEngineProfile *profile)
{
Q_D(QQuickWebEngineView);
- d->setProfile(profile);
+
+ if (d->m_profile == profile)
+ return;
+
+ if (!d->profileInitialized()) {
+ d->m_profile = profile;
+ return;
+ }
+
+ if (d->m_profile)
+ d->m_profile->d_ptr->removeWebContentsAdapterClient(d);
+
+ d->m_profile = profile;
+ d->m_profile->d_ptr->addWebContentsAdapterClient(d);
+ d->m_settings->setParentSettings(profile->settings());
+
+ d->updateAdapter();
+ Q_EMIT profileChanged();
}
QQuickWebEngineSettings *QQuickWebEngineView::settings()
@@ -980,40 +1008,22 @@ QQmlListProperty<QQuickWebEngineScript> QQuickWebEngineView::userScripts()
d->userScripts_clear);
}
-void QQuickWebEngineViewPrivate::setProfile(QQuickWebEngineProfile *profile)
+void QQuickWebEngineViewPrivate::updateAdapter()
{
- Q_Q(QQuickWebEngineView);
-
- if (profile == m_profile)
- return;
-
- if (!m_profileInitialized) {
- m_profile = profile;
- return;
- }
-
- if (m_profile)
- m_profile->d_ptr->removeWebContentsAdapterClient(this);
-
- m_profile = profile;
- m_profile->d_ptr->addWebContentsAdapterClient(this);
- Q_EMIT q->profileChanged();
- m_settings->setParentSettings(profile->settings());
-
- if (adapter->profile() != profileAdapter()->profile()) {
- // When the profile changes we need to create a new WebContentAdapter and reload the active URL.
- bool wasInitialized = adapter->isInitialized();
- QUrl activeUrl = adapter->activeUrl();
- adapter = QSharedPointer<WebContentsAdapter>::create();
- adapter->setClient(this);
- if (wasInitialized) {
- if (explicitUrl.isValid())
- adapter->load(explicitUrl);
- else if (activeUrl.isValid())
- adapter->load(activeUrl);
- else
- adapter->loadDefault();
- }
+ // When the profile changes we need to create a new WebContentAdapter and reload the active URL.
+ bool wasInitialized = adapter->isInitialized();
+ QUrl activeUrl = adapter->activeUrl();
+ adapter = QSharedPointer<WebContentsAdapter>::create();
+ adapter->setClient(this);
+ if (wasInitialized) {
+ if (!m_html.isEmpty())
+ adapter->setContent(m_html.toUtf8(), defaultMimeType, m_url);
+ else if (m_url.isValid())
+ adapter->load(m_url);
+ else if (activeUrl.isValid())
+ adapter->load(activeUrl);
+ else
+ adapter->loadDefault();
}
}
@@ -1178,7 +1188,7 @@ qreal QQuickWebEngineView::zoomFactor() const
{
Q_D(const QQuickWebEngineView);
if (!d->adapter->isInitialized())
- return d->m_defaultZoomFactor;
+ return d->m_zoomFactor;
return d->adapter->currentZoomFactor();
}
@@ -1194,8 +1204,10 @@ void QQuickWebEngineView::setBackgroundColor(const QColor &color)
if (color == d->m_backgroundColor)
return;
d->m_backgroundColor = color;
- d->adapter->backgroundColorChanged();
- emit backgroundColorChanged();
+ if (d->adapter->isInitialized()) {
+ d->adapter->setBackgroundColor(color);
+ emit backgroundColorChanged();
+ }
}
/*!
@@ -1963,7 +1975,6 @@ void QQuickWebEngineView::componentComplete()
QQuickItem::componentComplete();
Q_D(QQuickWebEngineView);
d->initializeProfile();
- d->adapter->setClient(d);
#ifndef QT_NO_ACCESSIBILITY
// Enable accessibility via a dynamic QQmlProperty, instead of using private API call
// QQuickAccessibleAttached::qmlAttachedProperties(this). The qmlContext is required, otherwise
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index fda67a6bf..ee38ece6b 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -160,6 +160,7 @@ public:
void updateAction(QQuickWebEngineView::WebAction) const;
void adoptWebContents(QtWebEngineCore::WebContentsAdapter *webContents);
void setProfile(QQuickWebEngineProfile *profile);
+ void updateAdapter();
void ensureContentsAdapter();
void setFullScreenMode(bool);
@@ -178,7 +179,8 @@ public:
#endif
QQmlComponent *contextMenuExtraItems;
QtWebEngineCore::WebEngineContextMenuData m_contextMenuData;
- QUrl explicitUrl;
+ QUrl m_url;
+ QString m_html;
QUrl iconUrl;
QQuickWebEngineFaviconProvider *faviconProvider;
int loadProgress;
@@ -203,7 +205,7 @@ private:
QList<QQuickWebEngineScript *> m_userScripts;
qreal m_dpiScale;
QColor m_backgroundColor;
- qreal m_defaultZoomFactor;
+ qreal m_zoomFactor;
bool m_ui2Enabled;
bool m_profileInitialized;
};