summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2016-06-13 10:16:32 +0200
committerAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2016-06-14 10:43:10 +0200
commit939d104cc5a8208a0bef94ca14889ccd584a3526 (patch)
tree4d89c122ad5014a32cd8d4fbad6b7418944d2fb6
parent5a7063154520544fe19bb57af3609afef898bffb (diff)
parent6c2a111f8c82b56388abf409a61a3e0d56a52156 (diff)
Merge branch '5.7' into dev
-rw-r--r--.qmake.conf1
-rw-r--r--dist/changes-5.6.12
-rw-r--r--dist/changes-5.7.05
-rw-r--r--examples/webenginewidgets/demobrowser/browsermainwindow.cpp1
-rw-r--r--examples/webenginewidgets/demobrowser/webview.cpp3
-rw-r--r--examples/webenginewidgets/demobrowser/webview.h3
-rw-r--r--examples/webenginewidgets/simplebrowser/main.cpp3
-rw-r--r--examples/webenginewidgets/simplebrowser/webview.cpp1
-rw-r--r--src/core/api/core_api.pro1
-rw-r--r--src/core/browser_context_qt.h2
-rw-r--r--src/core/clipboard_qt.cpp7
-rw-r--r--src/core/config/desktop_linux.pri8
-rw-r--r--src/core/content_client_qt.cpp30
-rw-r--r--src/core/core_gyp_generator.pro2
-rw-r--r--src/core/core_module.pro2
-rw-r--r--src/core/gl_surface_qt.cpp82
-rw-r--r--src/core/gyp_run.pro2
-rw-r--r--src/core/location_provider_qt.cpp34
-rw-r--r--src/core/render_widget_host_view_qt.cpp6
-rw-r--r--src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.cpp401
-rw-r--r--src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.h108
-rw-r--r--src/core/renderer/pepper/pepper_host_factory_qt.cpp18
-rw-r--r--src/core/web_contents_adapter.cpp19
-rw-r--r--src/core/web_contents_adapter_client.h1
-rw-r--r--src/core/web_contents_view_qt.cpp2
-rw-r--r--src/webengine/api/qquickwebenginesettings.cpp2
-rw-r--r--src/webengine/api/qquickwebengineview.cpp40
-rw-r--r--src/webengine/api/qquickwebengineview_p.h1
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h3
-rw-r--r--src/webengine/doc/qtwebengine.qdocconf4
-rw-r--r--src/webengine/doc/src/external-resources.qdoc42
-rw-r--r--src/webengine/doc/src/qtwebengine-features.qdoc234
-rw-r--r--src/webengine/doc/src/qtwebengine-index.qdoc1
-rw-r--r--src/webengine/doc/src/qtwebengine-overview.qdoc12
-rw-r--r--src/webengine/doc/src/qtwebengine-platform-notes.qdoc81
-rw-r--r--src/webengine/doc/src/webengineview.qdoc6
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.cpp29
-rw-r--r--src/webenginewidgets/api/qwebenginecertificateerror.cpp4
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp13
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h1
-rw-r--r--src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc4
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc15
-rw-r--r--src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc5
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp28
-rw-r--r--sync.profile2
-rw-r--r--tests/auto/quick/publicapi/tst_publicapi.cpp3
-rw-r--r--tests/auto/quick/qquickwebengineview/BLACKLIST3
-rw-r--r--tests/auto/quick/qquickwebengineview/qquickwebengineview.pro2
-rw-r--r--tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp138
-rw-r--r--tests/auto/widgets/positionplugin/plugin.cpp107
-rw-r--r--tests/auto/widgets/positionplugin/plugin.json9
-rw-r--r--tests/auto/widgets/positionplugin/positionplugin.pro13
-rw-r--r--tests/auto/widgets/qwebenginepage/BLACKLIST9
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp238
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp152
-rw-r--r--tests/auto/widgets/widgets.pro5
-rwxr-xr-xtools/buildscripts/find-included-moc-files4
-rwxr-xr-xtools/buildscripts/find-mocables4
-rw-r--r--tools/qmake/mkspecs/features/configure.prf9
-rw-r--r--tools/qmake/mkspecs/features/functions.prf12
-rw-r--r--tools/qmake/mkspecs/features/gyp_generator.prf2
61 files changed, 1459 insertions, 522 deletions
diff --git a/.qmake.conf b/.qmake.conf
index ffb3dafe0..5237fb5fd 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -1,6 +1,5 @@
QMAKEPATH += $$PWD/tools/qmake
load(qt_build_config)
-CONFIG += qt_example_installs
CONFIG += warning_clean
MODULE_VERSION = 5.8.0
diff --git a/dist/changes-5.6.1 b/dist/changes-5.6.1
index 5a568bda9..50ab2c7fe 100644
--- a/dist/changes-5.6.1
+++ b/dist/changes-5.6.1
@@ -23,7 +23,7 @@ information about a particular change.
****************************************************************************
- Chromium Snapshot:
- * Security fixes from Chromium up to version 50.0.2661.94
+ * Security fixes from Chromium up to version 51.0.2704.63
* [QTBUG-52602] Fixed devtools so it works with newer Chrome releases.
* [QTBUG-52085, QTBUG-53108] qrc urls can now load local files.
diff --git a/dist/changes-5.7.0 b/dist/changes-5.7.0
index 8b6e302b8..345a6ab9d 100644
--- a/dist/changes-5.7.0
+++ b/dist/changes-5.7.0
@@ -21,7 +21,7 @@ information about a particular change.
- Chromium Snapshot:
* The Chromium version has been updated to 49.0.2623.111.
- * In addition security fixes from Chromium 50 have been merged.
+ * In addition security fixes from Chromium 50 and 51 have been merged.
- Web Features:
* Drag'n'drop is now supported
@@ -29,6 +29,9 @@ information about a particular change.
if the PPAPI Widevine CDM plugin is installed.
* Spellchecking is now available if dictionaries are installed.
+- OS X:
+ * Added 'use_appstore_compliant_code' option to allow compiling WebEngine as Mac App Store compliant.
+
****************************************************************************
* Qt WebEngineQML *
****************************************************************************
diff --git a/examples/webenginewidgets/demobrowser/browsermainwindow.cpp b/examples/webenginewidgets/demobrowser/browsermainwindow.cpp
index fbee934db..14ed10dfc 100644
--- a/examples/webenginewidgets/demobrowser/browsermainwindow.cpp
+++ b/examples/webenginewidgets/demobrowser/browsermainwindow.cpp
@@ -352,7 +352,6 @@ void BrowserMainWindow::setupMenu()
QAction *m_find = editMenu->addAction(tr("&Find"));
m_find->setShortcuts(QKeySequence::Find);
connect(m_find, SIGNAL(triggered()), this, SLOT(slotEditFind()));
- new QShortcut(QKeySequence(Qt::Key_Slash), this, SLOT(slotEditFind()));
QAction *m_findNext = editMenu->addAction(tr("&Find Next"));
m_findNext->setShortcuts(QKeySequence::FindNext);
diff --git a/examples/webenginewidgets/demobrowser/webview.cpp b/examples/webenginewidgets/demobrowser/webview.cpp
index 633b72bf1..a785ae48b 100644
--- a/examples/webenginewidgets/demobrowser/webview.cpp
+++ b/examples/webenginewidgets/demobrowser/webview.cpp
@@ -349,8 +349,7 @@ void WebView::setPage(WebPage *_page)
connect(page(), SIGNAL(statusBarMessage(QString)),
SLOT(setStatusBarText(QString)));
#endif
- connect(page(), SIGNAL(loadingUrl(QUrl)),
- this, SIGNAL(urlChanged(QUrl)));
+ disconnect(page(), &QWebEnginePage::iconChanged, this, &WebView::iconChanged);
connect(page(), SIGNAL(iconChanged(QIcon)),
this, SLOT(onIconChanged(QIcon)));
connect(page(), &WebPage::featurePermissionRequested, this, &WebView::onFeaturePermissionRequested);
diff --git a/examples/webenginewidgets/demobrowser/webview.h b/examples/webenginewidgets/demobrowser/webview.h
index e3df8f795..8cb502fd1 100644
--- a/examples/webenginewidgets/demobrowser/webview.h
+++ b/examples/webenginewidgets/demobrowser/webview.h
@@ -111,9 +111,6 @@ protected:
void contextMenuEvent(QContextMenuEvent *event);
void wheelEvent(QWheelEvent *event);
-signals:
- void iconChanged(const QIcon &icon);
-
private slots:
void setProgress(int progress);
void loadFinished(bool success);
diff --git a/examples/webenginewidgets/simplebrowser/main.cpp b/examples/webenginewidgets/simplebrowser/main.cpp
index 750e7ae43..1d2796b8c 100644
--- a/examples/webenginewidgets/simplebrowser/main.cpp
+++ b/examples/webenginewidgets/simplebrowser/main.cpp
@@ -41,6 +41,7 @@
#include "browser.h"
#include "browserwindow.h"
#include <QApplication>
+#include <QWebEngineSettings>
QString getCommandLineUrlArgument()
{
@@ -59,6 +60,8 @@ int main(int argc, char **argv)
QApplication app(argc, argv);
app.setWindowIcon(QIcon(QLatin1String(":simplebrowser.svg")));
+ QWebEngineSettings::defaultSettings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
+
BrowserWindow *window = new BrowserWindow();
Browser::instance().addWindow(window);
diff --git a/examples/webenginewidgets/simplebrowser/webview.cpp b/examples/webenginewidgets/simplebrowser/webview.cpp
index 9a5a75092..657993fc6 100644
--- a/examples/webenginewidgets/simplebrowser/webview.cpp
+++ b/examples/webenginewidgets/simplebrowser/webview.cpp
@@ -45,6 +45,7 @@
#include "webpopupwindow.h"
#include "webview.h"
#include <QContextMenuEvent>
+#include <QDebug>
#include <QMenu>
#include <QMessageBox>
#include <QTimer>
diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro
index 19b67876c..a9f5adaba 100644
--- a/src/core/api/core_api.pro
+++ b/src/core/api/core_api.pro
@@ -15,6 +15,7 @@ CONFIG -= create_prl
# Copy this logic from qt_module.prf so that the intermediate library can be
# created to the same rules as the final module linking in core_module.pro.
!host_build:if(win32|mac):!macx-xcode {
+ contains(QT_CONFIG, simulator_and_device): CONFIG += iphonesimulator_and_iphoneos
contains(QT_CONFIG, debug_and_release):CONFIG += debug_and_release
contains(QT_CONFIG, build_all):CONFIG += build_all
}
diff --git a/src/core/browser_context_qt.h b/src/core/browser_context_qt.h
index 68e1244e1..13f7220bd 100644
--- a/src/core/browser_context_qt.h
+++ b/src/core/browser_context_qt.h
@@ -97,7 +97,7 @@ public:
BrowserContextAdapter *adapter() { return m_adapter; }
#if defined(ENABLE_SPELLCHECK)
- void failedToLoadDictionary(const std::string& language) override;
+ void failedToLoadDictionary(const std::string& language);
void setSpellCheckLanguage(const QString &language);
QString spellCheckLanguage() const;
void setSpellCheckEnabled(bool enabled);
diff --git a/src/core/clipboard_qt.cpp b/src/core/clipboard_qt.cpp
index bd62f4872..712ff5703 100644
--- a/src/core/clipboard_qt.cpp
+++ b/src/core/clipboard_qt.cpp
@@ -56,6 +56,13 @@
namespace QtWebEngineCore {
+static void registerMetaTypes()
+{
+ qRegisterMetaType<QClipboard::Mode>("QClipboard::Mode");
+}
+
+Q_CONSTRUCTOR_FUNCTION(registerMetaTypes)
+
Q_GLOBAL_STATIC(ClipboardChangeObserver, clipboardChangeObserver)
ClipboardChangeObserver::ClipboardChangeObserver()
diff --git a/src/core/config/desktop_linux.pri b/src/core/config/desktop_linux.pri
index a78082581..de0fbbc6b 100644
--- a/src/core/config/desktop_linux.pri
+++ b/src/core/config/desktop_linux.pri
@@ -6,5 +6,9 @@ GYP_CONFIG += \
desktop_linux=1 \
enable_widevine=1
-linux-clang: GYP_CONFIG += clang=1 host_clang=1 clang_use_chrome_plugins=0 make_clang_dir=/usr
-else: GYP_CONFIG += clang=0 host_clang=0
+clang {
+ GYP_CONFIG += clang=1 host_clang=1 clang_use_chrome_plugins=0 make_clang_dir=/usr
+ linux-clang-libc++: GYP_CONFIG += use_system_libcxx=1
+} else {
+ GYP_CONFIG += clang=0 host_clang=0
+}
diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index 158bb0895..49c018b23 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -57,6 +57,18 @@
#include <QLibraryInfo>
#include <QString>
+#if defined(Q_OS_WIN)
+#include <shlobj.h>
+static QString getLocalAppDataDir()
+{
+ QString result;
+ wchar_t path[MAX_PATH];
+ if (SHGetSpecialFolderPath(0, path, CSIDL_LOCAL_APPDATA, FALSE))
+ result = QDir::fromNativeSeparators(QString::fromWCharArray(path));
+ return result;
+}
+#endif
+
#if defined(ENABLE_PLUGINS)
// The plugin logic is based on chrome/common/chrome_content_client.cc:
@@ -199,10 +211,24 @@ void AddPepperWidevine(std::vector<content::PepperPluginInfo>* plugins)
pluginPaths << potentialWidevinePluginPath;
}
}
+#elif defined(Q_OS_WIN)
+ QDir potentialWidevineDir(getLocalAppDataDir() + "/Google/Chrome/User Data/WidevineCDM");
+ if (potentialWidevineDir.exists()) {
+ QFileInfoList widevineVersionDirs = potentialWidevineDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed);
+ for (int i = 0; i < widevineVersionDirs.size(); ++i) {
+ QString versionDirPath(widevineVersionDirs.at(i).absoluteFilePath());
+#ifdef WIN64
+ QString potentialWidevinePluginPath = versionDirPath + "/_platform_specific/win_x64/" + QString::fromLatin1(kWidevineCdmAdapterFileName);
+#else
+ QString potentialWidevinePluginPath = versionDirPath + "/_platform_specific/win_x86/" + QString::fromLatin1(kWidevineCdmAdapterFileName);
#endif
-#if defined(Q_OS_LINUX)
+ pluginPaths << potentialWidevinePluginPath;
+ }
+ }
+#elif defined(Q_OS_LINUX)
pluginPaths << QStringLiteral("/opt/google/chrome/libwidevinecdmadapter.so") // Google Chrome
- << QStringLiteral("/usr/lib/chromium/libwidevinecdmadapter.so"); // Arch
+ << QStringLiteral("/usr/lib/chromium/libwidevinecdmadapter.so") // Arch
+ << QStringLiteral("/usr/lib64/chromium/libwidevinecdmadapter.so"); // OpenSUSE style
#endif
}
diff --git a/src/core/core_gyp_generator.pro b/src/core/core_gyp_generator.pro
index 3e6a9eac0..cdff4ed64 100644
--- a/src/core/core_gyp_generator.pro
+++ b/src/core/core_gyp_generator.pro
@@ -73,6 +73,7 @@ SOURCES = \
render_widget_host_view_qt.cpp \
renderer/content_renderer_client_qt.cpp \
renderer/pepper/pepper_flash_browser_host_qt.cpp \
+ renderer/pepper/pepper_flash_clipboard_message_filter_qt.cpp \
renderer/pepper/pepper_flash_renderer_host_qt.cpp \
renderer/pepper/pepper_host_factory_qt.cpp \
renderer/pepper/pepper_isolated_file_system_message_filter.cpp \
@@ -155,6 +156,7 @@ HEADERS = \
render_widget_host_view_qt_delegate.h \
renderer/content_renderer_client_qt.h \
renderer/pepper/pepper_flash_browser_host_qt.h \
+ renderer/pepper/pepper_flash_clipboard_message_filter_qt.h \
renderer/pepper/pepper_flash_renderer_host_qt.h \
renderer/pepper/pepper_host_factory_qt.h \
renderer/pepper/pepper_isolated_file_system_message_filter.h \
diff --git a/src/core/core_module.pro b/src/core/core_module.pro
index fa402cc63..702b92441 100644
--- a/src/core/core_module.pro
+++ b/src/core/core_module.pro
@@ -14,6 +14,8 @@ load(qt_module)
api_library_name = qtwebenginecoreapi$$qtPlatformTargetSuffix()
api_library_path = $$OUT_PWD/api/$$getConfigDir()
+# Do not precompile any headers. We are only interested in the linker step.
+PRECOMPILED_HEADER =
LIBS_PRIVATE += -L$$api_library_path
CONFIG *= no_smart_library_merge
diff --git a/src/core/gl_surface_qt.cpp b/src/core/gl_surface_qt.cpp
index ef5b1d172..3982b9bd1 100644
--- a/src/core/gl_surface_qt.cpp
+++ b/src/core/gl_surface_qt.cpp
@@ -87,6 +87,7 @@ void* g_display;
const char* g_extensions = NULL;
+bool g_egl_surfaceless_context_supported = false;
} // namespace
@@ -109,6 +110,26 @@ private:
DISALLOW_COPY_AND_ASSIGN(GLSurfaceQtEGL);
};
+// The following comment is cited from chromium/ui/gl/gl_surface_egl.cc:
+// SurfacelessEGL is used as Offscreen surface when platform supports
+// KHR_surfaceless_context and GL_OES_surfaceless_context. This would avoid the
+// need to create a dummy EGLsurface in case we render to client API targets.
+class GLSurfacelessQtEGL : public GLSurfaceQt {
+public:
+ explicit GLSurfacelessQtEGL(const gfx::Size& size);
+
+ public:
+ bool Initialize() Q_DECL_OVERRIDE;
+ void Destroy() Q_DECL_OVERRIDE;
+ bool IsSurfaceless() const Q_DECL_OVERRIDE;
+ bool Resize(const gfx::Size& size, float scale_factor, bool has_alpha) Q_DECL_OVERRIDE;
+ EGLSurface GetHandle() Q_DECL_OVERRIDE;
+ void* GetShareHandle() Q_DECL_OVERRIDE;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(GLSurfacelessQtEGL);
+};
+
GLSurfaceQt::~GLSurfaceQt()
{
@@ -342,6 +363,23 @@ bool GLSurfaceQtEGL::InitializeOneOff()
return false;
}
+ g_egl_surfaceless_context_supported = ExtensionsContain(g_extensions, "EGL_KHR_surfaceless_context");
+ if (g_egl_surfaceless_context_supported) {
+ scoped_refptr<GLSurface> surface = new GLSurfacelessQtEGL(Size(1, 1));
+ scoped_refptr<GLContext> context = GLContext::CreateGLContext(
+ NULL, surface.get(), PreferIntegratedGpu);
+
+ if (!context->MakeCurrent(surface.get()))
+ g_egl_surfaceless_context_supported = false;
+
+ // Ensure context supports GL_OES_surfaceless_context.
+ if (g_egl_surfaceless_context_supported) {
+ g_egl_surfaceless_context_supported = context->HasExtension(
+ "GL_OES_surfaceless_context");
+ context->ReleaseCurrent(surface.get());
+ }
+ }
+
initialized = true;
return true;
}
@@ -426,7 +464,7 @@ bool GLSurfaceQtEGL::Initialize()
g_config,
pbuffer_attributes);
if (!m_surfaceBuffer) {
- LOG(ERROR) << "eglCreatePbufferSurface failed with error ", GetLastEGLErrorString();
+ LOG(ERROR) << "eglCreatePbufferSurface failed with error " << GetLastEGLErrorString();
Destroy();
return false;
}
@@ -502,6 +540,41 @@ void* GLSurfaceQt::GetConfig()
return g_config;
}
+GLSurfacelessQtEGL::GLSurfacelessQtEGL(const gfx::Size& size)
+ : GLSurfaceQt(size)
+{
+}
+
+bool GLSurfacelessQtEGL::Initialize()
+{
+ return true;
+}
+
+void GLSurfacelessQtEGL::Destroy()
+{
+}
+
+bool GLSurfacelessQtEGL::IsSurfaceless() const
+{
+ return true;
+}
+
+bool GLSurfacelessQtEGL::Resize(const gfx::Size& size, float scale_factor, bool has_alpha)
+{
+ m_size = size;
+ return true;
+}
+
+EGLSurface GLSurfacelessQtEGL::GetHandle()
+{
+ return EGL_NO_SURFACE;
+}
+
+void* GLSurfacelessQtEGL::GetShareHandle()
+{
+ return NULL;
+}
+
// static
scoped_refptr<GLSurface>
GLSurface::CreateOffscreenGLSurface(const gfx::Size& size)
@@ -525,7 +598,12 @@ GLSurface::CreateOffscreenGLSurface(const gfx::Size& size)
#endif
}
case kGLImplementationEGLGLES2: {
- scoped_refptr<GLSurface> surface = new GLSurfaceQtEGL(size);
+ scoped_refptr<GLSurface> surface;
+ if (g_egl_surfaceless_context_supported)
+ surface = new GLSurfacelessQtEGL(size);
+ else
+ surface = new GLSurfaceQtEGL(size);
+
if (!surface->Initialize())
return NULL;
return surface;
diff --git a/src/core/gyp_run.pro b/src/core/gyp_run.pro
index 2e2422dce..35b85b4c7 100644
--- a/src/core/gyp_run.pro
+++ b/src/core/gyp_run.pro
@@ -34,6 +34,7 @@ force_debug_info {
# Copy this logic from qt_module.prf so that ninja can run according
# to the same rules as the final module linking in core_module.pro.
!host_build:if(win32|mac):!macx-xcode {
+ contains(QT_CONFIG, simulator_and_device): CONFIG += iphonesimulator_and_iphoneos
contains(QT_CONFIG, debug_and_release):CONFIG += debug_and_release
contains(QT_CONFIG, build_all):CONFIG += build_all
}
@@ -81,6 +82,7 @@ contains(QT_ARCH, "arm") {
else: GYP_CONFIG += arm_fpu=\"$$MFPU\" arm_neon=0 arm_neon_optional=0
}
+ contains(QMAKE_CFLAGS, "-marm"): GYP_CONFIG += arm_thumb=0
contains(QMAKE_CFLAGS, "-mthumb"): GYP_CONFIG += arm_thumb=1
}
diff --git a/src/core/location_provider_qt.cpp b/src/core/location_provider_qt.cpp
index cc87d8417..c07bd4b0c 100644
--- a/src/core/location_provider_qt.cpp
+++ b/src/core/location_provider_qt.cpp
@@ -44,11 +44,13 @@
#include "type_conversion.h"
#include <QtCore/QCoreApplication>
+#include <QtCore/QMetaObject>
#include <QtCore/QThread>
#include <QtPositioning/QGeoPositionInfoSource>
-#include "base/message_loop/message_loop.h"
#include "base/bind.h"
+#include "base/memory/weak_ptr.h"
+#include "base/message_loop/message_loop.h"
#include "content/browser/geolocation/geolocation_provider_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/geolocation_provider.h"
@@ -63,9 +65,9 @@ public:
QtPositioningHelper(LocationProviderQt *provider);
~QtPositioningHelper();
- void start(bool highAccuracy);
- void stop();
- void refresh();
+ Q_INVOKABLE void start(bool highAccuracy);
+ Q_INVOKABLE void stop();
+ Q_INVOKABLE void refresh();
private Q_SLOTS:
void updatePosition(const QGeoPositionInfo &);
@@ -75,6 +77,7 @@ private Q_SLOTS:
private:
LocationProviderQt *m_locationProvider;
QGeoPositionInfoSource *m_positionInfoSource;
+ base::WeakPtrFactory<LocationProviderQt> m_locationProviderFactory;
void postToLocationProvider(const base::Closure &task);
friend class LocationProviderQt;
@@ -83,14 +86,13 @@ private:
QtPositioningHelper::QtPositioningHelper(LocationProviderQt *provider)
: m_locationProvider(provider)
, m_positionInfoSource(0)
+ , m_locationProviderFactory(provider)
{
Q_ASSERT(provider);
}
QtPositioningHelper::~QtPositioningHelper()
{
- if (m_locationProvider)
- m_locationProvider->m_positioningHelper = 0;
}
static bool isHighAccuracySource(const QGeoPositionInfoSource *source)
@@ -186,7 +188,8 @@ void QtPositioningHelper::updatePosition(const QGeoPositionInfo &pos)
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));
+ if (m_locationProvider)
+ postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, m_locationProviderFactory.GetWeakPtr(), newPos));
}
void QtPositioningHelper::error(QGeoPositionInfoSource::Error positioningError)
@@ -203,7 +206,8 @@ void QtPositioningHelper::error(QGeoPositionInfoSource::Error positioningError)
newPos.error_code = content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
break;
}
- postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, base::Unretained(m_locationProvider), newPos));
+ if (m_locationProvider)
+ postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, m_locationProviderFactory.GetWeakPtr(), newPos));
}
void QtPositioningHelper::timeout()
@@ -213,7 +217,8 @@ void QtPositioningHelper::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));
+ if (m_locationProvider)
+ postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, m_locationProviderFactory.GetWeakPtr(), newPos));
}
inline void QtPositioningHelper::postToLocationProvider(const base::Closure &task)
@@ -230,6 +235,7 @@ LocationProviderQt::~LocationProviderQt()
{
if (m_positioningHelper) {
m_positioningHelper->m_locationProvider = 0;
+ m_positioningHelper->m_locationProviderFactory.InvalidateWeakPtrs();
m_positioningHelper->deleteLater();
}
}
@@ -241,23 +247,21 @@ bool LocationProviderQt::StartProvider(bool highAccuracy)
m_positioningHelper = new QtPositioningHelper(this);
m_positioningHelper->moveToThread(guiThread);
}
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(&QtPositioningHelper::start
- , base::Unretained(m_positioningHelper), highAccuracy));
+
+ QMetaObject::invokeMethod(m_positioningHelper, "start", Qt::QueuedConnection, Q_ARG(bool, highAccuracy));
return true;
}
void LocationProviderQt::StopProvider()
{
if (m_positioningHelper)
- BrowserThread::PostTask(BrowserThread::UI,FROM_HERE, base::Bind(&QtPositioningHelper::stop
- , base::Unretained(m_positioningHelper)));
+ QMetaObject::invokeMethod(m_positioningHelper, "stop", Qt::QueuedConnection);
}
void LocationProviderQt::RequestRefresh()
{
if (m_positioningHelper)
- BrowserThread::PostTask(BrowserThread::UI,FROM_HERE, base::Bind(&QtPositioningHelper::refresh
- , base::Unretained(m_positioningHelper)));
+ QMetaObject::invokeMethod(m_positioningHelper, "refresh", Qt::QueuedConnection);
}
void LocationProviderQt::OnPermissionGranted()
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 34782b8c2..d6f88f74f 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -830,12 +830,12 @@ void RenderWidgetHostViewQt::sendDelegatedFrameAck()
void RenderWidgetHostViewQt::processMotionEvent(const ui::MotionEvent &motionEvent)
{
- if (!m_gestureProvider.OnTouchEvent(motionEvent).succeeded)
+ auto result = m_gestureProvider.OnTouchEvent(motionEvent);
+ if (!result.succeeded)
return;
- bool causesScrollingIfUncancelled = true;
blink::WebTouchEvent touchEvent = ui::CreateWebTouchEventFromMotionEvent(motionEvent,
- causesScrollingIfUncancelled);
+ result.moved_beyond_slop_region);
m_host->ForwardTouchEventWithLatencyInfo(touchEvent, CreateLatencyInfo(touchEvent));
}
diff --git a/src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.cpp b/src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.cpp
new file mode 100644
index 000000000..3202548ae
--- /dev/null
+++ b/src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.cpp
@@ -0,0 +1,401 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/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$
+**
+****************************************************************************/
+
+// based on chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc
+// 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 "pepper_flash_clipboard_message_filter_qt.h"
+
+#include "base/pickle.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/public/browser/browser_thread.h"
+#include "ipc/ipc_message.h"
+#include "ipc/ipc_message_macros.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/private/ppb_flash_clipboard.h"
+#include "ppapi/host/dispatch_host_message.h"
+#include "ppapi/host/host_message_context.h"
+#include "ppapi/host/ppapi_host.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/resource_message_params.h"
+#include "ui/base/clipboard/scoped_clipboard_writer.h"
+
+using content::BrowserThread;
+
+namespace QtWebEngineCore {
+
+namespace {
+
+const size_t kMaxClipboardWriteSize = 1000000;
+
+ui::ClipboardType ConvertClipboardType(uint32_t type)
+{
+ switch (type) {
+ case PP_FLASH_CLIPBOARD_TYPE_STANDARD:
+ return ui::CLIPBOARD_TYPE_COPY_PASTE;
+ case PP_FLASH_CLIPBOARD_TYPE_SELECTION:
+ return ui::CLIPBOARD_TYPE_SELECTION;
+ }
+ NOTREACHED();
+ return ui::CLIPBOARD_TYPE_COPY_PASTE;
+}
+
+// Functions to pack/unpack custom data from a pickle. See the header file for
+// more detail on custom formats in Pepper.
+// TODO(raymes): Currently pepper custom formats are stored in their own
+// native format type. However we should be able to store them in the same way
+// as "Web Custom" formats are. This would allow clipboard data to be shared
+// between pepper applications and web applications. However currently web apps
+// assume all data that is placed on the clipboard is UTF16 and pepper allows
+// arbitrary data so this change would require some reworking of the chrome
+// clipboard interface for custom data.
+bool JumpToFormatInPickle(const base::string16& format, base::PickleIterator* iter)
+{
+ uint32_t size = 0;
+ if (!iter->ReadUInt32(&size))
+ return false;
+ for (uint32_t i = 0; i < size; ++i) {
+ base::string16 stored_format;
+ if (!iter->ReadString16(&stored_format))
+ return false;
+ if (stored_format == format)
+ return true;
+ int skip_length;
+ if (!iter->ReadLength(&skip_length))
+ return false;
+ if (!iter->SkipBytes(skip_length))
+ return false;
+ }
+ return false;
+}
+
+bool IsFormatAvailableInPickle(const base::string16& format, const base::Pickle& pickle)
+{
+ base::PickleIterator iter(pickle);
+ return JumpToFormatInPickle(format, &iter);
+}
+
+std::string ReadDataFromPickle(const base::string16& format, const base::Pickle& pickle)
+{
+ std::string result;
+ base::PickleIterator iter(pickle);
+ if (!JumpToFormatInPickle(format, &iter) || !iter.ReadString(&result))
+ return std::string();
+ return result;
+}
+
+bool WriteDataToPickle(const std::map<base::string16, std::string>& data, base::Pickle* pickle)
+{
+ pickle->WriteUInt32(data.size());
+ for (std::map<base::string16, std::string>::const_iterator it = data.begin(); it != data.end(); ++it) {
+ if (!pickle->WriteString16(it->first))
+ return false;
+ if (!pickle->WriteString(it->second))
+ return false;
+ }
+ return true;
+}
+
+} // namespace
+
+PepperFlashClipboardMessageFilter::PepperFlashClipboardMessageFilter() {}
+
+PepperFlashClipboardMessageFilter::~PepperFlashClipboardMessageFilter() {}
+
+scoped_refptr<base::TaskRunner>
+PepperFlashClipboardMessageFilter::OverrideTaskRunnerForMessage(const IPC::Message& msg)
+{
+ // Clipboard writes should always occur on the UI thread due to the
+ // restrictions of various platform APIs. In general, the clipboard is not
+ // thread-safe, so all clipboard calls should be serviced from the UI thread.
+ if (msg.type() == PpapiHostMsg_FlashClipboard_WriteData::ID)
+ return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
+
+ // Windows needs clipboard reads to be serviced from the IO thread because
+ // these are sync IPCs which can result in deadlocks with plugins if serviced
+ // from the UI thread. Note that Windows clipboard calls ARE thread-safe so it
+ // is ok for reads and writes to be serviced from different threads.
+#if !defined(OS_WIN)
+ return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
+#else
+ return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
+#endif
+}
+
+int32_t PepperFlashClipboardMessageFilter::OnResourceMessageReceived(const IPC::Message& msg,
+ ppapi::host::HostMessageContext* context)
+{
+ PPAPI_BEGIN_MESSAGE_MAP(PepperFlashClipboardMessageFilter, msg)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_RegisterCustomFormat,
+ OnMsgRegisterCustomFormat)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_IsFormatAvailable,
+ OnMsgIsFormatAvailable)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_ReadData,
+ OnMsgReadData)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_WriteData,
+ OnMsgWriteData)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_GetSequenceNumber,
+ OnMsgGetSequenceNumber)
+ PPAPI_END_MESSAGE_MAP()
+ return PP_ERROR_FAILED;
+}
+
+int32_t PepperFlashClipboardMessageFilter::OnMsgRegisterCustomFormat(
+ ppapi::host::HostMessageContext* host_context,
+ const std::string& format_name)
+{
+ uint32_t format = m_custom_formats.RegisterFormat(format_name);
+ if (format == PP_FLASH_CLIPBOARD_FORMAT_INVALID)
+ return PP_ERROR_FAILED;
+ host_context->reply_msg = PpapiPluginMsg_FlashClipboard_RegisterCustomFormatReply(format);
+ return PP_OK;
+}
+
+int32_t PepperFlashClipboardMessageFilter::OnMsgIsFormatAvailable(
+ ppapi::host::HostMessageContext* host_context,
+ uint32_t clipboard_type,
+ uint32_t format)
+{
+ if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) {
+ NOTIMPLEMENTED();
+ return PP_ERROR_FAILED;
+ }
+
+ ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
+ ui::ClipboardType type = ConvertClipboardType(clipboard_type);
+ bool available = false;
+ switch (format) {
+ case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: {
+ bool plain = clipboard->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(), type);
+ bool plainw = clipboard->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(), type);
+ available = plain || plainw;
+ break;
+ }
+ case PP_FLASH_CLIPBOARD_FORMAT_HTML:
+ available = clipboard->IsFormatAvailable(ui::Clipboard::GetHtmlFormatType(), type);
+ break;
+ case PP_FLASH_CLIPBOARD_FORMAT_RTF:
+ available = clipboard->IsFormatAvailable(ui::Clipboard::GetRtfFormatType(), type);
+ break;
+ case PP_FLASH_CLIPBOARD_FORMAT_INVALID:
+ break;
+ default:
+ if (m_custom_formats.IsFormatRegistered(format)) {
+ std::string format_name = m_custom_formats.GetFormatName(format);
+ std::string clipboard_data;
+ clipboard->ReadData(ui::Clipboard::GetPepperCustomDataFormatType(), &clipboard_data);
+ base::Pickle pickle(clipboard_data.data(), clipboard_data.size());
+ available = IsFormatAvailableInPickle(base::UTF8ToUTF16(format_name), pickle);
+ }
+ break;
+ }
+
+ return available ? PP_OK : PP_ERROR_FAILED;
+}
+
+int32_t PepperFlashClipboardMessageFilter::OnMsgReadData(
+ ppapi::host::HostMessageContext* host_context,
+ uint32_t clipboard_type,
+ uint32_t format)
+{
+ if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) {
+ NOTIMPLEMENTED();
+ return PP_ERROR_FAILED;
+ }
+
+ ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
+ ui::ClipboardType type = ConvertClipboardType(clipboard_type);
+ std::string clipboard_string;
+ int32_t result = PP_ERROR_FAILED;
+ switch (format) {
+ case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: {
+ if (clipboard->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(), type)) {
+ base::string16 text;
+ clipboard->ReadText(type, &text);
+ if (!text.empty()) {
+ result = PP_OK;
+ clipboard_string = base::UTF16ToUTF8(text);
+ break;
+ }
+ }
+ // If the PlainTextW format isn't available or is empty, take the
+ // ASCII text format.
+ if (clipboard->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(), type)) {
+ result = PP_OK;
+ clipboard->ReadAsciiText(type, &clipboard_string);
+ }
+ break;
+ }
+ case PP_FLASH_CLIPBOARD_FORMAT_HTML: {
+ if (!clipboard->IsFormatAvailable(ui::Clipboard::GetHtmlFormatType(), type)) {
+ break;
+ }
+
+ base::string16 html;
+ std::string url;
+ uint32_t fragment_start;
+ uint32_t fragment_end;
+ clipboard->ReadHTML(type, &html, &url, &fragment_start, &fragment_end);
+ result = PP_OK;
+ clipboard_string = base::UTF16ToUTF8(html.substr(fragment_start, fragment_end - fragment_start));
+ break;
+ }
+ case PP_FLASH_CLIPBOARD_FORMAT_RTF: {
+ if (!clipboard->IsFormatAvailable(ui::Clipboard::GetRtfFormatType(), type)) {
+ break;
+ }
+ result = PP_OK;
+ clipboard->ReadRTF(type, &clipboard_string);
+ break;
+ }
+ case PP_FLASH_CLIPBOARD_FORMAT_INVALID:
+ break;
+ default:
+ if (m_custom_formats.IsFormatRegistered(format)) {
+ base::string16 format_name =
+ base::UTF8ToUTF16(m_custom_formats.GetFormatName(format));
+ std::string clipboard_data;
+ clipboard->ReadData(ui::Clipboard::GetPepperCustomDataFormatType(),
+ &clipboard_data);
+ base::Pickle pickle(clipboard_data.data(), clipboard_data.size());
+ if (IsFormatAvailableInPickle(format_name, pickle)) {
+ result = PP_OK;
+ clipboard_string = ReadDataFromPickle(format_name, pickle);
+ }
+ }
+ break;
+ }
+
+ if (result == PP_OK) {
+ host_context->reply_msg = PpapiPluginMsg_FlashClipboard_ReadDataReply(clipboard_string);
+ }
+ return result;
+}
+
+int32_t PepperFlashClipboardMessageFilter::OnMsgWriteData(
+ ppapi::host::HostMessageContext* host_context,
+ uint32_t clipboard_type,
+ const std::vector<uint32_t>& formats,
+ const std::vector<std::string>& data)
+{
+ if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) {
+ NOTIMPLEMENTED();
+ return PP_ERROR_FAILED;
+ }
+ if (formats.size() != data.size())
+ return PP_ERROR_FAILED;
+
+ ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
+ ui::ClipboardType type = ConvertClipboardType(clipboard_type);
+ // If no formats are passed in clear the clipboard.
+ if (formats.size() == 0) {
+ clipboard->Clear(type);
+ return PP_OK;
+ }
+
+ ui::ScopedClipboardWriter scw(type);
+ std::map<base::string16, std::string> custom_data_map;
+ int32_t res = PP_OK;
+ for (uint32_t i = 0; i < formats.size(); ++i) {
+ if (data[i].length() > kMaxClipboardWriteSize) {
+ res = PP_ERROR_NOSPACE;
+ break;
+ }
+
+ switch (formats[i]) {
+ case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT:
+ scw.WriteText(base::UTF8ToUTF16(data[i]));
+ break;
+ case PP_FLASH_CLIPBOARD_FORMAT_HTML:
+ scw.WriteHTML(base::UTF8ToUTF16(data[i]), std::string());
+ break;
+ case PP_FLASH_CLIPBOARD_FORMAT_RTF:
+ scw.WriteRTF(data[i]);
+ break;
+ case PP_FLASH_CLIPBOARD_FORMAT_INVALID:
+ res = PP_ERROR_BADARGUMENT;
+ break;
+ default:
+ if (m_custom_formats.IsFormatRegistered(formats[i])) {
+ std::string format_name = m_custom_formats.GetFormatName(formats[i]);
+ custom_data_map[base::UTF8ToUTF16(format_name)] = data[i];
+ } else {
+ // Invalid format.
+ res = PP_ERROR_BADARGUMENT;
+ break;
+ }
+ }
+
+ if (res != PP_OK)
+ break;
+ }
+
+ if (custom_data_map.size() > 0) {
+ base::Pickle pickle;
+ if (WriteDataToPickle(custom_data_map, &pickle)) {
+ scw.WritePickledData(pickle, ui::Clipboard::GetPepperCustomDataFormatType());
+ } else {
+ res = PP_ERROR_BADARGUMENT;
+ }
+ }
+
+ if (res != PP_OK) {
+ // Need to clear the objects so nothing is written.
+ scw.Reset();
+ }
+
+ return res;
+}
+
+int32_t PepperFlashClipboardMessageFilter::OnMsgGetSequenceNumber(
+ ppapi::host::HostMessageContext* host_context,
+ uint32_t clipboard_type)
+{
+ if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) {
+ NOTIMPLEMENTED();
+ return PP_ERROR_FAILED;
+ }
+
+ ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
+ ui::ClipboardType type = ConvertClipboardType(clipboard_type);
+ int64_t sequence_number = clipboard->GetSequenceNumber(type);
+ host_context->reply_msg = PpapiPluginMsg_FlashClipboard_GetSequenceNumberReply(sequence_number);
+ return PP_OK;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.h b/src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.h
new file mode 100644
index 000000000..c00e668ea
--- /dev/null
+++ b/src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/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$
+**
+****************************************************************************/
+
+// based on chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h
+// 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.
+
+#ifndef PEPPER_FLASH_CLIPBOARD_MESSAGE_FILTER_QT_H
+#define PEPPER_FLASH_CLIPBOARD_MESSAGE_FILTER_QT_H
+
+#include <string>
+#include <vector>
+
+#include "base/compiler_specific.h"
+#include "ppapi/host/resource_message_filter.h"
+#include "ppapi/shared_impl/flash_clipboard_format_registry.h"
+
+namespace ppapi {
+namespace host {
+struct HostMessageContext;
+}
+}
+
+namespace ui {
+class ScopedClipboardWriter;
+}
+
+namespace QtWebEngineCore {
+
+// Resource message filter for accessing the clipboard in Pepper. Pepper
+// supports reading/writing custom formats from the clipboard. Currently, all
+// custom formats that are read/written from the clipboard through pepper are
+// stored in a single real clipboard format (in the same way the "web custom"
+// clipboard formats are). This is done so that we don't have to have use real
+// clipboard types for each custom clipboard format which may be a limited
+// resource on a particular platform.
+class PepperFlashClipboardMessageFilter : public ppapi::host::ResourceMessageFilter {
+public:
+ PepperFlashClipboardMessageFilter();
+
+protected:
+ // ppapi::host::ResourceMessageFilter overrides.
+ scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage(const IPC::Message& msg) override;
+ int32_t OnResourceMessageReceived(const IPC::Message& msg, ppapi::host::HostMessageContext* context) override;
+
+private:
+ ~PepperFlashClipboardMessageFilter() override;
+
+ int32_t OnMsgRegisterCustomFormat(ppapi::host::HostMessageContext* host_context, const std::string& format_name);
+ int32_t OnMsgIsFormatAvailable(ppapi::host::HostMessageContext* host_context,
+ uint32_t clipboard_type,
+ uint32_t format);
+ int32_t OnMsgReadData(ppapi::host::HostMessageContext* host_context,
+ uint32_t clipoard_type,
+ uint32_t format);
+ int32_t OnMsgWriteData(ppapi::host::HostMessageContext* host_context,
+ uint32_t clipboard_type,
+ const std::vector<uint32_t>& formats,
+ const std::vector<std::string>& data);
+ int32_t OnMsgGetSequenceNumber(ppapi::host::HostMessageContext* host_context,
+ uint32_t clipboard_type);
+
+ int32_t WriteClipboardDataItem(uint32_t format,
+ const std::string& data,
+ ui::ScopedClipboardWriter* scw);
+
+ ppapi::FlashClipboardFormatRegistry m_custom_formats;
+
+ DISALLOW_COPY_AND_ASSIGN(PepperFlashClipboardMessageFilter);
+};
+
+} // namespace QtWebEngineCore
+
+#endif // PEPPER_FLASH_CLIPBOARD_MESSAGE_FILTER_QT_H
diff --git a/src/core/renderer/pepper/pepper_host_factory_qt.cpp b/src/core/renderer/pepper/pepper_host_factory_qt.cpp
index a0bab1e51..9aece100c 100644
--- a/src/core/renderer/pepper/pepper_host_factory_qt.cpp
+++ b/src/core/renderer/pepper/pepper_host_factory_qt.cpp
@@ -54,10 +54,10 @@
#include "ppapi/shared_impl/ppapi_permissions.h"
#include "pepper_flash_browser_host_qt.h"
+#include "pepper_flash_clipboard_message_filter_qt.h"
#include "pepper_isolated_file_system_message_filter.h"
using ppapi::host::MessageFilterHost;
-using ppapi::host::ResourceHost;
using ppapi::host::ResourceMessageFilter;
namespace QtWebEngineCore {
@@ -80,10 +80,18 @@ std::unique_ptr<ppapi::host::ResourceHost> PepperHostFactoryQt::CreateResourceHo
if (!host_->IsValidInstance(instance))
return nullptr;
- if (host_->GetPpapiHost()->permissions().HasPermission(ppapi::PERMISSION_FLASH)
- && message.type() == PpapiHostMsg_Flash_Create::ID)
- return base::WrapUnique(
- new PepperFlashBrowserHostQt(host_, instance, resource));
+ // Flash interfaces.
+ if (host_->GetPpapiHost()->permissions().HasPermission(ppapi::PERMISSION_FLASH)) {
+ switch (message.type()) {
+ case PpapiHostMsg_Flash_Create::ID:
+ return base::WrapUnique(new PepperFlashBrowserHostQt(host_, instance, resource));
+ case PpapiHostMsg_FlashClipboard_Create::ID: {
+ scoped_refptr<ResourceMessageFilter> clipboard_filter(new PepperFlashClipboardMessageFilter);
+ return base::WrapUnique(new MessageFilterHost(
+ host_->GetPpapiHost(), instance, resource, clipboard_filter));
+ }
+ }
+ }
// Permissions for the following interfaces will be checked at the
// time of the corresponding instance's methods calls (because
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 134b5b63c..15125b9d8 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -70,6 +70,7 @@
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/favicon_status.h"
+#include "content/public/common/content_constants.h"
#include <content/public/common/drop_data.h>
#include "content/public/common/page_state.h"
#include "content/public/common/page_zoom.h"
@@ -517,7 +518,12 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT
urlString.append(",");
urlString.append(encodedData.constData(), encodedData.length());
- content::NavigationController::LoadURLParams params((GURL(urlString)));
+ GURL dataUrlToLoad(urlString);
+ if (dataUrlToLoad.spec().size() > url::kMaxURLChars) {
+ d->adapterClient->loadFinished(false, baseUrl, false, net::ERR_ABORTED);
+ return;
+ }
+ content::NavigationController::LoadURLParams params((dataUrlToLoad));
params.load_type = content::NavigationController::LOAD_TYPE_DATA;
params.base_url_for_data_url = toGurl(baseUrl);
params.virtual_url_for_data_url = baseUrl.isEmpty() ? GURL(url::kAboutBlankURL) : toGurl(baseUrl);
@@ -1114,10 +1120,7 @@ static blink::WebDragOperationsMask toWeb(const Qt::DropActions action)
static void fillDropDataFromMimeData(content::DropData *dropData, const QMimeData *mimeData)
{
- if (mimeData->hasText())
- dropData->text = toNullableString16(mimeData->text());
- if (mimeData->hasHtml())
- dropData->html = toNullableString16(mimeData->html());
+ Q_ASSERT(dropData->filenames.empty());
Q_FOREACH (const QUrl &url, mimeData->urls()) {
if (url.isLocalFile()) {
ui::FileInfo uifi;
@@ -1125,6 +1128,12 @@ static void fillDropDataFromMimeData(content::DropData *dropData, const QMimeDat
dropData->filenames.push_back(uifi);
}
}
+ if (!dropData->filenames.empty())
+ return;
+ if (mimeData->hasHtml())
+ dropData->html = toNullableString16(mimeData->html());
+ else if (mimeData->hasText())
+ dropData->text = toNullableString16(mimeData->text());
}
void WebContentsAdapter::enterDrag(QDragEnterEvent *e, const QPoint &screenPos)
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 80aabaa4d..c50f38b38 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -257,6 +257,7 @@ public:
virtual void updateContentsSize(const QSizeF &size) = 0;
virtual void startDragging(const content::DropData &dropData, Qt::DropActions allowedActions,
const QPixmap &pixmap, const QPoint &offset) = 0;
+ virtual bool isEnabled() const = 0;
virtual QSharedPointer<BrowserContextAdapter> browserContextAdapter() = 0;
virtual WebContentsAdapter* webContentsAdapter() = 0;
diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp
index 1d39d8af8..e487fca46 100644
--- a/src/core/web_contents_view_qt.cpp
+++ b/src/core/web_contents_view_qt.cpp
@@ -120,6 +120,8 @@ void WebContentsViewQt::GetContainerBounds(gfx::Rect* out) const
void WebContentsViewQt::Focus()
{
+ if (!m_client->isEnabled())
+ return;
if (content::RenderWidgetHostView *rwhv = m_webContents->GetRenderWidgetHostView())
rwhv->Focus();
m_client->focusContainer();
diff --git a/src/webengine/api/qquickwebenginesettings.cpp b/src/webengine/api/qquickwebenginesettings.cpp
index 9096dd604..3fea83166 100644
--- a/src/webengine/api/qquickwebenginesettings.cpp
+++ b/src/webengine/api/qquickwebenginesettings.cpp
@@ -217,7 +217,7 @@ bool QQuickWebEngineSettings::errorPageEnabled() const
Disabled by default.
- \sa {Pepper Plugin API Support}
+ \sa {Pepper Plugin API}
*/
bool QQuickWebEngineSettings::pluginsEnabled() const
{
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 1b1dcec25..59b5d17db 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -124,6 +124,8 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
, m_dpiScale(1.0)
, m_backgroundColor(Qt::white)
, m_defaultZoomFactor(1.0)
+ // QTBUG-53467
+ , m_menuEnabled(true)
{
// The gold standard for mobile web content is 160 dpi, and the devicePixelRatio expected
// is the (possibly quantized) ratio of device dpi to 160 dpi.
@@ -141,6 +143,8 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
// 1x, 2x, 3x etc assets that fit an integral number of pixels.
setDevicePixelRatio(qMax(1, qRound(webPixelRatio)));
}
+ if (platform == QLatin1Literal("eglfs"))
+ m_menuEnabled = false;
#ifndef QT_NO_ACCESSIBILITY
QAccessible::installFactory(&webAccessibleFactory);
#endif // QT_NO_ACCESSIBILITY
@@ -191,6 +195,12 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu
{
Q_Q(QQuickWebEngineView);
+ if (!m_menuEnabled) {
+ qWarning("You are trying to open context menu on eglfs backend, which is not currently supported\n"
+ "See QTBUG-53467.");
+ return false;
+ }
+
// Assign the WebEngineView as the parent of the menu, so mouse events are properly propagated
// on OSX.
QObject *menu = ui()->addMenu(q, QString(), data.pos);
@@ -1075,6 +1085,12 @@ void QQuickWebEngineViewPrivate::startDragging(const content::DropData &dropData
adapter->startDragging(q_ptr->window(), dropData, allowedActions, pixmap, offset);
}
+bool QQuickWebEngineViewPrivate::isEnabled() const
+{
+ const Q_Q(QQuickWebEngineView);
+ return q->isEnabled();
+}
+
bool QQuickWebEngineView::isLoading() const
{
Q_D(const QQuickWebEngineView);
@@ -1184,24 +1200,32 @@ void QQuickWebEngineView::setBackgroundColor(const QColor &color)
The default value is false.
*/
-bool QQuickWebEngineView::isAudioMuted() const {
+bool QQuickWebEngineView::isAudioMuted() const
+{
const Q_D(QQuickWebEngineView);
- return d->adapter->isAudioMuted();
-
+ if (d->adapter)
+ return d->adapter->isAudioMuted();
+ return false;
}
-void QQuickWebEngineView::setAudioMuted(bool muted) {
+
+void QQuickWebEngineView::setAudioMuted(bool muted)
+{
Q_D(QQuickWebEngineView);
bool _isAudioMuted = isAudioMuted();
- d->adapter->setAudioMuted(muted);
- if (_isAudioMuted != muted) {
- Q_EMIT audioMutedChanged(muted);
+ if (d->adapter) {
+ d->adapter->setAudioMuted(muted);
+ if (_isAudioMuted != muted) {
+ Q_EMIT audioMutedChanged(muted);
+ }
}
}
bool QQuickWebEngineView::recentlyAudible() const
{
const Q_D(QQuickWebEngineView);
- return d->adapter->recentlyAudible();
+ if (d->adapter)
+ return d->adapter->recentlyAudible();
+ return false;
}
void QQuickWebEngineView::printToPdf(const QString& filePath, PrintedPageSizeId pageSizeId, PrintedPageOrientation orientation)
diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index d287b46ca..b72f79f30 100644
--- a/src/webengine/api/qquickwebengineview_p.h
+++ b/src/webengine/api/qquickwebengineview_p.h
@@ -54,6 +54,7 @@
#include <private/qtwebengineglobal_p.h>
#include "qquickwebenginescript_p.h"
#include <QQuickItem>
+#include <QtGui/qcolor.h>
QT_BEGIN_NAMESPACE
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index 82a9e9612..909763614 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -187,6 +187,7 @@ public:
virtual void updateContentsSize(const QSizeF &size) Q_DECL_OVERRIDE;
void startDragging(const content::DropData &dropData, Qt::DropActions allowedActions,
const QPixmap &pixmap, const QPoint &offset) Q_DECL_OVERRIDE;
+ virtual bool isEnabled() const Q_DECL_OVERRIDE;
virtual QSharedPointer<QtWebEngineCore::BrowserContextAdapter> browserContextAdapter() Q_DECL_OVERRIDE;
QtWebEngineCore::WebContentsAdapter *webContentsAdapter() Q_DECL_OVERRIDE;
@@ -233,6 +234,8 @@ private:
qreal m_dpiScale;
QColor m_backgroundColor;
qreal m_defaultZoomFactor;
+ // QTBUG-53467
+ bool m_menuEnabled;
};
#ifndef QT_NO_ACCESSIBILITY
diff --git a/src/webengine/doc/qtwebengine.qdocconf b/src/webengine/doc/qtwebengine.qdocconf
index baa4a9859..009902080 100644
--- a/src/webengine/doc/qtwebengine.qdocconf
+++ b/src/webengine/doc/qtwebengine.qdocconf
@@ -4,8 +4,6 @@ project = QtWebEngine
description = Qt WebEngine Reference Documentation
version = $QT_VERSION
-examplesinstallpath = qtwebengine
-
qhp.projects = QtWebEngine
qhp.QtWebEngine.file = qtwebengine.qhp
@@ -42,8 +40,10 @@ tagfile = ../../../doc/qtwebengine/qtwebengine.tags
depends += qtcore \
qtgui \
+ qtlocation \
qtnetwork \
qtprintsupport \
+ qtpositioning \
qtqml \
qtquick \
qtquickcontrols \
diff --git a/src/webengine/doc/src/external-resources.qdoc b/src/webengine/doc/src/external-resources.qdoc
index 6356e13bb..c4cfe24af 100644
--- a/src/webengine/doc/src/external-resources.qdoc
+++ b/src/webengine/doc/src/external-resources.qdoc
@@ -47,7 +47,47 @@
/*!
\externalpage http://www.openh264.org/
- \title OpenH264
+ \title OpenH264 Project Homepage
+*/
+
+/*!
+ \externalpage http://html5demos.com/drag
+ \title HTML5 Demos - Drag and Drop
+*/
+
+/*!
+ \externalpage http://html5demos.com/drag-anything
+ \title HTML5 Demos - Simple Drag and Drop
+*/
+
+/*!
+ \externalpage http://html5demos.com/dnd-upload
+ \title HTML5 Demos - Drag and Drop, Automatic Upload
+*/
+
+/*!
+ \externalpage http://html5demos.com/file-api
+ \title HTML5 Demos - File API
+*/
+
+/*!
+ \externalpage http://www.widevine.com/wv_drm.html
+ \title Widevine DRM
+*/
+
+/*!
+ \externalpage http://demo.castlabs.com/
+ \title castLabs
+*/
+
+/*!
+ \externalpage http://ssdemo04.swankmp.net/
+ \title Swank Motion Pictures, Inc.
+*/
+
+/*!
+ \externalpage https://shaka-player-demo.appspot.com/demo/
+ \title Shaka Player
*/
/*
diff --git a/src/webengine/doc/src/qtwebengine-features.qdoc b/src/webengine/doc/src/qtwebengine-features.qdoc
new file mode 100644
index 000000000..52f7da928
--- /dev/null
+++ b/src/webengine/doc/src/qtwebengine-features.qdoc
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \page qtwebengine-features.html
+ \title Qt WebEngine Features
+
+ \brief Summarizes Qt WebEngine features.
+
+ Qt WebEngine supports the following Chromium features:
+
+ \list
+ \li \l{Audio and Video Codecs}
+ \li \l{Chromium DevTools}
+ \li \l{Drag and Drop}
+ \li \l{Fullscreen}
+ \li \l{HTML5 DRM}
+ \li \l{HTML5 Geolocation}
+ \li \l{Pepper Plugin API}
+ \li \l{Print to PDF}
+ \li \l{WebRTC}
+ \endlist
+
+ \section1 Audio and Video Codecs
+
+ Qt WebEngine supports the MPEG-4 Part 14 (MP4) file format only if the
+ required proprietary audio and video codecs, such as H.264 and MPEG layer-3
+ (MP3), have been enabled. Proprietary codecs can be enabled by passing the
+ following option to qmake when building Qt WebEngine:
+
+ \code
+ qmake WEBENGINE_CONFIG+=use_proprietary_codecs
+ \endcode
+
+ \warning When distributing proprietary codec libraries, you must acquire
+ licenses for them.
+
+ \l FFmpeg is a cross-platform solution to record, convert, and stream audio
+ and video. It can be configured for use with several codecs, which rises
+ licensing issues during distribution with the codec libraries. For some
+ codecs, open source implementations, such as \l{OpenH264 Project Homepage}
+ {OpenH264}, are available.
+
+ \section1 Chromium DevTools
+
+ The Chromium DevTools provide the ability to inspect and debug layout and
+ performance issues of any web content.
+
+ This feature can be tested by launching a Qt WebEngine application with the
+ command line option \c {--remote-debugging-port=[your-port]} or by setting
+ the environment variable \c QTWEBENGINE_REMOTE_DEBUGGING, and then using a
+ Chromium based browser (such as \l{WebEngine Demo Browser Example}
+ {Demo Browser} or \l{WebEngine Quick Nano Browser}{Nano Browser}) to connect
+ to \c {http://localhost:[your-port]}.
+
+ For more information, see \l {Qt WebEngine Debugging and Profiling}.
+
+ \section1 Drag and Drop
+
+ Qt WebEngine supports HTML5 drag and drop.
+
+ This feature can be tested by opening an HTML5 drag and drop demo, such as
+ \l{HTML5 Demos - Drag and Drop}, \l{HTML5 Demos - Simple Drag and Drop}, or
+ \l{HTML5 Demos - Drag and Drop, Automatic Upload}, in \l{WebEngine Demo
+ Browser Example}{Demo Browser} or \l{WebEngine Quick Nano Browser}
+ {Nano Browser}.
+
+ Dragging files into the browser is not actually part of HTML5, but it is
+ supported. It can be tested by opening \l{HTML5 Demos - File API}.
+
+ Support for this feature was added in Qt 5.7.0.
+
+ \section1 Fullscreen
+
+ Qt WebEngine supports viewing web content in fullscreen mode. For more
+ information, see \l{WebEngineSettings::fullscreenSupportEnabled}
+ {WebEngineSettings.fullscreenSupportEnabled},
+ \l{WebEngineView::fullScreenRequested}{WebEngineView.fullScreenRequested},
+ QWebEngineSettings::FullScreenSupportEnabled, and
+ QWebEnginePage::fullScreenRequested.
+
+ This feature can be tested by playing a video from YouTube in \l{WebEngine
+ Demo Browser Example}{Demo Browser} or \l{WebEngine Quick Nano Browser}
+ {Nano Browser}, and clicking the full screen icon to go into fullscreen
+ mode.
+
+ Support for this feature was added in Qt 5.6.0.
+
+ \section1 HTML5 DRM
+
+ Qt WebEngine supports viewing DRM protected videos if the \l{Widevine DRM}
+ plugin has been installed.
+
+ The video format most commonly used by DRM services, H.264, requires
+ proprietary audio and video codecs. For more information about enabling the
+ codecs, see \l{Audio and Video Codecs}.
+
+ This feature can be tested by playing a video in \l{WebEngine Demo Browser
+ Example}{Demo Browser} or \l{WebEngine Quick Nano Browser}{Nano Browser}
+ from \l{castLabs}, \l{Swank Motion Pictures, Inc.}, or \l{Shaka Player}.
+
+ Support for this feature was added in Qt 5.7.0.
+
+ \section1 HTML5 Geolocation
+
+ Qt WebEngine supports JavaScript Geolocation API with \l {Qt Location} as a
+ backend. The application has to explicitly allow the feature by using
+ QWebEnginePage::Geolocation or \l{WebEngineView::Feature}
+ {WebEngineView.Feature}.
+
+ This feature can be tested if Qt Location has been built before Qt WebEngine.
+ The \c http://html5demos.com/geo page can be opened in the \l{WebEngine Demo
+ Browser Example}{Demo Browser} and allowed to find the current position of
+ the user. Note that on Windows an external GPS receiver must be connected to
+ the application. For more information, see \l{Qt Positioning}.
+
+ Support for this feature was added in Qt 5.5.0.
+
+ \section1 Pepper Plugin API
+
+ Qt WebEngine supports loading Pepper Plugin API (PPAPI) plugins if
+ WebEngineSettings::pluginsEnabled or QWebEngineSettings::PluginsEnabled
+ is set.
+
+ Except for the Adobe Flash Player plugin, the plugins must be loaded
+ manually using the Chromium command line syntax with the
+ \c --register-pepper-plugins argument. The argument value is a list of
+ entries, separated by commas, that contain the file path and one or several
+ MIME types, separated by semicolons:
+
+ \code
+ <file-path-plugin1>;<mime-type-plugin1>,<file-path-plugin2>;<mime-type1-plugin2>;<mime-type2-plugin2>
+ \endcode
+
+ For example:
+
+ \code
+ --register-pepper-plugins="libppapi_example.so;application/x-ppapi-example"
+ \endcode
+
+ The MIME type is important because it determines which embeds the plugin is
+ used for.
+
+ Support for this feature was added in Qt 5.6.0.
+
+ \section2 Pepper Flash Player Plugin Support
+
+ The Pepper Flash player plugin can be loaded automatically if it is
+ installed in one of the following locations, depending on the platform:
+
+ \list
+ \li Windows
+ \code
+ C:\Windows\SysWOW64\Macromed\Flash\pepflashplayer*.dll
+ C:\Windows\System32\Macromed\Flash\pepflashplayer*.dll
+ \endcode
+ \li OS X
+ \code
+ /Library/Internet Plug-Ins/PepperFlashPlayer/PepperFlashPlayer.plugin
+ \endcode
+ \li Linux
+ \code
+ /usr/lib/pepperflashplugin-nonfree/libpepflashplayer.so
+ /usr/lib/PepperFlash/libpepflashplayer.so
+ /usr/lib64/chromium/PepperFlash/libpepflashplayer.so
+ \endcode
+ \endlist
+
+ You can also load the Pepper Flash player from a specific location by using
+ command line arguments:
+
+ \code
+ --ppapi-flash-path=./libpepflashplayer.so
+ \endcode
+
+ By default, the Flash version is set to \c{11.2.999.999}. You can use the
+ \c{ppapi-flash-version=} argument to set another Flash version in the
+ format \c{major.minor.build.revision}:
+
+ \code
+ --ppapi-flash-version=16.0.0.235
+ \endcode
+
+ This feature can be tested in \l{WebEngine Demo Browser Example}{Demo Browser}
+ or \l{WebEngine Quick Nano Browser}{Nano Browser} if the Adobe Flash PPAPI
+ plugin is installed and plugins are enabled in the browser. To test the
+ feature, the \c https://helpx.adobe.com/flash-player.html page can be opened
+ in the browser.
+
+ \section1 Print to PDF
+
+ Qt WebEngine supports printing a web page to a PDF file. For more
+ information, see QWebEnginePage::printToPdf() and
+ \l{WebEngineView::printToPdf}{WebEngineView.printToPdf}.
+
+ This feature can be tested in \l{WebEngine Demo Browser Example}
+ {Demo Browser} by selecting \uicontrol File > \uicontrol {Print to PDF}.
+
+ Support for this feature was added in Qt 5.7.0.
+
+ \section1 WebRTC
+
+ WebRTC provides browsers with Real-Time Communications (RTC) capabilities
+ via simple APIs. For more information, see \l{WebEngineView::Feature}
+ {WebEngineView.Feature} and QWebEnginePage::Feature.
+
+ This feature can be tested by setting up a webcam or microphone and then
+ opening \c https://test.webrtc.org/ in \l{WebEngine Widgets Simple Browser
+ Example}{Simple Browser} or \l{WebEngine Quick Nano Browser}{Nano Browser}.
+*/
diff --git a/src/webengine/doc/src/qtwebengine-index.qdoc b/src/webengine/doc/src/qtwebengine-index.qdoc
index 4cca431f0..e7314fcf9 100644
--- a/src/webengine/doc/src/qtwebengine-index.qdoc
+++ b/src/webengine/doc/src/qtwebengine-index.qdoc
@@ -46,6 +46,7 @@
\list
\li \l{Qt WebEngine Overview}
+ \li \l{Qt WebEngine Features}
\li \l{Qt WebEngine Platform Notes}
\li \l{Qt WebEngine Licensing}
\li \l{Qt WebEngine Debugging and Profiling}
diff --git a/src/webengine/doc/src/qtwebengine-overview.qdoc b/src/webengine/doc/src/qtwebengine-overview.qdoc
index d4d9af199..7ae3afaf4 100644
--- a/src/webengine/doc/src/qtwebengine-overview.qdoc
+++ b/src/webengine/doc/src/qtwebengine-overview.qdoc
@@ -60,16 +60,16 @@
The functionality in Qt WebEngine is divided into the following modules:
\list
- \li \l{Qt WebEngine Widgets} for creating widget-based web applications
- \li \l{Qt WebEngine} for creating Qt Quick based web applications
- \li \l{Qt WebEngine Core} for interacting with Chromium
+ \li \l{Qt WebEngine Widgets Module} for creating widget-based web applications
+ \li \l{Qt WebEngine Module} for creating Qt Quick based web applications
+ \li \l{Qt WebEngine Core Module} for interacting with Chromium
\endlist
Page rendering and JavaScript execution are separated from the GUI process into the Qt WebEngine
Process. It is a library that must be shipped with the application if the Qt libraries are
bundled into the application.
- \section2 Qt WebEngine Widgets
+ \section2 Qt WebEngine Widgets Module
\image qtwebenginewidgets-model.png
@@ -82,7 +82,7 @@
\e cookies. Profiles can be used to isolate pages from each other. A typical use case is a
dedicated profile for a \e {private browsing} mode, where no information is permanently saved.
- \section2 Qt WebEngine
+ \section2 Qt WebEngine Module
\image qtwebengine-model.png
@@ -90,7 +90,7 @@
except that there is no separately accessible web engine page. The supported page functionality
is integrated into the web engine view.
- \section2 Qt WebEngine Core
+ \section2 Qt WebEngine Core Module
The Qt WebEngine core is based on the \l {Chromium Project}. Chromium provides its own network
and painting engines and is developed tightly together with its dependent modules, and
diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
index 4bb449016..ecec53bda 100644
--- a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
+++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
@@ -87,6 +87,7 @@
\section2 Linux
On Linux, Clang or GCC version 4.7 or later is required.
+ Supported configurations are \c linux-g++ and \c{linux-clang}.
Qt WebEngine requires \c pkg-config to detect most of its dependencies. The
following \c pkg-config files are required:
@@ -118,84 +119,6 @@
\note Qt WebEngine cannot be built for the 32-bit mode of OS X (using the
\c macx-clang-32 \c mkspec).
- \section1 Pepper Plugin API Support
-
- Qt WebEngine supports loading Pepper Plugin API (PPAPI) plugins if
- WebEngineSettings::pluginsEnabled or QWebEngineSettings::PluginsEnabled
- is set.
-
- Except for the Adobe Flash Player plugin, the plugins must be loaded manually using the
- Chromium command line syntax with the \c --register-pepper-plugins argument.
- The argument value is a list of entries, separated by commas, that contain the file path and
- one or several MIME types, separated by semicolons:
-
- \code
- <file-path-plugin1>;<mime-type-plugin1>,<file-path-plugin2>;<mime-type1-plugin2>;<mime-type2-plugin2>
- \endcode
-
- For example:
-
- \code
- --register-pepper-plugins="libppapi_example.so;application/x-ppapi-example"
- \endcode
-
- The MIME type is important because it determines which embeds the plugin is used for.
-
- \section2 Pepper Flash Player Plugin Support
-
- The Pepper Flash player plugin can be loaded automatically if it is installed in one of the
- following locations, depending on the platform:
-
- \list
- \li Windows
- \code
- C:\Windows\SysWOW64\Macromed\Flash\pepflashplayer*.dll
- C:\Windows\System32\Macromed\Flash\pepflashplayer*.dll
- \endcode
- \li OS X
- \code
- /Library/Internet Plug-Ins/PepperFlashPlayer/PepperFlashPlayer.plugin
- \endcode
- \li Linux
- \code
- /usr/lib/pepperflashplugin-nonfree/libpepflashplayer.so
- /usr/lib/PepperFlash/libpepflashplayer.so
- /usr/lib64/chromium/PepperFlash/libpepflashplayer.so
- \endcode
- \endlist
-
- You can also load the Pepper Flash player from a specific location by using command line
- arguments:
-
- \code
- --ppapi-flash-path=./libpepflashplayer.so
- \endcode
-
- By default, the Flash version is set to \c{11.2.999.999}. You can use the
- \c{ppapi-flash-version=} argument to set another Flash version in the
- in the format \c{major.minor.build.revision}:
-
- \code
- --ppapi-flash-version=16.0.0.235
- \endcode
-
- \section1 Audio and Video Codec Support
-
- Qt WebEngine supports the MPEG-4 Part 14 (MP4) file format only if the required proprietary
- audio and video codecs, such as H.264 and MPEG layer-3 (MP3), have been enabled. Proprietary
- codecs can be enabled by passing the following option to qmake:
-
- \code
- qmake WEBENGINE_CONFIG+=use_proprietary_codecs
- \endcode
-
- \warning When distributing proprietary codec libraries, you must acquire licenses for them.
-
- \l FFmpeg is a cross-platform solution to record, convert, and stream audio and video. It can
- be configured for use with several codecs, which rises licensing issues during distribution
- with the codec libraries. For some codecs, open source implementations, such as \l {OpenH264},
- are available.
-
\section1 Mac App Store Compatibility
By default, Qt WebEngine uses private OS X API, which might cause an application to be
@@ -203,7 +126,7 @@
calls, Qt WebEngine has to be recompiled:
\code
- qmake WEBENGINE_CONFIG += use_appstore_compliant_code
+ qmake WEBENGINE_CONFIG+=use_appstore_compliant_code
\endcode
However, this will cause some behavioral changes, such as:
diff --git a/src/webengine/doc/src/webengineview.qdoc b/src/webengine/doc/src/webengineview.qdoc
index a4630484e..0f83d0d23 100644
--- a/src/webengine/doc/src/webengineview.qdoc
+++ b/src/webengine/doc/src/webengineview.qdoc
@@ -404,7 +404,7 @@
\since QtWebEngine 1.1
Finds the specified string, \a subString, in the page.
- To clear the selection, just pass an empty string.
+ To clear the search highlight, just pass an empty string.
*/
/*!
@@ -412,7 +412,7 @@
\since QtWebEngine 1.1
Finds the specified string, \a subString, in the page, using the given \a options.
- To clear the selection, just pass an empty string.
+ To clear the search highlight, just pass an empty string.
\code
findText("Qt", WebEngineView.FindBackward | WebEngineView.FindCaseSensitively);
@@ -424,7 +424,7 @@
\since QtWebEngine 1.1
Finds the specified string, \a subString, in the page, using the given \a options.
- To clear the selection, just pass an empty string.
+ To clear the search highlight, just pass an empty string.
The \a resultCallback must take a boolean parameter. It will be called with
a value of true if the \a subString was found; otherwise the callback value
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 9ad86800c..5e39cc2b3 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
@@ -222,18 +222,33 @@ void RenderWidgetHostViewQtDelegateQuick::focusOutEvent(QFocusEvent *event)
void RenderWidgetHostViewQtDelegateQuick::mousePressEvent(QMouseEvent *event)
{
- if (!m_isPopup && (parentItem() && parentItem()->property("activeFocusOnPress").toBool()))
+ QQuickItem *parent = parentItem();
+ if (!m_isPopup && (parent && parent->property("activeFocusOnPress").toBool()))
forceActiveFocus();
+ if (parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) {
+ event->ignore();
+ return;
+ }
m_client->forwardEvent(event);
}
void RenderWidgetHostViewQtDelegateQuick::mouseMoveEvent(QMouseEvent *event)
{
+ QQuickItem *parent = parentItem();
+ if (parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) {
+ event->ignore();
+ return;
+ }
m_client->forwardEvent(event);
}
void RenderWidgetHostViewQtDelegateQuick::mouseReleaseEvent(QMouseEvent *event)
{
+ QQuickItem *parent = parentItem();
+ if (parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) {
+ event->ignore();
+ return;
+ }
m_client->forwardEvent(event);
}
@@ -254,14 +269,24 @@ void RenderWidgetHostViewQtDelegateQuick::wheelEvent(QWheelEvent *event)
void RenderWidgetHostViewQtDelegateQuick::touchEvent(QTouchEvent *event)
{
+ QQuickItem *parent = parentItem();
if (event->type() == QEvent::TouchBegin && !m_isPopup
- && (parentItem() && parentItem()->property("activeFocusOnPress").toBool()))
+ && (parent && parent->property("activeFocusOnPress").toBool()))
forceActiveFocus();
+ if (parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) {
+ event->ignore();
+ return;
+ }
m_client->forwardEvent(event);
}
void RenderWidgetHostViewQtDelegateQuick::hoverMoveEvent(QHoverEvent *event)
{
+ QQuickItem *parent = parentItem();
+ if (parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) {
+ event->ignore();
+ return;
+ }
m_client->forwardEvent(event);
}
diff --git a/src/webenginewidgets/api/qwebenginecertificateerror.cpp b/src/webenginewidgets/api/qwebenginecertificateerror.cpp
index ebe3cdbec..289bb7ec0 100644
--- a/src/webenginewidgets/api/qwebenginecertificateerror.cpp
+++ b/src/webenginewidgets/api/qwebenginecertificateerror.cpp
@@ -85,6 +85,10 @@ QWebEngineCertificateError::~QWebEngineCertificateError()
This enum describes the type of certificate error encountered.
+ The values of this enum type match the SSL errors Chromium provides.
+ QSslError::SslError values are not used directly, because the Qt error
+ categories cannot be mapped to the Chromium error categories.
+
\value SslPinnedKeyNotInCertificateChain The certificate did not match the built-in public keys
pinned for the host name.
\value CertificateCommonNameInvalid The certificate's common name did not match the host name.
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 0e7f02f16..3f11e5aef 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -1143,6 +1143,7 @@ bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData
view->contextMenuEvent(&event);
break;
case Qt::CustomContextMenu:
+ contextData = data;
Q_EMIT view->customContextMenuRequested(data.pos);
break;
case Qt::ActionsContextMenu:
@@ -1269,9 +1270,21 @@ void QWebEnginePagePrivate::startDragging(const content::DropData &dropData,
adapter->startDragging(view, dropData, allowedActions, pixmap, offset);
}
+bool QWebEnginePagePrivate::isEnabled() const
+{
+ const Q_Q(QWebEnginePage);
+ const QWidget *view = q->view();
+ if (view)
+ return view->isEnabled();
+ return true;
+}
+
QMenu *QWebEnginePage::createStandardContextMenu()
{
Q_D(QWebEnginePage);
+ if (!d->contextData.d)
+ return nullptr;
+
QMenu *menu = new QMenu(d->view);
QAction *action = 0;
const WebEngineContextMenuData &contextMenuData = *d->contextData.d;
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index 22bfaff95..26ef80e9a 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -135,6 +135,7 @@ public:
virtual void updateContentsSize(const QSizeF &size) Q_DECL_OVERRIDE;
void startDragging(const content::DropData &dropData, Qt::DropActions allowedActions,
const QPixmap &pixmap, const QPoint &offset) Q_DECL_OVERRIDE;
+ virtual bool isEnabled() const Q_DECL_OVERRIDE;
virtual QSharedPointer<QtWebEngineCore::BrowserContextAdapter> browserContextAdapter() Q_DECL_OVERRIDE;
QtWebEngineCore::WebContentsAdapter *webContentsAdapter() Q_DECL_OVERRIDE;
diff --git a/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc b/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
index e6236ec98..89d7cfb0c 100644
--- a/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
+++ b/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
@@ -248,7 +248,7 @@
\b {Qt WebEngine}
\code
QWebEnginePage page;
- page.runJavascript("document.documentElement.contentEditable = true");
+ page.runJavaScript("document.documentElement.contentEditable = true");
\endcode
@@ -287,7 +287,7 @@
\li QWebPage::setContentEditable
\li In the latest HTML standard, any document element can be made editable through the
\c contentEditable attribute. So \c runJavaScript is all that is needed:
- \c{page->runJavascript("document.documentElement.contentEditable = true")}
+ \c{page->runJavaScript("document.documentElement.contentEditable = true")}
\row
\li QWebPage::setLinkDelegationPolicy
\li There is no way to connect a signal to run C++ code when a link is clicked. However,
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index fab4827a0..539e809d4 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -281,6 +281,9 @@
the user clicks on the web page with the right mouse button. It is
called from the default \l{QWidget::}{contextMenuEvent()} handler. The popup menu's
ownership is transferred to the caller.
+
+ Returns \c nullptr if the context menu data is not initialized, for example when it
+ is called when there is actually no context menu requested.
*/
/*!
@@ -411,14 +414,14 @@
\fn void QWebEnginePage::findText(const QString &subString, FindFlags options)
Finds the specified string, \a subString, in the page, using the given \a options.
- To clear the selection, just pass an empty string.
+ To clear the search highlight, just pass an empty string.
*/
/*!
\fn void QWebEnginePage::findText(const QString &subString, FindFlags options, FunctorOrLambda resultCallback)
Finds the specified string, \a subString, in the page, using the given \a options.
- To clear the selection, just pass an empty string.
+ To clear the search highlight, just pass an empty string.
The \a resultCallback must take a boolean parameter. It will be called with a value of \c true
if the \a subString was found; otherwise the callback value will be \c false.
@@ -615,6 +618,10 @@
\warning This function works only for HTML, for other mime types (such as XHTML and SVG)
setContent() should be used instead.
+ \warning The content will be percent encoded before being sent to the renderer via IPC.
+ This may increase its size. The maximum size of the percent encoded content is
+ 2 megabytes minus 30 bytes.
+
\sa toHtml(), setContent(), load()
*/
@@ -630,6 +637,10 @@
\note This method will not affect session or global history for the page.
+ \warning The content will be percent encoded before being sent to the renderer via IPC.
+ This may increase its size. The maximum size of the percent encoded content is
+ 2 megabytes minus 6 bytes plus the length of the mime type string.
+
\sa toHtml(), setHtml()
*/
diff --git a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
index 3e0f4cf82..558aa1f50 100644
--- a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
@@ -88,7 +88,8 @@
This enum type specifies settings for web pages:
\value AutoLoadImages
- Automatically loads images on web pages. Enabled by default.
+ Automatically dowloads images for web pages. When this setting is
+ disabled, images are loaded from the cache. Enabled by default.
\value JavascriptEnabled
Enables the running of JavaScript programs. Enabled by default.
\value JavascriptCanOpenWindows
@@ -130,7 +131,7 @@
Enables displaying the built-in error pages of Chromium. Enabled by default.
\value PluginsEnabled
Enables support for Pepper plugins, such as the Flash player. Disabled by default.
- See also \l{Pepper Plugin API Support}. (Added in Qt 5.6)
+ See also \l{Pepper Plugin API}. (Added in Qt 5.6)
\value FullScreenSupportEnabled
Enables fullscreen support in an application. Disabled by default. (Added in Qt 5.6)
\value ScreenCaptureEnabled
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 3f70187e7..99621b602 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -298,6 +298,34 @@ void RenderWidgetHostViewQtDelegateWidget::hideEvent(QHideEvent *event)
bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event)
{
bool handled = false;
+
+ // Mimic QWidget::event() by ignoring mouse, keyboard, touch and tablet events if the widget is
+ // disabled.
+ if (!isEnabled()) {
+ switch (event->type()) {
+ case QEvent::TabletPress:
+ case QEvent::TabletRelease:
+ case QEvent::TabletMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ case QEvent::TouchCancel:
+ case QEvent::ContextMenu:
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+#ifndef QT_NO_WHEELEVENT
+ case QEvent::Wheel:
+#endif
+ return false;
+ default:
+ break;
+ }
+ }
+
if (event->type() == QEvent::MouseButtonDblClick) {
// QWidget keeps the Qt4 behavior where the DblClick event would replace the Press event.
// QtQuick is different by sending both the Press and DblClick events for the second press
diff --git a/sync.profile b/sync.profile
index 7d6daec35..e4a88e0c2 100644
--- a/sync.profile
+++ b/sync.profile
@@ -20,7 +20,7 @@
%dependencies = (
"qtbase" => "",
"qtdeclarative" => "",
- "qtxmlpatterns" => "",
+ "qtlocation" => "",
"qttools" => "",
# FIXME: take examples out into their own module to avoid a potential circular dependency later ?
"qtquickcontrols" => "",
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index 34170da8a..1937dca04 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -364,6 +364,7 @@ static QStringList expectedAPI = QStringList()
<< "QQuickWebEngineCertificateError.CertificateNonUniqueName --> Error"
<< "QQuickWebEngineCertificateError.CertificateWeakKey --> Error"
<< "QQuickWebEngineCertificateError.CertificateNameConstraintViolation --> Error"
+ << "QQuickWebEngineCertificateError.CertificateValidityTooLong --> Error"
<< "QQuickWebEngineCertificateError.url --> QUrl"
<< "QQuickWebEngineCertificateError.error --> Error"
<< "QQuickWebEngineCertificateError.description --> QString"
@@ -492,13 +493,11 @@ static QStringList expectedAPI = QStringList()
<< "QQuickWebEngineSettings.defaultTextEncodingChanged() --> void"
<< "QQuickWebEngineSettings.screenCaptureEnabled --> bool"
<< "QQuickWebEngineSettings.webGLEnabled --> bool"
- << "QQuickWebEngineSettings.webAudioEnabled --> bool"
<< "QQuickWebEngineSettings.accelerated2dCanvasEnabled --> bool"
<< "QQuickWebEngineSettings.autoLoadIconsForPage --> bool"
<< "QQuickWebEngineSettings.touchIconsEnabled --> bool"
<< "QQuickWebEngineSettings.screenCaptureEnabledChanged() --> void"
<< "QQuickWebEngineSettings.webGLEnabledChanged() --> void"
- << "QQuickWebEngineSettings.webAudioEnabledChanged() --> void"
<< "QQuickWebEngineSettings.accelerated2dCanvasEnabledChanged() --> void"
<< "QQuickWebEngineSettings.autoLoadIconsForPageChanged() --> void"
<< "QQuickWebEngineSettings.touchIconsEnabledChanged() --> void"
diff --git a/tests/auto/quick/qquickwebengineview/BLACKLIST b/tests/auto/quick/qquickwebengineview/BLACKLIST
index d4d5c9844..2cde59454 100644
--- a/tests/auto/quick/qquickwebengineview/BLACKLIST
+++ b/tests/auto/quick/qquickwebengineview/BLACKLIST
@@ -1,2 +1,5 @@
[transparentWebEngineViews]
windows
+
+[inputEventForwardingDisabledWhenActiveFocusOnPressDisabled]
+*
diff --git a/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro b/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro
index 826b47de7..36e74a2a8 100644
--- a/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro
+++ b/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro
@@ -1,6 +1,6 @@
include(../tests.pri)
exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc
-QT_PRIVATE += webengine-private
+QT_PRIVATE += webengine-private gui-private
HEADERS += ../shared/util.h
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index 0def76d6f..1c5461fa7 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -31,6 +31,7 @@
#include <QScopedPointer>
#include <QtCore/qelapsedtimer.h>
+#include <QtGui/qpa/qwindowsysteminterface.h>
#include <QtQml/QQmlEngine>
#include <QtTest/QtTest>
#include <private/qquickwebengineview_p.h>
@@ -71,6 +72,9 @@ private Q_SLOTS:
void basicRenderingSanity();
void setZoomFactor();
void printToPdf();
+ void stopSettingFocusWhenDisabled();
+ void stopSettingFocusWhenDisabled_data();
+ void inputEventForwardingDisabledWhenActiveFocusOnPressDisabled();
private:
inline QQuickWebEngineView *newWebEngineView();
@@ -514,5 +518,139 @@ void tst_QQuickWebEngineView::printToPdf()
QVERIFY(!QFile::exists(path));
}
+void tst_QQuickWebEngineView::stopSettingFocusWhenDisabled()
+{
+ QFETCH(bool, viewEnabled);
+ QFETCH(bool, activeFocusResult);
+
+ QQuickWebEngineView *view = webEngineView();
+ m_window->show();
+ view->setSize(QSizeF(640, 480));
+ view->setEnabled(viewEnabled);
+ view->loadHtml("<html><head><title>Title</title></head><body>Hello"
+ "<input id=\"input\" type=\"text\"></body></html>");
+ QVERIFY(waitForLoadSucceeded(view));
+
+ // When enabled, the view should get active focus after the page is loaded.
+ QTRY_COMPARE_WITH_TIMEOUT(view->hasActiveFocus(), activeFocusResult, 1000);
+ view->runJavaScript("document.getElementById(\"input\").focus()");
+ QTRY_COMPARE_WITH_TIMEOUT(view->hasActiveFocus(), activeFocusResult, 1000);
+}
+
+void tst_QQuickWebEngineView::stopSettingFocusWhenDisabled_data()
+{
+ QTest::addColumn<bool>("viewEnabled");
+ QTest::addColumn<bool>("activeFocusResult");
+
+ QTest::newRow("enabled view gets active focus") << true << true;
+ QTest::newRow("disabled view does not get active focus") << false << false;
+}
+
+class MouseTouchEventRecordingItem : public QQuickItem {
+public:
+ explicit MouseTouchEventRecordingItem(QQuickItem *parent = 0) :
+ QQuickItem(parent), m_eventCounter(0) {
+ setFlag(ItemHasContents);
+ setAcceptedMouseButtons(Qt::AllButtons);
+ setAcceptHoverEvents(true);
+ }
+
+ bool event(QEvent *event) Q_DECL_OVERRIDE
+ {
+ switch (event->type()) {
+ case QEvent::TabletPress:
+ case QEvent::TabletRelease:
+ case QEvent::TabletMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ case QEvent::TouchCancel:
+ case QEvent::HoverEnter:
+ case QEvent::HoverMove:
+ case QEvent::HoverLeave:
+ ++m_eventCounter;
+ event->accept();
+ return true;
+ default:
+ break;
+ }
+ return QQuickItem::event(event);
+ }
+
+ void clearEventCount()
+ {
+ m_eventCounter = 0;
+ }
+
+ int eventCount()
+ {
+ return m_eventCounter;
+ }
+
+private:
+ int m_eventCounter;
+};
+
+void tst_QQuickWebEngineView::inputEventForwardingDisabledWhenActiveFocusOnPressDisabled()
+{
+ QQuickWebEngineView *view = webEngineView();
+ MouseTouchEventRecordingItem item;
+ item.setParentItem(m_window->contentItem());
+ item.setSize(QSizeF(640, 480));
+ view->setParentItem(&item);
+ view->setSize(QSizeF(640, 480));
+ m_window->show();
+
+ // Simulate click and move of mouse, so that last known position in the application
+ // is updated, thus a mouse move event is not generated when we don't expect it.
+ QTest::mouseClick(view->window(), Qt::LeftButton);
+ item.clearEventCount();
+
+ // First disable view, so it does not receive focus on page load.
+ view->setEnabled(false);
+ view->setActiveFocusOnPress(false);
+ view->loadHtml("<html><head>"
+ "<script>"
+ "window.onload = function() { document.getElementById(\"input\").focus(); }"
+ "</script>"
+ "<title>Title</title></head><body>Hello"
+ "<input id=\"input\" type=\"text\"></body></html>");
+ QVERIFY(waitForLoadSucceeded(view));
+ QTRY_COMPARE_WITH_TIMEOUT(view->hasActiveFocus(), false, 1000);
+
+ // Enable the view back so we can try to interact with it.
+ view->setEnabled(true);
+
+ // Click on the view, to try and set focus.
+ QTest::mouseClick(view->window(), Qt::LeftButton);
+
+ // View should not have focus after click, because setActiveFocusOnPress is false.
+ QTRY_COMPARE_WITH_TIMEOUT(view->hasActiveFocus(), false, 1000);
+
+ // Now test sending various input events, to check that indeed all the input events are not
+ // forwarded to Chromium, but rather processed and accepted by the view's parent item.
+ QTest::mousePress(view->window(), Qt::LeftButton);
+ QTest::mouseRelease(view->window(), Qt::LeftButton);
+
+ QTouchDevice *device = new QTouchDevice;
+ device->setType(QTouchDevice::TouchScreen);
+ QWindowSystemInterface::registerTouchDevice(device);
+
+ QTest::touchEvent(view->window(), device).press(0, QPoint(0,0), view->window());
+ QTest::touchEvent(view->window(), device).move(0, QPoint(1, 1), view->window());
+ QTest::touchEvent(view->window(), device).release(0, QPoint(1, 1), view->window());
+
+ // We expect to catch 7 events - click = 2, press + release = 2, touches = 3.
+ QCOMPARE(item.eventCount(), 7);
+
+ // Manually forcing focus should still be possible.
+ view->forceActiveFocus();
+ QTRY_COMPARE_WITH_TIMEOUT(view->hasActiveFocus(), true, 1000);
+}
+
QTEST_MAIN(tst_QQuickWebEngineView)
#include "tst_qquickwebengineview.moc"
diff --git a/tests/auto/widgets/positionplugin/plugin.cpp b/tests/auto/widgets/positionplugin/plugin.cpp
deleted file mode 100644
index ca2e7eb45..000000000
--- a/tests/auto/widgets/positionplugin/plugin.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtPositioning/qgeopositioninfosource.h>
-#include <QtPositioning/qgeopositioninfosourcefactory.h>
-#include <QObject>
-#include <QtPlugin>
-
-class DummySource : public QGeoPositionInfoSource
-{
- Q_OBJECT
-
-public:
- DummySource(QObject *parent=0);
-
- void startUpdates() {}
- void stopUpdates() {}
- void requestUpdate(int) {}
-
- QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const;
- PositioningMethods supportedPositioningMethods() const;
-
- int minimumUpdateInterval() const;
- Error error() const;
-};
-
-DummySource::DummySource(QObject *parent) :
- QGeoPositionInfoSource(parent)
-{
-}
-
-QGeoPositionInfoSource::Error DummySource::error() const
-{
- return QGeoPositionInfoSource::NoError;
-}
-
-int DummySource::minimumUpdateInterval() const
-{
- return 1000;
-}
-
-QGeoPositionInfo DummySource::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const
-{
- Q_UNUSED(fromSatellitePositioningMethodsOnly);
- return QGeoPositionInfo(QGeoCoordinate(54.186824, 12.087262), QDateTime::currentDateTime());
-}
-
-QGeoPositionInfoSource::PositioningMethods DummySource::supportedPositioningMethods() const
-{
- return QGeoPositionInfoSource::AllPositioningMethods;
-}
-
-
-class QGeoPositionInfoSourceFactoryTest : public QObject, public QGeoPositionInfoSourceFactory
-{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/5.0"
- FILE "plugin.json")
- Q_INTERFACES(QGeoPositionInfoSourceFactory)
-
-public:
- QGeoPositionInfoSource *positionInfoSource(QObject *parent);
- QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent);
- QGeoAreaMonitorSource *areaMonitor(QObject *parent);
-};
-
-QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryTest::positionInfoSource(QObject *parent)
-{
- return new DummySource(parent);
-}
-
-QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryTest::satelliteInfoSource(QObject *)
-{
- return 0;
-}
-
-QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryTest::areaMonitor(QObject* )
-{
- return 0;
-}
-
-#include "plugin.moc"
diff --git a/tests/auto/widgets/positionplugin/plugin.json b/tests/auto/widgets/positionplugin/plugin.json
deleted file mode 100644
index 68acaded3..000000000
--- a/tests/auto/widgets/positionplugin/plugin.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "Keys": ["test.source"],
- "Provider": "test.source",
- "Position": true,
- "Satellite": false,
- "Monitor": false,
- "Priority": 0,
- "Testable": true
-}
diff --git a/tests/auto/widgets/positionplugin/positionplugin.pro b/tests/auto/widgets/positionplugin/positionplugin.pro
deleted file mode 100644
index 6f2e736c6..000000000
--- a/tests/auto/widgets/positionplugin/positionplugin.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-TARGET = qtwebengine_positioning_testplugin
-
-QT += positioning
-
-SOURCES += plugin.cpp
-
-OTHER_FILES += \
- plugin.json
-
-PLUGIN_TYPE = position
-PLUGIN_CLASS_NAME = TestPositionPlugin
-PLUGIN_EXTENDS = -
-load(qt_plugin)
diff --git a/tests/auto/widgets/qwebenginepage/BLACKLIST b/tests/auto/widgets/qwebenginepage/BLACKLIST
index 30b43d6b7..fcd36ba83 100644
--- a/tests/auto/widgets/qwebenginepage/BLACKLIST
+++ b/tests/auto/widgets/qwebenginepage/BLACKLIST
@@ -1,11 +1,2 @@
-[geolocationRequestJS]
-*
-
[macCopyUnicodeToClipboard]
osx
-
-[getUserMediaRequest]
-windows
-
-[setHtmlWithImageResource]
-*
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 3e0a5abae..e50692226 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -201,9 +201,6 @@ private Q_SLOTS:
void progressSignal();
void urlChange();
void requestedUrlAfterSetAndLoadFailures();
- void javaScriptWindowObjectCleared_data();
- void javaScriptWindowObjectCleared();
- void javaScriptWindowObjectClearedOnEvaluate();
void asyncAndDelete();
void earlyToHtml();
void setHtml();
@@ -215,7 +212,6 @@ private Q_SLOTS:
void hitTestContent();
void baseUrl_data();
void baseUrl();
- void renderHints();
void scrollPosition();
void scrollToAnchor();
void scrollbarsOff();
@@ -412,16 +408,21 @@ void tst_QWebEnginePage::geolocationRequestJS()
newPage, SLOT(requestPermission(const QUrl&, QWebEnginePage::Feature)));
QSignalSpy spyLoadFinished(newPage, SIGNAL(loadFinished(bool)));
- newPage->setHtml(QString("<html><body>test</body></html>"), QUrl());
+ newPage->setHtml(QString("<html><body>test</body></html>"), QUrl("qrc://secure/origin"));
QTRY_COMPARE(spyLoadFinished.count(), 1);
if (evaluateJavaScriptSync(newPage, QLatin1String("!navigator.geolocation")).toBool()) {
delete view;
W_QSKIP("Geolocation is not supported.", SkipSingle);
}
- evaluateJavaScriptSync(newPage, "var errorCode = 0; function error(err) { errorCode = err.code; } function success(pos) { } navigator.geolocation.getCurrentPosition(success, error)");
+ evaluateJavaScriptSync(newPage, "var errorCode = 0; var done = false; function error(err) { errorCode = err.code; done = true; } function success(pos) { done = true; } navigator.geolocation.getCurrentPosition(success, error)");
+
+ QTRY_VERIFY(evaluateJavaScriptSync(newPage, "done").toBool());
+ int result = evaluateJavaScriptSync(newPage, "errorCode").toInt();
+ if (result == 2)
+ QEXPECT_FAIL("", "No location service available.", Continue);
+ QCOMPARE(result, errorCode);
- QTRY_COMPARE(evaluateJavaScriptSync(newPage, "errorCode").toInt(), errorCode);
delete view;
}
@@ -3879,48 +3880,6 @@ void tst_QWebEnginePage::requestedUrlAfterSetAndLoadFailures()
QVERIFY(!spy.at(1).first().toBool());
}
-void tst_QWebEnginePage::javaScriptWindowObjectCleared_data()
-{
- QTest::addColumn<QString>("html");
- QTest::addColumn<int>("signalCount");
- QTest::newRow("with <script>") << "<html><body><script>i=0</script><p>hello world</p></body></html>" << 1;
- // NOTE: Empty scripts no longer cause this signal to be emitted.
- QTest::newRow("with empty <script>") << "<html><body><script></script><p>hello world</p></body></html>" << 0;
- QTest::newRow("without <script>") << "<html><body><p>hello world</p></body></html>" << 0;
-}
-
-void tst_QWebEnginePage::javaScriptWindowObjectCleared()
-{
-#if !defined(QWEBENGINEPAGE_JAVASCRIPTWINDOWOBJECTCLEARED)
- QSKIP("QWEBENGINEPAGE_JAVASCRIPTWINDOWOBJECTCLEARED");
-#else
- QWebEnginePage page;
- QSignalSpy spy(&page, SIGNAL(javaScriptWindowObjectCleared()));
- QFETCH(QString, html);
- page.setHtml(html);
-
- QFETCH(int, signalCount);
- QCOMPARE(spy.count(), signalCount);
-#endif
-}
-
-void tst_QWebEnginePage::javaScriptWindowObjectClearedOnEvaluate()
-{
-#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT)
- QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT");
-#else
- QWebEnginePage page;
- QSignalSpy spy(&page, SIGNAL(javaScriptWindowObjectCleared()));
- page.setHtml("<html></html>");
- QCOMPARE(spy.count(), 0);
- page.evaluateJavaScript("var a = 'a';");
- QCOMPARE(spy.count(), 1);
- // no new clear for a new script:
- page.evaluateJavaScript("var a = 1;");
- QCOMPARE(spy.count(), 1);
-#endif
-}
-
void tst_QWebEnginePage::asyncAndDelete()
{
QWebEnginePage *page = new QWebEnginePage;
@@ -3954,28 +3913,26 @@ void tst_QWebEnginePage::setHtml()
void tst_QWebEnginePage::setHtmlWithImageResource()
{
- // By default, only security origins of local files can load local resources.
- // So we should specify baseUrl to be a local file in order to get a proper origin and load the local image.
+ // We allow access to qrc resources from any security origin, including local and anonymous
QLatin1String html("<html><body><p>hello world</p><img src='qrc:/resources/image.png'/></body></html>");
QWebEnginePage page;
- page.setHtml(html, QUrl(QLatin1String("file:///path/to/file")));
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
+ page.setHtml(html, QUrl("file:///path/to/file"));
+ QTRY_COMPARE(spy.count(), 1);
QCOMPARE(evaluateJavaScriptSync(&page, "document.images.length").toInt(), 1);
QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].width").toInt(), 128);
QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].height").toInt(), 128);
- // Now we test the opposite: without a baseUrl as a local file, we cannot request local resources.
+ // Now we test the opposite: without a baseUrl as a local file, we can still request qrc resources.
page.setHtml(html);
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QTRY_COMPARE(spy.count(), 2);
QCOMPARE(evaluateJavaScriptSync(&page, "document.images.length").toInt(), 1);
- QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=118659", Continue);
- QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].width").toInt(), 0);
- QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=118659", Continue);
- QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].height").toInt(), 0);
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].width").toInt(), 128);
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].height").toInt(), 128);
}
void tst_QWebEnginePage::setHtmlWithStylesheetResource()
@@ -4154,167 +4111,30 @@ void tst_QWebEnginePage::baseUrl()
QCOMPARE(baseUrlSync(m_page), baseUrl);
}
-class DummyPaintEngine: public QPaintEngine {
-public:
-
- DummyPaintEngine()
- : QPaintEngine(QPaintEngine::AllFeatures)
- , renderHints(0)
- {
- }
-
- bool begin(QPaintDevice*)
- {
- setActive(true);
- return true;
- }
-
- bool end()
- {
- setActive(false);
- return false;
- }
-
- void updateState(const QPaintEngineState& state)
- {
- renderHints = state.renderHints();
- }
-
- void drawPath(const QPainterPath&) { }
- void drawPixmap(const QRectF&, const QPixmap&, const QRectF&) { }
-
- QPaintEngine::Type type() const
- {
- return static_cast<QPaintEngine::Type>(QPaintEngine::User + 2);
- }
-
- QPainter::RenderHints renderHints;
-};
-
-class DummyPaintDevice: public QPaintDevice {
-public:
- DummyPaintDevice()
- : QPaintDevice()
- , m_engine(new DummyPaintEngine)
- {
- }
-
- ~DummyPaintDevice()
- {
- delete m_engine;
- }
-
- QPaintEngine* paintEngine() const
- {
- return m_engine;
- }
-
- QPainter::RenderHints renderHints() const
- {
- return m_engine->renderHints;
- }
-
-protected:
- int metric(PaintDeviceMetric metric) const;
-
-private:
- DummyPaintEngine* m_engine;
- friend class DummyPaintEngine;
-};
-
-
-int DummyPaintDevice::metric(PaintDeviceMetric metric) const
-{
- switch (metric) {
- case PdmWidth:
- return 400;
- break;
-
- case PdmHeight:
- return 200;
- break;
-
- case PdmNumColors:
- return INT_MAX;
- break;
-
- case PdmDepth:
- return 32;
- break;
-
- default:
- break;
- }
- return 0;
-}
-
-void tst_QWebEnginePage::renderHints()
-{
-#if !defined(QWEBENGINEPAGE_RENDER)
- QSKIP("QWEBENGINEPAGE_RENDER");
-#else
- QString html("<html><body><p>Hello, world!</p></body></html>");
-
- QWebEnginePage page;
- page.setHtml(html);
- page.setViewportSize(page.contentsSize());
-
- // We will call frame->render and trap the paint engine state changes
- // to ensure that GraphicsContext does not clobber the render hints.
- DummyPaintDevice buffer;
- QPainter painter(&buffer);
-
- painter.setRenderHint(QPainter::TextAntialiasing, false);
- page.render(&painter);
- QVERIFY(!(buffer.renderHints() & QPainter::TextAntialiasing));
- QVERIFY(!(buffer.renderHints() & QPainter::SmoothPixmapTransform));
- QVERIFY(!(buffer.renderHints() & QPainter::HighQualityAntialiasing));
-
- painter.setRenderHint(QPainter::TextAntialiasing, true);
- page.render(&painter);
- QVERIFY(buffer.renderHints() & QPainter::TextAntialiasing);
- QVERIFY(!(buffer.renderHints() & QPainter::SmoothPixmapTransform));
- QVERIFY(!(buffer.renderHints() & QPainter::HighQualityAntialiasing));
-
- painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
- page.render(&painter);
- QVERIFY(buffer.renderHints() & QPainter::TextAntialiasing);
- QVERIFY(buffer.renderHints() & QPainter::SmoothPixmapTransform);
- QVERIFY(!(buffer.renderHints() & QPainter::HighQualityAntialiasing));
-
- painter.setRenderHint(QPainter::HighQualityAntialiasing, true);
- page.render(&painter);
- QVERIFY(buffer.renderHints() & QPainter::TextAntialiasing);
- QVERIFY(buffer.renderHints() & QPainter::SmoothPixmapTransform);
- QVERIFY(buffer.renderHints() & QPainter::HighQualityAntialiasing);
-#endif
-}
-
void tst_QWebEnginePage::scrollPosition()
{
-#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT)
- QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT");
-#else
// enlarged image in a small viewport, to provoke the scrollbars to appear
QString html("<html><body><img src='qrc:/image.png' height=500 width=500/></body></html>");
- QWebEnginePage page;
- page.setViewportSize(QSize(200, 200));
+ QWebEngineView view;
+ view.setFixedSize(200,200);
+ view.show();
- page.setHtml(html);
- page.setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
- page.setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
+ QTest::qWaitForWindowExposed(&view);
+
+ QSignalSpy loadSpy(view.page(), SIGNAL(loadFinished(bool)));
+ view.setHtml(html);
+ QTRY_COMPARE(loadSpy.count(), 1);
// try to set the scroll offset programmatically
- page.setScrollPosition(QPoint(23, 29));
- QCOMPARE(page.scrollPosition().x(), 23);
- QCOMPARE(page.scrollPosition().y(), 29);
+ view.page()->runJavaScript("window.scrollTo(23, 29);");
+ QTRY_COMPARE(view.page()->scrollPosition().x(), qreal(23));
+ QCOMPARE(view.page()->scrollPosition().y(), qreal(29));
- int x = page.evaluateJavaScript("window.scrollX").toInt();
- int y = page.evaluateJavaScript("window.scrollY").toInt();
+ int x = evaluateJavaScriptSync(view.page(), "window.scrollX").toInt();
+ int y = evaluateJavaScriptSync(view.page(), "window.scrollY").toInt();
QCOMPARE(x, 23);
QCOMPARE(y, 29);
-#endif
}
void tst_QWebEnginePage::scrollToAnchor()
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 8aaf9ccc3..afb53ba20 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -29,11 +29,20 @@
#include <qwebenginesettings.h>
#include <qnetworkrequest.h>
#include <qdiriterator.h>
+#include <qstackedlayout.h>
#include <qtemporarydir.h>
#define VERIFY_INPUTMETHOD_HINTS(actual, expect) \
QVERIFY(actual == expect);
+#define QTRY_COMPARE_WITH_TIMEOUT_FAIL_BLOCK(__expr, __expected, __timeout, __fail_block) \
+do { \
+ QTRY_IMPL(((__expr) == (__expected)), __timeout);\
+ if (__expr != __expected)\
+ __fail_block\
+ QCOMPARE((__expr), __expected); \
+} while (0)
+
class tst_QWebEngineView : public QObject
{
Q_OBJECT
@@ -61,6 +70,10 @@ private Q_SLOTS:
void setPalette_data();
void setPalette();
#endif
+ void doNotSendMouseKeyboardEventsWhenDisabled();
+ void doNotSendMouseKeyboardEventsWhenDisabled_data();
+ void stopSettingFocusWhenDisabled();
+ void stopSettingFocusWhenDisabled_data();
};
// This will be called before the first test function is executed.
@@ -591,5 +604,144 @@ void tst_QWebEngineView::renderingAfterMaxAndBack()
#endif
}
+class KeyboardAndMouseEventRecordingWidget : public QWidget {
+public:
+ explicit KeyboardAndMouseEventRecordingWidget(QWidget *parent = 0) :
+ QWidget(parent), m_eventCounter(0) {}
+
+ bool event(QEvent *event) Q_DECL_OVERRIDE
+ {
+ QString eventString;
+ switch (event->type()) {
+ case QEvent::TabletPress:
+ case QEvent::TabletRelease:
+ case QEvent::TabletMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ case QEvent::TouchCancel:
+ case QEvent::ContextMenu:
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+#ifndef QT_NO_WHEELEVENT
+ case QEvent::Wheel:
+#endif
+ ++m_eventCounter;
+ event->setAccepted(true);
+ QDebug(&eventString) << event;
+ m_eventHistory.append(eventString);
+ return true;
+ default:
+ break;
+ }
+ return QWidget::event(event);
+ }
+
+ void clearEventCount()
+ {
+ m_eventCounter = 0;
+ }
+
+ int eventCount()
+ {
+ return m_eventCounter;
+ }
+
+ void printEventHistory()
+ {
+ qDebug() << "Received events are:";
+ for (int i = 0; i < m_eventHistory.size(); ++i) {
+ qDebug() << m_eventHistory[i];
+ }
+ }
+
+private:
+ int m_eventCounter;
+ QVector<QString> m_eventHistory;
+};
+
+void tst_QWebEngineView::doNotSendMouseKeyboardEventsWhenDisabled()
+{
+ QFETCH(bool, viewEnabled);
+ QFETCH(int, resultEventCount);
+
+ KeyboardAndMouseEventRecordingWidget parentWidget;
+ QWebEngineView webView(&parentWidget);
+ webView.setEnabled(viewEnabled);
+ parentWidget.setLayout(new QStackedLayout);
+ parentWidget.layout()->addWidget(&webView);
+ webView.resize(640, 480);
+ parentWidget.show();
+ QTest::qWaitForWindowExposed(&webView);
+
+ QSignalSpy loadSpy(&webView, SIGNAL(loadFinished(bool)));
+ webView.setHtml("<html><head><title>Title</title></head><body>Hello"
+ "<input id=\"input\" type=\"text\"></body></html>");
+ QTRY_COMPARE(loadSpy.count(), 1);
+
+ // When the webView is enabled, the events are swallowed by it, and the parent widget
+ // does not receive any events, otherwise all events are processed by the parent widget.
+ parentWidget.clearEventCount();
+ QTest::mousePress(parentWidget.windowHandle(), Qt::LeftButton);
+ QTest::mouseMove(parentWidget.windowHandle(), QPoint(100, 100));
+ QTest::mouseRelease(parentWidget.windowHandle(), Qt::LeftButton,
+ Qt::KeyboardModifiers(), QPoint(100, 100));
+
+ // Wait a bit for the mouse events to be processed, so they don't interfere with the js focus
+ // below.
+ QTest::qWait(100);
+ evaluateJavaScriptSync(webView.page(), "document.getElementById(\"input\").focus()");
+ QTest::keyPress(parentWidget.windowHandle(), Qt::Key_H);
+
+ // Wait a bit for the key press to be handled. We have to do it, because the compare
+ // below could immediately finish successfully, without alloing for the events to be handled.
+ QTest::qWait(100);
+ QTRY_COMPARE_WITH_TIMEOUT_FAIL_BLOCK(parentWidget.eventCount(), resultEventCount,
+ 1000, parentWidget.printEventHistory(););
+}
+
+void tst_QWebEngineView::doNotSendMouseKeyboardEventsWhenDisabled_data()
+{
+ QTest::addColumn<bool>("viewEnabled");
+ QTest::addColumn<int>("resultEventCount");
+
+ QTest::newRow("enabled view receives events") << true << 0;
+ QTest::newRow("disabled view does not receive events") << false << 4;
+}
+
+void tst_QWebEngineView::stopSettingFocusWhenDisabled()
+{
+ QFETCH(bool, viewEnabled);
+ QFETCH(bool, focusResult);
+
+ QWebEngineView webView;
+ webView.resize(640, 480);
+ webView.show();
+ webView.setEnabled(viewEnabled);
+ QTest::qWaitForWindowExposed(&webView);
+
+ QSignalSpy loadSpy(&webView, SIGNAL(loadFinished(bool)));
+ webView.setHtml("<html><head><title>Title</title></head><body>Hello"
+ "<input id=\"input\" type=\"text\"></body></html>");
+ QTRY_COMPARE(loadSpy.count(), 1);
+
+ QTRY_COMPARE_WITH_TIMEOUT(webView.hasFocus(), focusResult, 1000);
+ evaluateJavaScriptSync(webView.page(), "document.getElementById(\"input\").focus()");
+ QTRY_COMPARE_WITH_TIMEOUT(webView.hasFocus(), focusResult, 1000);
+}
+
+void tst_QWebEngineView::stopSettingFocusWhenDisabled_data()
+{
+ QTest::addColumn<bool>("viewEnabled");
+ QTest::addColumn<bool>("focusResult");
+
+ QTest::newRow("enabled view gets focus") << true << true;
+ QTest::newRow("disabled view does not get focus") << false << false;
+}
+
QTEST_MAIN(tst_QWebEngineView)
#include "tst_qwebengineview.moc"
diff --git a/tests/auto/widgets/widgets.pro b/tests/auto/widgets/widgets.pro
index 7543a4382..2f5416701 100644
--- a/tests/auto/widgets/widgets.pro
+++ b/tests/auto/widgets/widgets.pro
@@ -17,8 +17,3 @@ SUBDIRS += \
!contains(WEBENGINE_CONFIG, no_spellcheck):!osx:!cross_compile {
SUBDIRS += qwebenginespellcheck
}
-
-qtHaveModule(positioning) {
- SUBDIRS += positionplugin
- qwebenginepage.depends = positionplugin
-}
diff --git a/tools/buildscripts/find-included-moc-files b/tools/buildscripts/find-included-moc-files
index e55f3824c..678b2d6f5 100755
--- a/tools/buildscripts/find-included-moc-files
+++ b/tools/buildscripts/find-included-moc-files
@@ -3,7 +3,9 @@
import re, sys, os
includedMocs = set()
-for f in filter(os.path.isfile, sys.argv[1:]):
+dir = sys.argv[1]
+files = sys.argv[2:]
+for f in filter(os.path.isfile, [os.path.join(dir, f) for f in files]):
inBlockComment = False
for line in open(f).readlines():
m = re.search('#include "(moc_\w+.cpp)"', line)
diff --git a/tools/buildscripts/find-mocables b/tools/buildscripts/find-mocables
index 7c383cfec..4bfa311b5 100755
--- a/tools/buildscripts/find-mocables
+++ b/tools/buildscripts/find-mocables
@@ -3,7 +3,9 @@
import re, sys, os
mocables = set()
-for f in filter(os.path.isfile, sys.argv[1:]):
+dir = sys.argv[1]
+files = sys.argv[2:]
+for f in filter(os.path.isfile, [os.path.join(dir, f) for f in files]):
inBlockComment = False
for line in open(f).readlines():
# Block comments handling
diff --git a/tools/qmake/mkspecs/features/configure.prf b/tools/qmake/mkspecs/features/configure.prf
index 679b282b3..7ef4b8545 100644
--- a/tools/qmake/mkspecs/features/configure.prf
+++ b/tools/qmake/mkspecs/features/configure.prf
@@ -26,7 +26,7 @@ defineTest(runConfigure) {
!config_khr:skipBuild("khronos development headers appear to be missing (mesa/libegl1-mesa-dev)")
REQUIRED_PACKAGES = dbus-1 fontconfig
- contains(QT_CONFIG, xcb): REQUIRED_PACKAGES += libdrm xcomposite xcursor xi xrandr xscrnsaver xtst
+ !cross_compile: contains(QT_CONFIG, xcb): REQUIRED_PACKAGES += libdrm xcomposite xcursor xi xrandr xscrnsaver xtst
contains(QT_CONFIG, pulseaudio): REQUIRED_PACKAGES += libpulse
contains(QT_CONFIG, system-png): REQUIRED_PACKAGES += libpng
contains(QT_CONFIG, system-harfbuzz): REQUIRED_PACKAGES += harfbuzz
@@ -117,11 +117,16 @@ defineTest(finalizeConfigure) {
} else {
log("Proprietary codecs (H264, MP3).... Not enabled (Default, enable with WEBENGINE_CONFIG+=use_proprietary_codecs)$${EOL}")
}
+ qtHaveModule(positioning): {
+ log("Geolocation....................... Enabled$${EOL}")
+ } else {
+ log("Geolocation....................... Not enabled (Requires Qt Positioning module)$${EOL}")
+ }
osx {
use?(appstore_compliant_code) {
log("AppStore Compliant ............... Enabled$${EOL}")
} else {
- log("AppStore Compliant ............... Not enabled (Default, enable with WEBENGINE_CONFIG += use_appstore_compliant_code)$${EOL}")
+ log("AppStore Compliant ............... Not enabled (Default, enable with WEBENGINE_CONFIG+=use_appstore_compliant_code)$${EOL}")
}
}
}
diff --git a/tools/qmake/mkspecs/features/functions.prf b/tools/qmake/mkspecs/features/functions.prf
index e321efc87..ed6fa289b 100644
--- a/tools/qmake/mkspecs/features/functions.prf
+++ b/tools/qmake/mkspecs/features/functions.prf
@@ -149,19 +149,13 @@ defineReplace(extractCFlag) {
}
defineReplace(findMocables) {
- input = $$1
- for (file, input): \
- infiles += $$absolute_path($$file, $$_PRO_FILE_PWD_)
- mocables = $$system("python $$QTWEBENGINE_ROOT/tools/buildscripts/find-mocables $$infiles")
- mocables = $$replace(mocables, $$re_escape($${_PRO_FILE_PWD_}/), '')
+ mocables = $$system("$$system_path(python $$QTWEBENGINE_ROOT/tools/buildscripts/find-mocables $$_PRO_FILE_PWD_ $$1)")
+ mocables = $$replace(mocables, $$re_escape($$system_path($${_PRO_FILE_PWD_}/)), '')
return($$mocables)
}
defineReplace(findIncludedMocFiles) {
- input = $$1
- for (file, input): \
- infiles += $$absolute_path($$file, $$_PRO_FILE_PWD_)
- return($$system("python $$QTWEBENGINE_ROOT/tools/buildscripts/find-included-moc-files $$infiles"))
+ return($$system("$$system_path(python $$QTWEBENGINE_ROOT/tools/buildscripts/find-included-moc-files $$_PRO_FILE_PWD_ $$1)"))
}
defineReplace(mocOutput) {
diff --git a/tools/qmake/mkspecs/features/gyp_generator.prf b/tools/qmake/mkspecs/features/gyp_generator.prf
index eea11ef09..0ba6de09c 100644
--- a/tools/qmake/mkspecs/features/gyp_generator.prf
+++ b/tools/qmake/mkspecs/features/gyp_generator.prf
@@ -17,7 +17,7 @@ defineReplace(mocAction) {
MOC_COMMAND = $$clean_path($$mocCmdBase())
MOC_COMMAND = $$replace(MOC_COMMAND, $$re_escape("$(DEFINES)"), $$DEFINES_LIST)
MOC_COMMAND = $$replace(MOC_COMMAND, $$re_escape("$(INCPATH)"), $$INCPATH)
- MOC_COMMAND = $$split(MOC_COMMAND, " ")
+ MOC_COMMAND = $$eval($$list($$MOC_COMMAND))
OUTPUT_FILE = $$MOC_GEN_DIR/$${OUTPUT_NAME}
contents = " {" \
" 'action_name':'$$OUTPUT_NAME'," \