summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/webengine/quicknanobrowser/quickwindow.qml12
-rw-r--r--examples/webengine/quicknanobrowser/util.h2
-rw-r--r--examples/webenginewidgets/browser/featurepermissionbar.cpp10
-rw-r--r--examples/webenginewidgets/browser/featurepermissionbar.h1
-rw-r--r--examples/webenginewidgets/browser/webview.cpp34
-rw-r--r--examples/webenginewidgets/browser/webview.h4
-rw-r--r--qtwebengine.pro6
m---------src/3rdparty0
-rw-r--r--src/core/access_token_store_qt.cpp34
-rw-r--r--src/core/access_token_store_qt.h23
-rw-r--r--src/core/browser_context_adapter.cpp100
-rw-r--r--src/core/browser_context_adapter.h78
-rw-r--r--src/core/browser_context_qt.cpp29
-rw-r--r--src/core/browser_context_qt.h5
-rw-r--r--src/core/content_browser_client_qt.cpp54
-rw-r--r--src/core/content_browser_client_qt.h19
-rw-r--r--src/core/core_gyp_generator.pro12
-rw-r--r--src/core/core_module.pro3
-rw-r--r--src/core/delegated_frame_node.cpp407
-rw-r--r--src/core/delegated_frame_node.h37
-rw-r--r--src/core/dev_tools_http_handler_delegate_qt.cpp87
-rw-r--r--src/core/location_provider_qt.cpp248
-rw-r--r--src/core/location_provider_qt.h76
-rw-r--r--src/core/render_widget_host_view_qt.cpp12
-rw-r--r--src/core/render_widget_host_view_qt.h2
-rw-r--r--src/core/render_widget_host_view_qt_delegate.h6
-rw-r--r--src/core/resources/devtools_discovery_page.html85
-rw-r--r--src/core/type_conversion.h6
-rw-r--r--src/core/web_contents_adapter.cpp28
-rw-r--r--src/core/web_contents_adapter.h4
-rw-r--r--src/core/web_contents_adapter_client.h4
-rw-r--r--src/core/web_contents_delegate_qt.cpp9
-rw-r--r--src/core/web_contents_delegate_qt.h4
-rw-r--r--src/core/web_engine_context.cpp72
-rw-r--r--src/core/web_engine_context.h8
-rw-r--r--src/core/web_engine_visited_links_manager.cpp9
-rw-r--r--src/core/web_engine_visited_links_manager.h3
-rw-r--r--src/webengine/api/qquickwebenginesettings.cpp47
-rw-r--r--src/webengine/api/qquickwebenginesettings_p.h26
-rw-r--r--src/webengine/api/qquickwebenginesettings_p_p.h1
-rw-r--r--src/webengine/api/qquickwebengineview.cpp56
-rw-r--r--src/webengine/api/qquickwebengineview_p.h7
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h10
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.cpp19
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.h3
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp15
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quickwindow.h3
-rw-r--r--src/webengine/webengine.pro2
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp33
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h11
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h5
-rw-r--r--src/webenginewidgets/api/qwebenginesettings.cpp34
-rw-r--r--src/webenginewidgets/api/qwebenginesettings.h2
-rw-r--r--src/webenginewidgets/api/qwebenginesettings_p.h1
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc24
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp20
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h3
-rw-r--r--src/webenginewidgets/webenginewidgets.pro2
-rw-r--r--tests/auto/quick/publicapi/tst_publicapi.cpp1
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp166
-rw-r--r--tests/quicktestbrowser/FeaturePermissionBar.qml8
-rw-r--r--tests/quicktestbrowser/ZoomController.qml102
-rw-r--r--tests/quicktestbrowser/quickwindow.qml26
-rw-r--r--tests/quicktestbrowser/resources.qrc1
-rw-r--r--tests/quicktestbrowser/util.h2
65 files changed, 1590 insertions, 573 deletions
diff --git a/examples/webengine/quicknanobrowser/quickwindow.qml b/examples/webengine/quicknanobrowser/quickwindow.qml
index 610144dca..b954629fb 100644
--- a/examples/webengine/quicknanobrowser/quickwindow.qml
+++ b/examples/webengine/quicknanobrowser/quickwindow.qml
@@ -93,6 +93,18 @@ ApplicationWindow {
tabs.removeTab(tabs.currentIndex)
}
}
+ Action {
+ shortcut: "Ctrl+0"
+ onTriggered: currentWebView.zoomFactor = 1.0;
+ }
+ Action {
+ shortcut: "Ctrl+-"
+ onTriggered: currentWebView.zoomFactor -= 0.1;
+ }
+ Action {
+ shortcut: "Ctrl+="
+ onTriggered: currentWebView.zoomFactor += 0.1;
+ }
toolBar: ToolBar {
id: navigationBar
diff --git a/examples/webengine/quicknanobrowser/util.h b/examples/webengine/quicknanobrowser/util.h
index bc1cf8beb..ca0f5f1d5 100644
--- a/examples/webengine/quicknanobrowser/util.h
+++ b/examples/webengine/quicknanobrowser/util.h
@@ -50,7 +50,7 @@ QUrl urlFromUserInput(const QString& userInput)
{
QFileInfo fileInfo(userInput);
if (fileInfo.exists())
- return QUrl(fileInfo.absoluteFilePath());
+ return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
return QUrl::fromUserInput(userInput);
}
diff --git a/examples/webenginewidgets/browser/featurepermissionbar.cpp b/examples/webenginewidgets/browser/featurepermissionbar.cpp
index 98f19ad1f..a47cbcd9e 100644
--- a/examples/webenginewidgets/browser/featurepermissionbar.cpp
+++ b/examples/webenginewidgets/browser/featurepermissionbar.cpp
@@ -80,12 +80,13 @@ FeaturePermissionBar::FeaturePermissionBar(QWidget *view)
l->addStretch();
QPushButton *allowButton = new QPushButton(tr("Allow"), this);
QPushButton *denyButton = new QPushButton(tr("Deny"), this);
+ QPushButton *discardButton = new QPushButton(QIcon(QStringLiteral(":closetab.png")), QString(), this);
connect(allowButton, &QPushButton::clicked, this, &FeaturePermissionBar::permissionGranted);
connect(denyButton, &QPushButton::clicked, this, &FeaturePermissionBar::permissionDenied);
- QPushButton *discardButton = new QPushButton(QIcon(QStringLiteral(":closetab.png")), QString(), this);
- connect(discardButton, &QPushButton::clicked, this, &QObject::deleteLater);
+ connect(discardButton, &QPushButton::clicked, this, &FeaturePermissionBar::permissionUnknown);
connect(allowButton, &QPushButton::clicked, this, &QObject::deleteLater);
connect(denyButton, &QPushButton::clicked, this, &QObject::deleteLater);
+ connect(discardButton, &QPushButton::clicked, this, &QObject::deleteLater);
l->addWidget(denyButton);
l->addWidget(allowButton);
l->addWidget(discardButton);
@@ -118,3 +119,8 @@ void FeaturePermissionBar::permissionGranted()
{
emit featurePermissionProvided(m_securityOrigin, m_feature, QWebEnginePage::PermissionGrantedByUser);
}
+
+void FeaturePermissionBar::permissionUnknown()
+{
+ emit featurePermissionProvided(m_securityOrigin, m_feature, QWebEnginePage::PermissionUnknown);
+}
diff --git a/examples/webenginewidgets/browser/featurepermissionbar.h b/examples/webenginewidgets/browser/featurepermissionbar.h
index 92ca04773..cee5a25b0 100644
--- a/examples/webenginewidgets/browser/featurepermissionbar.h
+++ b/examples/webenginewidgets/browser/featurepermissionbar.h
@@ -63,6 +63,7 @@ signals:
private slots:
void permissionDenied();
void permissionGranted();
+ void permissionUnknown();
private:
QWebEnginePage::Feature m_feature;
diff --git a/examples/webenginewidgets/browser/webview.cpp b/examples/webenginewidgets/browser/webview.cpp
index 5ea273e3a..9b42f2ab2 100644
--- a/examples/webenginewidgets/browser/webview.cpp
+++ b/examples/webenginewidgets/browser/webview.cpp
@@ -97,37 +97,15 @@ BrowserMainWindow *WebPage::mainWindow()
return BrowserApplication::instance()->mainWindow();
}
-#if defined(QWEBENGINEPAGE_ACCEPTNAVIGATIONREQUEST)
-bool WebPage::acceptNavigationRequest(QWebEngineFrame *frame, const QNetworkRequest &request, NavigationType type)
+bool WebPage::acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame)
{
- // ctrl open in new tab
- // ctrl-shift open in new tab and select
- // ctrl-alt open in new window
- if (type == QWebEnginePage::NavigationTypeLinkClicked
- && (m_keyboardModifiers & Qt::ControlModifier
- || m_pressedButtons == Qt::MidButton)) {
- bool newWindow = (m_keyboardModifiers & Qt::AltModifier);
- WebView *webView;
- if (newWindow) {
- BrowserApplication::instance()->newMainWindow();
- BrowserMainWindow *newMainWindow = BrowserApplication::instance()->mainWindow();
- webView = newMainWindow->currentTab();
- newMainWindow->raise();
- newMainWindow->activateWindow();
- webView->setFocus();
- } else {
- bool selectNewTab = (m_keyboardModifiers & Qt::ShiftModifier);
- webView = mainWindow()->tabWidget()->newTab(selectNewTab);
- }
- webView->load(request);
- m_keyboardModifiers = Qt::NoModifier;
- m_pressedButtons = Qt::NoButton;
- return false;
+ Q_UNUSED(type);
+ if (isMainFrame) {
+ m_loadingUrl = url;
+ emit loadingUrl(m_loadingUrl);
}
- m_loadingUrl = request.url();
- emit loadingUrl(m_loadingUrl);
+ return true;
}
-#endif
bool WebPage::certificateError(const QWebEngineCertificateError &error)
{
diff --git a/examples/webenginewidgets/browser/webview.h b/examples/webenginewidgets/browser/webview.h
index 2cedeb79b..5ed674f6a 100644
--- a/examples/webenginewidgets/browser/webview.h
+++ b/examples/webenginewidgets/browser/webview.h
@@ -65,9 +65,7 @@ public:
BrowserMainWindow *mainWindow();
protected:
-#if defined(QWEBENGINEPAGE_ACCEPTNAVIGATIONREQUEST)
- bool acceptNavigationRequest(QWebEngineFrame *frame, const QNetworkRequest &request, NavigationType type);
-#endif
+ bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame);
QWebEnginePage *createWindow(QWebEnginePage::WebWindowType type);
#if !defined(QT_NO_UITOOLS)
QObject *createPlugin(const QString &classId, const QUrl &url, const QStringList &paramNames, const QStringList &paramValues);
diff --git a/qtwebengine.pro b/qtwebengine.pro
index 366446c7a..5156e4620 100644
--- a/qtwebengine.pro
+++ b/qtwebengine.pro
@@ -1,8 +1,2 @@
load(qt_build_config)
-
-# As long as we are a module separate from the rest of Qt, we want to unconditionally build examples.
-# Once part of Qt 5, this should be removed and we should respect the Qt wide configuration.
-QTWEBENGINE_BUILD_PARTS = $$QT_BUILD_PARTS
-QTWEBENGINE_BUILD_PARTS *= examples
-
load(qt_parts)
diff --git a/src/3rdparty b/src/3rdparty
-Subproject 577cd47e54bb88c81b7a5b5a6d658d8d61b2c74
+Subproject 66388297cf2ca42049fb099237134ec33465e2f
diff --git a/src/core/access_token_store_qt.cpp b/src/core/access_token_store_qt.cpp
index 85a91c3f7..791d628ba 100644
--- a/src/core/access_token_store_qt.cpp
+++ b/src/core/access_token_store_qt.cpp
@@ -34,11 +34,27 @@
**
****************************************************************************/
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
#include "access_token_store_qt.h"
-#include <QDebug>
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/public/browser/browser_thread.h"
+
+#include "browser_context_qt.h"
+#include "browser_context_adapter.h"
+#include "content_browser_client_qt.h"
+#include "web_engine_context.h"
+
+using content::AccessTokenStore;
+using content::BrowserThread;
AccessTokenStoreQt::AccessTokenStoreQt()
+ : m_systemRequestContext(0)
{
}
@@ -48,9 +64,23 @@ AccessTokenStoreQt::~AccessTokenStoreQt()
void AccessTokenStoreQt::LoadAccessTokens(const LoadAccessTokensCallbackType& callback)
{
+ BrowserThread::PostTaskAndReply(BrowserThread::UI, FROM_HERE
+ , base::Bind(&AccessTokenStoreQt::performWorkOnUIThread, this)
+ , base::Bind(&AccessTokenStoreQt::respondOnOriginatingThread, this, callback));
+}
+
+void AccessTokenStoreQt::performWorkOnUIThread()
+{
+ m_systemRequestContext = WebEngineContext::current()->defaultBrowserContext()->browserContext()->GetRequestContext();
}
-void AccessTokenStoreQt::SaveAccessToken(const GURL& server_url, const base::string16& access_token)
+void AccessTokenStoreQt::respondOnOriginatingThread(const LoadAccessTokensCallbackType& callback)
{
+ callback.Run(m_accessTokenSet, m_systemRequestContext);
+ m_systemRequestContext = 0;
}
+void AccessTokenStoreQt::SaveAccessToken(const GURL& serverUrl, const base::string16& accessToken)
+{
+ m_accessTokenSet[serverUrl] = accessToken;
+}
diff --git a/src/core/access_token_store_qt.h b/src/core/access_token_store_qt.h
index 2a76681f0..9493da774 100644
--- a/src/core/access_token_store_qt.h
+++ b/src/core/access_token_store_qt.h
@@ -37,20 +37,33 @@
#ifndef ACCESS_TOKEN_STORE_QT_H
#define ACCESS_TOKEN_STORE_QT_H
+#include "base/memory/ref_counted.h"
#include "content/public/browser/access_token_store.h"
-#include <QtCore/qcompilerdetection.h> // Needed for Q_DECL_OVERRIDE
+#include <QtCore/qcompilerdetection.h>
+#include <QtCore/QFile>
+#include <QtCore/QScopedPointer>
-class AccessTokenStoreQt : public content::AccessTokenStore
-{
+namespace net {
+class URLRequestContextGetter;
+}
+
+class AccessTokenStoreQt : public content::AccessTokenStore {
public:
AccessTokenStoreQt();
~AccessTokenStoreQt();
- virtual void LoadAccessTokens(const LoadAccessTokensCallbackType& callback) Q_DECL_OVERRIDE;
- virtual void SaveAccessToken(const GURL& server_url, const base::string16& access_token) Q_DECL_OVERRIDE;
+ virtual void LoadAccessTokens(const LoadAccessTokensCallbackType& request) Q_DECL_OVERRIDE;
+ virtual void SaveAccessToken(const GURL& serverUrl, const base::string16& accessToken) Q_DECL_OVERRIDE;
private:
+ void performWorkOnUIThread();
+ void respondOnOriginatingThread(const LoadAccessTokensCallbackType& callback);
+
+
+ net::URLRequestContextGetter *m_systemRequestContext;
+ AccessTokenSet m_accessTokenSet;
+
DISALLOW_COPY_AND_ASSIGN(AccessTokenStoreQt);
};
diff --git a/src/core/browser_context_adapter.cpp b/src/core/browser_context_adapter.cpp
new file mode 100644
index 000000000..ccb6a385d
--- /dev/null
+++ b/src/core/browser_context_adapter.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "browser_context_adapter.h"
+
+#include "browser_context_qt.h"
+#include "web_engine_context.h"
+#include "web_engine_visited_links_manager.h"
+
+#include <QCoreApplication>
+#include <QDir>
+#include <QString>
+#include <QStringBuilder>
+#include <QStandardPaths>
+
+namespace {
+inline QString buildLocationFromStandardPath(const QString &standardPath, const QString &name) {
+ QString location = standardPath;
+ if (location.isEmpty())
+ location = QDir::homePath() % QDir::separator() % QChar::fromLatin1('.') % QCoreApplication::applicationName();
+
+ location.append(QDir::separator() % QLatin1String("QtWebEngine") % QDir::separator() % name);
+ return location;
+}
+}
+
+BrowserContextAdapter::BrowserContextAdapter(const QString &name, bool offTheRecord)
+ : m_name(name)
+ , m_offTheRecord(offTheRecord)
+ , m_browserContext(new BrowserContextQt(this))
+ , m_visitedLinksManager(new WebEngineVisitedLinksManager(this))
+{
+}
+
+BrowserContextAdapter::~BrowserContextAdapter()
+{
+}
+
+BrowserContextQt *BrowserContextAdapter::browserContext()
+{
+ return m_browserContext.data();
+}
+
+WebEngineVisitedLinksManager *BrowserContextAdapter::visitedLinksManager()
+{
+ return m_visitedLinksManager.data();
+}
+
+BrowserContextAdapter* BrowserContextAdapter::defaultContext()
+{
+ return WebEngineContext::current()->defaultBrowserContext();
+}
+
+BrowserContextAdapter* BrowserContextAdapter::offTheRecordContext()
+{
+ return WebEngineContext::current()->offTheRecordBrowserContext();
+}
+
+QString BrowserContextAdapter::dataPath() const
+{
+ return buildLocationFromStandardPath(QStandardPaths::writableLocation(QStandardPaths::DataLocation), m_name);
+}
+
+QString BrowserContextAdapter::cachePath() const
+{
+ return buildLocationFromStandardPath(QStandardPaths::writableLocation(QStandardPaths::CacheLocation), m_name);
+}
diff --git a/src/core/browser_context_adapter.h b/src/core/browser_context_adapter.h
new file mode 100644
index 000000000..e4e046c8e
--- /dev/null
+++ b/src/core/browser_context_adapter.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BROWSER_CONTEXT_ADAPTER_H
+#define BROWSER_CONTEXT_ADAPTER_H
+
+#include "qtwebenginecoreglobal.h"
+
+#include <QScopedPointer>
+#include <QSharedData>
+#include <QString>
+
+class BrowserContextQt;
+class WebEngineVisitedLinksManager;
+
+// Make a QSharedData if we need to open arbitrary BrowserContextAdapter beyond the defaults.
+class QWEBENGINE_EXPORT BrowserContextAdapter // : public QSharedData
+{
+public:
+ virtual ~BrowserContextAdapter();
+
+ static BrowserContextAdapter* defaultContext();
+ static BrowserContextAdapter* offTheRecordContext();
+
+ WebEngineVisitedLinksManager *visitedLinksManager();
+
+ BrowserContextQt *browserContext();
+ bool isOffTheRecord() const { return m_offTheRecord; }
+ QString dataPath() const;
+ QString cachePath() const;
+
+protected:
+ BrowserContextAdapter(const QString &name, bool offTheRecord = false);
+
+private:
+ const QString m_name;
+ bool m_offTheRecord;
+ QScopedPointer<BrowserContextQt> m_browserContext;
+ QScopedPointer<WebEngineVisitedLinksManager> m_visitedLinksManager;
+ friend class WebEngineContext;
+
+ Q_DISABLE_COPY(BrowserContextAdapter)
+};
+
+#endif // BROWSER_CONTEXT_ADAPTER_H
diff --git a/src/core/browser_context_qt.cpp b/src/core/browser_context_qt.cpp
index 44b6ca4ef..8dc4a3da2 100644
--- a/src/core/browser_context_qt.cpp
+++ b/src/core/browser_context_qt.cpp
@@ -36,6 +36,7 @@
#include "browser_context_qt.h"
+#include "browser_context_adapter.h"
#include "type_conversion.h"
#include "qtwebenginecoreglobal.h"
#include "resource_context_qt.h"
@@ -47,14 +48,8 @@
#include "content/public/browser/storage_partition.h"
#include "net/proxy/proxy_config_service.h"
-#include <QByteArray>
-#include <QCoreApplication>
-#include <QDir>
-#include <QStandardPaths>
-#include <QString>
-#include <QStringBuilder>
-
-BrowserContextQt::BrowserContextQt()
+BrowserContextQt::BrowserContextQt(BrowserContextAdapter *adapter)
+ : m_adapter(adapter)
{
resourceContext.reset(new ResourceContextQt(this));
}
@@ -67,29 +62,17 @@ BrowserContextQt::~BrowserContextQt()
base::FilePath BrowserContextQt::GetPath() const
{
- QString dataLocation = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
- if (dataLocation.isEmpty())
- dataLocation = QDir::homePath() % QDir::separator() % QChar::fromLatin1('.') % QCoreApplication::applicationName();
-
- dataLocation.append(QDir::separator() % QLatin1String("QtWebEngine"));
- dataLocation.append(QDir::separator() % QLatin1String("Default"));
- return base::FilePath(toFilePathString(dataLocation));
+ return base::FilePath(toFilePathString(m_adapter->dataPath()));
}
base::FilePath BrowserContextQt::GetCachePath() const
{
- QString cacheLocation = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
- if (cacheLocation.isEmpty())
- cacheLocation = QDir::homePath() % QDir::separator() % QChar::fromLatin1('.') % QCoreApplication::applicationName();
-
- cacheLocation.append(QDir::separator() % QLatin1String("QtWebEngine"));
- cacheLocation.append(QDir::separator() % QLatin1String("Default"));
- return base::FilePath(toFilePathString(cacheLocation));
+ return base::FilePath(toFilePathString(m_adapter->cachePath()));
}
bool BrowserContextQt::IsOffTheRecord() const
{
- return false;
+ return m_adapter->isOffTheRecord();
}
net::URLRequestContextGetter *BrowserContextQt::GetRequestContext()
diff --git a/src/core/browser_context_qt.h b/src/core/browser_context_qt.h
index 125c0fc46..634db6f3f 100644
--- a/src/core/browser_context_qt.h
+++ b/src/core/browser_context_qt.h
@@ -43,10 +43,12 @@
#include "net/url_request/url_request_context.h"
#include "download_manager_delegate_qt.h"
+class BrowserContextAdapter;
+
class BrowserContextQt : public content::BrowserContext
{
public:
- explicit BrowserContextQt();
+ explicit BrowserContextQt(BrowserContextAdapter *);
virtual ~BrowserContextQt();
@@ -70,6 +72,7 @@ private:
scoped_ptr<content::ResourceContext> resourceContext;
scoped_refptr<net::URLRequestContextGetter> url_request_getter_;
scoped_ptr<DownloadManagerDelegateQt> downloadManagerDelegate;
+ BrowserContextAdapter *m_adapter;
DISALLOW_COPY_AND_ASSIGN(BrowserContextQt);
};
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index ee403298b..1c0c75bad 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -54,11 +54,15 @@
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_share_group.h"
+#include "access_token_store_qt.h"
#include "browser_context_qt.h"
#include "certificate_error_controller.h"
#include "certificate_error_controller_p.h"
#include "desktop_screen_qt.h"
#include "dev_tools_http_handler_delegate_qt.h"
+#ifdef QT_USE_POSITIONING
+#include "location_provider_qt.h"
+#endif
#include "media_capture_devices_dispatcher.h"
#include "resource_dispatcher_host_delegate_qt.h"
#include "web_contents_delegate_qt.h"
@@ -202,12 +206,10 @@ public:
void PreMainMessageLoopRun() Q_DECL_OVERRIDE
{
- m_browserContext.reset(new BrowserContextQt());
}
void PostMainMessageLoopRun()
{
- m_browserContext.reset();
}
int PreCreateThreads() Q_DECL_OVERRIDE
@@ -218,13 +220,7 @@ public:
return 0;
}
- BrowserContextQt* browser_context() const {
- return m_browserContext.get();
- }
-
private:
- scoped_ptr<BrowserContextQt> m_browserContext;
-
DISALLOW_COPY_AND_ASSIGN(BrowserMainPartsQt);
};
@@ -353,22 +349,15 @@ content::AccessTokenStore *ContentBrowserClientQt::CreateAccessTokenStore()
return new AccessTokenStoreQt;
}
-BrowserContextQt* ContentBrowserClientQt::browser_context() {
- Q_ASSERT(m_browserMainParts);
- return static_cast<BrowserMainPartsQt*>(m_browserMainParts)->browser_context();
-}
-
-net::URLRequestContextGetter* ContentBrowserClientQt::CreateRequestContext(content::BrowserContext* content_browser_context, content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors)
+net::URLRequestContextGetter* ContentBrowserClientQt::CreateRequestContext(content::BrowserContext* browser_context, content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors)
{
- if (content_browser_context != browser_context())
- fprintf(stderr, "Warning: off the record browser context not implemented !\n");
- return static_cast<BrowserContextQt*>(browser_context())->CreateRequestContext(protocol_handlers);
+ return static_cast<BrowserContextQt*>(browser_context)->CreateRequestContext(protocol_handlers);
}
-void ContentBrowserClientQt::enableInspector(bool enable)
+void ContentBrowserClientQt::enableInspector(bool enable, content::BrowserContext* browser_context)
{
if (enable && !m_devtools) {
- m_devtools.reset(new DevToolsHttpHandlerDelegateQt(browser_context()));
+ m_devtools.reset(new DevToolsHttpHandlerDelegateQt(browser_context));
} else if (!enable && m_devtools) {
m_devtools.reset();
}
@@ -393,19 +382,18 @@ void ContentBrowserClientQt::AllowCertificateError(int render_process_id, int re
contentsDelegate->allowCertificateError(errorController);
}
-void ContentBrowserClientQt::RequestGeolocationPermission(content::WebContents *webContents,
- int bridge_id,
- const GURL &requesting_frame,
- bool user_gesture,
- base::Callback<void(bool)> result_callback,
- base::Closure *cancel_callback)
+void ContentBrowserClientQt::RequestGeolocationPermission(content::WebContents *webContents, int /*bridgeId*/, const GURL &requestingFrameOrigin, bool /*userGesture*/, base::Callback<void (bool)> resultCallback, base::Closure *cancelCallback)
+{
+ WebContentsDelegateQt* contentsDelegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate());
+ Q_ASSERT(contentsDelegate);
+ contentsDelegate->requestGeolocationPermission(requestingFrameOrigin, resultCallback, cancelCallback);
+}
+
+content::LocationProvider *ContentBrowserClientQt::OverrideSystemLocationProvider()
{
- Q_UNUSED(webContents);
- Q_UNUSED(bridge_id);
- Q_UNUSED(requesting_frame);
- Q_UNUSED(user_gesture);
- Q_UNUSED(cancel_callback);
-
- // TODO: Add geolocation support
- result_callback.Run(false);
+#ifdef QT_USE_POSITIONING
+ return new LocationProviderQt;
+#else
+ return 0; // Leave it up to Chromium to figure something out.
+#endif
}
diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h
index 4f216030c..879546994 100644
--- a/src/core/content_browser_client_qt.h
+++ b/src/core/content_browser_client_qt.h
@@ -78,8 +78,8 @@ public:
virtual void ResourceDispatcherHostCreated() Q_DECL_OVERRIDE;
virtual gfx::GLShareGroup* GetInProcessGpuShareGroup() Q_DECL_OVERRIDE;
virtual content::MediaObserver* GetMediaObserver() Q_DECL_OVERRIDE;
+ virtual content::AccessTokenStore* CreateAccessTokenStore() Q_DECL_OVERRIDE;
virtual void OverrideWebkitPrefs(content::RenderViewHost *, const GURL &, WebPreferences *) Q_DECL_OVERRIDE;
- virtual content::AccessTokenStore *CreateAccessTokenStore() Q_DECL_OVERRIDE;
virtual void AllowCertificateError(
int render_process_id,
int render_frame_id,
@@ -91,19 +91,14 @@ public:
bool strict_enforcement,
const base::Callback<void(bool)>& callback,
content::CertificateRequestResultType* result) Q_DECL_OVERRIDE;
- virtual void RequestGeolocationPermission(
- content::WebContents *webContents,
- int bridge_id,
- const GURL &requesting_frame,
- bool user_gesture,
- base::Callback<void(bool)> result_callback,
- base::Closure *cancel_callback) Q_DECL_OVERRIDE;
+ void RequestGeolocationPermission(content::WebContents* web_contents, int, const GURL& requesting_frame
+ , bool, base::Callback<void(bool)> resultCallback
+ , base::Closure* cancelCallback) Q_DECL_OVERRIDE;
+ content::LocationProvider* OverrideSystemLocationProvider() Q_DECL_OVERRIDE;
- BrowserContextQt* browser_context();
+ virtual net::URLRequestContextGetter *CreateRequestContext(content::BrowserContext *browser_context, content::ProtocolHandlerMap *protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptorss) Q_DECL_OVERRIDE;
- virtual net::URLRequestContextGetter *CreateRequestContext(content::BrowserContext *content_browser_context, content::ProtocolHandlerMap *protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptorss) Q_DECL_OVERRIDE;
-
- void enableInspector(bool);
+ void enableInspector(bool enable, content::BrowserContext *browser_context);
private:
BrowserMainPartsQt* m_browserMainParts;
diff --git a/src/core/core_gyp_generator.pro b/src/core/core_gyp_generator.pro
index 38aba3a76..4514475ec 100644
--- a/src/core/core_gyp_generator.pro
+++ b/src/core/core_gyp_generator.pro
@@ -11,7 +11,7 @@ TEMPLATE = lib
# gyp/ninja will take care of the compilation, qmake/make will finish with linking and install.
TARGET = QtWebEngineCore
QT += qml quick
-QT_PRIVATE += gui-private
+QT_PRIVATE += quick-private gui-private core-private
# Defining keywords such as 'signal' clashes with the chromium code base.
DEFINES += QT_NO_KEYWORDS \
@@ -36,6 +36,7 @@ SOURCES = \
access_token_store_qt.cpp \
browser_accessibility_manager_qt.cpp \
browser_accessibility_qt.cpp \
+ browser_context_adapter.cpp \
browser_context_qt.cpp \
certificate_error_controller.cpp \
chromium_gpu_helper.cpp \
@@ -84,6 +85,7 @@ HEADERS = \
access_token_store_qt.h \
browser_accessibility_manager_qt.h \
browser_accessibility_qt.h \
+ browser_context_adapter.h \
browser_context_qt.h \
certificate_error_controller_p.h \
certificate_error_controller.h \
@@ -117,6 +119,7 @@ HEADERS = \
resource_dispatcher_host_delegate_qt.h \
stream_video_node.h \
surface_factory_qt.h \
+ type_conversion.h \
url_request_context_getter_qt.h \
url_request_qrc_job_qt.h \
web_contents_adapter.h \
@@ -131,3 +134,10 @@ HEADERS = \
web_engine_visited_links_manager.h \
web_event_factory.h \
yuv_video_node.h
+
+qtHaveModule(positioning) {
+ SOURCES += location_provider_qt.cpp
+ HEADERS += location_provider_qt.h
+ DEFINES += QT_USE_POSITIONING=1
+ QT += positioning
+}
diff --git a/src/core/core_module.pro b/src/core/core_module.pro
index ceb248372..1a7b0878f 100644
--- a/src/core/core_module.pro
+++ b/src/core/core_module.pro
@@ -3,8 +3,9 @@ TARGET = QtWebEngineCore
CMAKE_MODULE_TESTS = "-"
+qtHaveModule(positioning):QT += positioning
QT += qml quick
-QT_PRIVATE += gui-private
+QT_PRIVATE += quick-private gui-private core-private
# Needed to set a CFBundleIdentifier
QMAKE_INFO_PLIST = Info_mac.plist
diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp
index 1a393a0c7..0a24333db 100644
--- a/src/core/delegated_frame_node.cpp
+++ b/src/core/delegated_frame_node.cpp
@@ -55,6 +55,7 @@
#include "base/bind.h"
#include "cc/output/delegated_frame_data.h"
#include "cc/quads/checkerboard_draw_quad.h"
+#include "cc/quads/debug_border_draw_quad.h"
#include "cc/quads/draw_quad.h"
#include "cc/quads/render_pass_draw_quad.h"
#include "cc/quads/solid_color_draw_quad.h"
@@ -62,80 +63,60 @@
#include "cc/quads/texture_draw_quad.h"
#include "cc/quads/tile_draw_quad.h"
#include "cc/quads/yuv_video_draw_quad.h"
+#include "content/common/host_shared_bitmap_manager.h"
#include <QOpenGLContext>
-#include <QOpenGLFramebufferObject>
#include <QOpenGLFunctions>
-#include <QSGAbstractRenderer>
-#include <QSGEngine>
#include <QSGSimpleRectNode>
#include <QSGSimpleTextureNode>
#include <QSGTexture>
+#include <private/qsgadaptationlayer_p.h>
#if !defined(QT_NO_EGL)
#include <EGL/egl.h>
#include <EGL/eglext.h>
#endif
-class RenderPassTexture : public QSGTexture, protected QOpenGLFunctions
-{
-public:
- RenderPassTexture(const cc::RenderPass::Id &id);
-
- const cc::RenderPass::Id &id() const { return m_id; }
- void bind();
-
- int textureId() const { return m_fbo ? m_fbo->texture() : 0; }
- QSize textureSize() const { return m_rect.size(); }
- bool hasAlphaChannel() const { return m_format != GL_RGB; }
- bool hasMipmaps() const { return false; }
-
- void setRect(const QRect &rect) { m_rect = rect; }
- void setFormat(GLenum format) { m_format = format; }
- QSGNode *rootNode() { return m_rootNode.data(); }
-
- void grab();
-
-private:
- cc::RenderPass::Id m_id;
- QRect m_rect;
- GLenum m_format;
-
- QScopedPointer<QSGEngine> m_sgEngine;
- QScopedPointer<QSGRootNode> m_rootNode;
- QScopedPointer<QSGAbstractRenderer> m_renderer;
- QScopedPointer<QOpenGLFramebufferObject> m_fbo;
-};
-
class MailboxTexture : public QSGTexture, protected QOpenGLFunctions {
public:
- MailboxTexture(const cc::TransferableResource &resource);
+ MailboxTexture(const gpu::MailboxHolder &mailboxHolder, const QSize textureSize);
virtual int textureId() const Q_DECL_OVERRIDE { return m_textureId; }
- void setTextureSize(const QSize& size) { m_textureSize = size; }
virtual QSize textureSize() const Q_DECL_OVERRIDE { return m_textureSize; }
virtual bool hasAlphaChannel() const Q_DECL_OVERRIDE { return m_hasAlpha; }
void setHasAlphaChannel(bool hasAlpha) { m_hasAlpha = hasAlpha; }
virtual bool hasMipmaps() const Q_DECL_OVERRIDE { return false; }
virtual void bind() Q_DECL_OVERRIDE;
- bool needsToFetch() const { return !m_textureId; }
- cc::TransferableResource &resource() { return m_resource; }
- cc::ReturnedResource returnResource();
+ gpu::MailboxHolder &mailboxHolder() { return m_mailboxHolder; }
void fetchTexture(gpu::gles2::MailboxManager *mailboxManager);
void setTarget(GLenum target);
- void incImportCount() { ++m_importCount; }
private:
- cc::TransferableResource m_resource;
+ gpu::MailboxHolder m_mailboxHolder;
int m_textureId;
QSize m_textureSize;
bool m_hasAlpha;
GLenum m_target;
- int m_importCount;
#ifdef Q_OS_QNX
EGLStreamData m_eglStreamData;
#endif
};
+class ResourceHolder {
+public:
+ ResourceHolder(const cc::TransferableResource &resource);
+ QSharedPointer<QSGTexture> initTexture(bool quadIsAllOpaque, RenderWidgetHostViewQtDelegate *apiDelegate = 0);
+ QSGTexture *texture() const { return m_texture.data(); }
+ cc::TransferableResource &transferableResource() { return m_resource; }
+ cc::ReturnedResource returnResource();
+ void incImportCount() { ++m_importCount; }
+ bool needsToFetch() const { return !m_resource.is_software && m_texture && !m_texture.data()->textureId(); }
+
+private:
+ QWeakPointer<QSGTexture> m_texture;
+ cc::TransferableResource m_resource;
+ int m_importCount;
+};
+
class RectClipNode : public QSGClipNode
{
public:
@@ -144,23 +125,13 @@ private:
QSGGeometry m_geometry;
};
-static inline QSharedPointer<RenderPassTexture> findRenderPassTexture(const cc::RenderPass::Id &id, const QList<QSharedPointer<RenderPassTexture> > &list)
-{
- Q_FOREACH (const QSharedPointer<RenderPassTexture> &texture, list)
- if (texture->id() == id)
- return texture;
- return QSharedPointer<RenderPassTexture>();
-}
-
-static inline QSharedPointer<MailboxTexture> &findMailboxTexture(unsigned resourceId
- , QHash<unsigned, QSharedPointer<MailboxTexture> > &usedTextures
- , QHash<unsigned, QSharedPointer<MailboxTexture> > &candidateTextures)
+static inline QSharedPointer<QSGLayer> findRenderPassLayer(const cc::RenderPass::Id &id, const QList<QPair<cc::RenderPass::Id, QSharedPointer<QSGLayer> > > &list)
{
- QSharedPointer<MailboxTexture> &texture = usedTextures[resourceId];
- if (!texture)
- texture = candidateTextures.take(resourceId);
- Q_ASSERT(texture);
- return texture;
+ typedef QPair<cc::RenderPass::Id, QSharedPointer<QSGLayer> > Pair;
+ Q_FOREACH (const Pair &pair, list)
+ if (pair.first == id)
+ return pair.second;
+ return QSharedPointer<QSGLayer>();
}
static QSGNode *buildRenderPassChain(QSGNode *chainParent)
@@ -294,59 +265,20 @@ static void deleteChromiumSync(gfx::TransferableFence *sync)
Q_ASSERT(!*sync);
}
-RenderPassTexture::RenderPassTexture(const cc::RenderPass::Id &id)
- : QSGTexture()
- , m_id(id)
- , m_format(GL_RGBA)
- , m_sgEngine(new QSGEngine)
- , m_rootNode(new QSGRootNode)
-{
- initializeOpenGLFunctions();
-}
-
-void RenderPassTexture::bind()
-{
- glBindTexture(GL_TEXTURE_2D, m_fbo ? m_fbo->texture() : 0);
- updateBindOptions();
-}
-
-void RenderPassTexture::grab()
-{
- if (!m_renderer) {
- m_sgEngine->initialize(QOpenGLContext::currentContext());
- m_renderer.reset(m_sgEngine->createRenderer());
- m_renderer->setRootNode(m_rootNode.data());
- }
-
- if (!m_fbo || m_fbo->size() != m_rect.size() || m_fbo->format().internalTextureFormat() != m_format)
- {
- QOpenGLFramebufferObjectFormat format;
- format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
- format.setInternalTextureFormat(m_format);
-
- m_fbo.reset(new QOpenGLFramebufferObject(m_rect.size(), format));
- glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
- updateBindOptions(true);
- }
-
- m_renderer->setDeviceRect(m_rect.size());
- m_renderer->setViewportRect(m_rect.size());
- QRectF mirrored(m_rect.left(), m_rect.bottom(), m_rect.width(), -m_rect.height());
- m_renderer->setProjectionMatrixToRect(mirrored);
- m_renderer->setClearColor(Qt::transparent);
-
- m_renderer->renderScene(m_fbo->handle());
-}
-
-MailboxTexture::MailboxTexture(const cc::TransferableResource &resource)
- : m_resource(resource)
+MailboxTexture::MailboxTexture(const gpu::MailboxHolder &mailboxHolder, const QSize textureSize)
+ : m_mailboxHolder(mailboxHolder)
, m_textureId(0)
- , m_textureSize(toQt(resource.size))
+ , m_textureSize(textureSize)
, m_hasAlpha(false)
, m_target(GL_TEXTURE_2D)
- , m_importCount(1)
{
initializeOpenGLFunctions();
+
+ // Assume that resources without a size will be used with a full source rect.
+ // Setting a size of 1x1 will let any texture node compute a normalized source
+ // rect of (0, 0) to (1, 1) while an empty texture size would set (0, 0) on all corners.
+ if (m_textureSize.isEmpty())
+ m_textureSize = QSize(1, 1);
}
void MailboxTexture::bind()
@@ -373,7 +305,55 @@ void MailboxTexture::setTarget(GLenum target)
m_target = target;
}
-cc::ReturnedResource MailboxTexture::returnResource()
+void MailboxTexture::fetchTexture(gpu::gles2::MailboxManager *mailboxManager)
+{
+ gpu::gles2::Texture *tex = ConsumeTexture(mailboxManager, m_target, m_mailboxHolder.mailbox);
+
+ // The texture might already have been deleted (e.g. when navigating away from a page).
+ if (tex) {
+ m_textureId = service_id(tex);
+#ifdef Q_OS_QNX
+ if (m_target == GL_TEXTURE_EXTERNAL_OES) {
+ m_eglStreamData = eglstream_connect_consumer(tex);
+ }
+#endif
+ }
+}
+
+ResourceHolder::ResourceHolder(const cc::TransferableResource &resource)
+ : m_resource(resource)
+ , m_importCount(1)
+{
+}
+
+QSharedPointer<QSGTexture> ResourceHolder::initTexture(bool quadNeedsBlending, RenderWidgetHostViewQtDelegate *apiDelegate)
+{
+ QSharedPointer<QSGTexture> texture = m_texture.toStrongRef();
+ if (!texture) {
+ if (m_resource.is_software) {
+ Q_ASSERT(apiDelegate);
+ scoped_ptr<cc::SharedBitmap> sharedBitmap = content::HostSharedBitmapManager::current()->GetSharedBitmapFromId(m_resource.size, m_resource.mailbox_holder.mailbox);
+ // QSG interprets QImage::hasAlphaChannel meaning that a node should enable blending
+ // to draw it but Chromium keeps this information in the quads.
+ // The input format is currently always Format_ARGB32_Premultiplied, so assume that all
+ // alpha bytes are 0xff if quads aren't requesting blending and avoid the conversion
+ // from Format_ARGB32_Premultiplied to Format_RGB32 just to get hasAlphaChannel to
+ // return false.
+ QImage::Format format = quadNeedsBlending ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
+ QImage image(sharedBitmap->pixels(), m_resource.size.width(), m_resource.size.height(), format);
+ texture.reset(apiDelegate->createTextureFromImage(image.copy()));
+ } else {
+ texture.reset(new MailboxTexture(m_resource.mailbox_holder, toQt(m_resource.size)));
+ static_cast<MailboxTexture *>(texture.data())->setHasAlphaChannel(quadNeedsBlending);
+ }
+ m_texture = texture;
+ }
+ // All quads using a resource should request the same blending state.
+ Q_ASSERT(texture->hasAlphaChannel() || !quadNeedsBlending);
+ return texture;
+}
+
+cc::ReturnedResource ResourceHolder::returnResource()
{
cc::ReturnedResource returned;
// The ResourceProvider ensures that the resource isn't used by the parent compositor's GL
@@ -389,20 +369,6 @@ cc::ReturnedResource MailboxTexture::returnResource()
return returned;
}
-void MailboxTexture::fetchTexture(gpu::gles2::MailboxManager *mailboxManager)
-{
- gpu::gles2::Texture *tex = ConsumeTexture(mailboxManager, m_target, m_resource.mailbox_holder.mailbox);
-
- // The texture might already have been deleted (e.g. when navigating away from a page).
- if (tex) {
- m_textureId = service_id(tex);
-#ifdef Q_OS_QNX
- if (m_target == GL_TEXTURE_EXTERNAL_OES) {
- m_eglStreamData = eglstream_connect_consumer(tex);
- }
-#endif
- }
-}
RectClipNode::RectClipNode(const QRectF &rect)
: m_geometry(QSGGeometry::defaultAttributes_Point2D(), 4)
@@ -429,9 +395,12 @@ void DelegatedFrameNode::preprocess()
// We can now wait for the Chromium GPU thread to produce textures that will be
// rendered on our quads and fetch the IDs from the mailboxes we were given.
QList<MailboxTexture *> mailboxesToFetch;
- Q_FOREACH (const QSharedPointer<MailboxTexture> &mailboxTexture, m_data->mailboxTextures.values())
- if (mailboxTexture->needsToFetch())
- mailboxesToFetch.append(mailboxTexture.data());
+ typedef QHash<unsigned, QSharedPointer<ResourceHolder> >::const_iterator ResourceHolderIterator;
+ ResourceHolderIterator end = m_chromiumCompositorData->resourceHolders.constEnd();
+ for (ResourceHolderIterator it = m_chromiumCompositorData->resourceHolders.constBegin(); it != end ; ++it) {
+ if ((*it)->needsToFetch())
+ mailboxesToFetch.append(static_cast<MailboxTexture *>((*it)->texture()));
+ }
if (!mailboxesToFetch.isEmpty()) {
QMap<uint32, gfx::TransferableFence> transferredFences;
@@ -442,7 +411,7 @@ void DelegatedFrameNode::preprocess()
Q_FOREACH (MailboxTexture *mailboxTexture, mailboxesToFetch) {
m_numPendingSyncPoints++;
- AddSyncPointCallbackOnGpuThread(gpuMessageLoop, syncPointManager, mailboxTexture->resource().mailbox_holder.sync_point, base::Bind(&DelegatedFrameNode::syncPointRetired, this, &mailboxesToFetch));
+ AddSyncPointCallbackOnGpuThread(gpuMessageLoop, syncPointManager, mailboxTexture->mailboxHolder().sync_point, base::Bind(&DelegatedFrameNode::syncPointRetired, this, &mailboxesToFetch));
}
m_mailboxesFetchedWaitCond.wait(&m_mutex);
@@ -452,7 +421,7 @@ void DelegatedFrameNode::preprocess()
// Tell GL to wait until Chromium is done generating resource textures on the GPU thread
// for each mailbox. We can safely start referencing those textures onto geometries afterward.
Q_FOREACH (MailboxTexture *mailboxTexture, mailboxesToFetch) {
- gfx::TransferableFence fence = transferredFences.take(mailboxTexture->resource().mailbox_holder.sync_point);
+ gfx::TransferableFence fence = transferredFences.take(mailboxTexture->mailboxHolder().sync_point);
waitChromiumSync(&fence);
deleteChromiumSync(&fence);
}
@@ -464,14 +433,19 @@ void DelegatedFrameNode::preprocess()
}
// Then render any intermediate RenderPass in order.
- Q_FOREACH (const QSharedPointer<RenderPassTexture> &renderPass, m_renderPassTextures)
- renderPass->grab();
+ typedef QPair<cc::RenderPass::Id, QSharedPointer<QSGLayer> > Pair;
+ Q_FOREACH (const Pair &pair, m_sgObjects.renderPassLayers) {
+ // The layer is non-live, request a one-time update here.
+ pair.second->scheduleUpdate();
+ // Proceed with the actual update.
+ pair.second->updateTexture();
+ }
}
-void DelegatedFrameNode::commit(DelegatedFrameNodeData* data, cc::ReturnedResourceArray *resourcesToRelease)
+void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, cc::ReturnedResourceArray *resourcesToRelease, RenderWidgetHostViewQtDelegate *apiDelegate)
{
- m_data = data;
- cc::DelegatedFrameData* frameData = m_data->frameData.get();
+ m_chromiumCompositorData = chromiumCompositorData;
+ cc::DelegatedFrameData* frameData = m_chromiumCompositorData->frameData.get();
if (!frameData)
return;
@@ -479,14 +453,15 @@ void DelegatedFrameNode::commit(DelegatedFrameNodeData* data, cc::ReturnedResour
// countering the scale of devicePixel-scaled tiles when rendering them
// to the final surface.
QMatrix4x4 matrix;
- matrix.scale(1 / m_data->frameDevicePixelRatio, 1 / m_data->frameDevicePixelRatio);
+ matrix.scale(1 / m_chromiumCompositorData->frameDevicePixelRatio, 1 / m_chromiumCompositorData->frameDevicePixelRatio);
setMatrix(matrix);
- // Keep the old texture lists around to find the ones we can re-use.
- QList<QSharedPointer<RenderPassTexture> > oldRenderPassTextures;
- m_renderPassTextures.swap(oldRenderPassTextures);
- QHash<unsigned, QSharedPointer<MailboxTexture> > mailboxTextureCandidates;
- m_data->mailboxTextures.swap(mailboxTextureCandidates);
+ // Keep the old objects in scope to hold a ref on layers, resources and textures
+ // that we can re-use. Destroy the remaining objects before returning.
+ SGObjects previousSGObjects;
+ qSwap(m_sgObjects, previousSGObjects);
+ QHash<unsigned, QSharedPointer<ResourceHolder> > resourceCandidates;
+ qSwap(m_chromiumCompositorData->resourceHolders, resourceCandidates);
// A frame's resource_list only contains the new resources to be added to the scene. Quads can
// still reference resources that were added in previous frames. Add them to the list of
@@ -494,14 +469,21 @@ void DelegatedFrameNode::commit(DelegatedFrameNodeData* data, cc::ReturnedResour
// to the producing child compositor.
for (unsigned i = 0; i < frameData->resource_list.size(); ++i) {
const cc::TransferableResource &res = frameData->resource_list.at(i);
- if (QSharedPointer<MailboxTexture> texture = mailboxTextureCandidates.value(res.id))
- texture->incImportCount();
+ if (QSharedPointer<ResourceHolder> resource = resourceCandidates.value(res.id))
+ resource->incImportCount();
else
- mailboxTextureCandidates[res.id] = QSharedPointer<MailboxTexture>(new MailboxTexture(res));
+ resourceCandidates[res.id] = QSharedPointer<ResourceHolder>(new ResourceHolder(res));
}
frameData->resource_list.clear();
+ // There is currently no way to know which and how quads changed since the last frame.
+ // We have to reconstruct the node chain with their geometries on every update.
+ // Intermediate render pass node chains are going to be destroyed when previousSGObjects
+ // goes out of scope together with any QSGLayer that could reference them.
+ while (QSGNode *oldChain = firstChild())
+ delete oldChain;
+
// The RenderPasses list is actually a tree where a parent RenderPass is connected
// to its dependencies through a RenderPass::Id reference in one or more RenderPassQuads.
// The list is already ordered with intermediate RenderPasses placed before their
@@ -515,21 +497,24 @@ void DelegatedFrameNode::commit(DelegatedFrameNodeData* data, cc::ReturnedResour
QSGNode *renderPassParent = 0;
if (pass != rootRenderPass) {
- QSharedPointer<RenderPassTexture> rpTexture = findRenderPassTexture(pass->id, oldRenderPassTextures);
- if (!rpTexture)
- rpTexture = QSharedPointer<RenderPassTexture>(new RenderPassTexture(pass->id));
- m_renderPassTextures.append(rpTexture);
- rpTexture->setRect(toQt(pass->output_rect));
- rpTexture->setFormat(pass->has_transparent_background ? GL_RGBA : GL_RGB);
- renderPassParent = rpTexture->rootNode();
+ QSharedPointer<QSGLayer> rpLayer = findRenderPassLayer(pass->id, previousSGObjects.renderPassLayers);
+ if (!rpLayer) {
+ rpLayer = QSharedPointer<QSGLayer>(apiDelegate->createLayer());
+ // Avoid any premature texture update since we need to wait
+ // for the GPU thread to produce the dependent resources first.
+ rpLayer->setLive(false);
+ }
+ QSharedPointer<QSGRootNode> rootNode(new QSGRootNode);
+ rpLayer->setRect(toQt(pass->output_rect));
+ rpLayer->setSize(toQt(pass->output_rect.size()));
+ rpLayer->setFormat(pass->has_transparent_background ? GL_RGBA : GL_RGB);
+ rpLayer->setItem(rootNode.data());
+ m_sgObjects.renderPassLayers.append(QPair<cc::RenderPass::Id, QSharedPointer<QSGLayer> >(pass->id, rpLayer));
+ m_sgObjects.renderPassRootNodes.append(rootNode);
+ renderPassParent = rootNode.data();
} else
renderPassParent = this;
- // There is currently no way to know which and how quads changed since the last frame.
- // We have to reconstruct the node chain with their geometries on every update.
- while (QSGNode *oldChain = renderPassParent->firstChild())
- delete oldChain;
-
QSGNode *renderPassChain = buildRenderPassChain(renderPassParent);
const cc::SharedQuadState *currentLayerState = 0;
QSGNode *currentLayerChain = 0;
@@ -555,37 +540,28 @@ void DelegatedFrameNode::commit(DelegatedFrameNodeData* data, cc::ReturnedResour
break;
} case cc::DrawQuad::RENDER_PASS: {
const cc::RenderPassDrawQuad *renderPassQuad = cc::RenderPassDrawQuad::MaterialCast(quad);
- QSGTexture *texture = findRenderPassTexture(renderPassQuad->render_pass_id, m_renderPassTextures).data();
+ QSGTexture *layer = findRenderPassLayer(renderPassQuad->render_pass_id, m_sgObjects.renderPassLayers).data();
// cc::GLRenderer::DrawRenderPassQuad silently ignores missing render passes.
- if (!texture)
+ if (!layer)
continue;
- QSGSimpleTextureNode *textureNode = new QSGSimpleTextureNode;
- textureNode->setRect(toQt(quad->rect));
- textureNode->setTexture(texture);
- currentLayerChain->appendChildNode(textureNode);
+ // Only QSGImageNode currently supports QSGLayer textures.
+ QSGImageNode *imageNode = apiDelegate->createImageNode();
+ imageNode->setTargetRect(toQt(quad->rect));
+ imageNode->setInnerTargetRect(toQt(quad->rect));
+ imageNode->setTexture(layer);
+ imageNode->update();
+ currentLayerChain->appendChildNode(imageNode);
break;
} case cc::DrawQuad::TEXTURE_CONTENT: {
const cc::TextureDrawQuad *tquad = cc::TextureDrawQuad::MaterialCast(quad);
- QSharedPointer<MailboxTexture> &texture = findMailboxTexture(tquad->resource_id, m_data->mailboxTextures, mailboxTextureCandidates);
-
- // FIXME: TransferableResource::size isn't always set properly for TextureDrawQuads, use the size of its DrawQuad::rect instead.
- texture->setTextureSize(toQt(quad->rect.size()));
-
- // TransferableResource::format seems to always be GL_BGRA even though it might not
- // contain any pixel with alpha < 1.0. The information about if they need blending
- // for the contents itself is actually stored in quads.
- // Tell the scene graph to enable blending for a texture only when at least one quad asks for it.
- // Do not rely on DrawQuad::ShouldDrawWithBlending() since the shared_quad_state->opacity
- // case will be handled by QtQuick by fetching this information from QSGOpacityNodes.
- if (!quad->visible_rect.IsEmpty() && !quad->opaque_rect.Contains(quad->visible_rect))
- texture->setHasAlphaChannel(true);
+ ResourceHolder *resource = findAndHoldResource(tquad->resource_id, resourceCandidates);
QSGSimpleTextureNode *textureNode = new QSGSimpleTextureNode;
textureNode->setTextureCoordinatesTransform(tquad->flipped ? QSGSimpleTextureNode::MirrorVertically : QSGSimpleTextureNode::NoTransform);
textureNode->setRect(toQt(quad->rect));
- textureNode->setFiltering(texture->resource().filter == GL_LINEAR ? QSGTexture::Linear : QSGTexture::Nearest);
- textureNode->setTexture(texture.data());
+ textureNode->setFiltering(resource->transferableResource().filter == GL_LINEAR ? QSGTexture::Linear : QSGTexture::Nearest);
+ textureNode->setTexture(initAndHoldTexture(resource, quad->ShouldDrawWithBlending(), apiDelegate));
currentLayerChain->appendChildNode(textureNode);
break;
} case cc::DrawQuad::SOLID_COLOR: {
@@ -601,46 +577,67 @@ void DelegatedFrameNode::commit(DelegatedFrameNodeData* data, cc::ReturnedResour
rectangleNode->setColor(toQt(scquad->color));
currentLayerChain->appendChildNode(rectangleNode);
break;
+ } case cc::DrawQuad::DEBUG_BORDER: {
+ const cc::DebugBorderDrawQuad *dbquad = cc::DebugBorderDrawQuad::MaterialCast(quad);
+ QSGGeometryNode *geometryNode = new QSGGeometryNode;
+
+ QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4);
+ geometry->setDrawingMode(GL_LINE_LOOP);
+ geometry->setLineWidth(dbquad->width);
+ // QSGGeometry::updateRectGeometry would actually set the corners in the following order:
+ // top-left, bottom-left, top-right, bottom-right, leading to a nice criss cross, instead
+ // of having a closed loop.
+ const gfx::Rect &r(dbquad->rect);
+ geometry->vertexDataAsPoint2D()[0].set(r.x(), r.y());
+ geometry->vertexDataAsPoint2D()[1].set(r.x() + r.width(), r.y());
+ geometry->vertexDataAsPoint2D()[2].set(r.x() + r.width(), r.y() + r.height());
+ geometry->vertexDataAsPoint2D()[3].set(r.x(), r.y() + r.height());
+ geometryNode->setGeometry(geometry);
+
+ QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
+ material->setColor(toQt(dbquad->color));
+ geometryNode->setMaterial(material);
+
+ geometryNode->setFlags(QSGNode::OwnsGeometry | QSGNode::OwnsMaterial);
+ currentLayerChain->appendChildNode(geometryNode);
+ break;
} case cc::DrawQuad::TILED_CONTENT: {
const cc::TileDrawQuad *tquad = cc::TileDrawQuad::MaterialCast(quad);
- QSharedPointer<MailboxTexture> &texture = findMailboxTexture(tquad->resource_id, m_data->mailboxTextures, mailboxTextureCandidates);
-
- if (!quad->visible_rect.IsEmpty() && !quad->opaque_rect.Contains(quad->visible_rect))
- texture->setHasAlphaChannel(true);
+ ResourceHolder *resource = findAndHoldResource(tquad->resource_id, resourceCandidates);
QSGSimpleTextureNode *textureNode = new QSGSimpleTextureNode;
textureNode->setRect(toQt(quad->rect));
- textureNode->setFiltering(texture->resource().filter == GL_LINEAR ? QSGTexture::Linear : QSGTexture::Nearest);
- textureNode->setTexture(texture.data());
-
- // FIXME: Find out if we can implement a QSGSimpleTextureNode::setSourceRect instead of this hack.
- // This has to be done at the end since many QSGSimpleTextureNode methods would overwrite this.
- QSGGeometry::updateTexturedRectGeometry(textureNode->geometry(), textureNode->rect(), textureNode->texture()->convertToNormalizedSourceRect(toQt(tquad->tex_coord_rect)));
+ textureNode->setSourceRect(toQt(tquad->tex_coord_rect));
+ textureNode->setFiltering(resource->transferableResource().filter == GL_LINEAR ? QSGTexture::Linear : QSGTexture::Nearest);
+ textureNode->setTexture(initAndHoldTexture(resource, quad->ShouldDrawWithBlending(), apiDelegate));
currentLayerChain->appendChildNode(textureNode);
break;
} case cc::DrawQuad::YUV_VIDEO_CONTENT: {
const cc::YUVVideoDrawQuad *vquad = cc::YUVVideoDrawQuad::MaterialCast(quad);
- QSharedPointer<MailboxTexture> &yTexture = findMailboxTexture(vquad->y_plane_resource_id, m_data->mailboxTextures, mailboxTextureCandidates);
- QSharedPointer<MailboxTexture> &uTexture = findMailboxTexture(vquad->u_plane_resource_id, m_data->mailboxTextures, mailboxTextureCandidates);
- QSharedPointer<MailboxTexture> &vTexture = findMailboxTexture(vquad->v_plane_resource_id, m_data->mailboxTextures, mailboxTextureCandidates);
-
- // Do not use a reference for this one, it might be null.
- QSharedPointer<MailboxTexture> aTexture;
+ ResourceHolder *yResource = findAndHoldResource(vquad->y_plane_resource_id, resourceCandidates);
+ ResourceHolder *uResource = findAndHoldResource(vquad->u_plane_resource_id, resourceCandidates);
+ ResourceHolder *vResource = findAndHoldResource(vquad->v_plane_resource_id, resourceCandidates);
+ ResourceHolder *aResource = 0;
// This currently requires --enable-vp8-alpha-playback and needs a video with alpha data to be triggered.
if (vquad->a_plane_resource_id)
- aTexture = findMailboxTexture(vquad->a_plane_resource_id, m_data->mailboxTextures, mailboxTextureCandidates);
+ aResource = findAndHoldResource(vquad->a_plane_resource_id, resourceCandidates);
- YUVVideoNode *videoNode = new YUVVideoNode(yTexture.data(), uTexture.data(), vTexture.data(), aTexture.data(), toQt(vquad->tex_coord_rect));
+ YUVVideoNode *videoNode = new YUVVideoNode(
+ initAndHoldTexture(yResource, quad->ShouldDrawWithBlending()),
+ initAndHoldTexture(uResource, quad->ShouldDrawWithBlending()),
+ initAndHoldTexture(vResource, quad->ShouldDrawWithBlending()),
+ aResource ? initAndHoldTexture(aResource, quad->ShouldDrawWithBlending()) : 0, toQt(vquad->tex_coord_rect));
videoNode->setRect(toQt(quad->rect));
currentLayerChain->appendChildNode(videoNode);
break;
#ifdef GL_OES_EGL_image_external
} case cc::DrawQuad::STREAM_VIDEO_CONTENT: {
const cc::StreamVideoDrawQuad *squad = cc::StreamVideoDrawQuad::MaterialCast(quad);
- QSharedPointer<MailboxTexture> &texture = findMailboxTexture(squad->resource_id, m_data->mailboxTextures, mailboxTextureCandidates);
+ ResourceHolder *resource = findAndHoldResource(squad->resource_id, resourceCandidates);
+ MailboxTexture *texture = static_cast<MailboxTexture *>(initAndHoldTexture(resource, quad->ShouldDrawWithBlending()));
texture->setTarget(GL_TEXTURE_EXTERNAL_OES); // since this is not default TEXTURE_2D type
- StreamVideoNode *svideoNode = new StreamVideoNode(texture.data());
+ StreamVideoNode *svideoNode = new StreamVideoNode(texture);
svideoNode->setRect(toQt(squad->rect));
svideoNode->setTextureMatrix(toQt(squad->matrix.matrix()));
currentLayerChain->appendChildNode(svideoNode);
@@ -653,8 +650,30 @@ void DelegatedFrameNode::commit(DelegatedFrameNodeData* data, cc::ReturnedResour
}
// Send resources of remaining candidates back to the child compositors so that they can be freed or reused.
- Q_FOREACH (const QSharedPointer<MailboxTexture> &mailboxTexture, mailboxTextureCandidates.values())
- resourcesToRelease->push_back(mailboxTexture->returnResource());
+ typedef QHash<unsigned, QSharedPointer<ResourceHolder> >::const_iterator ResourceHolderIterator;
+ ResourceHolderIterator end = resourceCandidates.constEnd();
+ for (ResourceHolderIterator it = resourceCandidates.constBegin(); it != end ; ++it)
+ resourcesToRelease->push_back((*it)->returnResource());
+}
+
+ResourceHolder *DelegatedFrameNode::findAndHoldResource(unsigned resourceId, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates)
+{
+ // ResourceHolders must survive when the scene graph destroys our node branch
+ QSharedPointer<ResourceHolder> &resource = m_chromiumCompositorData->resourceHolders[resourceId];
+ if (!resource)
+ resource = candidates.take(resourceId);
+ Q_ASSERT(resource);
+ return resource.data();
+}
+
+QSGTexture *DelegatedFrameNode::initAndHoldTexture(ResourceHolder *resource, bool quadIsAllOpaque, RenderWidgetHostViewQtDelegate *apiDelegate)
+{
+ // QSGTextures must be destroyed in the scene graph thread as part of the QSGNode tree,
+ // so we can't store them with the ResourceHolder in m_chromiumCompositorData.
+ // Hold them through a QSharedPointer solely on the root DelegatedFrameNode of the web view
+ // and access them through a QWeakPointer from the resource holder to find them later.
+ m_sgObjects.textureStrongRefs.append(resource->initTexture(quadIsAllOpaque, apiDelegate));
+ return m_sgObjects.textureStrongRefs.last().data();
}
void DelegatedFrameNode::fetchTexturesAndUnlockQt(DelegatedFrameNode *frameNode, QList<MailboxTexture *> *mailboxesToFetch)
diff --git a/src/core/delegated_frame_node.h b/src/core/delegated_frame_node.h
index a031a464f..b866c94b4 100644
--- a/src/core/delegated_frame_node.h
+++ b/src/core/delegated_frame_node.h
@@ -38,6 +38,7 @@
#define DELEGATED_FRAME_NODE_H
#include "base/memory/scoped_ptr.h"
+#include "cc/quads/render_pass.h"
#include "cc/resources/transferable_resource.h"
#include <QMutex>
#include <QSGNode>
@@ -46,20 +47,25 @@
#include <QWaitCondition>
#include "chromium_gpu_helper.h"
+#include "render_widget_host_view_qt_delegate.h"
+
+QT_BEGIN_NAMESPACE
+class QSGLayer;
+QT_END_NAMESPACE
namespace cc {
class DelegatedFrameData;
}
class MailboxTexture;
-class RenderPassTexture;
+class ResourceHolder;
// Separating this data allows another DelegatedFrameNode to reconstruct the QSGNode tree from the mailbox textures
// and render pass information.
-class DelegatedFrameNodeData : public QSharedData {
+class ChromiumCompositorData : public QSharedData {
public:
- DelegatedFrameNodeData() : frameDevicePixelRatio(1) { }
- QHash<unsigned, QSharedPointer<MailboxTexture> > mailboxTextures;
+ ChromiumCompositorData() : frameDevicePixelRatio(1) { }
+ QHash<unsigned, QSharedPointer<ResourceHolder> > resourceHolders;
scoped_ptr<cc::DelegatedFrameData> frameData;
qreal frameDevicePixelRatio;
};
@@ -69,20 +75,27 @@ public:
DelegatedFrameNode();
~DelegatedFrameNode();
void preprocess();
- void commit(DelegatedFrameNodeData* data, cc::ReturnedResourceArray *resourcesToRelease);
+ void commit(ChromiumCompositorData *chromiumCompositorData, cc::ReturnedResourceArray *resourcesToRelease, RenderWidgetHostViewQtDelegate *apiDelegate);
private:
- QExplicitlySharedDataPointer<DelegatedFrameNodeData> m_data;
- QList<QSharedPointer<RenderPassTexture> > m_renderPassTextures;
- int m_numPendingSyncPoints;
- QMap<uint32, gfx::TransferableFence> m_mailboxGLFences;
- QWaitCondition m_mailboxesFetchedWaitCond;
- QMutex m_mutex;
-
// Making those callbacks static bypasses base::Bind's ref-counting requirement
// of the this pointer when the callback is a method.
static void fetchTexturesAndUnlockQt(DelegatedFrameNode *frameNode, QList<MailboxTexture *> *mailboxesToFetch);
static void syncPointRetired(DelegatedFrameNode *frameNode, QList<MailboxTexture *> *mailboxesToFetch);
+
+ ResourceHolder *findAndHoldResource(unsigned resourceId, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates);
+ QSGTexture *initAndHoldTexture(ResourceHolder *resource, bool quadIsAllOpaque, RenderWidgetHostViewQtDelegate *apiDelegate = 0);
+
+ QExplicitlySharedDataPointer<ChromiumCompositorData> m_chromiumCompositorData;
+ struct SGObjects {
+ QList<QPair<cc::RenderPass::Id, QSharedPointer<QSGLayer> > > renderPassLayers;
+ QList<QSharedPointer<QSGRootNode> > renderPassRootNodes;
+ QList<QSharedPointer<QSGTexture> > textureStrongRefs;
+ } m_sgObjects;
+ int m_numPendingSyncPoints;
+ QMap<uint32, gfx::TransferableFence> m_mailboxGLFences;
+ QWaitCondition m_mailboxesFetchedWaitCond;
+ QMutex m_mutex;
};
#endif // DELEGATED_FRAME_NODE_H
diff --git a/src/core/dev_tools_http_handler_delegate_qt.cpp b/src/core/dev_tools_http_handler_delegate_qt.cpp
index 4f8992dab..1bb8ec1f1 100644
--- a/src/core/dev_tools_http_handler_delegate_qt.cpp
+++ b/src/core/dev_tools_http_handler_delegate_qt.cpp
@@ -34,6 +34,10 @@
**
****************************************************************************/
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
#include "dev_tools_http_handler_delegate_qt.h"
#include <QByteArray>
@@ -42,16 +46,90 @@
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/devtools_http_handler.h"
#include "content/public/browser/devtools_target.h"
+#include "content/public/browser/favicon_status.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/content_switches.h"
#include "net/socket/stream_listen_socket.h"
#include "net/socket/tcp_listen_socket.h"
using namespace content;
+namespace {
+
+const char kTargetTypePage[] = "page";
+
+class Target : public content::DevToolsTarget {
+public:
+ explicit Target(WebContents* web_contents);
+
+ virtual std::string GetId() const OVERRIDE { return id_; }
+ virtual std::string GetParentId() const OVERRIDE { return std::string(); }
+ virtual std::string GetType() const OVERRIDE { return kTargetTypePage; }
+ virtual std::string GetTitle() const OVERRIDE { return title_; }
+ virtual std::string GetDescription() const OVERRIDE { return std::string(); }
+ virtual GURL GetURL() const OVERRIDE { return url_; }
+ virtual GURL GetFaviconURL() const OVERRIDE { return favicon_url_; }
+ virtual base::TimeTicks GetLastActivityTime() const OVERRIDE {
+ return last_activity_time_;
+ }
+ virtual bool IsAttached() const OVERRIDE {
+ return agent_host_->IsAttached();
+ }
+ virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() const OVERRIDE {
+ return agent_host_;
+ }
+ virtual bool Activate() const OVERRIDE;
+ virtual bool Close() const OVERRIDE;
+
+private:
+ scoped_refptr<DevToolsAgentHost> agent_host_;
+ std::string id_;
+ std::string title_;
+ GURL url_;
+ GURL favicon_url_;
+ base::TimeTicks last_activity_time_;
+};
+
+Target::Target(WebContents* web_contents) {
+ agent_host_ = DevToolsAgentHost::GetOrCreateFor(web_contents->GetRenderViewHost());
+ id_ = agent_host_->GetId();
+ title_ = base::UTF16ToUTF8(web_contents->GetTitle());
+ url_ = web_contents->GetURL();
+ content::NavigationController& controller = web_contents->GetController();
+ content::NavigationEntry* entry = controller.GetActiveEntry();
+ if (entry != NULL && entry->GetURL().is_valid())
+ favicon_url_ = entry->GetFavicon().url;
+ last_activity_time_ = web_contents->GetLastActiveTime();
+}
+
+bool Target::Activate() const {
+ RenderViewHost* rvh = agent_host_->GetRenderViewHost();
+ if (!rvh)
+ return false;
+ WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
+ if (!web_contents)
+ return false;
+ web_contents->GetDelegate()->ActivateContents(web_contents);
+ return true;
+}
+
+bool Target::Close() const {
+ RenderViewHost* rvh = agent_host_->GetRenderViewHost();
+ if (!rvh)
+ return false;
+ rvh->ClosePage();
+ return true;
+}
+
+} // namespace
+
DevToolsHttpHandlerDelegateQt::DevToolsHttpHandlerDelegateQt(BrowserContext* browser_context)
: m_browserContext(browser_context)
{
@@ -107,7 +185,14 @@ scoped_ptr<DevToolsTarget> DevToolsHttpHandlerDelegateQt::CreateNewTarget(const
void DevToolsHttpHandlerDelegateQt::EnumerateTargets(TargetCallback callback)
{
- callback.Run(TargetList());
+ TargetList targets;
+ std::vector<RenderViewHost*> rvh_list = content::DevToolsAgentHost::GetValidRenderViewHosts();
+ for (std::vector<RenderViewHost*>::iterator it = rvh_list.begin(); it != rvh_list.end(); ++it) {
+ WebContents* web_contents = WebContents::FromRenderViewHost(*it);
+ if (web_contents)
+ targets.push_back(new Target(web_contents));
+ }
+ callback.Run(targets);
}
scoped_ptr<net::StreamListenSocket> DevToolsHttpHandlerDelegateQt::CreateSocketForTethering(net::StreamListenSocket::Delegate* delegate, std::string* name)
diff --git a/src/core/location_provider_qt.cpp b/src/core/location_provider_qt.cpp
new file mode 100644
index 000000000..cdc9f1a44
--- /dev/null
+++ b/src/core/location_provider_qt.cpp
@@ -0,0 +1,248 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "location_provider_qt.h"
+
+#include <math.h>
+
+#include "type_conversion.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QThread>
+#include <QtPositioning/QGeoPositionInfoSource>
+
+#include "base/message_loop/message_loop.h"
+#include "base/bind.h"
+#include "content/browser/geolocation/geolocation_provider_impl.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/geolocation_provider.h"
+
+using content::BrowserThread;
+
+class QtPositioningHelper : public QObject {
+ Q_OBJECT
+public:
+ QtPositioningHelper(LocationProviderQt *provider);
+ ~QtPositioningHelper();
+
+ bool start(bool highAccuracy);
+ void stop();
+ void refresh();
+
+private Q_SLOTS:
+ void updatePosition(const QGeoPositionInfo &);
+ void error(QGeoPositionInfoSource::Error positioningError);
+ void timeout();
+
+private:
+ LocationProviderQt *m_locationProvider;
+ QGeoPositionInfoSource *m_positionInfoSource;
+
+ void postToLocationProvider(const base::Closure &task);
+};
+
+QtPositioningHelper::QtPositioningHelper(LocationProviderQt *provider)
+ : m_locationProvider(provider)
+ , m_positionInfoSource(0)
+{
+ Q_ASSERT(provider);
+}
+
+QtPositioningHelper::~QtPositioningHelper()
+{
+ m_locationProvider->m_positioningHelper = 0;
+}
+
+bool QtPositioningHelper::start(bool highAccuracy)
+{
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ Q_UNUSED(highAccuracy);
+ // FIXME: go through availableSources until one supports QGeoPositionInfoSource::SatellitePositioningMethods
+ // for the highAccuracy case.
+ m_positionInfoSource = QGeoPositionInfoSource::createDefaultSource(this);
+ if (!m_positionInfoSource)
+ return false;
+
+ connect(m_positionInfoSource, &QGeoPositionInfoSource::positionUpdated, this, &QtPositioningHelper::updatePosition);
+ // disambiguate the error getter and the signal in QGeoPositionInfoSource.
+ connect(m_positionInfoSource, static_cast<void (QGeoPositionInfoSource::*)(QGeoPositionInfoSource::Error)>(&QGeoPositionInfoSource::error)
+ , this, &QtPositioningHelper::error);
+ connect(m_positionInfoSource, &QGeoPositionInfoSource::updateTimeout, this, &QtPositioningHelper::timeout);
+
+ m_positionInfoSource->startUpdates();
+ return true;
+}
+
+void QtPositioningHelper::stop()
+{
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!m_positionInfoSource)
+ return;
+ m_positionInfoSource->stopUpdates();
+}
+
+void QtPositioningHelper::refresh()
+{
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!m_positionInfoSource)
+ return;
+ m_positionInfoSource->stopUpdates();
+}
+
+void QtPositioningHelper::updatePosition(const QGeoPositionInfo &pos)
+{
+ if (!pos.isValid())
+ return;
+ Q_ASSERT(m_positionInfoSource->error() == QGeoPositionInfoSource::NoError);
+ content::Geoposition newPos;
+ newPos.error_code = content::Geoposition::ERROR_CODE_NONE;
+ newPos.error_message.clear();
+
+ newPos.timestamp = toTime(pos.timestamp());
+ newPos.latitude = pos.coordinate().latitude();
+ newPos.longitude = pos.coordinate().longitude();
+
+ const double altitude = pos.coordinate().altitude();
+ if (!qIsNaN(altitude))
+ newPos.altitude = altitude;
+
+ // Chromium's geoposition needs a valid (as in >=0.) accuracy field.
+ // try and get an accuracy estimate from QGeoPositionInfo.
+ // If we don't have any accuracy info, 100m seems a pesimistic enough default.
+ if (!pos.hasAttribute(QGeoPositionInfo::VerticalAccuracy) && !pos.hasAttribute(QGeoPositionInfo::HorizontalAccuracy))
+ newPos.accuracy = 100;
+ else {
+ const double vAccuracy = pos.hasAttribute(QGeoPositionInfo::VerticalAccuracy) ? pos.attribute(QGeoPositionInfo::VerticalAccuracy) : 0;
+ const double hAccuracy = pos.hasAttribute(QGeoPositionInfo::HorizontalAccuracy) ? pos.attribute(QGeoPositionInfo::HorizontalAccuracy) : 0;
+ newPos.accuracy = sqrt(vAccuracy * vAccuracy + hAccuracy * hAccuracy);
+ }
+
+ // And now the "nice to have" fields (-1 means invalid).
+ newPos.speed = pos.hasAttribute(QGeoPositionInfo::GroundSpeed) ? pos.attribute(QGeoPositionInfo::GroundSpeed) : -1;
+ newPos.heading = pos.hasAttribute(QGeoPositionInfo::Direction) ? pos.attribute(QGeoPositionInfo::Direction) : -1;
+
+ postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, base::Unretained(m_locationProvider), newPos));
+}
+
+void QtPositioningHelper::error(QGeoPositionInfoSource::Error positioningError)
+{
+ Q_ASSERT(positioningError != QGeoPositionInfoSource::NoError);
+ content::Geoposition newPos;
+ switch (positioningError) {
+ case QGeoPositionInfoSource::AccessError:
+ newPos.error_code = content::Geoposition::ERROR_CODE_PERMISSION_DENIED;
+ break;
+ case QGeoPositionInfoSource::ClosedError:
+ case QGeoPositionInfoSource::UnknownSourceError: // position unavailable is as good as it gets in Geoposition
+ default:
+ newPos.error_code = content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
+ break;
+ }
+ postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, base::Unretained(m_locationProvider), newPos));
+}
+
+void QtPositioningHelper::timeout()
+{
+ content::Geoposition newPos;
+ // content::Geoposition::ERROR_CODE_TIMEOUT is not handled properly in the renderer process, and the timeout
+ // argument used in JS never comes all the way to the browser process.
+ // Let's just treat it like any other error where the position is unavailable.
+ newPos.error_code = content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
+ postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, base::Unretained(m_locationProvider), newPos));
+}
+
+inline void QtPositioningHelper::postToLocationProvider(const base::Closure &task)
+{
+ LocationProviderQt::messageLoop()->PostTask(FROM_HERE, task);
+}
+
+#include "location_provider_qt.moc"
+
+LocationProviderQt::LocationProviderQt()
+ : m_positioningHelper(0)
+{
+}
+
+LocationProviderQt::~LocationProviderQt()
+{
+ m_positioningHelper->deleteLater();
+}
+
+bool LocationProviderQt::StartProvider(bool highAccuracy)
+{
+ DCHECK(base::MessageLoop::current() == messageLoop());
+ QThread *guiThread = qApp->thread();
+ if (!m_positioningHelper) {
+ m_positioningHelper = new QtPositioningHelper(this);
+ m_positioningHelper->moveToThread(guiThread);
+ }
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(base::IgnoreResult(&QtPositioningHelper::start)
+ , base::Unretained(m_positioningHelper), highAccuracy));
+ return true;
+}
+
+void LocationProviderQt::StopProvider()
+{
+ DCHECK(base::MessageLoop::current() == messageLoop());
+ if (m_positioningHelper)
+ BrowserThread::PostTask(BrowserThread::UI,FROM_HERE, base::Bind(&QtPositioningHelper::stop
+ , base::Unretained(m_positioningHelper)));
+}
+
+void LocationProviderQt::RequestRefresh()
+{
+ DCHECK(base::MessageLoop::current() == messageLoop());
+ if (m_positioningHelper)
+ BrowserThread::PostTask(BrowserThread::UI,FROM_HERE, base::Bind(&QtPositioningHelper::refresh
+ , base::Unretained(m_positioningHelper)));
+}
+
+void LocationProviderQt::OnPermissionGranted()
+{
+ RequestRefresh();
+}
+
+void LocationProviderQt::updatePosition(const content::Geoposition &position)
+{
+ DCHECK(base::MessageLoop::current() == messageLoop());
+ m_lastKnownPosition = position;
+ NotifyCallback(position);
+}
+
+base::MessageLoop *LocationProviderQt::messageLoop()
+{
+ return static_cast<content::GeolocationProviderImpl*>(content::GeolocationProvider::GetInstance())->message_loop();
+}
diff --git a/src/core/location_provider_qt.h b/src/core/location_provider_qt.h
new file mode 100644
index 000000000..c3e462092
--- /dev/null
+++ b/src/core/location_provider_qt.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LOCATION_PROVIDER_QT_H
+#define LOCATION_PROVIDER_QT_H
+
+#include <QtCore/qcompilerdetection.h>
+
+#include "content/browser/geolocation/location_provider_base.h"
+#include "content/public/common/geoposition.h"
+
+QT_FORWARD_DECLARE_CLASS(QThread)
+class QtPositioningHelper;
+
+namespace base {
+class MessageLoop;
+}
+
+class LocationProviderQt : public content::LocationProviderBase
+{
+public:
+ LocationProviderQt();
+ virtual ~LocationProviderQt();
+
+ // LocationProviderBase
+ virtual bool StartProvider(bool highAccuracy) Q_DECL_OVERRIDE;
+ virtual void StopProvider() Q_DECL_OVERRIDE;
+ virtual void GetPosition(content::Geoposition *position) Q_DECL_OVERRIDE { *position = m_lastKnownPosition; }
+ virtual void RequestRefresh() Q_DECL_OVERRIDE;
+ virtual void OnPermissionGranted() Q_DECL_OVERRIDE;
+
+private:
+ friend class QtPositioningHelper;
+
+ static base::MessageLoop *messageLoop();
+ void updatePosition(const content::Geoposition &);
+
+ content::Geoposition m_lastKnownPosition;
+ QtPositioningHelper *m_positioningHelper;
+};
+//#define QT_USE_POSITIONING 1
+
+#endif // LOCATION_PROVIDER_QT_H
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index c221e94e3..fec9caabc 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -189,7 +189,7 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost* widget
: m_host(content::RenderWidgetHostImpl::From(widget))
, m_gestureProvider(QtGestureProviderConfig(), this)
, m_sendMotionActionDown(false)
- , m_frameNodeData(new DelegatedFrameNodeData)
+ , m_chromiumCompositorData(new ChromiumCompositorData)
, m_needsDelegatedFrameAck(false)
, m_didFirstVisuallyNonEmptyLayout(false)
, m_adapterClient(0)
@@ -594,14 +594,14 @@ void RenderWidgetHostViewQt::OnSwapCompositorFrame(uint32 output_surface_id, sco
m_needsDelegatedFrameAck = true;
m_pendingOutputSurfaceId = output_surface_id;
Q_ASSERT(frame->delegated_frame_data);
- Q_ASSERT(!m_frameNodeData->frameData || m_frameNodeData->frameData->resource_list.empty());
- m_frameNodeData->frameData = frame->delegated_frame_data.Pass();
- m_frameNodeData->frameDevicePixelRatio = frame->metadata.device_scale_factor;
+ Q_ASSERT(!m_chromiumCompositorData->frameData || m_chromiumCompositorData->frameData->resource_list.empty());
+ m_chromiumCompositorData->frameData = frame->delegated_frame_data.Pass();
+ m_chromiumCompositorData->frameDevicePixelRatio = frame->metadata.device_scale_factor;
// Support experimental.viewport.devicePixelRatio, see GetScreenInfo implementation below.
float dpiScale = this->dpiScale();
if (dpiScale != 0 && dpiScale != 1)
- m_frameNodeData->frameDevicePixelRatio /= dpiScale;
+ m_chromiumCompositorData->frameDevicePixelRatio /= dpiScale;
m_delegate->update();
@@ -661,7 +661,7 @@ QSGNode *RenderWidgetHostViewQt::updatePaintNode(QSGNode *oldNode)
if (!frameNode)
frameNode = new DelegatedFrameNode;
- frameNode->commit(m_frameNodeData.data(), &m_resourcesToRelease);
+ frameNode->commit(m_chromiumCompositorData.data(), &m_resourcesToRelease, m_delegate.get());
// This is possibly called from the Qt render thread, post the ack back to the UI
// to tell the child compositors to release resources and trigger a new frame.
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index d4a3ff248..fdb43dcae 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -235,7 +235,7 @@ private:
QMap<int, int> m_touchIdMapping;
scoped_ptr<RenderWidgetHostViewQtDelegate> m_delegate;
- QExplicitlySharedDataPointer<DelegatedFrameNodeData> m_frameNodeData;
+ QExplicitlySharedDataPointer<ChromiumCompositorData> m_chromiumCompositorData;
cc::ReturnedResourceArray m_resourcesToRelease;
bool m_needsDelegatedFrameAck;
bool m_didFirstVisuallyNonEmptyLayout;
diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h
index 3f6d9caac..0fb3d1d5f 100644
--- a/src/core/render_widget_host_view_qt_delegate.h
+++ b/src/core/render_widget_host_view_qt_delegate.h
@@ -46,7 +46,10 @@ QT_BEGIN_NAMESPACE
class QCursor;
class QEvent;
class QPainter;
+class QSGImageNode;
+class QSGLayer;
class QSGNode;
+class QSGTexture;
class QVariant;
class QWindow;
class QInputMethodEvent;
@@ -78,6 +81,9 @@ public:
virtual void hide() = 0;
virtual bool isVisible() const = 0;
virtual QWindow* window() const = 0;
+ virtual QSGTexture *createTextureFromImage(const QImage &) = 0;
+ virtual QSGLayer *createLayer() = 0;
+ virtual QSGImageNode *createImageNode() = 0;
virtual void update() = 0;
virtual void updateCursor(const QCursor &) = 0;
virtual void resize(int width, int height) = 0;
diff --git a/src/core/resources/devtools_discovery_page.html b/src/core/resources/devtools_discovery_page.html
index 79463cc16..7aac74932 100644
--- a/src/core/resources/devtools_discovery_page.html
+++ b/src/core/resources/devtools_discovery_page.html
@@ -1,18 +1,55 @@
-<!--
-Copyright (c) 2013 BlackBerry Limited. All rights reserved.
--->
<html>
<head>
-<title>QtWebEngine remote debugging</title>
+<title>QtWebEngine Remote Debugging</title>
<style>
+body {
+ background-color: rgb(245, 245, 245);
+ font-family: Helvetica, Arial, sans-serif;
+ text-shadow: rgba(255, 255, 255, 0.496094) 0px 1px 0px;
+}
+
+#caption {
+ color: black;
+ font-size: 16px;
+ margin-top: 30px;
+ margin-bottom: 0px;
+ margin-left: 70px;
+ height: 20px;
+ text-align: left;
+}
+
+#items {
+ margin-left: 60px;
+ margin-right: 60px;
+ -webkit-box-orient: horizontal;
+ -webkit-box-lines: multiple;
+}
+
+.frontend_ref {
+ color: black;
+ text-decoration: initial;
+}
+
+.text {
+ background: no-repeat 0;
+ background-size: 16px;
+ font-size: 12px;
+ margin: 4px 0px 0px 4px;
+ overflow: hidden;
+ padding: 2px 0px 0px 20px;
+ text-align: left;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
</style>
<script>
+
function onLoad() {
- var tabs_list_request = new XMLHttpRequest();
- tabs_list_request.open('GET', '/json/list?t=' + new Date().getTime(), true);
- tabs_list_request.onreadystatechange = onReady;
- tabs_list_request.send();
+ var tabsListRequest = new XMLHttpRequest();
+ tabsListRequest.open('GET', '/json/list', true);
+ tabsListRequest.onreadystatechange = onReady;
+ tabsListRequest.send();
}
function onReady() {
@@ -24,23 +61,35 @@ function onReady() {
}
}
+function overrideFrontendUrl(item) {
+ if (window.location.hash) {
+ var overridden_url = window.location.hash.substr(1);
+ var ws_suffix = item.webSocketDebuggerUrl.replace('ws://', 'ws=');
+ if (overridden_url.indexOf('?') == -1)
+ return overridden_url + '?' + ws_suffix;
+ else
+ return overridden_url + '&' + ws_suffix;
+ }
+ return item.devtoolsFrontendUrl;
+}
+
function appendItem(item_object) {
var frontend_ref;
if (item_object.devtoolsFrontendUrl) {
frontend_ref = document.createElement('a');
- frontend_ref.href = item_object.devtoolsFrontendUrl;
+ frontend_ref.href = overrideFrontendUrl(item_object);
frontend_ref.title = item_object.title;
} else {
frontend_ref = document.createElement('div');
- frontend_ref.title = 'The tab already has active debugging session';
+ frontend_ref.title = 'The tab already has an active debug session';
}
+ frontend_ref.className = 'frontend_ref';
var text = document.createElement('div');
- if (item_object.title)
- text.innerText = item_object.title;
- else
- text.innerText = '(untitled tab)';
- text.style.cssText = 'background-image:url(' + item_object.faviconUrl + ')';
+ text.className = 'text';
+ text.innerText = item_object.description || item_object.title;
+ text.style.cssText = 'background-image:url(' +
+ item_object.faviconUrl + ')';
frontend_ref.appendChild(text);
var item = document.createElement('p');
@@ -51,7 +100,9 @@ function appendItem(item_object) {
</script>
</head>
<body onload='onLoad()'>
- <div id='caption'>Inspectable WebContents</div>
- <div id='items'></div>
+ <div id='caption'>Inspectable pages</div>
+ <div id='items'>
+ </div>
+ <hr>
</body>
</html>
diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h
index 9d9cdd675..f88e5dd21 100644
--- a/src/core/type_conversion.h
+++ b/src/core/type_conversion.h
@@ -135,6 +135,10 @@ inline QDateTime toQt(base::Time time)
return QDateTime::fromMSecsSinceEpoch(time.ToJavaTime());
}
+inline base::Time toTime(const QDateTime &dateTime) {
+ return base::Time::FromInternalValue(dateTime.toMSecsSinceEpoch());
+}
+
inline base::FilePath::StringType toFilePathString(const QString &str)
{
#if defined(OS_WIN)
@@ -150,7 +154,7 @@ inline base::FilePath toFilePath(const QString &str)
}
template <typename T>
-inline T fileListingHelper(const QString &) {qFatal("Specialization missing for %s.", Q_FUNC_INFO);}
+inline T fileListingHelper(const QString &) {qFatal("Specialization missing for %s.", Q_FUNC_INFO); return T(); }
template <>
inline ui::SelectedFileInfo fileListingHelper<ui::SelectedFileInfo>(const QString &file)
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 3f223f733..678b558c1 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -41,6 +41,7 @@
#include "web_contents_adapter.h"
#include "web_contents_adapter_p.h"
+#include "browser_context_adapter.h"
#include "browser_context_qt.h"
#include "content_browser_client_qt.h"
#include "javascript_dialog_manager_qt.h"
@@ -175,9 +176,8 @@ static QStringList listRecursively(const QDir& dir) {
return ret;
}
-static content::WebContents *createBlankWebContents(WebContentsAdapterClient *adapterClient)
+static content::WebContents *createBlankWebContents(WebContentsAdapterClient *adapterClient, content::BrowserContext *browserContext)
{
- content::BrowserContext* browserContext = ContentBrowserClientQt::Get()->browser_context();
content::WebContents::CreateParams create_params(browserContext, NULL);
create_params.routing_id = MSG_ROUTING_NONE;
create_params.initial_size = gfx::Size(kTestWindowWidth, kTestWindowHeight);
@@ -222,7 +222,7 @@ static void serializeNavigationHistory(const content::NavigationController &cont
}
}
-void deserializeNavigationHistory(QDataStream &input, int *currentIndex, std::vector<content::NavigationEntry*> *entries)
+void deserializeNavigationHistory(QDataStream &input, int *currentIndex, std::vector<content::NavigationEntry*> *entries, content::BrowserContext *browserContext)
{
int version;
input >> version;
@@ -278,7 +278,7 @@ void deserializeNavigationHistory(QDataStream &input, int *currentIndex, std::ve
false,
// The extra headers are not sync'ed across sessions.
std::string(),
- ContentBrowserClientQt::Get()->browser_context());
+ browserContext);
entry->SetTitle(toString16(title));
entry->SetPageState(content::PageState::CreateFromEncodedData(std::string(pageState.data(), pageState.size())));
@@ -308,13 +308,13 @@ QExplicitlySharedDataPointer<WebContentsAdapter> WebContentsAdapter::createFromS
{
int currentIndex;
std::vector<content::NavigationEntry*> entries;
- deserializeNavigationHistory(input, &currentIndex, &entries);
+ deserializeNavigationHistory(input, &currentIndex, &entries, adapterClient->browserContextAdapter()->browserContext());
if (currentIndex == -1)
return QExplicitlySharedDataPointer<WebContentsAdapter>();
// Unlike WebCore, Chromium only supports Restoring to a new WebContents instance.
- content::WebContents* newWebContents = createBlankWebContents(adapterClient);
+ content::WebContents* newWebContents = createBlankWebContents(adapterClient, adapterClient->browserContextAdapter()->browserContext());
content::NavigationController &controller = newWebContents->GetController();
controller.Restore(currentIndex, content::NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY, &entries);
@@ -350,7 +350,7 @@ void WebContentsAdapter::initialize(WebContentsAdapterClient *adapterClient)
// Create our own if a WebContents wasn't provided at construction.
if (!d->webContents)
- d->webContents.reset(createBlankWebContents(adapterClient));
+ d->webContents.reset(createBlankWebContents(adapterClient, adapterClient->browserContextAdapter()->browserContext()));
// This might replace any adapter that has been initialized with this WebEngineSettings.
adapterClient->webEngineSettings()->setWebContentsAdapter(this);
@@ -625,7 +625,13 @@ qreal WebContentsAdapter::currentZoomFactor() const
void WebContentsAdapter::enableInspector(bool enable)
{
- ContentBrowserClientQt::Get()->enableInspector(enable);
+ ContentBrowserClientQt::Get()->enableInspector(enable, browserContext());
+}
+
+BrowserContextQt* WebContentsAdapter::browserContext()
+{
+ Q_D(WebContentsAdapter);
+ return static_cast<BrowserContextQt*>(d->webContents->GetBrowserContext());
}
QAccessibleInterface *WebContentsAdapter::browserAccessible()
@@ -724,6 +730,12 @@ void WebContentsAdapter::grantMediaAccessPermission(const QUrl &securityOrigin,
MediaCaptureDevicesDispatcher::GetInstance()->handleMediaAccessPermissionResponse(d->webContents.get(), securityOrigin, flags);
}
+void WebContentsAdapter::runGeolocationRequestCallback(const QUrl &securityOrigin, bool allowed)
+{
+ Q_D(WebContentsAdapter);
+ d->webContentsDelegate->m_lastGeolocationRequestCallbacks.first.Run(allowed);
+}
+
void WebContentsAdapter::dpiScaleChanged()
{
Q_D(WebContentsAdapter);
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 6bec50316..18542d039 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -48,6 +48,7 @@
namespace content {
class WebContents;
}
+class BrowserContextQt;
class WebContentsAdapterPrivate;
struct WebPreferences;
@@ -108,14 +109,17 @@ public:
void wasShown();
void wasHidden();
void grantMediaAccessPermission(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags flags);
+ void runGeolocationRequestCallback(const QUrl &securityOrigin, bool allowed);
void dpiScaleChanged();
QAccessibleInterface *browserAccessible();
+ BrowserContextQt* browserContext();
private:
Q_DISABLE_COPY(WebContentsAdapter);
Q_DECLARE_PRIVATE(WebContentsAdapter);
QScopedPointer<WebContentsAdapterPrivate> d_ptr;
+
friend class WebContentsDelegateQt;
};
#endif // WEB_CONTENTS_ADAPTER_H
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 8fd401fe4..df2039ba6 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -48,6 +48,7 @@
QT_FORWARD_DECLARE_CLASS(QVariant)
+class BrowserContextAdapter;
class CertificateErrorController;
class JavaScriptDialogController;
class RenderWidgetHostViewQt;
@@ -171,11 +172,14 @@ public:
virtual QObject *accessibilityParentObject() = 0;
virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) = 0;
virtual void authenticationRequired(const QUrl &requestUrl, const QString &realm, bool isProxy, const QString &challengingHost, QString *outUser, QString *outPassword) = 0;
+ virtual void runGeolocationPermissionRequest(const QUrl &securityOrigin) = 0;
virtual void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) = 0;
virtual WebEngineSettings *webEngineSettings() const = 0;
virtual void allowCertificateError(const QExplicitlySharedDataPointer<CertificateErrorController> &errorController) = 0;
+ virtual BrowserContextAdapter* browserContextAdapter() = 0;
+
};
#endif // WEB_CONTENTS_ADAPTER_CLIENT_H
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index c2cccfedb..46830f865 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -40,6 +40,7 @@
#include "web_contents_delegate_qt.h"
+#include "browser_context_adapter.h"
#include "media_capture_devices_dispatcher.h"
#include "type_conversion.h"
#include "web_contents_adapter_client.h"
@@ -270,7 +271,7 @@ void WebContentsDelegateQt::DidNavigateAnyFrame(const content::LoadCommittedDeta
{
if (!params.should_update_history)
return;
- WebEngineContext::current()->visitedLinksManager()->addUrl(params.url);
+ m_viewClient->browserContextAdapter()->visitedLinksManager()->addUrl(params.url);
}
@@ -300,3 +301,9 @@ void WebContentsDelegateQt::allowCertificateError(const QExplicitlySharedDataPoi
{
m_viewClient->allowCertificateError(errorController);
}
+
+void WebContentsDelegateQt::requestGeolocationPermission(const GURL &requestingFrameOrigin, base::Callback<void (bool)> resultCallback, base::Closure *cancelCallback)
+{
+ m_lastGeolocationRequestCallbacks = qMakePair(resultCallback, cancelCallback);
+ m_viewClient->runGeolocationPermissionRequest(toQt(requestingFrameOrigin));
+}
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index 2ab5fc8cd..29a548f47 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -40,6 +40,8 @@
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
+#include "base/callback.h"
+
#include "javascript_dialog_manager_qt.h"
#include <QtCore/qcompilerdetection.h>
@@ -88,7 +90,9 @@ public:
void overrideWebPreferences(content::WebContents *, WebPreferences*);
void allowCertificateError(const QExplicitlySharedDataPointer<CertificateErrorController> &) ;
+ void requestGeolocationPermission(const GURL &requestingFrameOrigin, base::Callback<void (bool)> resultCallback, base::Closure *cancelCallback);
+ QPair<base::Callback<void (bool)>, base::Closure*> m_lastGeolocationRequestCallbacks;
private:
WebContentsAdapter *createWindow(content::WebContents *new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture);
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index ac9a921e7..b17ee124c 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -65,6 +65,7 @@
#include "content/public/app/startup_helper_win.h"
#endif // OS_WIN
+#include "browser_context_adapter.h"
#include "content_browser_client_qt.h"
#include "content_client_qt.h"
#include "content_main_delegate_qt.h"
@@ -73,7 +74,7 @@
#include "type_conversion.h"
#include "surface_factory_qt.h"
#include "web_engine_library_info.h"
-#include "web_engine_visited_links_manager.h"
+#include <QFileInfo>
#include <QGuiApplication>
#include <QOpenGLContext>
#include <QStringList>
@@ -89,6 +90,37 @@ void destroyContext()
sContext = 0;
}
+bool usingSoftwareDynamicGL()
+{
+#if defined(Q_OS_WIN)
+ HMODULE handle = static_cast<HMODULE>(QOpenGLContext::openGLModuleHandle());
+ wchar_t path[MAX_PATH];
+ DWORD size = GetModuleFileName(handle, path, MAX_PATH);
+ QFileInfo openGLModule(QString::fromWCharArray(path, size));
+ return openGLModule.fileName() == QLatin1String("opengl32sw.dll");
+#else
+ return false;
+#endif
+}
+
+bool usingQtQuick2DRenderer()
+{
+ const QStringList args = QGuiApplication::arguments();
+ QString device;
+ for (int index = 0; index < args.count(); ++index) {
+ if (args.at(index).startsWith(QLatin1String("--device="))) {
+ device = args.at(index).mid(9);
+ break;
+ }
+ }
+
+ if (device.isEmpty())
+ device = QString::fromLocal8Bit(qgetenv("QMLSCENE_DEVICE"));
+
+ // This assumes that the plugin is installed and is going to be used by QtQuick.
+ return device == QLatin1String("softwarecontext");
+}
+
} // namespace
WebEngineContext::~WebEngineContext()
@@ -107,9 +139,18 @@ scoped_refptr<WebEngineContext> WebEngineContext::current()
return sContext;
}
-WebEngineVisitedLinksManager *WebEngineContext::visitedLinksManager()
+BrowserContextAdapter* WebEngineContext::defaultBrowserContext()
{
- return m_visitedLinksManager.get();
+ if (!m_defaultBrowserContext)
+ m_defaultBrowserContext.reset(new BrowserContextAdapter(QStringLiteral("Default"), false));
+ return m_defaultBrowserContext.get();
+}
+
+BrowserContextAdapter* WebEngineContext::offTheRecordBrowserContext()
+{
+ if (!m_offTheRecordBrowserContext)
+ m_offTheRecordBrowserContext.reset(new BrowserContextAdapter(QStringLiteral("OTR"), true));
+ return m_offTheRecordBrowserContext.get();
}
#ifndef CHROMIUM_VERSION
@@ -176,16 +217,20 @@ WebEngineContext::WebEngineContext()
GLContextHelper::initialize();
- const char *glType;
- switch (QOpenGLContext::currentContext()->openGLModuleType()) {
- case QOpenGLContext::LibGL:
- glType = gfx::kGLImplementationDesktopName;
- break;
- case QOpenGLContext::LibGLES:
- glType = gfx::kGLImplementationEGLName;
- break;
+ if (usingSoftwareDynamicGL() || usingQtQuick2DRenderer()) {
+ parsedCommandLine->AppendSwitch(switches::kDisableGpu);
+ } else {
+ const char *glType;
+ switch (QOpenGLContext::openGLModuleType()) {
+ case QOpenGLContext::LibGL:
+ glType = gfx::kGLImplementationDesktopName;
+ break;
+ case QOpenGLContext::LibGLES:
+ glType = gfx::kGLImplementationEGLName;
+ break;
+ }
+ parsedCommandLine->AppendSwitchASCII(switches::kUseGL, glType);
}
- parsedCommandLine->AppendSwitchASCII(switches::kUseGL, glType);
content::UtilityProcessHostImpl::RegisterUtilityMainThreadFactory(content::CreateInProcessUtilityThread);
content::RenderProcessHostImpl::RegisterRendererMainThreadFactory(content::CreateInProcessRendererThread);
@@ -208,7 +253,4 @@ WebEngineContext::WebEngineContext()
// thread to avoid a thread check assertion in its constructor when it
// first gets referenced on the IO thread.
MediaCaptureDevicesDispatcher::GetInstance();
-
- // Ensure we have a VisitedLinksMaster instance up and running
- m_visitedLinksManager.reset(new WebEngineVisitedLinksManager);
}
diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h
index d1cd9a7a5..0b3ad8678 100644
--- a/src/core/web_engine_context.h
+++ b/src/core/web_engine_context.h
@@ -49,15 +49,16 @@ class BrowserMainRunner;
class ContentMainRunner;
}
+class BrowserContextAdapter;
class ContentMainDelegateQt;
class SurfaceFactoryQt;
-class WebEngineVisitedLinksManager;
class WebEngineContext : public base::RefCounted<WebEngineContext> {
public:
static scoped_refptr<WebEngineContext> current();
- WebEngineVisitedLinksManager *visitedLinksManager();
+ BrowserContextAdapter *defaultBrowserContext();
+ BrowserContextAdapter *offTheRecordBrowserContext();
private:
friend class base::RefCounted<WebEngineContext>;
@@ -71,7 +72,8 @@ private:
#if defined(OS_ANDROID)
scoped_ptr<SurfaceFactoryQt> m_surfaceFactory;
#endif
- scoped_ptr<WebEngineVisitedLinksManager> m_visitedLinksManager;
+ scoped_ptr<BrowserContextAdapter> m_defaultBrowserContext;
+ scoped_ptr<BrowserContextAdapter> m_offTheRecordBrowserContext;
};
#endif // WEB_ENGINE_CONTEXT_H
diff --git a/src/core/web_engine_visited_links_manager.cpp b/src/core/web_engine_visited_links_manager.cpp
index 36467ca21..a2f6dbf9f 100644
--- a/src/core/web_engine_visited_links_manager.cpp
+++ b/src/core/web_engine_visited_links_manager.cpp
@@ -36,8 +36,9 @@
#include "web_engine_visited_links_manager.h"
-#include "content_browser_client_qt.h"
+#include "browser_context_adapter.h"
#include "browser_context_qt.h"
+#include "content_browser_client_qt.h"
#include "type_conversion.h"
#include "base/memory/scoped_ptr.h"
@@ -80,11 +81,11 @@ void WebEngineVisitedLinksManager::deleteVisitedLinkDataForUrls(const QList<QUrl
m_visitedLinkMaster->DeleteURLs(&iterator);
}
-WebEngineVisitedLinksManager::WebEngineVisitedLinksManager()
+WebEngineVisitedLinksManager::WebEngineVisitedLinksManager(BrowserContextAdapter *adapter)
: m_delegate(new VisitedLinkDelegateQt)
{
- Q_ASSERT(ContentBrowserClientQt::Get() && ContentBrowserClientQt::Get()->browser_context());
- BrowserContextQt *browserContext = ContentBrowserClientQt::Get()->browser_context();
+ Q_ASSERT(adapter && adapter->browserContext());
+ BrowserContextQt *browserContext = adapter->browserContext();
m_visitedLinkMaster.reset(new visitedlink::VisitedLinkMaster(browserContext, m_delegate.data(), /* persist to disk = */true));
m_visitedLinkMaster->Init();
}
diff --git a/src/core/web_engine_visited_links_manager.h b/src/core/web_engine_visited_links_manager.h
index aa44dd9cf..5b0286c51 100644
--- a/src/core/web_engine_visited_links_manager.h
+++ b/src/core/web_engine_visited_links_manager.h
@@ -49,6 +49,7 @@ namespace visitedlink {
class VisitedLinkMaster;
}
+class BrowserContextAdapter;
class VisitedLinkDelegateQt;
class GURL;
@@ -57,7 +58,7 @@ class QWEBENGINE_EXPORT WebEngineVisitedLinksManager {
public:
virtual~WebEngineVisitedLinksManager();
- WebEngineVisitedLinksManager();
+ WebEngineVisitedLinksManager(BrowserContextAdapter*);
void deleteAllVisitedLinkData();
void deleteVisitedLinkDataForUrls(const QList<QUrl> &);
diff --git a/src/webengine/api/qquickwebenginesettings.cpp b/src/webengine/api/qquickwebenginesettings.cpp
index 743d22d81..e46b1a80d 100644
--- a/src/webengine/api/qquickwebenginesettings.cpp
+++ b/src/webengine/api/qquickwebenginesettings.cpp
@@ -43,6 +43,20 @@ QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QList<QQuickWebEngineSettingsPrivate*>, allSettings)
+class QQuickWebEngineGlobalSettings {
+ QQuickWebEngineSettings globalSettings;
+public:
+ QQuickWebEngineGlobalSettings() {
+ // globalSettings shouldn't be in that list.
+ allSettings->removeAll(globalSettings.d_func());
+ globalSettings.d_func()->coreSettings->initDefaults();
+ }
+
+ QQuickWebEngineSettings *data() { return &globalSettings; }
+};
+
+Q_GLOBAL_STATIC(QQuickWebEngineGlobalSettings, globalInstance)
+
QQuickWebEngineSettingsPrivate::QQuickWebEngineSettingsPrivate()
: coreSettings(new WebEngineSettings(this))
{
@@ -64,16 +78,9 @@ WebEngineSettings *QQuickWebEngineSettingsPrivate::fallbackSettings() const
return QQuickWebEngineSettings::globalSettings()->d_func()->coreSettings.data();
}
-
QQuickWebEngineSettings *QQuickWebEngineSettings::globalSettings()
{
- static QQuickWebEngineSettings *globals = 0;
- if (!globals) {
- globals = new QQuickWebEngineSettings;
- allSettings->removeAll(globals->d_func());
- globals->d_func()->coreSettings->initDefaults();
- }
- return globals;
+ return globalInstance()->data();
}
QQuickWebEngineSettings::~QQuickWebEngineSettings()
@@ -161,7 +168,7 @@ void QQuickWebEngineSettings::setAutoLoadImages(bool on)
// could be from the fallback and is prone to changing later on.
d->coreSettings->setAttribute(WebEngineSettings::AutoLoadImages, on);
if (wasOn ^ on)
- Q_EMIT autoLoadImagesChanged(on);
+ Q_EMIT autoLoadImagesChanged();
}
void QQuickWebEngineSettings::setJavascriptEnabled(bool on)
@@ -170,7 +177,7 @@ void QQuickWebEngineSettings::setJavascriptEnabled(bool on)
bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::JavascriptEnabled);
d->coreSettings->setAttribute(WebEngineSettings::JavascriptEnabled, on);
if (wasOn ^ on)
- Q_EMIT javascriptEnabledChanged(on);
+ Q_EMIT javascriptEnabledChanged();
}
void QQuickWebEngineSettings::setJavascriptCanOpenWindows(bool on)
@@ -179,7 +186,7 @@ void QQuickWebEngineSettings::setJavascriptCanOpenWindows(bool on)
bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::JavascriptCanOpenWindows);
d->coreSettings->setAttribute(WebEngineSettings::JavascriptCanOpenWindows, on);
if (wasOn ^ on)
- Q_EMIT javascriptCanOpenWindowsChanged(on);
+ Q_EMIT javascriptCanOpenWindowsChanged();
}
void QQuickWebEngineSettings::setJavascriptCanAccessClipboard(bool on)
@@ -188,7 +195,7 @@ void QQuickWebEngineSettings::setJavascriptCanAccessClipboard(bool on)
bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::JavascriptCanAccessClipboard);
d->coreSettings->setAttribute(WebEngineSettings::JavascriptCanAccessClipboard, on);
if (wasOn ^ on)
- Q_EMIT javascriptCanAccessClipboardChanged(on);
+ Q_EMIT javascriptCanAccessClipboardChanged();
}
void QQuickWebEngineSettings::setLinksIncludedInFocusChain(bool on)
@@ -197,7 +204,7 @@ void QQuickWebEngineSettings::setLinksIncludedInFocusChain(bool on)
bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::LinksIncludedInFocusChain);
d->coreSettings->setAttribute(WebEngineSettings::LinksIncludedInFocusChain, on);
if (wasOn ^ on)
- Q_EMIT linksIncludedInFocusChainChanged(on);
+ Q_EMIT linksIncludedInFocusChainChanged();
}
void QQuickWebEngineSettings::setLocalStorageEnabled(bool on)
@@ -206,7 +213,7 @@ void QQuickWebEngineSettings::setLocalStorageEnabled(bool on)
bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::LocalStorageEnabled);
d->coreSettings->setAttribute(WebEngineSettings::LocalStorageEnabled, on);
if (wasOn ^ on)
- Q_EMIT localStorageEnabledChanged(on);
+ Q_EMIT localStorageEnabledChanged();
}
void QQuickWebEngineSettings::setLocalContentCanAccessRemoteUrls(bool on)
@@ -215,7 +222,7 @@ void QQuickWebEngineSettings::setLocalContentCanAccessRemoteUrls(bool on)
bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::LocalContentCanAccessRemoteUrls);
d->coreSettings->setAttribute(WebEngineSettings::LocalContentCanAccessRemoteUrls, on);
if (wasOn ^ on)
- Q_EMIT localContentCanAccessRemoteUrlsChanged(on);
+ Q_EMIT localContentCanAccessRemoteUrlsChanged();
}
@@ -225,7 +232,7 @@ void QQuickWebEngineSettings::setSpatialNavigationEnabled(bool on)
bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::SpatialNavigationEnabled);
d->coreSettings->setAttribute(WebEngineSettings::SpatialNavigationEnabled, on);
if (wasOn ^ on)
- Q_EMIT spatialNavigationEnabledChanged(on);
+ Q_EMIT spatialNavigationEnabledChanged();
}
void QQuickWebEngineSettings::setLocalContentCanAccessFileUrls(bool on)
@@ -234,7 +241,7 @@ void QQuickWebEngineSettings::setLocalContentCanAccessFileUrls(bool on)
bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::LocalContentCanAccessFileUrls);
d->coreSettings->setAttribute(WebEngineSettings::LocalContentCanAccessFileUrls, on);
if (wasOn ^ on)
- Q_EMIT localContentCanAccessFileUrlsChanged(on);
+ Q_EMIT localContentCanAccessFileUrlsChanged();
}
void QQuickWebEngineSettings::setHyperlinkAuditingEnabled(bool on)
@@ -243,7 +250,7 @@ void QQuickWebEngineSettings::setHyperlinkAuditingEnabled(bool on)
bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::HyperlinkAuditingEnabled);
d->coreSettings->setAttribute(WebEngineSettings::HyperlinkAuditingEnabled, on);
if (wasOn ^ on)
- Q_EMIT hyperlinkAuditingEnabledChanged(on);
+ Q_EMIT hyperlinkAuditingEnabledChanged();
}
void QQuickWebEngineSettings::setErrorPageEnabled(bool on)
@@ -252,7 +259,7 @@ void QQuickWebEngineSettings::setErrorPageEnabled(bool on)
bool wasOn = d->coreSettings->testAttribute(WebEngineSettings::ErrorPageEnabled);
d->coreSettings->setAttribute(WebEngineSettings::ErrorPageEnabled, on);
if (wasOn ^ on)
- Q_EMIT errorPageEnabledChanged(on);
+ Q_EMIT errorPageEnabledChanged();
}
void QQuickWebEngineSettings::setDefaultTextEncoding(QString encoding)
@@ -261,7 +268,7 @@ void QQuickWebEngineSettings::setDefaultTextEncoding(QString encoding)
const QString oldDefaultTextEncoding = d->coreSettings->defaultTextEncoding();
d->coreSettings->setDefaultTextEncoding(encoding);
if (oldDefaultTextEncoding.compare(encoding))
- Q_EMIT defaultTextEncodingChanged(encoding);
+ Q_EMIT defaultTextEncodingChanged();
}
QQuickWebEngineSettings::QQuickWebEngineSettings()
diff --git a/src/webengine/api/qquickwebenginesettings_p.h b/src/webengine/api/qquickwebenginesettings_p.h
index 4a7c2f834..040a5f5fb 100644
--- a/src/webengine/api/qquickwebenginesettings_p.h
+++ b/src/webengine/api/qquickwebenginesettings_p.h
@@ -44,6 +44,7 @@
QT_BEGIN_NAMESPACE
class QQuickWebEngineSettingsPrivate;
+class QQuickWebEngineGlobalSettings;
class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineSettings : public QObject {
Q_OBJECT
@@ -92,24 +93,25 @@ public:
void setDefaultTextEncoding(QString encoding);
signals:
- void autoLoadImagesChanged(bool on);
- void javascriptEnabledChanged(bool on);
- void javascriptCanOpenWindowsChanged(bool on);
- void javascriptCanAccessClipboardChanged(bool on);
- void linksIncludedInFocusChainChanged(bool on);
- void localStorageEnabledChanged(bool on);
- void localContentCanAccessRemoteUrlsChanged(bool on);
- void spatialNavigationEnabledChanged(bool on);
- void localContentCanAccessFileUrlsChanged(bool on);
- void hyperlinkAuditingEnabledChanged(bool on);
- void errorPageEnabledChanged(bool on);
- void defaultTextEncodingChanged(QString encoding);
+ void autoLoadImagesChanged();
+ void javascriptEnabledChanged();
+ void javascriptCanOpenWindowsChanged();
+ void javascriptCanAccessClipboardChanged();
+ void linksIncludedInFocusChainChanged();
+ void localStorageEnabledChanged();
+ void localContentCanAccessRemoteUrlsChanged();
+ void spatialNavigationEnabledChanged();
+ void localContentCanAccessFileUrlsChanged();
+ void hyperlinkAuditingEnabledChanged();
+ void errorPageEnabledChanged();
+ void defaultTextEncodingChanged();
private:
QQuickWebEngineSettings();
Q_DISABLE_COPY(QQuickWebEngineSettings)
Q_DECLARE_PRIVATE(QQuickWebEngineSettings)
friend class QQuickWebEngineViewPrivate;
+ friend class QQuickWebEngineGlobalSettings;
QScopedPointer<QQuickWebEngineSettingsPrivate> d_ptr;
};
diff --git a/src/webengine/api/qquickwebenginesettings_p_p.h b/src/webengine/api/qquickwebenginesettings_p_p.h
index 8f3e95eea..05a163b92 100644
--- a/src/webengine/api/qquickwebenginesettings_p_p.h
+++ b/src/webengine/api/qquickwebenginesettings_p_p.h
@@ -44,7 +44,6 @@ QT_BEGIN_NAMESPACE
class QQuickWebEngineSettingsPrivate : public WebEngineSettingsDelegate {
public:
QQuickWebEngineSettingsPrivate();
- QQuickWebEngineSettingsPrivate(WebContentsAdapter *adapter);
void apply() Q_DECL_OVERRIDE;
WebEngineSettings *fallbackSettings() const Q_DECL_OVERRIDE;
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index ad850e84e..dccbb5b9f 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -37,6 +37,7 @@
#include "qquickwebengineview_p.h"
#include "qquickwebengineview_p_p.h"
+#include "browser_context_adapter.h"
#include "certificate_error_controller.h"
#include "javascript_dialog_controller.h"
#include "qquickwebenginehistory_p.h"
@@ -217,6 +218,11 @@ void QQuickWebEngineViewPrivate::allowCertificateError(const QExplicitlySharedDa
Q_UNUSED(errorController);
}
+void QQuickWebEngineViewPrivate::runGeolocationPermissionRequest(const QUrl &url)
+{
+ Q_EMIT e->featurePermissionRequested(url, QQuickWebEngineViewExperimental::Geolocation);
+}
+
void QQuickWebEngineViewPrivate::runFileChooser(FileChooserMode mode, const QString &defaultFileName, const QStringList &acceptedMimeTypes)
{
ui()->showFilePicker(mode, defaultFileName, acceptedMimeTypes, adapter);
@@ -343,9 +349,11 @@ void QQuickWebEngineViewPrivate::adoptNewWindow(WebContentsAdapter *newWebConten
switch (disposition) {
case WebContentsAdapterClient::NewForegroundTabDisposition:
- case WebContentsAdapterClient::NewBackgroundTabDisposition:
request.m_destination = QQuickWebEngineView::NewViewInTab;
break;
+ case WebContentsAdapterClient::NewBackgroundTabDisposition:
+ request.m_destination = QQuickWebEngineView::NewViewInBackgroundTab;
+ break;
case WebContentsAdapterClient::NewPopupDisposition:
request.m_destination = QQuickWebEngineView::NewViewInDialog;
break;
@@ -356,7 +364,7 @@ void QQuickWebEngineViewPrivate::adoptNewWindow(WebContentsAdapter *newWebConten
Q_UNREACHABLE();
}
- emit e->newViewRequested(&request);
+ Q_EMIT e->newViewRequested(&request);
}
void QQuickWebEngineViewPrivate::close()
@@ -387,11 +395,11 @@ void QQuickWebEngineViewPrivate::runMediaAccessPermissionRequest(const QUrl &sec
return;
QQuickWebEngineViewExperimental::Feature feature;
if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture) && requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
- feature = QQuickWebEngineViewExperimental::MediaAudioVideoDevices;
+ feature = QQuickWebEngineViewExperimental::MediaAudioVideoCapture;
else if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture))
- feature = QQuickWebEngineViewExperimental::MediaAudioDevices;
+ feature = QQuickWebEngineViewExperimental::MediaAudioCapture;
else // WebContentsAdapterClient::MediaVideoCapture
- feature = QQuickWebEngineViewExperimental::MediaVideoDevices;
+ feature = QQuickWebEngineViewExperimental::MediaVideoCapture;
Q_EMIT e->featurePermissionRequested(securityOrigin, feature);
}
@@ -401,6 +409,11 @@ QObject *QQuickWebEngineViewPrivate::accessibilityParentObject()
return q;
}
+BrowserContextAdapter *QQuickWebEngineViewPrivate::browserContextAdapter()
+{
+ return BrowserContextAdapter::defaultContext();
+}
+
WebEngineSettings *QQuickWebEngineViewPrivate::webEngineSettings() const
{
return m_settings->d_func()->coreSettings.data();
@@ -557,6 +570,17 @@ void QQuickWebEngineView::stop()
d->adapter->stop();
}
+void QQuickWebEngineView::setZoomFactor(qreal arg)
+{
+ Q_D(QQuickWebEngineView);
+ qreal oldFactor = d->adapter->currentZoomFactor();
+ d->adapter->setZoomFactor(arg);
+ if (qFuzzyCompare(oldFactor, d->adapter->currentZoomFactor()))
+ return;
+
+ emit zoomFactorChanged(arg);
+}
+
void QQuickWebEngineViewPrivate::didRunJavaScript(quint64 requestId, const QVariant &result)
{
Q_Q(QQuickWebEngineView);
@@ -620,6 +644,12 @@ QQuickWebEngineViewExperimental *QQuickWebEngineView::experimental() const
return d->e.data();
}
+qreal QQuickWebEngineView::zoomFactor() const
+{
+ Q_D(const QQuickWebEngineView);
+ return d->adapter->currentZoomFactor();
+}
+
bool QQuickWebEngineViewExperimental::inspectable() const
{
Q_D(const QQuickWebEngineView);
@@ -685,22 +715,26 @@ QQuickWebEngineHistory *QQuickWebEngineViewExperimental::navigationHistory() con
void QQuickWebEngineViewExperimental::grantFeaturePermission(const QUrl &securityOrigin, QQuickWebEngineViewExperimental::Feature feature, bool granted)
{
- if (!granted && feature >= MediaAudioDevices && feature <= MediaAudioVideoDevices) {
+ if (!granted && feature >= MediaAudioCapture && feature <= MediaAudioVideoCapture) {
d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaNone);
return;
}
switch (feature) {
- case MediaAudioDevices:
+ case MediaAudioCapture:
d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaAudioCapture);
break;
- case MediaVideoDevices:
+ case MediaVideoCapture:
d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaVideoCapture);
break;
- case MediaAudioVideoDevices:
- d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaRequestFlags(WebContentsAdapterClient::MediaAudioCapture
- | WebContentsAdapterClient::MediaVideoCapture));
+ case MediaAudioVideoCapture:
+ d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaRequestFlags(WebContentsAdapterClient::MediaAudioCapture | WebContentsAdapterClient::MediaVideoCapture));
+ break;
+ case Geolocation:
+ d_ptr->adapter->runGeolocationRequestCallback(securityOrigin, granted);
break;
+ default:
+ Q_UNREACHABLE();
}
}
diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index 22713ee22..9f6493022 100644
--- a/src/webengine/api/qquickwebengineview_p.h
+++ b/src/webengine/api/qquickwebengineview_p.h
@@ -56,6 +56,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem {
Q_PROPERTY(QString title READ title NOTIFY titleChanged)
Q_PROPERTY(bool canGoBack READ canGoBack NOTIFY urlChanged)
Q_PROPERTY(bool canGoForward READ canGoForward NOTIFY urlChanged)
+ Q_PROPERTY(qreal zoomFactor READ zoomFactor WRITE setZoomFactor NOTIFY zoomFactorChanged)
Q_ENUMS(NavigationRequestAction);
Q_ENUMS(NavigationType);
Q_ENUMS(LoadStatus);
@@ -75,6 +76,7 @@ public:
QString title() const;
bool canGoBack() const;
bool canGoForward() const;
+ qreal zoomFactor() const;
QQuickWebEngineViewExperimental *experimental() const;
@@ -116,7 +118,8 @@ public:
enum NewViewDestination {
NewViewInWindow,
NewViewInTab,
- NewViewInDialog
+ NewViewInDialog,
+ NewViewInBackgroundTab
};
// must match WebContentsAdapterClient::JavaScriptConsoleMessageLevel
@@ -133,6 +136,7 @@ public Q_SLOTS:
void goForward();
void reload();
void stop();
+ void setZoomFactor(qreal arg);
Q_SIGNALS:
void titleChanged();
@@ -143,6 +147,7 @@ Q_SIGNALS:
void linkHovered(const QUrl &hoveredUrl);
void navigationRequested(QQuickWebEngineNavigationRequest *request);
void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID);
+ void zoomFactorChanged(qreal arg);
protected:
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index 6662f1f02..46388bfbb 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -88,9 +88,10 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineViewExperimental : public QObjec
public:
enum Feature {
- MediaAudioDevices,
- MediaVideoDevices,
- MediaAudioVideoDevices
+ MediaAudioCapture,
+ MediaVideoCapture,
+ MediaAudioVideoCapture,
+ Geolocation
};
enum FindFlag {
@@ -178,6 +179,9 @@ public:
virtual QObject *accessibilityParentObject() Q_DECL_OVERRIDE;
virtual WebEngineSettings *webEngineSettings() const Q_DECL_OVERRIDE;
virtual void allowCertificateError(const QExplicitlySharedDataPointer<CertificateErrorController> &errorController);
+ virtual void runGeolocationPermissionRequest(QUrl const&) Q_DECL_OVERRIDE;
+
+ virtual BrowserContextAdapter *browserContextAdapter() Q_DECL_OVERRIDE;
void setDevicePixelRatio(qreal);
void adoptWebContents(WebContentsAdapter *webContents);
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
index a2f60d4ef..209b5fbea 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
@@ -43,6 +43,8 @@
#include <QQuickWindow>
#include <QVariant>
#include <QWindow>
+#include <private/qquickwindow_p.h>
+#include <private/qsgcontext_p.h>
RenderWidgetHostViewQtDelegateQuick::RenderWidgetHostViewQtDelegateQuick(RenderWidgetHostViewQtDelegateClient *client, bool isPopup)
: m_client(client)
@@ -123,6 +125,23 @@ QWindow* RenderWidgetHostViewQtDelegateQuick::window() const
return QQuickItem::window();
}
+QSGTexture *RenderWidgetHostViewQtDelegateQuick::createTextureFromImage(const QImage &image)
+{
+ return QQuickItem::window()->createTextureFromImage(image, QQuickWindow::TextureCanUseAtlas);
+}
+
+QSGLayer *RenderWidgetHostViewQtDelegateQuick::createLayer()
+{
+ QSGRenderContext *renderContext = QQuickWindowPrivate::get(QQuickItem::window())->context;
+ return renderContext->sceneGraphContext()->createLayer(renderContext);
+}
+
+QSGImageNode *RenderWidgetHostViewQtDelegateQuick::createImageNode()
+{
+ QSGRenderContext *renderContext = QQuickWindowPrivate::get(QQuickItem::window())->context;
+ return renderContext->sceneGraphContext()->createImageNode();
+}
+
void RenderWidgetHostViewQtDelegateQuick::update()
{
QQuickItem::update();
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.h b/src/webengine/render_widget_host_view_qt_delegate_quick.h
index ddc581289..112d97377 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.h
@@ -57,6 +57,9 @@ public:
virtual void hide() Q_DECL_OVERRIDE;
virtual bool isVisible() const Q_DECL_OVERRIDE;
virtual QWindow* window() const Q_DECL_OVERRIDE;
+ virtual QSGTexture *createTextureFromImage(const QImage &) Q_DECL_OVERRIDE;
+ virtual QSGLayer *createLayer() Q_DECL_OVERRIDE;
+ virtual QSGImageNode *createImageNode() Q_DECL_OVERRIDE;
virtual void update() Q_DECL_OVERRIDE;
virtual void updateCursor(const QCursor &) Q_DECL_OVERRIDE;
virtual void resize(int width, int height) Q_DECL_OVERRIDE;
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
index da8d3d806..6a0e416e0 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
@@ -95,6 +95,21 @@ QWindow *RenderWidgetHostViewQtDelegateQuickWindow::window() const
return const_cast<RenderWidgetHostViewQtDelegateQuickWindow*>(this);
}
+QSGTexture *RenderWidgetHostViewQtDelegateQuickWindow::createTextureFromImage(const QImage &image)
+{
+ return m_realDelegate->createTextureFromImage(image);
+}
+
+QSGLayer *RenderWidgetHostViewQtDelegateQuickWindow::createLayer()
+{
+ return m_realDelegate->createLayer();
+}
+
+QSGImageNode *RenderWidgetHostViewQtDelegateQuickWindow::createImageNode()
+{
+ return m_realDelegate->createImageNode();
+}
+
void RenderWidgetHostViewQtDelegateQuickWindow::update()
{
QQuickWindow::update();
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
index eeab4a79a..e6c793143 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
@@ -60,6 +60,9 @@ public:
virtual void hide() Q_DECL_OVERRIDE;
virtual bool isVisible() const Q_DECL_OVERRIDE;
virtual QWindow* window() const Q_DECL_OVERRIDE;
+ virtual QSGTexture *createTextureFromImage(const QImage &) Q_DECL_OVERRIDE;
+ virtual QSGLayer *createLayer() Q_DECL_OVERRIDE;
+ virtual QSGImageNode *createImageNode() Q_DECL_OVERRIDE;
virtual void update() Q_DECL_OVERRIDE;
virtual void updateCursor(const QCursor &) Q_DECL_OVERRIDE;
virtual void resize(int width, int height) Q_DECL_OVERRIDE;
diff --git a/src/webengine/webengine.pro b/src/webengine/webengine.pro
index 6f48e9d49..128ae043d 100644
--- a/src/webengine/webengine.pro
+++ b/src/webengine/webengine.pro
@@ -6,7 +6,7 @@ CMAKE_MODULE_TESTS = "-"
DEFINES += QT_BUILD_WEBENGINE_LIB
QT += qml quick
-QT_PRIVATE += webenginecore quick-private
+QT_PRIVATE += webenginecore quick-private gui-private core-private
QMAKE_DOCS = $$PWD/doc/qtwebengine.qdocconf
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 72b16f28b..3f5fd53b5 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -23,6 +23,7 @@
#include "qwebenginepage.h"
#include "qwebenginepage_p.h"
+#include "browser_context_adapter.h"
#include "certificate_error_controller.h"
#include "javascript_dialog_controller.h"
#include "qwebenginehistory.h"
@@ -342,6 +343,12 @@ void QWebEnginePagePrivate::runMediaAccessPermissionRequest(const QUrl &security
Q_EMIT q->featurePermissionRequested(securityOrigin, requestedFeature);
}
+void QWebEnginePagePrivate::runGeolocationPermissionRequest(const QUrl &securityOrigin)
+{
+ Q_Q(QWebEnginePage);
+ Q_EMIT q->featurePermissionRequested(securityOrigin, QWebEnginePage::Geolocation);
+}
+
QObject *QWebEnginePagePrivate::accessibilityParentObject()
{
return view;
@@ -410,6 +417,11 @@ void QWebEnginePagePrivate::recreateFromSerializedHistory(QDataStream &input)
}
}
+BrowserContextAdapter *QWebEnginePagePrivate::browserContextAdapter()
+{
+ return BrowserContextAdapter::defaultContext();
+}
+
QWebEnginePage::QWebEnginePage(QObject* parent)
: QObject(parent)
, d_ptr(new QWebEnginePagePrivate)
@@ -624,6 +636,13 @@ bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData
return true;
}
+void QWebEnginePagePrivate::navigationRequested(int navigationType, const QUrl &url, int &navigationRequestAction, bool isMainFrame)
+{
+ Q_Q(QWebEnginePage);
+ bool accepted = q->acceptNavigationRequest(url, static_cast<QWebEnginePage::NavigationType>(navigationType), isMainFrame);
+ navigationRequestAction = accepted ? WebContentsAdapterClient::AcceptRequest : WebContentsAdapterClient::IgnoreRequest;
+}
+
void QWebEnginePagePrivate::javascriptDialog(QSharedPointer<JavaScriptDialogController> controller)
{
Q_Q(QWebEnginePage);
@@ -743,6 +762,8 @@ QMenu *QWebEnginePage::createStandardContextMenu()
void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEnginePage::Feature feature, QWebEnginePage::PermissionPolicy policy)
{
Q_D(QWebEnginePage);
+ if (policy == PermissionUnknown)
+ return;
WebContentsAdapterClient::MediaRequestFlags flags = WebContentsAdapterClient::MediaNone;
switch (feature) {
case MediaAudioVideoCapture:
@@ -761,6 +782,10 @@ void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEngine
}
d->adapter->grantMediaAccessPermission(securityOrigin, flags);
}
+ d->adapter->grantMediaAccessPermission(securityOrigin, flags);
+ break;
+ case QWebEnginePage::Geolocation:
+ d->adapter->runGeolocationRequestCallback(securityOrigin, (policy == PermissionGrantedByUser) ? true : false);
break;
default:
break;
@@ -945,6 +970,14 @@ bool QWebEnginePage::certificateError(const QWebEngineCertificateError &)
return false;
}
+bool QWebEnginePage::acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame)
+{
+ Q_UNUSED(url);
+ Q_UNUSED(type);
+ Q_UNUSED(isMainFrame);
+ return true;
+}
+
QT_END_NAMESPACE
#include "moc_qwebenginepage.cpp"
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index 7856b8243..afb62ceda 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -136,6 +136,16 @@ public:
PermissionDeniedByUser
};
+ // must match WebContentsAdapterClient::NavigationType
+ enum NavigationType {
+ NavigationTypeLinkClicked,
+ NavigationTypeTyped,
+ NavigationTypeFormSubmitted,
+ NavigationTypeBackForward,
+ NavigationTypeReload,
+ NavigationTypeOther
+ };
+
enum Feature {
#ifndef Q_QDOC
Notifications = 0,
@@ -248,6 +258,7 @@ protected:
virtual bool javaScriptPrompt(const QUrl &securityOrigin, const QString& msg, const QString& defaultValue, QString* result);
virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID);
virtual bool certificateError(const QWebEngineCertificateError &certificateError);
+ virtual bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame);
private:
Q_DECLARE_PRIVATE(QWebEnginePage);
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index 54129229f..23d577c94 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -122,7 +122,7 @@ public:
virtual void adoptNewWindow(WebContentsAdapter *newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &initialGeometry) Q_DECL_OVERRIDE;
virtual void close() Q_DECL_OVERRIDE;
virtual bool contextMenuRequested(const WebEngineContextMenuData &data) Q_DECL_OVERRIDE;
- virtual void navigationRequested(int, const QUrl &, int &, bool) Q_DECL_OVERRIDE { }
+ virtual void navigationRequested(int navigationType, const QUrl &url, int &navigationRequestAction, bool isMainFrame) Q_DECL_OVERRIDE;
virtual void requestFullScreen(bool) Q_DECL_OVERRIDE { }
virtual bool isFullScreen() const Q_DECL_OVERRIDE { return false; }
virtual void javascriptDialog(QSharedPointer<JavaScriptDialogController>) Q_DECL_OVERRIDE;
@@ -135,10 +135,13 @@ public:
virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE;
virtual void authenticationRequired(const QUrl &requestUrl, const QString &realm, bool isProxy, const QString &challengingHost, QString *outUser, QString *outPassword) Q_DECL_OVERRIDE;
virtual void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) Q_DECL_OVERRIDE;
+ virtual void runGeolocationPermissionRequest(const QUrl &securityOrigin) Q_DECL_OVERRIDE;
virtual QObject *accessibilityParentObject() Q_DECL_OVERRIDE;
virtual WebEngineSettings *webEngineSettings() const Q_DECL_OVERRIDE;
virtual void allowCertificateError(const QExplicitlySharedDataPointer<CertificateErrorController> &controller) Q_DECL_OVERRIDE;
+ virtual BrowserContextAdapter *browserContextAdapter() Q_DECL_OVERRIDE;
+
void updateAction(QWebEnginePage::WebAction) const;
void updateNavigationActions();
void _q_webActionTriggered(bool checked);
diff --git a/src/webenginewidgets/api/qwebenginesettings.cpp b/src/webenginewidgets/api/qwebenginesettings.cpp
index 729a09f56..3a0f4fced 100644
--- a/src/webenginewidgets/api/qwebenginesettings.cpp
+++ b/src/webenginewidgets/api/qwebenginesettings.cpp
@@ -39,7 +39,7 @@
#include <QDebug>
-QT_USE_NAMESPACE
+QT_BEGIN_NAMESPACE
static WebEngineSettings::Attribute toWebEngineAttribute(QWebEngineSettings::WebAttribute attribute) {
switch (attribute) {
@@ -74,7 +74,21 @@ static WebEngineSettings::Attribute toWebEngineAttribute(QWebEngineSettings::Web
}
}
-Q_GLOBAL_STATIC(QList<QWebEngineSettingsPrivate*>, allSettings);
+Q_GLOBAL_STATIC(QList<QWebEngineSettingsPrivate*>, allSettings)
+
+class QWebEngineGlobalSettings {
+ QWebEngineSettings globalSettings;
+public:
+ QWebEngineGlobalSettings() {
+ // globalSettings shouldn't be in that list.
+ allSettings->removeAll(globalSettings.d_func());
+ globalSettings.d_func()->coreSettings->initDefaults();
+ }
+
+ QWebEngineSettings *data() { return &globalSettings; }
+};
+
+Q_GLOBAL_STATIC(QWebEngineGlobalSettings, globalInstance)
QWebEngineSettingsPrivate::QWebEngineSettingsPrivate()
: coreSettings(new WebEngineSettings(this))
@@ -92,25 +106,13 @@ void QWebEngineSettingsPrivate::apply()
}
}
-void QWebEngineSettingsPrivate::initDefaults()
-{
- coreSettings->initDefaults();
-}
-
WebEngineSettings *QWebEngineSettingsPrivate::fallbackSettings() const {
return QWebEngineSettings::globalSettings()->d_func()->coreSettings.data();
}
QWebEngineSettings *QWebEngineSettings::globalSettings()
{
- static QWebEngineSettings* globalSettings = 0;
- if (!globalSettings) {
- globalSettings = new QWebEngineSettings;
- // globalSettings shouldn't be in that list.
- allSettings->removeAll(globalSettings->d_func());
- globalSettings->d_func()->initDefaults();
- }
- return globalSettings;
+ return globalInstance()->data();
}
Q_STATIC_ASSERT_X(static_cast<int>(WebEngineSettings::StandardFont) == static_cast<int>(QWebEngineSettings::StandardFont), "The enum values must match");
@@ -215,3 +217,5 @@ void QWebEngineSettings::resetAttribute(QWebEngineSettings::WebAttribute attr)
{
setAttribute(attr, globalSettings()->testAttribute(attr));
}
+
+QT_END_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebenginesettings.h b/src/webenginewidgets/api/qwebenginesettings.h
index d9f57a935..29825f5a4 100644
--- a/src/webenginewidgets/api/qwebenginesettings.h
+++ b/src/webenginewidgets/api/qwebenginesettings.h
@@ -31,6 +31,7 @@ class QIcon;
class QPixmap;
class QUrl;
class QWebEngineSettingsPrivate;
+class QWebEngineGlobalSettings;
class QWEBENGINEWIDGETS_EXPORT QWebEngineSettings {
public:
@@ -87,6 +88,7 @@ private:
Q_DECLARE_PRIVATE(QWebEngineSettings);
QScopedPointer<QWebEngineSettingsPrivate> d_ptr;
friend class QWebEnginePagePrivate;
+ friend class QWebEngineGlobalSettings;
QWebEngineSettings();
~QWebEngineSettings();
diff --git a/src/webenginewidgets/api/qwebenginesettings_p.h b/src/webenginewidgets/api/qwebenginesettings_p.h
index 830e8b360..12464fa02 100644
--- a/src/webenginewidgets/api/qwebenginesettings_p.h
+++ b/src/webenginewidgets/api/qwebenginesettings_p.h
@@ -48,7 +48,6 @@ class QWebEngineSettingsPrivate : public WebEngineSettingsDelegate {
public:
QWebEngineSettingsPrivate();
- void initDefaults();
void apply() Q_DECL_OVERRIDE;
WebEngineSettings *fallbackSettings() const Q_DECL_OVERRIDE;
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index e89b10ab8..af435d170 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -147,6 +147,21 @@
*/
/*!
+ \enum QWebEnginePage::NavigationType
+
+ This enum describes the type of a navigation request.
+
+ \value NavigationTypeLinkClicked The navigation request resulted from a clicked link.
+ \value NavigationTypeTyped The navigation request resulted from an explicitly loaded url.
+ \value NavigationTypeFormSubmitted The navigation request resulted from a form submission.
+ \value NavigationTypeBackForward The navigation request resulted from a back/forward action.
+ \value NavigationTypeReload The navigation request resulted from a reload action.
+ \value NavigationTypeOther The navigation request was triggered by other means not covered by the above.
+
+ \sa acceptNavigationRequest()
+*/
+
+/*!
\enum QWebEnginePage::Feature
This enum describes the platform feature access categories that the user may be asked to grant or deny access to.
@@ -209,6 +224,15 @@
*/
/*!
+ \fn bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame)
+ This function is called whenever there is a request to navigate to a specified \a url by means of the specified navigation type \atype.
+ The \a isMainFrame argument marks if the request corresponds to the main frame, or a sub frame.
+ If the request is accepted Chromium will continue to load the page, else the request will be ignored.
+ The default implementation accepts the navigation request.
+*/
+
+
+/*!
\fn void QWebEnginePage::javaScriptAlert(const QUrl &securityOrigin, const QString& msg)
This function is called whenever a JavaScript program running in a frame affiliated with \a securityOrigin calls the alert() function with
the message \a msg.
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
index c4a32d685..e49259a59 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -44,9 +44,11 @@
#include <QOpenGLContext>
#include <QResizeEvent>
#include <QSGAbstractRenderer>
-#include <QSGEngine>
#include <QSGNode>
#include <QWindow>
+#include <private/qsgcontext_p.h>
+#include <private/qsgengine_p.h>
+
static const int MaxTooltipLength = 1024;
@@ -143,6 +145,22 @@ QWindow* RenderWidgetHostViewQtDelegateWidget::window() const
return root ? root->windowHandle() : 0;
}
+QSGTexture *RenderWidgetHostViewQtDelegateWidget::createTextureFromImage(const QImage &image)
+{
+ return m_sgEngine->createTextureFromImage(image, QSGEngine::TextureCanUseAtlas);
+}
+
+QSGLayer *RenderWidgetHostViewQtDelegateWidget::createLayer()
+{
+ QSGEnginePrivate *enginePrivate = QSGEnginePrivate::get(m_sgEngine.data());
+ return enginePrivate->sgContext->createLayer(enginePrivate->sgRenderContext.data());
+}
+
+QSGImageNode *RenderWidgetHostViewQtDelegateWidget::createImageNode()
+{
+ return QSGEnginePrivate::get(m_sgEngine.data())->sgContext->createImageNode();
+}
+
void RenderWidgetHostViewQtDelegateWidget::update()
{
#if (QT_VERSION < QT_VERSION_CHECK(5, 4, 0))
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
index 0b553d8eb..670e22f31 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
@@ -65,6 +65,9 @@ public:
virtual void hide() Q_DECL_OVERRIDE;
virtual bool isVisible() const Q_DECL_OVERRIDE;
virtual QWindow* window() const Q_DECL_OVERRIDE;
+ virtual QSGTexture *createTextureFromImage(const QImage &) Q_DECL_OVERRIDE;
+ virtual QSGLayer *createLayer() Q_DECL_OVERRIDE;
+ virtual QSGImageNode *createImageNode() Q_DECL_OVERRIDE;
virtual void update() Q_DECL_OVERRIDE;
virtual void updateCursor(const QCursor &) Q_DECL_OVERRIDE;
virtual void resize(int width, int height) Q_DECL_OVERRIDE;
diff --git a/src/webenginewidgets/webenginewidgets.pro b/src/webenginewidgets/webenginewidgets.pro
index 71240cbaf..296b62475 100644
--- a/src/webenginewidgets/webenginewidgets.pro
+++ b/src/webenginewidgets/webenginewidgets.pro
@@ -6,7 +6,7 @@ CMAKE_MODULE_TESTS = "-"
DEFINES += QT_BUILD_WEBENGINEWIDGETS_LIB
QT += webengine widgets network quick
-QT_PRIVATE += webenginecore
+QT_PRIVATE += webenginecore quick-private gui-private core-private
QMAKE_DOCS = $$PWD/doc/qtwebenginewidgets.qdocconf
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index f7cffb8b1..abb8d3d7b 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -90,6 +90,7 @@ static QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.NewViewInWindow --> NewViewDestination"
<< "QQuickWebEngineView.NewViewInTab --> NewViewDestination"
<< "QQuickWebEngineView.NewViewInDialog --> NewViewDestination"
+ << "QQuickWebEngineView.NewViewInBackgroundTab --> NewViewDestination"
<< "QQuickWebEngineView.InfoMessageLevel --> JavaScriptConsoleMessageLevel"
<< "QQuickWebEngineView.WarningMessageLevel --> JavaScriptConsoleMessageLevel"
<< "QQuickWebEngineView.ErrorMessageLevel --> JavaScriptConsoleMessageLevel"
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 6fb46057d..85939a686 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -107,11 +107,11 @@ private Q_SLOTS:
void contextMenuCopy();
void contextMenuPopulatedOnce();
void acceptNavigationRequest();
+ void acceptNavigationRequestNavigationType();
void geolocationRequestJS();
void loadFinished();
void actionStates();
void popupFormSubmission();
- void acceptNavigationRequestWithNewWindow();
void userStyleSheet();
void userStyleSheetFromLocalFileUrl();
void userStyleSheetFromQrcUrl();
@@ -133,8 +133,6 @@ private Q_SLOTS:
void textEditing();
void backActionUpdate();
void frameAt();
- void requestCache();
- void loadCachedPage();
void protectBindingsRuntimeObjectsFromCollector();
void localURLSchemes();
void testOptionalJSObjects();
@@ -240,7 +238,6 @@ void tst_QWebEnginePage::cleanupTestCase()
cleanupFiles(); // Be nice
}
-#if defined(QWEBENGINEPAGE_ACCEPTNAVIGATIONREQUEST)
class NavigationRequestOverride : public QWebEnginePage
{
public:
@@ -248,21 +245,18 @@ public:
bool m_acceptNavigationRequest;
protected:
- virtual bool acceptNavigationRequest(QWebEngineFrame* frame, const QNetworkRequest &request, QWebEnginePage::NavigationType type) {
- Q_UNUSED(frame);
- Q_UNUSED(request);
+ virtual bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame)
+ {
+ Q_UNUSED(url);
Q_UNUSED(type);
+ Q_UNUSED(isMainFrame);
return m_acceptNavigationRequest;
}
};
-#endif
void tst_QWebEnginePage::acceptNavigationRequest()
{
-#if !defined(QWEBENGINEPAGE_ACCEPTNAVIGATIONREQUEST)
- QSKIP("QWEBENGINEPAGE_ACCEPTNAVIGATIONREQUEST");
-#else
QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool)));
NavigationRequestOverride* newPage = new NavigationRequestOverride(m_view, false);
@@ -278,11 +272,10 @@ void tst_QWebEnginePage::acceptNavigationRequest()
evaluateJavaScriptSync(m_view->page(), "tstform.submit();");
QTRY_COMPARE(loadSpy.count(), 2);
- QCOMPARE(m_view->page()->toPlainText(), QString("foo?"));
+ QCOMPARE(toPlainTextSync(m_view->page()), QString("foo?"));
// Restore default page
m_view->setPage(0);
-#endif
}
#if defined(QWEBENGINEPAGE_SETFEATUREPERMISSION)
@@ -439,23 +432,22 @@ public:
connect(this, SIGNAL(geometryChangeRequested(QRect)), this, SLOT(slotGeometryChangeRequested(QRect)));
}
-#if defined(QWEBENGINEPAGE_ACCEPTNAVIGATIONREQUEST)
struct Navigation {
- QWebEngineFrame *frame;
- QNetworkRequest request;
NavigationType type;
+ QUrl url;
+ bool isMainFrame;
};
QList<Navigation> navigations;
- virtual bool acceptNavigationRequest(QWebEngineFrame* frame, const QNetworkRequest &request, NavigationType type) {
+ virtual bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame)
+ {
Navigation n;
- n.frame = frame;
- n.request = request;
+ n.url = url;
n.type = type;
+ n.isMainFrame = isMainFrame;
navigations.append(n);
return true;
}
-#endif
QList<TestPage*> createdWindows;
virtual QWebEnginePage* createWindow(WebWindowType) {
@@ -471,6 +463,42 @@ private Q_SLOTS:
}
};
+void tst_QWebEnginePage::acceptNavigationRequestNavigationType()
+{
+
+ TestPage page;
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+
+ page.load(QUrl("qrc:///resources/script.html"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(page.navigations.count(), 1);
+
+ page.load(QUrl("qrc:///resources/content.html"));
+ QTRY_COMPARE(loadSpy.count(), 2);
+ QTRY_COMPARE(page.navigations.count(), 2);
+
+ page.triggerAction(QWebEnginePage::Stop);
+ QVERIFY(page.history()->canGoBack());
+ page.triggerAction(QWebEnginePage::Back);
+
+ QTRY_COMPARE(loadSpy.count(), 3);
+ QTRY_COMPARE(page.navigations.count(), 3);
+
+ page.triggerAction(QWebEnginePage::Reload);
+ QTRY_COMPARE(loadSpy.count(), 4);
+ QTRY_COMPARE(page.navigations.count(), 4);
+
+ QList<QWebEnginePage::NavigationType> expectedList;
+ expectedList << QWebEnginePage::NavigationTypeTyped
+ << QWebEnginePage::NavigationTypeTyped
+ << QWebEnginePage::NavigationTypeBackForward
+ << QWebEnginePage::NavigationTypeReload;
+ QVERIFY(expectedList.count() == page.navigations.count());
+ for (int i = 0; i < expectedList.count(); ++i) {
+ QCOMPARE(page.navigations[i].type, expectedList[i]);
+ }
+}
+
void tst_QWebEnginePage::popupFormSubmission()
{
TestPage page;
@@ -491,38 +519,6 @@ void tst_QWebEnginePage::popupFormSubmission()
QVERIFY(url.contains("?foo=bar"));
}
-void tst_QWebEnginePage::acceptNavigationRequestWithNewWindow()
-{
-#if !defined(QWEBENGINESETTINGS)
- QSKIP("QWEBENGINESETTINGS");
-#else
- TestPage* page = new TestPage(m_view);
- page->settings()->setAttribute(QWebEngineSettings::LinksIncludedInFocusChain, true);
- m_page = page;
- m_view->setPage(m_page);
-
- m_view->setUrl(QString("data:text/html,<a href=\"data:text/html,Reached\" target=\"_blank\">Click me</a>"));
- QVERIFY(::waitForSignal(m_view, SIGNAL(loadFinished(bool))));
-
- QFocusEvent fe(QEvent::FocusIn);
- m_page->event(&fe);
-
- QVERIFY(m_page->focusNextPrevChild(/*next*/ true));
-
- QKeyEvent keyEnter(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
- m_page->event(&keyEnter);
-
- QCOMPARE(page->navigations.count(), 2);
-
- TestPage::Navigation n = page->navigations.at(1);
- QVERIFY(!n.frame);
- QCOMPARE(n.request.url().toString(), QString("data:text/html,Reached"));
- QVERIFY(n.type == QWebEnginePage::NavigationTypeLinkClicked);
-
- QCOMPARE(page->createdWindows.count(), 1);
-#endif
-}
-
class TestNetworkManager : public QNetworkAccessManager
{
public:
@@ -1606,72 +1602,6 @@ void tst_QWebEnginePage::textEditing()
#endif
}
-void tst_QWebEnginePage::requestCache()
-{
-#if !defined(ACCEPTNAVIGATIONREQUEST)
- QSKIP("ACCEPTNAVIGATIONREQUEST");
-#else
- TestPage page;
- QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
-
- page.setUrl(QString("data:text/html,<a href=\"data:text/html,Reached\" target=\"_blank\">Click me</a>"));
- QTRY_COMPARE(loadSpy.count(), 1);
- QTRY_COMPARE(page.navigations.count(), 1);
-
- page.setUrl(QString("data:text/html,<a href=\"data:text/html,Reached\" target=\"_blank\">Click me2</a>"));
- QTRY_COMPARE(loadSpy.count(), 2);
- QTRY_COMPARE(page.navigations.count(), 2);
-
- page.triggerAction(QWebEnginePage::Stop);
- QVERIFY(page.history()->canGoBack());
- page.triggerAction(QWebEnginePage::Back);
-
- QTRY_COMPARE(loadSpy.count(), 3);
- QTRY_COMPARE(page.navigations.count(), 3);
- QCOMPARE(page.navigations.at(0).request.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt(),
- (int)QNetworkRequest::PreferNetwork);
- QCOMPARE(page.navigations.at(1).request.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt(),
- (int)QNetworkRequest::PreferNetwork);
- QCOMPARE(page.navigations.at(2).request.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt(),
- (int)QNetworkRequest::PreferCache);
-#endif
-}
-
-void tst_QWebEnginePage::loadCachedPage()
-{
-#if !defined(QWEBENGINESETTINGS)
- QSKIP("QWEBENGINESETTINGS");
-#else
- TestPage page;
- QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
- page.settings()->setMaximumPagesInCache(3);
-
- page.load(QUrl("data:text/html,This is first page"));
-
- QTRY_COMPARE(loadSpy.count(), 1);
- QTRY_COMPARE(page.navigations.count(), 1);
-
- QUrl firstPageUrl = page.url();
- page.load(QUrl("data:text/html,This is second page"));
-
- QTRY_COMPARE(loadSpy.count(), 2);
- QTRY_COMPARE(page.navigations.count(), 2);
-
- page.triggerAction(QWebEnginePage::Stop);
- QVERIFY(page.history()->canGoBack());
-
- QSignalSpy urlSpy(&page, SIGNAL(urlChanged(QUrl)));
- QVERIFY(urlSpy.isValid());
-
- page.triggerAction(QWebEnginePage::Back);
- ::waitForSignal(&page, SIGNAL(urlChanged(QUrl)));
- QCOMPARE(urlSpy.size(), 1);
-
- QList<QVariant> arguments1 = urlSpy.takeFirst();
- QCOMPARE(arguments1.at(0).toUrl(), firstPageUrl);
-#endif
-}
-
void tst_QWebEnginePage::backActionUpdate()
{
QWebEngineView view;
diff --git a/tests/quicktestbrowser/FeaturePermissionBar.qml b/tests/quicktestbrowser/FeaturePermissionBar.qml
index dd2e0f714..68ad43195 100644
--- a/tests/quicktestbrowser/FeaturePermissionBar.qml
+++ b/tests/quicktestbrowser/FeaturePermissionBar.qml
@@ -69,12 +69,14 @@ Rectangle {
Layout.fillWidth: true
function textForFeature(feature) {
- if (feature === WebEngineViewExperimental.MediaAudioDevices)
+ if (feature === WebEngineViewExperimental.MediaAudioCapture)
return "your microphone"
- if (feature === WebEngineViewExperimental.MediaVideoDevices)
+ if (feature === WebEngineViewExperimental.MediaVideoCapture)
return "your camera"
- if (feature === WebEngineViewExperimental.MediaAudioVideoDevices)
+ if (feature === WebEngineViewExperimental.MediaAudioVideoCapture)
return "your camera and microphone"
+ if (feature === WebEngineViewExperimental.Geolocation)
+ return "your position"
}
}
diff --git a/tests/quicktestbrowser/ZoomController.qml b/tests/quicktestbrowser/ZoomController.qml
new file mode 100644
index 000000000..a714ed2a9
--- /dev/null
+++ b/tests/quicktestbrowser/ZoomController.qml
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.3
+import QtQuick.Controls 1.2
+import QtQuick.Layouts 1.1
+
+Rectangle {
+ property alias zoomFactor: slider.value ;
+ function zoomIn() {
+ visible = true
+ visibilityTimer.restart()
+ zoomFactor = zoomFactor + 0.25;
+ }
+ function zoomOut() {
+ visible = true
+ visibilityTimer.restart()
+ zoomFactor = zoomFactor - 0.25;
+ }
+ function reset() { zoomFactor = 1.0 }
+
+ width: 220
+ height: 30
+ color: palette.window
+ visible: false
+ radius: 4
+
+ SystemPalette {
+ id: palette
+ }
+ Timer {
+ id: visibilityTimer
+ interval: 3000
+ repeat: false
+ onTriggered: zoomController.visible = false
+ }
+
+ RowLayout {
+ anchors.margins: 4
+ anchors.fill: parent
+ ToolButton {
+ id: plusButton
+ text: '+'
+ onClicked: zoomIn()
+ }
+ ToolButton {
+ text: '\u2014'
+ id: minusButton
+ onClicked: zoomOut()
+ }
+ Slider {
+ id: slider
+ maximumValue: 5.0
+ minimumValue: 0.25
+ Layout.fillWidth: true;
+ stepSize: 0.05
+ value: 1
+ onValueChanged: visibilityTimer.restart()
+ }
+ Button {
+ text: "Reset"
+ onClicked: reset()
+ }
+ }
+}
diff --git a/tests/quicktestbrowser/quickwindow.qml b/tests/quicktestbrowser/quickwindow.qml
index 6a5ef3187..b1be6db3e 100644
--- a/tests/quicktestbrowser/quickwindow.qml
+++ b/tests/quicktestbrowser/quickwindow.qml
@@ -122,6 +122,18 @@ ApplicationWindow {
browserWindow.showNormal()
}
}
+ Action {
+ shortcut: "Ctrl+0"
+ onTriggered: zoomController.reset()
+ }
+ Action {
+ shortcut: "Ctrl+-"
+ onTriggered: zoomController.zoomOut()
+ }
+ Action {
+ shortcut: "Ctrl+="
+ onTriggered: zoomController.zoomIn()
+ }
Menu {
id: backHistoryMenu
@@ -342,7 +354,7 @@ ApplicationWindow {
var tab = tabs.createEmptyTab()
request.openIn(tab.item.webView)
} else if (request.destination == WebEngineView.NewViewInDialog) {
- var dialog = dialogComponent.createObject()
+ var dialog = dialogComponent.createObject(webEngineView)
request.openIn(dialog.webView)
} else {
var component = Qt.createComponent("quickwindow.qml")
@@ -399,4 +411,16 @@ ApplicationWindow {
}
}
}
+ ZoomController {
+ id: zoomController
+ y: parent.mapFromItem(currentWebView, 0 , 0).y - 4
+ anchors.right: parent.right
+ width: (parent.width > 800) ? parent.width * 0.25 : 220
+ anchors.rightMargin: (parent.width > 400) ? 100 : 0
+ }
+ Binding {
+ target: currentWebView
+ property: "zoomFactor"
+ value: zoomController.zoomFactor
+ }
}
diff --git a/tests/quicktestbrowser/resources.qrc b/tests/quicktestbrowser/resources.qrc
index cdc3d2304..4880b3d65 100644
--- a/tests/quicktestbrowser/resources.qrc
+++ b/tests/quicktestbrowser/resources.qrc
@@ -4,6 +4,7 @@
<file>ContextMenuExtras.qml</file>
<file>FeaturePermissionBar.qml</file>
<file>ButtonWithMenu.qml</file>
+ <file>ZoomController.qml</file>
</qresource>
<qresource prefix="icons">
<!-- To the risk of this breaking more often, do not duplicate the resources since this application won't be deployed -->
diff --git a/tests/quicktestbrowser/util.h b/tests/quicktestbrowser/util.h
index bad41d6a7..85db8c25b 100644
--- a/tests/quicktestbrowser/util.h
+++ b/tests/quicktestbrowser/util.h
@@ -50,7 +50,7 @@ QUrl urlFromUserInput(const QString& userInput)
{
QFileInfo fileInfo(userInput);
if (fileInfo.exists())
- return QUrl(fileInfo.absoluteFilePath());
+ return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
return QUrl::fromUserInput(userInput);
}