summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael BrĂ¼ning <michael.bruning@qt.io>2016-12-07 13:55:20 +0100
committerMichael BrĂ¼ning <michael.bruning@qt.io>2016-12-07 13:55:20 +0100
commitc7f8e360da41df8b81004fe45f1582845a951c2b (patch)
tree32cf6ecb336af7d89a0a86153bb07ee49f23baa9
parent3d000cfc013158f56c0b088c9ee99b03938ef50b (diff)
parent5ec330cec86cd7781ced295790ce93ac8748dcc4 (diff)
Merge remote-tracking branch 'origin/5.8' into dev
Conflicts: src/3rdparty Change-Id: Ie7b7c469aa24716816a23b8fe7a8df9f477a9f67
-rw-r--r--dist/changes-5.7.157
-rw-r--r--dist/changes-5.8.095
m---------src/3rdparty0
-rw-r--r--src/core/api/qwebengineurlrequestinfo.cpp5
-rw-r--r--src/core/api/qwebengineurlrequestinfo.h5
-rw-r--r--src/core/common/qt_ipc_logging.cpp48
-rw-r--r--src/core/config/common.pri2
-rw-r--r--src/core/config/desktop_linux.pri2
-rw-r--r--src/core/config/mac_osx.pri2
-rw-r--r--src/core/config/windows.pri2
-rw-r--r--src/core/core_common.pri1
-rw-r--r--src/core/core_gyp_generator.pro8
-rw-r--r--src/core/network_delegate_qt.cpp26
-rw-r--r--src/core/pdfium_document_wrapper_qt.cpp (renamed from src/core/pdfium_printing_wrapper_qt.cpp)127
-rw-r--r--src/core/pdfium_document_wrapper_qt.h (renamed from src/core/pdfium_printing_wrapper_qt.h)29
-rw-r--r--src/core/render_view_observer_host_qt.cpp9
-rw-r--r--src/core/render_view_observer_host_qt.h1
-rw-r--r--src/core/render_widget_host_view_qt.cpp13
-rw-r--r--src/core/render_widget_host_view_qt.h11
-rw-r--r--src/core/renderer/render_view_observer_qt.cpp5
-rw-r--r--src/core/renderer/render_view_observer_qt.h1
-rw-r--r--src/core/url_request_custom_job.cpp3
-rw-r--r--src/core/url_request_qrc_job_qt.cpp1
-rw-r--r--src/core/web_contents_adapter.cpp40
-rw-r--r--src/core/web_contents_adapter.h9
-rw-r--r--src/core/web_contents_adapter_client.h3
-rw-r--r--src/core/web_contents_delegate_qt.cpp18
-rw-r--r--src/core/web_contents_delegate_qt.h1
-rw-r--r--src/core/web_engine_context.cpp52
-rw-r--r--src/webengine/api/qquickwebenginefaviconprovider.cpp2
-rw-r--r--src/webengine/api/qquickwebengineview.cpp19
-rw-r--r--src/webengine/api/qquickwebengineview_p.h6
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h3
-rw-r--r--src/webengine/doc/src/qtwebengine-platform-notes.qdoc4
-rw-r--r--src/webengine/webengine.pro4
-rw-r--r--src/webenginewidgets/api/qtwebenginewidgetsglobal.cpp22
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp171
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h6
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp28
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h1
-rw-r--r--src/webenginewidgets/webenginewidgets.pro7
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp16
-rw-r--r--tests/auto/quick/qmltests/BLACKLIST6
-rw-r--r--tests/auto/quick/qmltests/data/tst_linkHovered.qml50
-rw-r--r--tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp3
-rw-r--r--tests/auto/quick/shared/util.h32
-rw-r--r--tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp9
-rw-r--r--tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp21
-rw-r--r--tests/auto/widgets/qwebenginepage/qwebenginepage.pro2
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp316
-rw-r--r--tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp27
-rw-r--r--tests/auto/widgets/qwebenginespellcheck/tst_qwebenginespellcheck.cpp7
-rw-r--r--tests/auto/widgets/qwebengineview/BLACKLIST2
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp91
-rw-r--r--tests/auto/widgets/tests.pri2
-rw-r--r--tests/auto/widgets/util.h23
-rw-r--r--tools/qmake/mkspecs/features/configure.prf3
-rw-r--r--tools/qmake/mkspecs/features/functions.prf2
58 files changed, 931 insertions, 530 deletions
diff --git a/dist/changes-5.7.1 b/dist/changes-5.7.1
new file mode 100644
index 000000000..bf5934320
--- /dev/null
+++ b/dist/changes-5.7.1
@@ -0,0 +1,57 @@
+Qt 5.7.1 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.7.0.
+
+Qt 5.7.1 contains a merge from Qt 5.6.2 and all changes in Qt 5.6.2 are
+also in Qt 5.7.1. For more see changes-5.6.2.
+
+Qt 5.7 introduces many new features and improvements as well as bugfixes
+over the 5.6.x series. For more details, refer to the online documentation
+included in this distribution. The documentation is also available online:
+
+ http://doc.qt.io/qt-5/index.html
+
+The Qt version 5.7 series is binary compatible with the 5.6.x series.
+Applications compiled for 5.6 will continue to run with 5.7.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+ https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* General *
+****************************************************************************
+
+ - Chromium Snapshot:
+ * Security fixes from Chromium up to version 54.0.2840.87
+ Including: CVE-2016-5133, CVE-2016-5147, CVE-2016-5153, CVE-2016-5155,
+ CVE-2016-5161, CVE-2016-5166, CVE-2016-5170, CVE-2016-5171,
+ CVE-2016-5172, CVE-2016-5181, CVE-2016-5185, CVE-2016-5186,
+ CVE-2016-5187, CVE-2016-5188, CVE-2016-5192, CVE-2016-5198
+ * Support for macOS 10.12 Sierra
+ * Various backported crash and assert fixes
+
+ - QtWebEngineCore:
+ * [QTBUG-51244, QTBUG-54795] Fixed select control issues
+ * Fixed several focus issues.
+ * Fixed regression with fine-grained wheel events.
+ * [QTBUG-54221] Fixed editing short-cuts in plugins.
+ * [QTBUG-54222] Fixed potential infinite loop on history load.
+ * Fixed Flash plugin clipboard access.
+
+****************************************************************************
+* Platform Specific Changes *
+****************************************************************************
+
+ - Linux:
+ * [QTBUG-55367] Fixed reading timezone when running sandboxed
+ * Fixed crash when using Wayland QPA
+ * Improved OpenGL check, so EGL/GLES2 mode can be used with Desktop
+ OpenGL if the driver has th ARB_ES2_compatibility extension.
+
+ - Windows:
+ * [QTBUG-52201, QTBUG-55501, QTBUG-56020] Fixed crashes and asserts
+ upon initialization of the global shared OpenGL context.
diff --git a/dist/changes-5.8.0 b/dist/changes-5.8.0
new file mode 100644
index 000000000..abead3c38
--- /dev/null
+++ b/dist/changes-5.8.0
@@ -0,0 +1,95 @@
+Qt 5.8 introduces many new features and improvements as well as bugfixes
+over the 5.7.x series. For more details, refer to the online documentation
+included in this distribution. The documentation is also available online:
+
+ http://doc.qt.io/qt-5/index.html
+
+The Qt version 5.8 series is binary compatible with the 5.7.x series.
+Applications compiled for 5.7 will continue to run with 5.8.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+ https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+
+****************************************************************************
+* General *
+****************************************************************************
+
+ - Important Changes:
+ * The enum value ResourceTypeUnknown has changed value because there was
+ a mismatch between 5.6 and 5.7+ definitions. In general any unknown
+ ResourceType value should be handled as unknown for forward
+ compatibility, because more types are and can be added in later
+ Qt versions.
+
+ - Chromium Snapshot:
+ * The Chromium version has been updated to 53.0.2785.148.
+
+ - General:
+ * Spellchecking support has been introduced.
+ * Build time options can now be controlled via arguments to the global
+ configure script or app.
+ * [QTBUG-52999] Added focusOnNavigationEnabled setting which allows
+ controlling whether a web view will receive focus on a navigation
+ request. Previously the view always received the focus.
+ * [QTBUG-54902] Added setting to allow secure content to run insecure
+ content.
+ * [QTBUG-54918] Printing will now include the CSS background of the
+ printed elements by default. This restores the default behavior from Qt
+ WebKit. It can be controlled via the PrintElementBackgrounds web
+ setting.
+ * Some chrome:// URLs are now supported. For instance chrome://gpu.
+ * [QTBUG-53042] Pepper Flash glyph draw is now supported.
+ * A DownloadType has been added to download items.
+ * Greasemonkey attributes are now supported in user scripts.
+ * [QTBUG-55766] Added support for colored underline and background
+ to InputMethodEvent.
+ * Qt no-opengl builds are now supported.
+
+
+****************************************************************************
+* Qt WebEngine[QML] *
+****************************************************************************
+
+ - General:
+ * [QTBUG-53467][QTBUG-51177] Qt WebEngine (QML) now optionally uses Qt
+ Quick 2 Controls to show standard dialogs.
+ * [QTBUG-51190] Added ability to provide custom dialogs for HTTP and
+ proxy authentication, JavaScript alerts, file and color picking, and
+ form validation messages.
+ * [QTBUG-52554] Added ability to show custom context menu.
+
+ - QQuickWebEngineView:
+ * ToolTip (HTML title attributes) are now handled.
+ * View Source feature is now supported.
+
+
+****************************************************************************
+* Qt WebEngineWidgets *
+****************************************************************************
+
+ - Scenegraph Integration:
+ * Using the software rasterizing scenegraph backend is now supported.
+
+ - Printing:
+ * Enables printing QWebPage content on a QPrinter. Currently does not
+ support previewing the document. Widgets only for the moment.
+
+ - QWebEnginePage:
+ * Introduced a new save method to save a page to a predefined location.
+
+
+****************************************************************************
+* Platform Specific Changes *
+****************************************************************************
+
+ - Linux:
+ * Pepper Flash is now also searched for in /usr/lib/adobe-flashplugin/
+
+ - Windows:
+ * MSVC2015 and Windows 10 SDK are now required.
diff --git a/src/3rdparty b/src/3rdparty
-Subproject f5a732820b31651bafc60cd64f85b85c7f82532
+Subproject 93b3786290ac16c95f15c95e2c2f3d8254171ab
diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp
index bd2fecac2..a3806fc63 100644
--- a/src/core/api/qwebengineurlrequestinfo.cpp
+++ b/src/core/api/qwebengineurlrequestinfo.cpp
@@ -64,7 +64,7 @@ ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypePing, content::RESOURCE
ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeServiceWorker, content::RESOURCE_TYPE_SERVICE_WORKER)
ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeCspReport, content::RESOURCE_TYPE_CSP_REPORT)
ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypePluginResource, content::RESOURCE_TYPE_PLUGIN_RESOURCE)
-ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeUnknown, content::RESOURCE_TYPE_LAST_TYPE)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeLast, content::RESOURCE_TYPE_LAST_TYPE)
ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::LinkNavigation, QWebEngineUrlRequestInfo::NavigationTypeLink)
ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::TypedNavigation, QWebEngineUrlRequestInfo::NavigationTypeTyped)
@@ -175,6 +175,9 @@ QWebEngineUrlRequestInfo::QWebEngineUrlRequestInfo(QWebEngineUrlRequestInfoPriva
HTTP POST requests to specified servers. (Added in Qt 5.7)
\value ResourceTypePluginResource A resource requested by a plugin. (Added in Qt 5.7)
\value ResourceTypeUnknown Unknown request type.
+
+ \note For forward compatibility all values not matched should be treated as unknown,
+ not just \c ResourceTypeUnknown.
*/
/*!
diff --git a/src/core/api/qwebengineurlrequestinfo.h b/src/core/api/qwebengineurlrequestinfo.h
index d75ceabf6..52463a1b3 100644
--- a/src/core/api/qwebengineurlrequestinfo.h
+++ b/src/core/api/qwebengineurlrequestinfo.h
@@ -75,7 +75,10 @@ public:
ResourceTypeServiceWorker, // the main resource of a service worker.
ResourceTypeCspReport, // Content Security Policy (CSP) violation report
ResourceTypePluginResource, // A resource requested by a plugin
- ResourceTypeUnknown
+#ifndef Q_QDOC
+ ResourceTypeLast,
+#endif
+ ResourceTypeUnknown = 255
};
enum NavigationType {
diff --git a/src/core/common/qt_ipc_logging.cpp b/src/core/common/qt_ipc_logging.cpp
new file mode 100644
index 000000000..124124de1
--- /dev/null
+++ b/src/core/common/qt_ipc_logging.cpp
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** 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-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "ipc/ipc_message.h" // For IPC_MESSAGE_LOG_ENABLED
+
+#if defined(IPC_MESSAGE_LOG_ENABLED)
+#define IPC_MESSAGE_MACROS_LOG_ENABLED
+#include "content/public/common/content_ipc_logging.h"
+#define IPC_LOG_TABLE_ADD_ENTRY(msg_id, logger) \
+ content::RegisterIPCLogger(msg_id, logger)
+#include "common/qt_messages.h"
+#endif
diff --git a/src/core/config/common.pri b/src/core/config/common.pri
index 7a9656fca..b5bb23684 100644
--- a/src/core/config/common.pri
+++ b/src/core/config/common.pri
@@ -2,8 +2,6 @@
# Trigger Qt-specific build conditions.
GYP_CONFIG += use_qt=1
-# Enable printing. We enable preview because we use preview logic even if we don't support preview.
-GYP_CONFIG += enable_basic_printing=1 enable_print_preview=1
# We do not want to ship more external binary blobs, so let v8 embed its startup data.
GYP_CONFIG += v8_use_external_startup_data=0
# WebSpeech requires Google API keys and adds dependencies on speex and flac.
diff --git a/src/core/config/desktop_linux.pri b/src/core/config/desktop_linux.pri
index e28d7eb7c..23044619b 100644
--- a/src/core/config/desktop_linux.pri
+++ b/src/core/config/desktop_linux.pri
@@ -5,6 +5,8 @@ include(linux.pri)
GYP_CONFIG += \
desktop_linux=1 \
enable_widevine=1 \
+ enable_basic_printing=1 \
+ enable_print_preview=1 \
enable_pdf=1
clang {
diff --git a/src/core/config/mac_osx.pri b/src/core/config/mac_osx.pri
index be037cbde..4111236ed 100644
--- a/src/core/config/mac_osx.pri
+++ b/src/core/config/mac_osx.pri
@@ -26,6 +26,8 @@ GYP_CONFIG += \
make_clang_dir=\"$${QMAKE_CLANG_DIR}\" \
clang_use_chrome_plugins=0 \
enable_widevine=1 \
+ enable_basic_printing=1 \
+ enable_print_preview=1 \
enable_pdf=1
# Force touch API is used in 49-based Chromium, which is included starting with 10.10.3 SDK, so we
diff --git a/src/core/config/windows.pri b/src/core/config/windows.pri
index 9564cf9b7..a1c116ff8 100644
--- a/src/core/config/windows.pri
+++ b/src/core/config/windows.pri
@@ -7,6 +7,8 @@ GYP_CONFIG += \
remoting=0 \
use_ash=0 \
enable_widevine=1 \
+ enable_basic_printing=1 \
+ enable_print_preview=1 \
enable_pdf=1
# Libvpx build needs additional search path on Windows.
diff --git a/src/core/core_common.pri b/src/core/core_common.pri
index 721e8c71a..9c29aea71 100644
--- a/src/core/core_common.pri
+++ b/src/core/core_common.pri
@@ -10,4 +10,3 @@ CHROMIUM_SRC_DIR = $$QTWEBENGINE_ROOT/$$getChromiumSrcDir()
INCLUDEPATH += $$CHROMIUM_SRC_DIR
qtHaveModule(positioning):QT += positioning
-qtHaveModule(printsupport):QT += printsupport
diff --git a/src/core/core_gyp_generator.pro b/src/core/core_gyp_generator.pro
index 2fae21c4d..a09683ba6 100644
--- a/src/core/core_gyp_generator.pro
+++ b/src/core/core_gyp_generator.pro
@@ -53,6 +53,7 @@ SOURCES = \
clipboard_qt.cpp \
color_chooser_qt.cpp \
color_chooser_controller.cpp \
+ common/qt_ipc_logging.cpp \
common/qt_messages.cpp \
common/user_script_data.cpp \
content_client_qt.cpp \
@@ -74,6 +75,7 @@ SOURCES = \
native_web_keyboard_event_qt.cpp \
network_delegate_qt.cpp \
ozone_platform_eglfs.cpp \
+ pdfium_document_wrapper_qt.cpp \
permission_manager_qt.cpp \
process_main.cpp \
proxy_config_service_qt.cpp \
@@ -154,6 +156,7 @@ HEADERS = \
media_capture_devices_dispatcher.h \
network_delegate_qt.h \
ozone_platform_eglfs.h \
+ pdfium_document_wrapper_qt.h \
permission_manager_qt.h \
process_main.h \
proxy_config_service_qt.h \
@@ -210,8 +213,3 @@ qtHaveModule(positioning) {
HEADERS += location_provider_qt.h
DEFINES += QT_USE_POSITIONING=1
}
-
-qtHaveModule(printsupport) {
- SOURCES += pdfium_printing_wrapper_qt.cpp
- HEADERS += pdfium_printing_wrapper_qt.h
-}
diff --git a/src/core/network_delegate_qt.cpp b/src/core/network_delegate_qt.cpp
index ed54f2ec8..9b4c415c9 100644
--- a/src/core/network_delegate_qt.cpp
+++ b/src/core/network_delegate_qt.cpp
@@ -58,7 +58,7 @@
namespace QtWebEngineCore {
-int pageTransitionToNavigationType(ui::PageTransition transition)
+WebContentsAdapterClient::NavigationType pageTransitionToNavigationType(ui::PageTransition transition)
{
int32_t qualifier = ui::PageTransitionGetQualifier(transition);
@@ -81,6 +81,18 @@ int pageTransitionToNavigationType(ui::PageTransition transition)
}
}
+QWebEngineUrlRequestInfo::ResourceType toQt(content::ResourceType resourceType)
+{
+ if (resourceType >= 0 && resourceType < content::ResourceType(QWebEngineUrlRequestInfo::ResourceTypeLast))
+ return static_cast<QWebEngineUrlRequestInfo::ResourceType>(resourceType);
+ return QWebEngineUrlRequestInfo::ResourceTypeUnknown;
+}
+
+QWebEngineUrlRequestInfo::NavigationType toQt(WebContentsAdapterClient::NavigationType navigationType)
+{
+ return static_cast<QWebEngineUrlRequestInfo::NavigationType>(navigationType);
+}
+
NetworkDelegateQt::NetworkDelegateQt(URLRequestContextGetterQt *requestContext)
: m_requestContextGetter(requestContext)
{
@@ -94,7 +106,7 @@ int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, const net::C
const content::ResourceRequestInfo *resourceInfo = content::ResourceRequestInfo::ForRequest(request);
content::ResourceType resourceType = content::RESOURCE_TYPE_LAST_TYPE;
- int navigationType = QWebEngineUrlRequestInfo::NavigationTypeOther;
+ WebContentsAdapterClient::NavigationType navigationType = WebContentsAdapterClient::OtherNavigation;
if (resourceInfo) {
resourceType = resourceInfo->GetResourceType();
@@ -105,11 +117,11 @@ int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, const net::C
QWebEngineUrlRequestInterceptor* interceptor = m_requestContextGetter->m_requestInterceptor;
if (interceptor) {
- QWebEngineUrlRequestInfoPrivate *infoPrivate = new QWebEngineUrlRequestInfoPrivate(static_cast<QWebEngineUrlRequestInfo::ResourceType>(resourceType)
- , static_cast<QWebEngineUrlRequestInfo::NavigationType>(navigationType)
- , qUrl
- , toQt(request->first_party_for_cookies())
- , QByteArray::fromStdString(request->method()));
+ QWebEngineUrlRequestInfoPrivate *infoPrivate = new QWebEngineUrlRequestInfoPrivate(toQt(resourceType),
+ toQt(navigationType),
+ qUrl,
+ toQt(request->first_party_for_cookies()),
+ QByteArray::fromStdString(request->method()));
QWebEngineUrlRequestInfo requestInfo(infoPrivate);
interceptor->interceptRequest(requestInfo);
if (requestInfo.changed()) {
diff --git a/src/core/pdfium_printing_wrapper_qt.cpp b/src/core/pdfium_document_wrapper_qt.cpp
index fceb381af..7c43c77db 100644
--- a/src/core/pdfium_printing_wrapper_qt.cpp
+++ b/src/core/pdfium_document_wrapper_qt.cpp
@@ -36,23 +36,22 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
-#include "pdfium_printing_wrapper_qt.h"
+#if defined (ENABLE_PDF)
+#include "pdfium_document_wrapper_qt.h"
#include <QtCore/qhash.h>
#include <QtGui/qimage.h>
#include <QtGui/qpainter.h>
-#include <QtPrintSupport/qprinter.h>
#include "third_party/pdfium/public/fpdf_doc.h"
#include "third_party/pdfium/public/fpdfview.h"
namespace QtWebEngineCore {
-int PdfiumPrintingWrapperQt::m_libraryUsers = 0;
+int PdfiumDocumentWrapperQt::m_libraryUsers = 0;
-class PDFiumPageWrapper {
+class QWEBENGINE_EXPORT PdfiumPageWrapperQt {
public:
- PDFiumPageWrapper(void *data, int pageIndex, int targetWidth, int targetHeight)
+ PdfiumPageWrapperQt(void *data, int pageIndex, int targetWidth, int targetHeight)
: m_pageData(FPDF_LoadPage(data, pageIndex))
, m_width(FPDF_GetPageWidth(m_pageData))
, m_height(FPDF_GetPageHeight(m_pageData))
@@ -61,7 +60,7 @@ public:
{
}
- PDFiumPageWrapper()
+ PdfiumPageWrapperQt()
: m_pageData(nullptr)
, m_width(-1)
, m_height(-1)
@@ -70,7 +69,7 @@ public:
{
}
- virtual ~PDFiumPageWrapper()
+ virtual ~PdfiumPageWrapperQt()
{
FPDF_ClosePage(m_pageData);
}
@@ -125,111 +124,49 @@ private:
};
-PdfiumPrintingWrapperQt::PdfiumPrintingWrapperQt(const void *pdfData, size_t size, const char *password)
+PdfiumDocumentWrapperQt::PdfiumDocumentWrapperQt(const void *pdfData, size_t size, const QSize& imageSize, const char *password)
+ : m_imageSize(imageSize * 2.0)
{
- Q_ASSERT(pdfData);
- Q_ASSERT(size);
- if (m_libraryUsers++ == 0)
- FPDF_InitLibrary();
+ Q_ASSERT(pdfData);
+ Q_ASSERT(size);
+ if (m_libraryUsers++ == 0)
+ FPDF_InitLibrary();
- m_documentHandle = FPDF_LoadMemDocument(pdfData, static_cast<int>(size), password);
- m_pageCount = FPDF_GetPageCount(m_documentHandle);
+ m_documentHandle = FPDF_LoadMemDocument(pdfData, static_cast<int>(size), password);
+ m_pageCount = FPDF_GetPageCount(m_documentHandle);
}
-bool PdfiumPrintingWrapperQt::printOnPrinter(QPrinter &printer)
+QImage PdfiumDocumentWrapperQt::pageAsQImage(size_t index)
{
if (!m_documentHandle || !m_pageCount) {
-#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
- qWarning("Failure to print on printer %ls: invalid document.\n", qUtf16Printable(printer.printerName()));
-#endif
- return false;
- }
-
- int toPage = printer.toPage();
- int fromPage = printer.fromPage();
- bool ascendingOrder = true;
-
- if (fromPage == 0 && toPage == 0) {
- fromPage = 1;
- toPage = m_pageCount;
+ qWarning("Failure to generate QImage from invalid or empty PDF document.");
+ return QImage();
}
- fromPage = qMax(1, fromPage);
- toPage = qMin(m_pageCount, toPage);
- if (printer.pageOrder() == QPrinter::LastPageFirst) {
- qSwap(fromPage, toPage);
- ascendingOrder = false;
+ if (static_cast<int>(index) >= m_pageCount) {
+ qWarning("Failure to generate QImage from PDF data: index out of bounds.");
+ return QImage();
}
- int documentCopies = printer.copyCount();
- int pageCopies = 1;
- if (printer.collateCopies()) {
- pageCopies = documentCopies;
- documentCopies = 1;
+ PdfiumPageWrapperQt *pageWrapper = nullptr;
+ if (!m_cachedPages.contains(index)) {
+ pageWrapper = new PdfiumPageWrapperQt(m_documentHandle, index,
+ m_imageSize.width(), m_imageSize.height());
+ m_cachedPages.insert(index, pageWrapper);
+ } else {
+ pageWrapper = m_cachedPages.value(index);
}
- QRect printerPageRect = printer.pageRect();
- int doubledPrinterWidth = 2 * printerPageRect.width();
- int doubledPrinterHeight = 2 * printerPageRect.height();
-
- QPainter painter;
- if (!painter.begin(&printer)) {
-#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
- qWarning("Failure to print on printer %ls: Could not open printer for painting.\n", qUtf16Printable(printer.printerName()));
-#endif
- return false;
- }
-
- QHash<int, PDFiumPageWrapper*> cachedPages;
- for (int printedDocuments = 0; printedDocuments < documentCopies; printedDocuments++) {
- int currentPageIndex = fromPage;
- while (true) {
- for (int printedPages = 0; printedPages < pageCopies; printedPages++) {
- if (printer.printerState() == QPrinter::Aborted
- || printer.printerState() == QPrinter::Error)
- return false;
-
- PDFiumPageWrapper *currentPageWrapper;
- if (!cachedPages.contains(currentPageIndex - 1)) {
- currentPageWrapper
- = new PDFiumPageWrapper(m_documentHandle, currentPageIndex - 1
- , doubledPrinterWidth, doubledPrinterHeight);
- cachedPages.insert(currentPageIndex - 1, currentPageWrapper);
- } else {
- currentPageWrapper = cachedPages.value(currentPageIndex - 1);
- }
-
- QImage currentImage = currentPageWrapper->image();
- painter.drawImage(printerPageRect, currentImage, currentImage.rect());
- if (printedPages < pageCopies - 1)
- printer.newPage();
- }
-
- if (currentPageIndex == toPage)
- break;
-
- if (ascendingOrder)
- currentPageIndex++;
- else
- currentPageIndex--;
-
- printer.newPage();
- }
- if (printedDocuments < documentCopies - 1)
- printer.newPage();
- }
- painter.end();
-
- qDeleteAll(cachedPages);
-
- return true;
+ return pageWrapper->image();
}
-PdfiumPrintingWrapperQt::~PdfiumPrintingWrapperQt()
+PdfiumDocumentWrapperQt::~PdfiumDocumentWrapperQt()
{
+ qDeleteAll(m_cachedPages);
FPDF_CloseDocument(m_documentHandle);
if (--m_libraryUsers == 0)
FPDF_DestroyLibrary();
}
}
+#endif // defined (ENABLE_PDF)
diff --git a/src/core/pdfium_printing_wrapper_qt.h b/src/core/pdfium_document_wrapper_qt.h
index 3aaf2b461..42ac94a28 100644
--- a/src/core/pdfium_printing_wrapper_qt.h
+++ b/src/core/pdfium_document_wrapper_qt.h
@@ -37,30 +37,35 @@
**
****************************************************************************/
-#ifndef PDFIUM_PRINTING_WRAPPER_QT_H
-#define PDFIUM_PRINTING_WRAPPER_QT_H
+#ifndef PDFIUM_DOCUMENT_WRAPPER_QT_H
+#define PDFIUM_DOCUMENT_WRAPPER_QT_H
-#include <QtCore/qglobal.h>
+#if defined(ENABLE_PDF)
+#include "qtwebenginecoreglobal.h"
-QT_BEGIN_NAMESPACE
-class QPrinter;
-QT_END_NAMESPACE
+#include <QtCore/qglobal.h>
+#include <QtCore/qhash.h>
+#include <QtGui/qimage.h>
namespace QtWebEngineCore {
+class PdfiumPageWrapperQt;
-class PdfiumPrintingWrapperQt
+class QWEBENGINE_EXPORT PdfiumDocumentWrapperQt
{
public:
- PdfiumPrintingWrapperQt(const void *pdfData, size_t size, const char *password = nullptr);
- virtual ~PdfiumPrintingWrapperQt();
- bool printOnPrinter(QPrinter &printer);
+ PdfiumDocumentWrapperQt(const void *pdfData, size_t size, const QSize &imageSize, const char *password = nullptr);
+ virtual ~PdfiumDocumentWrapperQt();
+ QImage pageAsQImage(size_t index);
int pageCount() const { return m_pageCount; }
private:
static int m_libraryUsers;
- void *m_documentHandle;
int m_pageCount;
+ void *m_documentHandle;
+ QSize m_imageSize;
+ QHash<int, PdfiumPageWrapperQt*> m_cachedPages;
};
} // namespace QtWebEngineCore
-#endif // PDFIUM_PRINTING_WRAPPER_QT_H
+#endif // defined (ENABLE_PDF)
+#endif // PDFIUM_DOCUMENT_WRAPPER_QT_H
diff --git a/src/core/render_view_observer_host_qt.cpp b/src/core/render_view_observer_host_qt.cpp
index c03cecb38..643eba007 100644
--- a/src/core/render_view_observer_host_qt.cpp
+++ b/src/core/render_view_observer_host_qt.cpp
@@ -71,8 +71,6 @@ bool RenderViewObserverHostQt::OnMessageReceived(const IPC::Message& message)
onDidFetchDocumentMarkup)
IPC_MESSAGE_HANDLER(RenderViewObserverHostQt_DidFetchDocumentInnerText,
onDidFetchDocumentInnerText)
- IPC_MESSAGE_HANDLER(RenderViewObserverHostQt_DidFirstVisuallyNonEmptyLayout,
- onDidFirstVisuallyNonEmptyLayout)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -89,11 +87,4 @@ void RenderViewObserverHostQt::onDidFetchDocumentInnerText(quint64 requestId, co
m_adapterClient->didFetchDocumentInnerText(requestId, toQt(innerText));
}
-void RenderViewObserverHostQt::onDidFirstVisuallyNonEmptyLayout()
-{
- RenderWidgetHostViewQt *rwhv = static_cast<RenderWidgetHostViewQt*>(web_contents()->GetRenderWidgetHostView());
- if (rwhv)
- rwhv->didFirstVisuallyNonEmptyLayout();
-}
-
} // namespace QtWebEngineCore
diff --git a/src/core/render_view_observer_host_qt.h b/src/core/render_view_observer_host_qt.h
index f352be7b9..42d232b01 100644
--- a/src/core/render_view_observer_host_qt.h
+++ b/src/core/render_view_observer_host_qt.h
@@ -63,7 +63,6 @@ private:
bool OnMessageReceived(const IPC::Message& message) Q_DECL_OVERRIDE;
void onDidFetchDocumentMarkup(quint64 requestId, const base::string16& markup);
void onDidFetchDocumentInnerText(quint64 requestId, const base::string16& innerText);
- void onDidFirstVisuallyNonEmptyLayout();
WebContentsAdapterClient *m_adapterClient;
};
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 097dda1cd..70ffe0dcb 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -236,7 +236,7 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost* widget
, m_touchMotionStarted(false)
, m_chromiumCompositorData(new ChromiumCompositorData)
, m_needsDelegatedFrameAck(false)
- , m_didFirstVisuallyNonEmptyLayout(false)
+ , m_loadVisuallyCommittedState(NotCommitted)
, m_adapterClient(0)
, m_imeInProgress(false)
, m_receivedEmptyImeText(false)
@@ -676,9 +676,11 @@ void RenderWidgetHostViewQt::OnSwapCompositorFrame(uint32_t output_surface_id, c
m_delegate->update();
- if (m_didFirstVisuallyNonEmptyLayout) {
+ if (m_loadVisuallyCommittedState == NotCommitted) {
+ m_loadVisuallyCommittedState = DidFirstCompositorFrameSwap;
+ } else if (m_loadVisuallyCommittedState == DidFirstVisuallyNonEmptyPaint) {
m_adapterClient->loadVisuallyCommitted();
- m_didFirstVisuallyNonEmptyLayout = false;
+ m_loadVisuallyCommittedState = NotCommitted;
}
if (scrollOffsetChanged)
@@ -1244,9 +1246,4 @@ void RenderWidgetHostViewQt::handleFocusEvent(QFocusEvent *ev)
}
}
-void RenderWidgetHostViewQt::didFirstVisuallyNonEmptyLayout()
-{
- m_didFirstVisuallyNonEmptyLayout = true;
-}
-
} // namespace QtWebEngineCore
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index d6c77fada..0b2d7bc9d 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -104,6 +104,12 @@ class RenderWidgetHostViewQt
#endif // QT_NO_ACCESSIBILITY
{
public:
+ enum LoadVisuallyCommittedState {
+ NotCommitted,
+ DidFirstVisuallyNonEmptyPaint,
+ DidFirstCompositorFrameSwap
+ };
+
RenderWidgetHostViewQt(content::RenderWidgetHost* widget);
~RenderWidgetHostViewQt();
@@ -193,7 +199,8 @@ public:
#ifndef QT_NO_ACCESSIBILITY
virtual void accessibilityActiveChanged(bool active) Q_DECL_OVERRIDE;
#endif // QT_NO_ACCESSIBILITY
- void didFirstVisuallyNonEmptyLayout();
+ LoadVisuallyCommittedState getLoadVisuallyCommittedState() const { return m_loadVisuallyCommittedState; }
+ void setLoadVisuallyCommittedState(LoadVisuallyCommittedState state) { m_loadVisuallyCommittedState = state; }
gfx::SizeF lastContentsSize() const { return m_lastContentsSize; }
@@ -218,7 +225,7 @@ private:
QExplicitlySharedDataPointer<ChromiumCompositorData> m_chromiumCompositorData;
cc::ReturnedResourceArray m_resourcesToRelease;
bool m_needsDelegatedFrameAck;
- bool m_didFirstVisuallyNonEmptyLayout;
+ LoadVisuallyCommittedState m_loadVisuallyCommittedState;
uint32_t m_pendingOutputSurfaceId;
QMetaObject::Connection m_adapterClientDestroyedConnection;
diff --git a/src/core/renderer/render_view_observer_qt.cpp b/src/core/renderer/render_view_observer_qt.cpp
index 393b4752c..97485afad 100644
--- a/src/core/renderer/render_view_observer_qt.cpp
+++ b/src/core/renderer/render_view_observer_qt.cpp
@@ -83,11 +83,6 @@ void RenderViewObserverQt::onSetBackgroundColor(quint32 color)
render_view()->GetWebFrameWidget()->setBaseBackgroundColor(color);
}
-void RenderViewObserverQt::OnFirstVisuallyNonEmptyLayout()
-{
- Send(new RenderViewObserverHostQt_DidFirstVisuallyNonEmptyLayout(routing_id()));
-}
-
bool RenderViewObserverQt::OnMessageReceived(const IPC::Message& message)
{
bool handled = true;
diff --git a/src/core/renderer/render_view_observer_qt.h b/src/core/renderer/render_view_observer_qt.h
index b62c815af..538ebea8a 100644
--- a/src/core/renderer/render_view_observer_qt.h
+++ b/src/core/renderer/render_view_observer_qt.h
@@ -57,7 +57,6 @@ private:
void onFetchDocumentInnerText(quint64 requestId);
void onSetBackgroundColor(quint32 color);
- void OnFirstVisuallyNonEmptyLayout() Q_DECL_OVERRIDE;
void OnDestruct() Q_DECL_OVERRIDE { }
virtual bool OnMessageReceived(const IPC::Message& message) Q_DECL_OVERRIDE;
diff --git a/src/core/url_request_custom_job.cpp b/src/core/url_request_custom_job.cpp
index 887222285..d093efd0a 100644
--- a/src/core/url_request_custom_job.cpp
+++ b/src/core/url_request_custom_job.cpp
@@ -229,6 +229,9 @@ void URLRequestCustomJobShared::setReplyDevice(QIODevice *device)
if (m_device && !m_device->isReadable())
m_device->open(QIODevice::ReadOnly);
+ qint64 size = m_device ? m_device->size() : -1;
+ if (size > 0)
+ m_job->set_expected_content_size(size);
if (m_device && m_device->isReadable())
content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyStarted, m_weakFactory.GetWeakPtr()));
else
diff --git a/src/core/url_request_qrc_job_qt.cpp b/src/core/url_request_qrc_job_qt.cpp
index ffe9b6dc6..97460f0b7 100644
--- a/src/core/url_request_qrc_job_qt.cpp
+++ b/src/core/url_request_qrc_job_qt.cpp
@@ -120,6 +120,7 @@ void URLRequestQrcJobQt::startGetHead()
// Open file
if (m_file.open(QIODevice::ReadOnly)) {
m_remainingBytes = m_file.size();
+ set_expected_content_size(m_remainingBytes);
// Notify that the headers are complete
NotifyHeadersComplete();
} else {
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index fadbd6d2e..cafaad93d 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -50,7 +50,7 @@
#include "browser_context_qt.h"
#include "download_manager_delegate_qt.h"
#include "media_capture_devices_dispatcher.h"
-#include "pdfium_printing_wrapper_qt.h"
+#include "pdfium_document_wrapper_qt.h"
#include "print_view_manager_qt.h"
#include "qwebenginecallback_p.h"
#include "renderer_host/web_channel_ipc_transport_host.h"
@@ -92,9 +92,6 @@
#include <QtGui/qaccessible.h>
#include <QtGui/qdrag.h>
#include <QtGui/qpixmap.h>
-#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER)
-#include <QtPrintSupport/qprinter.h>
-#endif // QT_NO_PRINTER
#include <QtWebChannel/QWebChannel>
namespace QtWebEngineCore {
@@ -188,21 +185,9 @@ static void callbackOnEvaluateJS(WebContentsAdapterClient *adapterClient, quint6
static void callbackOnPrintingFinished(WebContentsAdapterClient *adapterClient, int requestId, const std::vector<char>& result)
{
- if (requestId) {
+ if (requestId)
adapterClient->didPrintPage(requestId, QByteArray(result.data(), result.size()));
- }
-}
-
-#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER)
-static void callbackOnPrintingOnPrinterFinished(WebContentsAdapterClient *adapterClient, int requestId, QPrinter *printer, const std::vector<char> &result)
-{
- if (requestId) {
- PdfiumPrintingWrapperQt printWrapper(result.data(), result.size());
- bool printerResult = printWrapper.printOnPrinter(*printer);
- adapterClient->didPrintPageOnPrinter(requestId, printerResult);
- }
}
-#endif // QT_NO_PRINTER
static content::WebContents *createBlankWebContents(WebContentsAdapterClient *adapterClient, content::BrowserContext *browserContext)
{
@@ -978,14 +963,14 @@ void WebContentsAdapter::printToPDF(const QPageLayout &pageLayout, const QString
#endif // if defined(ENABLE_BASIC_PRINTING)
}
-quint64 WebContentsAdapter::printToPDFCallbackResult(const QPageLayout &pageLayout)
+quint64 WebContentsAdapter::printToPDFCallbackResult(const QPageLayout &pageLayout, const bool colorMode)
{
#if defined(ENABLE_BASIC_PRINTING)
Q_D(WebContentsAdapter);
PrintViewManagerQt::PrintToPDFCallback callback = base::Bind(&callbackOnPrintingFinished
, d->adapterClient
, d->nextRequestId);
- PrintViewManagerQt::FromWebContents(webContents())->PrintToPDFWithCallback(pageLayout, true
+ PrintViewManagerQt::FromWebContents(webContents())->PrintToPDFWithCallback(pageLayout, colorMode
, callback);
return d->nextRequestId++;
#else
@@ -993,23 +978,6 @@ quint64 WebContentsAdapter::printToPDFCallbackResult(const QPageLayout &pageLayo
#endif // if defined(ENABLE_BASIC_PRINTING)
}
-#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER)
-quint64 WebContentsAdapter::printOnPrinterCallbackResult(QPrinter *printer)
-{
-#if defined(ENABLE_BASIC_PRINTING)
- Q_D(WebContentsAdapter);
- PrintViewManagerQt::PrintToPDFCallback callback
- = base::Bind(&callbackOnPrintingOnPrinterFinished, d->adapterClient
- , d->nextRequestId, printer);
- PrintViewManagerQt::FromWebContents(webContents())->PrintToPDFWithCallback(
- printer->pageLayout(), printer->colorMode() == QPrinter::Color, callback);
- return d->nextRequestId++;
-#else
- return 0;
-#endif // if defined(ENABLE_BASIC_PRINTING)
-}
-#endif // QT_NO_PRINTER
-
QPointF WebContentsAdapter::lastScrollOffset() const
{
Q_D(const WebContentsAdapter);
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 7a109770e..3befe6d27 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -58,9 +58,6 @@ class QAccessibleInterface;
class QDragEnterEvent;
class QDragMoveEvent;
class QPageLayout;
-#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER)
-class QPrinter;
-#endif // QT_NO_PRINTER
class QString;
class QWebChannel;
QT_END_NAMESPACE
@@ -175,11 +172,7 @@ public:
void leaveDrag();
void initUpdateDragCursorMessagePollingTimer();
void printToPDF(const QPageLayout&, const QString&);
- quint64 printToPDFCallbackResult(const QPageLayout &);
-
-#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER)
- quint64 printOnPrinterCallbackResult(QPrinter *printer);
-#endif
+ quint64 printToPDFCallbackResult(const QPageLayout &, const bool colorMode = true);
// meant to be used within WebEngineCore only
content::WebContents *webContents() const;
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 85a379409..4e15df753 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -347,9 +347,6 @@ public:
virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) = 0;
virtual void didFindText(quint64 requestId, int matchCount) = 0;
virtual void didPrintPage(quint64 requestId, const QByteArray &result) = 0;
-#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER)
- virtual void didPrintPageOnPrinter(quint64 requestId, bool result) = 0;
-#endif
virtual void passOnFocus(bool reverse) = 0;
// returns the last QObject (QWidget/QQuickItem) based object in the accessibility
// hierarchy before going into the BrowserAccessibility tree
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 36acfe62e..87badc189 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -51,6 +51,7 @@
#include "file_picker_controller.h"
#include "media_capture_devices_dispatcher.h"
#include "network_delegate_qt.h"
+#include "render_widget_host_view_qt.h"
#include "type_conversion.h"
#include "web_contents_adapter_client.h"
#include "web_contents_adapter_p.h"
@@ -387,6 +388,21 @@ void WebContentsDelegateQt::WasShown()
web_cache::WebCacheManager::GetInstance()->ObserveActivity(web_contents()->GetRenderProcessHost()->GetID());
}
+void WebContentsDelegateQt::DidFirstVisuallyNonEmptyPaint()
+{
+ RenderWidgetHostViewQt *rwhv = static_cast<RenderWidgetHostViewQt*>(web_contents()->GetRenderWidgetHostView());
+ if (!rwhv)
+ return;
+
+ RenderWidgetHostViewQt::LoadVisuallyCommittedState loadVisuallyCommittedState = rwhv->getLoadVisuallyCommittedState();
+ if (loadVisuallyCommittedState == RenderWidgetHostViewQt::NotCommitted) {
+ rwhv->setLoadVisuallyCommittedState(RenderWidgetHostViewQt::DidFirstVisuallyNonEmptyPaint);
+ } else if (loadVisuallyCommittedState == RenderWidgetHostViewQt::DidFirstCompositorFrameSwap) {
+ m_viewClient->loadVisuallyCommitted();
+ rwhv->setLoadVisuallyCommittedState(RenderWidgetHostViewQt::NotCommitted);
+ }
+}
+
void WebContentsDelegateQt::RequestToLockMouse(content::WebContents *web_contents, bool user_gesture, bool last_unlocked_by_target)
{
Q_UNUSED(user_gesture);
@@ -422,7 +438,7 @@ void WebContentsDelegateQt::requestGeolocationPermission(const QUrl &requestingO
m_viewClient->runGeolocationPermissionRequest(requestingOrigin);
}
-extern int pageTransitionToNavigationType(ui::PageTransition transition);
+extern WebContentsAdapterClient::NavigationType pageTransitionToNavigationType(ui::PageTransition transition);
void WebContentsDelegateQt::launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame)
{
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index dad1e50f1..683b14ddf 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -135,6 +135,7 @@ public:
virtual void DidUpdateFaviconURL(const std::vector<content::FaviconURL> &candidates) Q_DECL_OVERRIDE;
virtual void DidNavigateAnyFrame(content::RenderFrameHost *render_frame_host, const content::LoadCommittedDetails &details, const content::FrameNavigateParams &params) Q_DECL_OVERRIDE;
virtual void WasShown() Q_DECL_OVERRIDE;
+ virtual void DidFirstVisuallyNonEmptyPaint() Q_DECL_OVERRIDE;
void overrideWebPreferences(content::WebContents *, content::WebPreferences*);
void allowCertificateError(const QSharedPointer<CertificateErrorController> &) ;
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 491835e45..152859bee 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -240,17 +240,15 @@ QObject *WebEngineContext::globalQObject()
#define CHROMIUM_VERSION // This is solely to keep Qt Creator happy.
#endif
+const static char kChromiumFlagsEnv[] = "QTWEBENGINE_CHROMIUM_FLAGS";
+const static char kDisableSandboxEnv[] = "QTWEBENGINE_DISABLE_SANDBOX";
+
WebEngineContext::WebEngineContext()
: m_mainDelegate(new ContentMainDelegateQt)
, m_contentRunner(content::ContentMainRunner::Create())
, m_browserRunner(content::BrowserMainRunner::Create())
, m_globalQObject(new QObject())
{
- QStringList appArgs = QCoreApplication::arguments();
- bool useEmbeddedSwitches = appArgs.removeAll(QStringLiteral("--enable-embedded-switches"));
-#if defined(QTWEBENGINE_EMBEDDED_SWITCHES)
- useEmbeddedSwitches = !appArgs.removeAll(QStringLiteral("--disable-embedded-switches"));
-#endif
#ifdef Q_OS_LINUX
// Call qputenv before BrowserMainRunnerImpl::Initialize is called.
@@ -261,32 +259,35 @@ WebEngineContext::WebEngineContext()
// Allow us to inject javascript like any webview toolkit.
content::RenderFrameHost::AllowInjectingJavaScriptForAndroidWebView();
-#if defined(Q_OS_WIN)
- // We must initialize the command line with the UTF-16 arguments vector we got from
- // QCoreApplication. CommandLine::Init ignores its arguments on Windows and calls
- // GetCommandLineW() instead.
base::CommandLine::CreateEmpty();
base::CommandLine* parsedCommandLine = base::CommandLine::ForCurrentProcess();
+ QStringList appArgs = QCoreApplication::arguments();
+ if (qEnvironmentVariableIsSet(kChromiumFlagsEnv)) {
+ appArgs = appArgs.mid(0, 1); // Take application name and drop the rest
+ appArgs.append(QString::fromLocal8Bit(qgetenv(kChromiumFlagsEnv)).split(' '));
+ }
+
+ bool useEmbeddedSwitches = false;
+#if defined(QTWEBENGINE_EMBEDDED_SWITCHES)
+ useEmbeddedSwitches = !appArgs.removeAll(QStringLiteral("--disable-embedded-switches"));
+#else
+ useEmbeddedSwitches = appArgs.removeAll(QStringLiteral("--enable-embedded-switches"));
+#endif
base::CommandLine::StringVector argv;
argv.resize(appArgs.size());
- std::transform(appArgs.constBegin(), appArgs.constEnd(), argv.begin(), &toString16);
- parsedCommandLine->InitFromArgv(argv);
+#if defined(Q_OS_WIN)
+ for (int i = 0; i < appArgs.size(); ++i)
+ argv[i] = toString16(appArgs[i]);
#else
- QVector<QByteArray> args;
- Q_FOREACH (const QString& arg, appArgs)
- args << arg.toUtf8();
-
- QVector<const char*> argv(args.size());
- for (int i = 0; i < args.size(); ++i)
- argv[i] = args[i].constData();
- base::CommandLine::Init(argv.size(), argv.constData());
- base::CommandLine* parsedCommandLine = base::CommandLine::ForCurrentProcess();
+ for (int i = 0; i < appArgs.size(); ++i)
+ argv[i] = appArgs[i].toStdString();
#endif
+ parsedCommandLine->InitFromArgv(argv);
parsedCommandLine->AppendSwitchPath(switches::kBrowserSubprocessPath, WebEngineLibraryInfo::getPath(content::CHILD_PROCESS_EXE));
// Enable sandboxing on OS X and Linux (Desktop / Embedded) by default.
- bool disable_sandbox = qEnvironmentVariableIsSet("QTWEBENGINE_DISABLE_SANDBOX");
+ bool disable_sandbox = qEnvironmentVariableIsSet(kDisableSandboxEnv);
if (!disable_sandbox) {
#if defined(Q_OS_WIN)
parsedCommandLine->AppendSwitch(switches::kNoSandbox);
@@ -328,7 +329,14 @@ WebEngineContext::WebEngineContext()
#ifndef QT_NO_OPENGL
if (!usingANGLE() && !usingSoftwareDynamicGL() && !usingQtQuick2DRenderer()) {
if (qt_gl_global_share_context() && qt_gl_global_share_context()->isValid()) {
- if (!strcmp(qt_gl_global_share_context()->nativeHandle().typeName(), "QEGLNativeContext")) {
+ // If the native handle is QEGLNativeContext try to use GL ES/2, if there is no native handle
+ // assume we are using wayland and try GL ES/2, and finally Ozone demands GL ES/2 too.
+ if (qt_gl_global_share_context()->nativeHandle().isNull()
+#ifdef USE_OZONE
+ || true
+#endif
+ || !strcmp(qt_gl_global_share_context()->nativeHandle().typeName(), "QEGLNativeContext"))
+ {
if (qt_gl_global_share_context()->isOpenGLES()) {
glType = gl::kGLImplementationEGLName;
} else {
diff --git a/src/webengine/api/qquickwebenginefaviconprovider.cpp b/src/webengine/api/qquickwebenginefaviconprovider.cpp
index fe8436d6c..b5ad6960a 100644
--- a/src/webengine/api/qquickwebenginefaviconprovider.cpp
+++ b/src/webengine/api/qquickwebenginefaviconprovider.cpp
@@ -152,7 +152,7 @@ QQuickWebEngineView *QQuickWebEngineFaviconProvider::viewForIconUrl(const QUrl &
// latest WebEngineView which was raised an iconChanged signal.
if (m_latestView) {
QList<QUrl> *iconUrls = m_iconUrlMap[m_latestView];
- if (iconUrls->contains(iconUrl))
+ if (iconUrls && iconUrls->contains(iconUrl))
return m_latestView;
}
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 6ca9954cf..f0811014b 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -1066,8 +1066,8 @@ void QQuickWebEngineView::setTestSupport(QQuickWebEngineTestSupport *testSupport
{
Q_D(QQuickWebEngineView);
d->m_testSupport = testSupport;
+ Q_EMIT testSupportChanged();
}
-
#endif
bool QQuickWebEngineView::activeFocusOnPress() const
@@ -1302,16 +1302,23 @@ bool QQuickWebEngineView::recentlyAudible() const
void QQuickWebEngineView::printToPdf(const QString& filePath, PrintedPageSizeId pageSizeId, PrintedPageOrientation orientation)
{
+#if defined(ENABLE_PDF)
Q_D(const QQuickWebEngineView);
QPageSize layoutSize(static_cast<QPageSize::PageSizeId>(pageSizeId));
QPageLayout::Orientation layoutOrientation = static_cast<QPageLayout::Orientation>(orientation);
QPageLayout pageLayout(layoutSize, layoutOrientation, QMarginsF(0.0, 0.0, 0.0, 0.0));
d->adapter->printToPDF(pageLayout, filePath);
+#else
+ Q_UNUSED(filePath);
+ Q_UNUSED(pageSizeId);
+ Q_UNUSED(orientation);
+#endif
}
void QQuickWebEngineView::printToPdf(const QJSValue &callback, PrintedPageSizeId pageSizeId, PrintedPageOrientation orientation)
{
+#if defined (ENABLE_PDF)
Q_D(QQuickWebEngineView);
QPageSize layoutSize(static_cast<QPageSize::PageSizeId>(pageSizeId));
QPageLayout::Orientation layoutOrientation = static_cast<QPageLayout::Orientation>(orientation);
@@ -1322,6 +1329,16 @@ void QQuickWebEngineView::printToPdf(const QJSValue &callback, PrintedPageSizeId
quint64 requestId = d->adapter->printToPDFCallbackResult(pageLayout);
d->m_callbacks.insert(requestId, callback);
+#else
+ Q_UNUSED(pageSizeId);
+ Q_UNUSED(orientation);
+
+ // Call back with null result.
+ QJSValueList args;
+ args.append(QJSValue(QByteArray().data()));
+ QJSValue callbackCopy = callback;
+ callbackCopy.call(args);
+#endif
}
void QQuickWebEngineView::replaceMisspelledWord(const QString &replacement)
diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index 16c4799b5..4f9e483bc 100644
--- a/src/webengine/api/qquickwebengineview_p.h
+++ b/src/webengine/api/qquickwebengineview_p.h
@@ -125,7 +125,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem {
Q_PROPERTY(uint webChannelWorld READ webChannelWorld WRITE setWebChannelWorld NOTIFY webChannelWorldChanged REVISION 3)
#ifdef ENABLE_QML_TESTSUPPORT_API
- Q_PROPERTY(QQuickWebEngineTestSupport *testSupport READ testSupport WRITE setTestSupport FINAL)
+ Q_PROPERTY(QQuickWebEngineTestSupport *testSupport READ testSupport WRITE setTestSupport NOTIFY testSupportChanged FINAL)
#endif
Q_FLAGS(FindFlags);
@@ -513,6 +513,10 @@ Q_SIGNALS:
Q_REVISION(4) void fileDialogRequested(QQuickWebEngineFileDialogRequest *request);
Q_REVISION(4) void formValidationMessageRequested(QQuickWebEngineFormValidationMessageRequest *request);
+#ifdef ENABLE_QML_TESTSUPPORT_API
+ void testSupportChanged();
+#endif
+
protected:
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
void itemChange(ItemChange, const ItemChangeData &) Q_DECL_OVERRIDE;
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index b111e92cd..d692140ef 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -123,9 +123,6 @@ public:
virtual void didFetchDocumentInnerText(quint64, const QString&) Q_DECL_OVERRIDE { }
virtual void didFindText(quint64, int) Q_DECL_OVERRIDE;
virtual void didPrintPage(quint64 requestId, const QByteArray &result) Q_DECL_OVERRIDE;
-#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER)
- virtual void didPrintPageOnPrinter(quint64, bool) Q_DECL_OVERRIDE { }
-#endif
virtual void passOnFocus(bool reverse) Q_DECL_OVERRIDE;
virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE;
virtual void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) Q_DECL_OVERRIDE;
diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
index c5ebe0f06..615e3eed0 100644
--- a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
+++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
@@ -62,14 +62,14 @@
On all platforms, the following tools are required:
\list
- \li \l Python 2.7 or later
+ \li \l Python 2.7.5 or later
\li Bison, Flex
\li GPerf
\endlist
\section2 Windows
- On Windows, Visual Studio 2013 or Visual Studio 2015 is required.
+ On Windows, Visual Studio 2015 and Windows 10 SDK are required.
\section2 Linux
diff --git a/src/webengine/webengine.pro b/src/webengine/webengine.pro
index 99b9c4e6f..2bbf82810 100644
--- a/src/webengine/webengine.pro
+++ b/src/webengine/webengine.pro
@@ -65,6 +65,10 @@ contains(WEBENGINE_CONFIG, use_spellchecker) {
DEFINES += ENABLE_SPELLCHECK
}
+contains(WEBENGINE_CONFIG, enable_pdf) {
+ DEFINES += ENABLE_PDF
+}
+
!build_pass {
chromium_attributions.commands = \
cd $$shell_quote($$shell_path($$PWD/../3rdparty)) && \
diff --git a/src/webenginewidgets/api/qtwebenginewidgetsglobal.cpp b/src/webenginewidgets/api/qtwebenginewidgetsglobal.cpp
index e47f135e8..a39c0e483 100644
--- a/src/webenginewidgets/api/qtwebenginewidgetsglobal.cpp
+++ b/src/webenginewidgets/api/qtwebenginewidgetsglobal.cpp
@@ -48,18 +48,26 @@ namespace QtWebEngineCore
}
QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_OPENGL
+Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
+#endif
+
static void initialize()
{
- //On window/ANGLE, calling QtWebEngine::initialize from DllMain will result in a crash.
- //To ensure it doesn't, we check that when loading the library
- //QCoreApplication is not yet instantiated, ensuring the call will be deferred
-#if defined(Q_OS_WIN)
- if (QCoreApplication::instance()
- && QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) {
+#ifndef QT_NO_OPENGL
+ if (QCoreApplication::instance()) {
+ //On window/ANGLE, calling QtWebEngine::initialize from DllMain will result in a crash.
+ if (!qt_gl_global_share_context()) {
+ qWarning("Qt WebEngine seems to be initialized from a plugin. Please "
+ "set Qt::AA_ShareOpenGLContexts using QCoreApplication::setAttribute "
+ "before constructing QGuiApplication.");
+ }
return;
}
-#endif
+ //QCoreApplication is not yet instantiated, ensuring the call will be deferred
qAddPreRoutine(QtWebEngineCore::initialize);
+#endif // QT_NO_OPENGL
}
Q_CONSTRUCTOR_FUNCTION(initialize)
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index ca160c362..16e9438c9 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -47,6 +47,7 @@
#include "favicon_manager.h"
#include "file_picker_controller.h"
#include "javascript_dialog_controller.h"
+#include "pdfium_document_wrapper_qt.h"
#include "qwebenginefullscreenrequest.h"
#include "qwebenginehistory.h"
#include "qwebenginehistory_p.h"
@@ -79,6 +80,9 @@
#include <QMenu>
#include <QMessageBox>
#include <QMimeData>
+#ifndef QT_NO_PRINTER
+#include <QPrinter>
+#endif
#include <QStandardPaths>
#include <QStyle>
#include <QTimer>
@@ -92,6 +96,87 @@ using namespace QtWebEngineCore;
static const int MaxTooltipLength = 1024;
+#ifndef QT_NO_PRINTER
+#if defined(ENABLE_PDF)
+static bool printPdfDataOnPrinter(const QByteArray& data, QPrinter& printer)
+{
+ QRect printerPageRect = printer.pageRect();
+ PdfiumDocumentWrapperQt pdfiumWrapper(data.constData(), data.size(), printerPageRect.size());
+
+ int toPage = printer.toPage();
+ int fromPage = printer.fromPage();
+ bool ascendingOrder = true;
+
+ if (fromPage == 0 && toPage == 0) {
+ fromPage = 1;
+ toPage = pdfiumWrapper.pageCount();
+ }
+ fromPage = qMax(1, fromPage);
+ toPage = qMin(pdfiumWrapper.pageCount(), toPage);
+
+ if (printer.pageOrder() == QPrinter::LastPageFirst) {
+ qSwap(fromPage, toPage);
+ ascendingOrder = false;
+ }
+
+ int pageCopies = 1;
+ int documentCopies = 1;
+
+ if (!printer.supportsMultipleCopies())
+ documentCopies = printer.copyCount();
+
+ if (printer.collateCopies()) {
+ pageCopies = documentCopies;
+ documentCopies = 1;
+ }
+
+ QPainter painter;
+ if (!painter.begin(&printer)) {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+ qWarning("Failure to print on printer %ls: Could not open printer for painting.", qUtf16Printable(printer.printerName()));
+#else
+ qWarning("Failure to print on printer %s: Could not open printer for painting.", qPrintable(printer.printerName()));
+#endif
+ return false;
+ }
+
+ for (int printedDocuments = 0; printedDocuments < documentCopies; printedDocuments++) {
+ int currentPageIndex = fromPage;
+ while (true) {
+ for (int printedPages = 0; printedPages < pageCopies; printedPages++) {
+ if (printer.printerState() == QPrinter::Aborted
+ || printer.printerState() == QPrinter::Error)
+ return false;
+
+ QImage currentImage = pdfiumWrapper.pageAsQImage(currentPageIndex - 1);
+ if (currentImage.isNull())
+ return false;
+
+ painter.drawImage(printerPageRect, currentImage, currentImage.rect());
+ if (printedPages < pageCopies - 1)
+ printer.newPage();
+ }
+
+ if (currentPageIndex == toPage)
+ break;
+
+ if (ascendingOrder)
+ currentPageIndex++;
+ else
+ currentPageIndex--;
+
+ printer.newPage();
+ }
+ if (printedDocuments < documentCopies - 1)
+ printer.newPage();
+ }
+ painter.end();
+
+ return true;
+}
+#endif // defined(ENABLE_PDF)
+#endif // QT_NO_PRINTER
+
static QWebEnginePage::WebWindowType toWindowType(WebContentsAdapterClient::WindowOpenDisposition disposition)
{
switch (disposition) {
@@ -142,6 +227,9 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
, fullscreenMode(false)
, webChannel(nullptr)
, webChannelWorldId(QWebEngineScript::MainWorld)
+#ifndef QT_NO_PRINTER
+ , currentPrinter(nullptr)
+#endif
{
memset(actions, 0, sizeof(actions));
}
@@ -154,7 +242,16 @@ QWebEnginePagePrivate::~QWebEnginePagePrivate()
RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client)
{
- return new RenderWidgetHostViewQtDelegateWidget(client);
+ // Set the QWebEngineView as the parent for a popup delegate, so that the new popup window
+ // responds properly to clicks in case the QWebEngineView is inside a modal QDialog. Setting the
+ // parent essentially notifies the OS that the popup window is part of the modal session, and
+ // should allow interaction.
+ // The new delegate will not be deleted by the parent view though, because we unset the parent
+ // when the parent is destroyed. The delegate will be destroyed by Chromium when the popup is
+ // dismissed.
+ // If the delegate is not for a popup, but for a newly created QWebEngineView, the parent is 0
+ // just like before.
+ return new RenderWidgetHostViewQtDelegateWidget(client, this->view);
}
void QWebEnginePagePrivate::titleChanged(const QString &title)
@@ -380,15 +477,27 @@ void QWebEnginePagePrivate::didFindText(quint64 requestId, int matchCount)
void QWebEnginePagePrivate::didPrintPage(quint64 requestId, const QByteArray &result)
{
- m_callbacks.invoke(requestId, result);
-}
-
+#if defined(ENABLE_PDF)
#ifndef QT_NO_PRINTER
-void QWebEnginePagePrivate::didPrintPageOnPrinter(quint64 requestId, bool result)
-{
+ // If no currentPrinter is set that means that were printing to PDF only.
+ if (!currentPrinter) {
+ m_callbacks.invoke(requestId, result);
+ return;
+ }
+
+ bool printerResult = printPdfDataOnPrinter(result, *currentPrinter);
+
+ m_callbacks.invoke(requestId, printerResult);
+ currentPrinter = nullptr;
+#else // If print support is disabled, only PDF printing is available.
m_callbacks.invoke(requestId, result);
+#endif // ifndef QT_NO_PRINTER
+#else // defined(ENABLE_PDF)
+ // we should never enter this branch, but just for safe-keeping...
+ Q_UNUSED(result);
+ m_callbacks.invoke(requestId, QByteArray());
+#endif // defined(ENABLE_PDF)
}
-#endif
void QWebEnginePagePrivate::passOnFocus(bool reverse)
{
@@ -1835,8 +1944,23 @@ QSizeF QWebEnginePage::contentsSize() const
*/
void QWebEnginePage::printToPdf(const QString &filePath, const QPageLayout &pageLayout)
{
+#if defined(ENABLE_PDF)
Q_D(const QWebEnginePage);
+#ifndef QT_NO_PRINTER
+ if (d->currentPrinter) {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+ qWarning("Cannot print to PDF while at the same time printing on printer %ls", qUtf16Printable(d->currentPrinter->printerName()));
+#else
+ qWarning("Cannot print to PDF while at the same time printing on printer %s", qPrintable(d->currentPrinter->printerName()));
+#endif
+ return;
+ }
+#endif
d->adapter->printToPDF(pageLayout, filePath);
+#else
+ Q_UNUSED(filePath);
+ Q_UNUSED(pageLayout);
+#endif // if defined(ENABLE_PDF)
}
@@ -1854,8 +1978,24 @@ void QWebEnginePage::printToPdf(const QString &filePath, const QPageLayout &page
void QWebEnginePage::printToPdf(const QWebEngineCallback<const QByteArray&> &resultCallback, const QPageLayout &pageLayout)
{
Q_D(QWebEnginePage);
+#if defined(ENABLE_PDF)
+#ifndef QT_NO_PRINTER
+ if (d->currentPrinter) {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+ qWarning("Cannot print to PDF while at the same time printing on printer %ls", qUtf16Printable(d->currentPrinter->printerName()));
+#else
+ qWarning("Cannot print to PDF while at the same time printing on printer %s", qPrintable(d->currentPrinter->printerName()));
+#endif
+ d->m_callbacks.invokeEmpty(resultCallback);
+ return;
+ }
+#endif // ifndef QT_NO_PRINTER
quint64 requestId = d->adapter->printToPDFCallbackResult(pageLayout);
d->m_callbacks.registerCallback(requestId, resultCallback);
+#else // if defined(ENABLE_PDF)
+ Q_UNUSED(pageLayout);
+ d->m_callbacks.invokeEmpty(resultCallback);
+#endif // if defined(ENABLE_PDF)
}
#ifndef QT_NO_PRINTER
@@ -1875,8 +2015,23 @@ void QWebEnginePage::printToPdf(const QWebEngineCallback<const QByteArray&> &res
void QWebEnginePage::print(QPrinter *printer, const QWebEngineCallback<bool> &resultCallback)
{
Q_D(QWebEnginePage);
- quint64 requestId = d->adapter->printOnPrinterCallbackResult(printer);
+#if defined(ENABLE_PDF)
+ if (d->currentPrinter) {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+ qWarning("Cannot print page on printer %ls: Already printing on %ls.", qUtf16Printable(printer->printerName()), qUtf16Printable(d->currentPrinter->printerName()));
+#else
+ qWarning("Cannot print page on printer %s: Already printing on %s.", qPrintable(printer->printerName()), qPrintable(d->currentPrinter->printerName()));
+#endif
+ d->m_callbacks.invokeDirectly(resultCallback, false);
+ return;
+ }
+ d->currentPrinter = printer;
+ quint64 requestId = d->adapter->printToPDFCallbackResult(printer->pageLayout(), printer->colorMode() == QPrinter::Color);
d->m_callbacks.registerCallback(requestId, resultCallback);
+#else // if defined(ENABLE_PDF)
+ Q_UNUSED(printer);
+ d->m_callbacks.invokeDirectly(resultCallback, false);
+#endif // if defined(ENABLE_PDF)
}
#endif // QT_NO_PRINTER
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index 8d78429d8..0ad077a0e 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -119,9 +119,6 @@ public:
virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) Q_DECL_OVERRIDE;
virtual void didFindText(quint64 requestId, int matchCount) Q_DECL_OVERRIDE;
virtual void didPrintPage(quint64 requestId, const QByteArray &result) Q_DECL_OVERRIDE;
-#ifndef QT_NO_PRINTER
- virtual void didPrintPageOnPrinter(quint64 requestId, bool result) Q_DECL_OVERRIDE;
-#endif
virtual void passOnFocus(bool reverse) Q_DECL_OVERRIDE;
virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE;
virtual void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) Q_DECL_OVERRIDE;
@@ -181,6 +178,9 @@ public:
mutable QtWebEngineCore::CallbackDirectory m_callbacks;
mutable QAction *actions[QWebEnginePage::WebActionCount];
+#ifndef QT_NO_PRINTER
+ QPrinter *currentPrinter;
+#endif // QT_NO_PRINTER
};
QT_END_NAMESPACE
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 eb3a3931a..27268d26b 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -138,6 +138,21 @@ RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(Rende
setAttribute(Qt::WA_AcceptTouchEvents);
setAttribute(Qt::WA_OpaquePaintEvent);
setAttribute(Qt::WA_AlwaysShowToolTips);
+
+ if (parent) {
+ // Unset the popup parent if the parent is being destroyed, thus making sure a double
+ // delete does not happen.
+ // Also in case the delegate is destroyed before its parent (when a popup is simply
+ // dismissed), this connection will automatically be removed by ~QObject(), preventing
+ // a use-after-free.
+ connect(parent, &QObject::destroyed,
+ this, &RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete);
+ }
+}
+
+void RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete()
+{
+ setParent(Q_NULLPTR);
}
void RenderWidgetHostViewQtDelegateWidget::initAsChild(WebContentsAdapterClient* container)
@@ -164,7 +179,11 @@ void RenderWidgetHostViewQtDelegateWidget::initAsPopup(const QRect& screenRect)
// to be destroyed.
setAttribute(Qt::WA_ShowWithoutActivating);
setFocusPolicy(Qt::NoFocus);
- setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
+
+ // macOS doesn't like Qt::ToolTip when QWebEngineView is inside a modal dialog, specifically by
+ // not forwarding click events to the popup. So we use Qt::Tool which behaves the same way, but
+ // works on macOS too.
+ setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
setGeometry(screenRect);
show();
@@ -183,6 +202,13 @@ QRectF RenderWidgetHostViewQtDelegateWidget::contentsRect() const
void RenderWidgetHostViewQtDelegateWidget::setKeyboardFocus()
{
+ // If the corresponding window is inactive (for example, because of a popup),
+ // the active focus cannot be set. Sync up with the Window System to try to
+ // reactivate the window in time if the other window (possibly popup) which took
+ // the focus is already closed.
+ if (window() && !window()->isActive())
+ QGuiApplication::sync();
+
m_rootItem->forceActiveFocus();
}
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
index 77907ec5a..68e6a176b 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
@@ -87,6 +87,7 @@ protected:
private slots:
void onWindowPosChanged();
+ void removeParentBeforeParentDelete();
private:
RenderWidgetHostViewQtDelegateClient *m_client;
diff --git a/src/webenginewidgets/webenginewidgets.pro b/src/webenginewidgets/webenginewidgets.pro
index 64e475422..b60de6e1e 100644
--- a/src/webenginewidgets/webenginewidgets.pro
+++ b/src/webenginewidgets/webenginewidgets.pro
@@ -52,4 +52,11 @@ contains(WEBENGINE_CONFIG, use_spellchecker) {
DEFINES += ENABLE_SPELLCHECK
}
+contains(WEBENGINE_CONFIG, enable_pdf) {
+ DEFINES += ENABLE_PDF
+}
+
+qtHaveModule(printsupport) {
+ QT += printsupport
+}
load(qt_module)
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
index 180953ed4..89ebbac62 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
@@ -192,21 +192,21 @@ void tst_QWebEngineUrlRequestInterceptor::requestedUrl()
page.profile()->setRequestInterceptor(&interceptor);
page.setUrl(QUrl("qrc:///resources/__placeholder__"));
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QVERIFY(spy.wait());
QCOMPARE(spy.count(), 1);
QCOMPARE(interceptor.observedUrls.at(0), QUrl("qrc:///resources/content.html"));
QCOMPARE(page.requestedUrl(), QUrl("qrc:///resources/__placeholder__"));
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
page.setUrl(QUrl("qrc:/non-existent.html"));
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QVERIFY(spy.wait());
QCOMPARE(spy.count(), 2);
QCOMPARE(interceptor.observedUrls.at(2), QUrl("qrc:/non-existent.html"));
QCOMPARE(page.requestedUrl(), QUrl("qrc:///resources/__placeholder__"));
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
page.setUrl(QUrl("http://abcdef.abcdef"));
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QVERIFY(spy.wait());
QCOMPARE(spy.count(), 3);
QCOMPARE(interceptor.observedUrls.at(3), QUrl("http://abcdef.abcdef/"));
QCOMPARE(page.requestedUrl(), QUrl("qrc:///resources/__placeholder__"));
@@ -222,23 +222,23 @@ void tst_QWebEngineUrlRequestInterceptor::setUrlSameUrl()
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
page.setUrl(QUrl("qrc:///resources/__placeholder__"));
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QVERIFY(spy.wait());
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
QCOMPARE(spy.count(), 1);
page.setUrl(QUrl("qrc:///resources/__placeholder__"));
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QVERIFY(spy.wait());
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
QCOMPARE(spy.count(), 2);
// Now a case without redirect.
page.setUrl(QUrl("qrc:///resources/content.html"));
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QVERIFY(spy.wait());
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
QCOMPARE(spy.count(), 3);
page.setUrl(QUrl("qrc:///resources/__placeholder__"));
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QVERIFY(spy.wait());
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
QCOMPARE(spy.count(), 4);
}
@@ -252,7 +252,7 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrl()
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
page.setUrl(QUrl("qrc:///resources/firstparty.html"));
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QVERIFY(spy.wait());
QCOMPARE(interceptor.observedUrls.at(0), QUrl("qrc:///resources/firstparty.html"));
QCOMPARE(interceptor.observedUrls.at(1), QUrl("qrc:///resources/content.html"));
QCOMPARE(interceptor.firstPartyUrls.at(0), QUrl("qrc:///resources/firstparty.html"));
diff --git a/tests/auto/quick/qmltests/BLACKLIST b/tests/auto/quick/qmltests/BLACKLIST
index d281020df..2673c7eb2 100644
--- a/tests/auto/quick/qmltests/BLACKLIST
+++ b/tests/auto/quick/qmltests/BLACKLIST
@@ -1,9 +1,3 @@
-[DesktopWebEngineViewLinkHovered::test_linkHovered]
-*
-
-[DesktopWebEngineViewLinkHovered::test_linkHoveredDoesntEmitRepeated]
-*
-
[WebViewGeopermission::test_deniedGeolocationByUser]
osx
diff --git a/tests/auto/quick/qmltests/data/tst_linkHovered.qml b/tests/auto/quick/qmltests/data/tst_linkHovered.qml
index b049f07a3..362130bab 100644
--- a/tests/auto/quick/qmltests/data/tst_linkHovered.qml
+++ b/tests/auto/quick/qmltests/data/tst_linkHovered.qml
@@ -29,6 +29,7 @@
import QtQuick 2.0
import QtTest 1.0
import QtWebEngine 1.2
+import QtWebEngine.testsupport 1.0
TestWebEngineView {
id: webEngineView
@@ -38,8 +39,16 @@ TestWebEngineView {
property string lastUrl
+ testSupport: WebEngineTestSupport { }
+
+ SignalSpy {
+ id: loadVisuallyCommittedSpy
+ target: webEngineView.testSupport
+ signalName: "loadVisuallyCommitted"
+ }
+
SignalSpy {
- id: spy
+ id: linkHoveredSpy
target: webEngineView
signalName: "linkHovered"
}
@@ -61,53 +70,60 @@ TestWebEngineView {
}
function init() {
- webEngineView.lastUrl = ""
- spy.clear()
+ webEngineView.lastUrl = "";
+ loadVisuallyCommittedSpy.clear();
+ linkHoveredSpy.clear();
}
function test_linkHovered() {
- compare(spy.count, 0)
+ compare(linkHoveredSpy.count, 0);
mouseMove(webEngineView, 100, 300)
webEngineView.url = Qt.resolvedUrl("test2.html")
verify(webEngineView.waitForLoadSucceeded())
// We get a linkHovered signal with empty hoveredUrl after page load
- spy.wait()
- compare(spy.count, 1)
+ linkHoveredSpy.wait();
+ compare(linkHoveredSpy.count, 1);
compare(webEngineView.lastUrl, "")
+ // Wait for the page to be rendered before trying to test based on input events
+ loadVisuallyCommittedSpy.wait();
+
mouseMove(webEngineView, 100, 100)
- spy.wait()
- compare(spy.count, 2)
+ linkHoveredSpy.wait();
+ compare(linkHoveredSpy.count, 2);
compare(webEngineView.lastUrl, Qt.resolvedUrl("test1.html"))
mouseMove(webEngineView, 100, 300)
- spy.wait()
- compare(spy.count, 3)
+ linkHoveredSpy.wait();
+ compare(linkHoveredSpy.count, 3);
compare(webEngineView.lastUrl, "")
}
function test_linkHoveredDoesntEmitRepeated() {
- compare(spy.count, 0)
+ compare(linkHoveredSpy.count, 0);
webEngineView.url = Qt.resolvedUrl("test2.html")
verify(webEngineView.waitForLoadSucceeded())
// We get a linkHovered signal with empty hoveredUrl after page load
- spy.wait()
- compare(spy.count, 1)
+ linkHoveredSpy.wait();
+ compare(linkHoveredSpy.count, 1);
compare(webEngineView.lastUrl, "")
+ // Wait for the page to be rendered before trying to test based on input events
+ loadVisuallyCommittedSpy.wait();
+
for (var i = 0; i < 100; i += 10)
mouseMove(webEngineView, 100, 100 + i)
- spy.wait()
- compare(spy.count, 2)
+ linkHoveredSpy.wait();
+ compare(linkHoveredSpy.count, 2);
compare(webEngineView.lastUrl, Qt.resolvedUrl("test1.html"))
for (var i = 0; i < 100; i += 10)
mouseMove(webEngineView, 100, 300 + i)
- spy.wait()
- compare(spy.count, 3)
+ linkHoveredSpy.wait();
+ compare(linkHoveredSpy.count, 3);
compare(webEngineView.lastUrl, "")
}
}
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index 2d68fd744..2a43c9c1c 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -151,7 +151,8 @@ void tst_QQuickWebEngineView::stopEnabledAfterLoadStarted()
LoadStartedCatcher catcher(webEngineView());
webEngineView()->setUrl(urlFromTestPath("html/basic_page.html"));
- waitForSignal(&catcher, SIGNAL(finished()));
+ QSignalSpy spy(&catcher, &LoadStartedCatcher::finished);
+ QVERIFY(spy.wait());
QCOMPARE(webEngineView()->isLoading(), true);
diff --git a/tests/auto/quick/shared/util.h b/tests/auto/quick/shared/util.h
index 063caa766..674c2da34 100644
--- a/tests/auto/quick/shared/util.h
+++ b/tests/auto/quick/shared/util.h
@@ -91,45 +91,25 @@ private:
QQuickWebEngineView *m_webEngineView;
};
-/**
- * Starts an event loop that runs until the given signal is received.
- * Optionally the event loop
- * can return earlier on a timeout.
- *
- * \return \p true if the requested signal was received
- * \p false on timeout
- */
-inline bool waitForSignal(QObject *obj, const char *signal, int timeout = 10000)
-{
- QEventLoop loop;
- QObject::connect(obj, signal, &loop, SLOT(quit()));
- QTimer timer;
- QSignalSpy timeoutSpy(&timer, SIGNAL(timeout()));
- if (timeout > 0) {
- QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
- timer.setSingleShot(true);
- timer.start(timeout);
- }
- loop.exec();
- return timeoutSpy.isEmpty();
-}
-
inline bool waitForLoadSucceeded(QQuickWebEngineView *webEngineView, int timeout = 10000)
{
LoadSpy loadSpy(webEngineView);
- return waitForSignal(&loadSpy, SIGNAL(loadSucceeded()), timeout);
+ QSignalSpy spy(&loadSpy, &LoadSpy::loadSucceeded);
+ return spy.wait(timeout);
}
inline bool waitForLoadFailed(QQuickWebEngineView *webEngineView, int timeout = 10000)
{
LoadSpy loadSpy(webEngineView);
- return waitForSignal(&loadSpy, SIGNAL(loadFailed()), timeout);
+ QSignalSpy spy(&loadSpy, &LoadSpy::loadFailed);
+ return spy.wait(timeout);
}
inline bool waitForViewportReady(QQuickWebEngineView *webEngineView, int timeout = 10000)
{
#ifdef ENABLE_QML_TESTSUPPORT_API
- return waitForSignal(reinterpret_cast<QObject *>(webEngineView->testSupport()), SIGNAL(loadVisuallyCommitted()), timeout);
+ QSignalSpy spy(reinterpret_cast<QObject *>(webEngineView->testSupport()), SIGNAL(loadVisuallyCommitted()));
+ return spy.wait(timeout);
#else
Q_UNUSED(webEngineView)
Q_UNUSED(timeout)
diff --git a/tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp b/tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp
index 3ed4bcc71..85bfa80f3 100644
--- a/tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp
+++ b/tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp
@@ -88,7 +88,8 @@ void tst_QWebEngineAccessibility::hierarchy()
"<input type='text' value='some text'></input>" \
"</body></html>");
webView.show();
- ::waitForSignal(&webView, SIGNAL(loadFinished(bool)));
+ QSignalSpy spyFinished(&webView, &QWebEngineView::loadFinished);
+ QVERIFY(spyFinished.wait());
QAccessibleInterface *view = QAccessible::queryAccessibleInterface(&webView);
QVERIFY(view);
@@ -150,7 +151,8 @@ void tst_QWebEngineAccessibility::text()
"<input type='text' value='Good day!' placeholder='day'></input>" \
"</body></html>");
webView.show();
- ::waitForSignal(&webView, SIGNAL(loadFinished(bool)));
+ QSignalSpy spyFinished(&webView, &QWebEngineView::loadFinished);
+ QVERIFY(spyFinished.wait());
QAccessibleInterface *view = QAccessible::queryAccessibleInterface(&webView);
// Wait for accessibility to be fully initialized
@@ -215,7 +217,8 @@ void tst_QWebEngineAccessibility::value()
"<div class='progress' role='progressbar' aria-valuenow='77' aria-valuemin='22' aria-valuemax='99'></div>" \
"</body></html>");
webView.show();
- ::waitForSignal(&webView, SIGNAL(loadFinished(bool)));
+ QSignalSpy spyFinished(&webView, &QWebEngineView::loadFinished);
+ QVERIFY(spyFinished.wait());
QAccessibleInterface *view = QAccessible::queryAccessibleInterface(&webView);
QTRY_COMPARE(view->child(0)->childCount(), 2);
diff --git a/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp b/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp
index a329b7307..dffd995c9 100644
--- a/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp
+++ b/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp
@@ -370,22 +370,21 @@ void tst_QWebEngineHistory::saveAndRestore_crash_2()
{
QByteArray buffer;
saveHistory(hist, &buffer);
- QWebEnginePage* page2 = new QWebEnginePage(this);
- QWebEngineHistory* hist2 = page2->history();
+ QWebEnginePage page2(this);
+ QWebEngineHistory* hist2 = page2.history();
for (unsigned i = 0; i < 5; i++) {
restoreHistory(hist2, &buffer);
saveHistory(hist2, &buffer);
}
- delete page2;
}
void tst_QWebEngineHistory::saveAndRestore_crash_3()
{
QByteArray buffer;
saveHistory(hist, &buffer);
- QWebEnginePage* page2 = new QWebEnginePage(this);
+ QWebEnginePage page2(this);
QWebEngineHistory* hist1 = hist;
- QWebEngineHistory* hist2 = page2->history();
+ QWebEngineHistory* hist2 = page2.history();
for (unsigned i = 0; i < 5; i++) {
restoreHistory(hist1, &buffer);
restoreHistory(hist2, &buffer);
@@ -395,7 +394,6 @@ void tst_QWebEngineHistory::saveAndRestore_crash_3()
saveHistory(hist2, &buffer);
hist2->clear();
}
- delete page2;
}
void tst_QWebEngineHistory::saveAndRestore_crash_4()
@@ -406,18 +404,18 @@ void tst_QWebEngineHistory::saveAndRestore_crash_4()
QByteArray buffer;
saveHistory(hist, &buffer);
- QWebEnginePage* page2 = new QWebEnginePage(this);
+ QScopedPointer<QWebEnginePage> page2(new QWebEnginePage(this));
// The initial crash was in PageCache.
page2->settings()->setMaximumPagesInCache(3);
// Load the history in a new page, waiting for the load to finish.
QEventLoop waitForLoadFinished;
- QObject::connect(page2, SIGNAL(loadFinished(bool)), &waitForLoadFinished, SLOT(quit()), Qt::QueuedConnection);
+ QObject::connect(page2.data(), SIGNAL(loadFinished(bool)), &waitForLoadFinished, SLOT(quit()), Qt::QueuedConnection);
QDataStream load(&buffer, QIODevice::ReadOnly);
load >> *page2->history();
waitForLoadFinished.exec();
- delete page2;
+ page2.reset();
// Give some time for the PageCache cleanup 0-timer to fire.
QTest::qWait(50);
#endif
@@ -456,12 +454,11 @@ void tst_QWebEngineHistory::clear()
QVERIFY(hist->count() == 1); // Leave current item.
QVERIFY(!actionBack->isEnabled());
- QWebEnginePage* page2 = new QWebEnginePage(this);
- QWebEngineHistory* hist2 = page2->history();
+ QWebEnginePage page2(this);
+ QWebEngineHistory* hist2 = page2.history();
QVERIFY(hist2->count() == 0);
hist2->clear();
QVERIFY(hist2->count() == 0); // Do not change anything.
- delete page2;
}
void tst_QWebEngineHistory::historyItemFromDeletedPage()
diff --git a/tests/auto/widgets/qwebenginepage/qwebenginepage.pro b/tests/auto/widgets/qwebenginepage/qwebenginepage.pro
index 70786e70f..df733c473 100644
--- a/tests/auto/widgets/qwebenginepage/qwebenginepage.pro
+++ b/tests/auto/widgets/qwebenginepage/qwebenginepage.pro
@@ -1,2 +1,4 @@
include(../tests.pri)
QT *= core-private gui-private
+
+contains(WEBENGINE_CONFIG, enable_pdf): DEFINES+=QWEBENGINEPAGE_PDFPRINTINGENABLED
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index f16c42976..287af511f 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -333,25 +333,23 @@ protected:
void tst_QWebEnginePage::acceptNavigationRequest()
{
- QWebEngineView *view = new QWebEngineView();
- QSignalSpy loadSpy(view, SIGNAL(loadFinished(bool)));
+ QWebEngineView view;
+ QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
- NavigationRequestOverride* newPage = new NavigationRequestOverride(view, false);
- view->setPage(newPage);
+ NavigationRequestOverride* newPage = new NavigationRequestOverride(&view, false);
+ view.setPage(newPage);
- view->setHtml(QString("<html><body><form name='tstform' action='data:text/html,foo'method='get'>"
+ view.setHtml(QString("<html><body><form name='tstform' action='data:text/html,foo'method='get'>"
"<input type='text'><input type='submit'></form></body></html>"), QUrl());
QTRY_COMPARE(loadSpy.count(), 1);
- evaluateJavaScriptSync(view->page(), "tstform.submit();");
+ evaluateJavaScriptSync(view.page(), "tstform.submit();");
newPage->m_acceptNavigationRequest = true;
- evaluateJavaScriptSync(view->page(), "tstform.submit();");
+ evaluateJavaScriptSync(view.page(), "tstform.submit();");
QTRY_COMPARE(loadSpy.count(), 2);
- QCOMPARE(toPlainTextSync(view->page()), QString("foo?"));
-
- delete view;
+ QCOMPARE(toPlainTextSync(view.page()), QString("foo?"));
}
class JSTestPage : public QWebEnginePage
@@ -389,11 +387,10 @@ private:
/*
void tst_QWebEnginePage::infiniteLoopJS()
{
- JSTestPage* newPage = new JSTestPage(m_view);
- m_view->setPage(newPage);
+ JSTestPage newPage(m_view);
+ m_view->setPage(&newPage);
m_view->setHtml(QString("<html><body>test</body></html>"), QUrl());
m_view->page()->evaluateJavaScript("var run = true; var a = 1; while (run) { a++; }");
- delete newPage;
}
*/
@@ -409,9 +406,9 @@ void tst_QWebEnginePage::geolocationRequestJS()
{
QFETCH(bool, allowed);
QFETCH(int, errorCode);
- QWebEngineView *view = new QWebEngineView;
- JSTestPage *newPage = new JSTestPage(view);
- newPage->setView(view);
+ QWebEngineView view;
+ JSTestPage *newPage = new JSTestPage(&view);
+ newPage->setView(&view);
newPage->setGeolocationPermission(allowed);
connect(newPage, SIGNAL(featurePermissionRequested(const QUrl&, QWebEnginePage::Feature)),
@@ -420,10 +417,8 @@ void tst_QWebEnginePage::geolocationRequestJS()
QSignalSpy spyLoadFinished(newPage, SIGNAL(loadFinished(bool)));
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;
+ if (evaluateJavaScriptSync(newPage, QLatin1String("!navigator.geolocation")).toBool())
W_QSKIP("Geolocation is not supported.", SkipSingle);
- }
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)");
@@ -432,8 +427,6 @@ void tst_QWebEnginePage::geolocationRequestJS()
if (result == 2)
QEXPECT_FAIL("", "No location service available.", Continue);
QCOMPARE(result, errorCode);
-
- delete view;
}
void tst_QWebEnginePage::loadFinished()
@@ -490,7 +483,8 @@ void tst_QWebEnginePage::pasteImage()
clipboard->setImage(origImage);
QWebEnginePage *page = m_view->page();
page->load(QUrl("qrc:///resources/pasteimage.html"));
- QVERIFY(waitForSignal(m_view, SIGNAL(loadFinished(bool))));
+ QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
+ QVERIFY(spyFinished.wait());
page->triggerAction(QWebEnginePage::Paste);
QTRY_VERIFY(evaluateJavaScriptSync(page,
"window.myImageDataURL ? window.myImageDataURL.length : 0").toInt() > 0);
@@ -661,7 +655,8 @@ void tst_QWebEnginePage::userStyleSheet()
m_page->settings()->setUserStyleSheetUrl(QUrl("data:text/css;charset=utf-8;base64,"
+ QByteArray("p { background-image: url('http://does.not/exist.png');}").toBase64()));
m_view->setHtml("<p>hello world</p>");
- QVERIFY(::waitForSignal(m_view, SIGNAL(loadFinished(bool))));
+ QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
+ QVERIFY(spyFinished.wait());
QVERIFY(networkManager->requestedUrls.count() >= 1);
QCOMPARE(networkManager->requestedUrls.at(0), QUrl("http://does.not/exist.png"));
@@ -679,7 +674,8 @@ void tst_QWebEnginePage::userStyleSheetFromLocalFileUrl()
QUrl styleSheetUrl = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebenginepage/resources/user.css"));
m_page->settings()->setUserStyleSheetUrl(styleSheetUrl);
m_view->setHtml("<p>hello world</p>");
- QVERIFY(::waitForSignal(m_view, SIGNAL(loadFinished(bool))));
+ QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
+ QVERIFY(spyFinished.wait());
QVERIFY(networkManager->requestedUrls.count() >= 1);
QCOMPARE(networkManager->requestedUrls.at(0), QUrl("http://does.not/exist.png"));
@@ -696,7 +692,8 @@ void tst_QWebEnginePage::userStyleSheetFromQrcUrl()
m_page->settings()->setUserStyleSheetUrl(QUrl("qrc:///resources/user.css"));
m_view->setHtml("<p>hello world</p>");
- QVERIFY(::waitForSignal(m_view, SIGNAL(loadFinished(bool))));
+ QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
+ QVERIFY(spyFinished.wait());
QVERIFY(networkManager->requestedUrls.count() >= 1);
QCOMPARE(networkManager->requestedUrls.at(0), QUrl("http://does.not/exist.png"));
@@ -723,10 +720,12 @@ void tst_QWebEnginePage::modified()
QSKIP("QWEBENGINEPAGE_ISMODIFIED");
#else
m_page->setUrl(QUrl("data:text/html,<body>blub"));
- QVERIFY(::waitForSignal(m_view, SIGNAL(loadFinished(bool))));
+ QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
+ QVERIFY(spyFinished.wait());
m_page->setUrl(QUrl("data:text/html,<body id=foo contenteditable>blah"));
- QVERIFY(::waitForSignal(m_view, SIGNAL(loadFinished(bool))));
+ QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
+ QVERIFY(spyFinished.wait());
QVERIFY(!m_page->isModified());
@@ -750,7 +749,8 @@ void tst_QWebEnginePage::modified()
QVERIFY(!m_page->history()->forwardItem().isValid());
m_page->history()->back();
- QVERIFY(::waitForSignal(m_view, SIGNAL(loadFinished(bool))));
+ QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
+ QVERIFY(spyFinished.wait());
QVERIFY(!m_page->history()->canGoBack());
QVERIFY(m_page->history()->canGoForward());
@@ -772,7 +772,8 @@ void tst_QWebEnginePage::modified()
m_page->setUrl(QUrl("data:text/html,<body>This is fourth page"));
QCOMPARE(m_page->history()->count(), 2);
m_page->setUrl(QUrl("data:text/html,<body>This is fifth page"));
- QVERIFY(::waitForSignal(m_page, SIGNAL(saveFrameStateRequested(QWebEngineFrame*,QWebEngineHistoryItem*))));
+ QSignalSpy spy(m_page, &QWebEnginePage::saveFrameStateRequested);
+ QVERIFY(spy.wait());
#endif
}
@@ -1225,7 +1226,7 @@ void tst_QWebEnginePage::cursorMovements()
#if !defined(QWEBENGINEPAGE_SELECTEDTEXT)
QSKIP("QWEBENGINEPAGE_SELECTEDTEXT");
#else
- CursorTrackedPage* page = new CursorTrackedPage;
+ QScopedPointer<CursorTrackedPage> page(new CursorTrackedPage);
QString content("<html><body><p id=one>The quick brown fox</p><p id=two>jumps over the lazy dog</p><p>May the source<br/>be with you!</p></body></html>");
page->setHtml(content);
@@ -1234,7 +1235,7 @@ void tst_QWebEnginePage::cursorMovements()
"var node = document.getElementById(\"one\"); " \
"range.selectNode(node); " \
"getSelection().addRange(range);";
- evaluateJavaScriptSync(page, script);
+ evaluateJavaScriptSync(page.data(), script);
QCOMPARE(page->selectedText().trimmed(), QString::fromLatin1("The quick brown fox"));
QRegExp regExp(" style=\".*\"");
@@ -1415,20 +1416,18 @@ void tst_QWebEnginePage::cursorMovements()
page->triggerAction(QWebEnginePage::MoveToNextWord);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 12);
-
- delete page;
#endif
}
void tst_QWebEnginePage::textSelection()
{
- QWebEngineView *view = new QWebEngineView;
- CursorTrackedPage *page = new CursorTrackedPage(view);
+ QWebEngineView view;
+ CursorTrackedPage *page = new CursorTrackedPage(&view);
QString content("<html><body><p id=one>The quick brown fox</p>" \
"<p id=two>jumps over the lazy dog</p>" \
"<p>May the source<br/>be with you!</p></body></html>");
- page->setView(view);
- QSignalSpy loadSpy(view, SIGNAL(loadFinished(bool)));
+ page->setView(&view);
+ QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
page->setHtml(content);
QTRY_COMPARE(loadSpy.count(), 1);
@@ -1522,8 +1521,6 @@ void tst_QWebEnginePage::textSelection()
QCOMPARE(page->action(QWebEnginePage::SelectStartOfDocument)->isEnabled(), true);
QCOMPARE(page->action(QWebEnginePage::SelectEndOfDocument)->isEnabled(), true);
#endif
-
- delete view;
}
void tst_QWebEnginePage::textEditing()
@@ -1531,7 +1528,7 @@ void tst_QWebEnginePage::textEditing()
#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT)
QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT");
#else
- CursorTrackedPage* page = new CursorTrackedPage;
+ QScopedPointer<CursorTrackedPage> page(new CursorTrackedPage);
QString content("<html><body><p id=one>The quick brown fox</p>" \
"<p id=two>jumps over the lazy dog</p>" \
"<p>May the source<br/>be with you!</p></body></html>");
@@ -1644,8 +1641,6 @@ void tst_QWebEnginePage::textEditing()
// this is only true if there is an editable selection
QCOMPARE(page->action(QWebEnginePage::Cut)->isEnabled(), true);
QCOMPARE(page->action(QWebEnginePage::RemoveFormat)->isEnabled(), true);
-
- delete page;
#endif
}
@@ -1711,12 +1706,12 @@ void tst_QWebEnginePage::inputMethods()
QFETCH(QString, viewType);
QWebEnginePage* page = new QWebEnginePage;
QObject* view = 0;
- QObject* container = 0;
+ QScopedPointer<QObject> container(0);
if (viewType == "QWebEngineView") {
QWebEngineView* wv = new QWebEngineView;
wv->setPage(page);
view = wv;
- container = view;
+ container.reset(view);
} else if (viewType == "QGraphicsWebView") {
QGraphicsWebView* wv = new QGraphicsWebView;
wv->setPage(page);
@@ -1728,7 +1723,7 @@ void tst_QWebEnginePage::inputMethods()
scene->addItem(wv);
wv->setGeometry(QRect(0, 0, 500, 500));
- container = gv;
+ container.reset(gv);
} else
QVERIFY2(false, "Unknown view type");
@@ -2396,8 +2391,6 @@ void tst_QWebEnginePage::inputMethods()
QCOMPARE(inputValue2, QString("\n\nthird line"));
// END - Newline test for textarea
-
- delete container;
#endif
}
@@ -2736,22 +2729,19 @@ void tst_QWebEnginePage::screenshot()
QDir::setCurrent(TESTS_SOURCE_DIR);
QFETCH(QString, html);
- QWebEnginePage* page = new QWebEnginePage;
- page->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
- page->setHtml(html, QUrl::fromLocalFile(TESTS_SOURCE_DIR));
- ::waitForSignal(page, SIGNAL(loadFinished(bool)), 2000);
+ QWebEnginePage page;
+ page.settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
+ page.setHtml(html, QUrl::fromLocalFile(TESTS_SOURCE_DIR));
+ QVERIFY(spyFinished.wait(2000));
// take screenshot without a view
- takeScreenshot(page);
+ takeScreenshot(&page);
- QWebEngineView* view = new QWebEngineView;
- view->setPage(page);
+ QWebEngineView view;
+ view.setPage(&page);
// take screenshot when attached to a view
- takeScreenshot(page);
-
- delete page;
- delete view;
+ takeScreenshot(&page);
QDir::setCurrent(QApplication::applicationDirPath());
#endif
@@ -2865,7 +2855,8 @@ void tst_QWebEnginePage::testStopScheduledPageRefresh()
"<meta http-equiv=\"refresh\"content=\"0;URL=qrc:///resources/index.html\">"
"</head><body><h1>Page redirects immediately...</h1>"
"</body></html>");
- QVERIFY(::waitForSignal(&page1, SIGNAL(loadFinished(bool))));
+ QSignalSpy spyFinished(&page1, &QWebEnginePage::loadFinished);
+ QVERIFY(spyFinished.wait();
QTest::qWait(500);
QCOMPARE(page1.url(), QUrl(QLatin1String("qrc:///resources/index.html")));
@@ -3217,7 +3208,8 @@ void tst_QWebEnginePage::deleteQWebEngineViewTwice()
mainWindow.setCentralWidget(webView);
webView->load(QUrl("qrc:///resources/frame_a.html"));
mainWindow.show();
- QVERIFY(::waitForSignal(webView, SIGNAL(loadFinished(bool))));
+ QSignalSpy spyFinished(webView, &QWebEngineView::loadFinished);
+ QVERIFY(spyFinished.wait());
}
}
@@ -3272,7 +3264,8 @@ void tst_QWebEnginePage::renderOnRepaintRequestedShouldNotRecurse()
page.setHtml("zalan loves trunk", QUrl());
- QVERIFY(::waitForSignal(&r, SIGNAL(finished())));
+ QSignalSpy spyFinished(&r, &RepaintRequestedRenderer::finished);
+ QVERIFY(spyFinished.wait());
#endif
}
@@ -3323,9 +3316,10 @@ void tst_QWebEnginePage::loadSignalsOrder()
QFETCH(QUrl, url);
QWebEnginePage page;
SpyForLoadSignalsOrder loadSpy(&page);
- waitForSignal(&loadSpy, SIGNAL(started()), 500);
+ QSignalSpy spyLoadSpy(&loadSpy, &SpyForLoadSignalsOrder::started);
+ QVERIFY(spyLoadSpy.wait(500));
page.load(url);
- QTRY_VERIFY_WITH_TIMEOUT(loadSpy.isFinished(), 500);
+ QTRY_VERIFY(loadSpy.isFinished());
}
void tst_QWebEnginePage::undoActionHaveCustomText()
@@ -3412,26 +3406,25 @@ private:
void tst_QWebEnginePage::getUserMediaRequest()
{
- GetUserMediaTestPage *page = new GetUserMediaTestPage();
+ GetUserMediaTestPage page;
// We need to load content from a resource in order for the securityOrigin to be valid.
- QSignalSpy loadSpy(page, SIGNAL(loadFinished(bool)));
- page->load(QUrl("qrc:///resources/content.html"));
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+ page.load(QUrl("qrc:///resources/content.html"));
QTRY_COMPARE(loadSpy.count(), 1);
- QVERIFY(evaluateJavaScriptSync(page, QStringLiteral("!!navigator.webkitGetUserMedia")).toBool());
- evaluateJavaScriptSync(page, QStringLiteral("navigator.webkitGetUserMedia({audio: true}, function() {}, function(){})"));
- QTRY_VERIFY(page->gotFeatureRequest(QWebEnginePage::MediaAudioCapture));
+ QVERIFY(evaluateJavaScriptSync(&page, QStringLiteral("!!navigator.webkitGetUserMedia")).toBool());
+ evaluateJavaScriptSync(&page, QStringLiteral("navigator.webkitGetUserMedia({audio: true}, function() {}, function(){})"));
+ QTRY_VERIFY(page.gotFeatureRequest(QWebEnginePage::MediaAudioCapture));
// Might end up failing due to the lack of physical media devices deeper in the content layer, so the JS callback is not guaranteed to be called,
// but at least we go through that code path, potentially uncovering failing assertions.
- page->acceptPendingRequest();
+ page.acceptPendingRequest();
- page->runJavaScript(QStringLiteral("errorCallbackCalled = false;"));
- evaluateJavaScriptSync(page, QStringLiteral("navigator.webkitGetUserMedia({audio: true, video: true}, function() {}, function(){errorCallbackCalled = true;})"));
- QTRY_VERIFY(page->gotFeatureRequest(QWebEnginePage::MediaAudioVideoCapture));
- page->rejectPendingRequest(); // Should always end up calling the error callback in JS.
- QTRY_VERIFY(evaluateJavaScriptSync(page, QStringLiteral("errorCallbackCalled;")).toBool());
- delete page;
+ page.runJavaScript(QStringLiteral("errorCallbackCalled = false;"));
+ evaluateJavaScriptSync(&page, QStringLiteral("navigator.webkitGetUserMedia({audio: true, video: true}, function() {}, function(){errorCallbackCalled = true;})"));
+ QTRY_VERIFY(page.gotFeatureRequest(QWebEnginePage::MediaAudioVideoCapture));
+ page.rejectPendingRequest(); // Should always end up calling the error callback in JS.
+ QTRY_VERIFY(evaluateJavaScriptSync(&page, QStringLiteral("errorCallbackCalled;")).toBool());
}
void tst_QWebEnginePage::savePage()
@@ -3449,7 +3442,8 @@ void tst_QWebEnginePage::savePage()
const QString urlPrefix = QStringLiteral("data:text/html,<h1>");
const QString text = QStringLiteral("There is Thingumbob shouting!");
page->load(QUrl(urlPrefix + text));
- waitForSignal(page, SIGNAL(loadFinished(bool)));
+ QSignalSpy spyFinished(page, &QWebEnginePage::loadFinished);
+ QVERIFY(spyFinished.wait());
QCOMPARE(toPlainTextSync(page), text);
// Save the loaded page as HTML.
@@ -3460,12 +3454,12 @@ void tst_QWebEnginePage::savePage()
// Load something else.
page->load(QUrl(urlPrefix + QLatin1String("It's a Snark!")));
- waitForSignal(page, SIGNAL(loadFinished(bool)));
+ QVERIFY(spyFinished.wait());
QVERIFY(toPlainTextSync(page) != text);
// Load the saved page and compare the contents.
page->load(QUrl::fromLocalFile(filePath));
- waitForSignal(page, SIGNAL(loadFinished(bool)));
+ QVERIFY(spyFinished.wait());
QCOMPARE(toPlainTextSync(page), text);
}
@@ -3704,13 +3698,13 @@ void tst_QWebEnginePage::runJavaScript()
void tst_QWebEnginePage::fullScreenRequested()
{
JavaScriptCallbackWatcher watcher;
- QWebEngineView* view = new QWebEngineView;
- QWebEnginePage* page = view->page();
- view->show();
+ QWebEngineView view;
+ QWebEnginePage* page = view.page();
+ view.show();
page->settings()->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, true);
- QSignalSpy loadSpy(view, SIGNAL(loadFinished(bool)));
+ QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
page->load(QUrl("qrc:///resources/fullscreen.html"));
QTRY_COMPARE(loadSpy.count(), 1);
@@ -3725,7 +3719,7 @@ void tst_QWebEnginePage::fullScreenRequested()
if (acceptRequest) request.accept(); else request.reject();
});
- QTest::keyPress(view->focusProxy(), Qt::Key_Space);
+ QTest::keyPress(view.focusProxy(), Qt::Key_Space);
QTRY_VERIFY(evaluateJavaScriptSync(page, "document.webkitIsFullScreen").toBool());
page->runJavaScript("document.webkitExitFullscreen()", JavaScriptCallbackUndefined());
QVERIFY(watcher.wait());
@@ -3733,12 +3727,10 @@ void tst_QWebEnginePage::fullScreenRequested()
acceptRequest = false;
page->runJavaScript("document.webkitFullscreenEnabled", JavaScriptCallback(true));
- QTest::keyPress(view->focusProxy(), Qt::Key_Space);
+ QTest::keyPress(view.focusProxy(), Qt::Key_Space);
QVERIFY(watcher.wait());
page->runJavaScript("document.webkitIsFullScreen", JavaScriptCallback(false));
QVERIFY(watcher.wait());
-
- delete view;
}
void tst_QWebEnginePage::symmetricUrl()
@@ -3791,7 +3783,8 @@ void tst_QWebEnginePage::progressSignal()
QUrl dataUrl("data:text/html,<h1>Test");
m_view->setUrl(dataUrl);
- ::waitForSignal(m_view, SIGNAL(loadFinished(bool)));
+ QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished);
+ QVERIFY(spyFinished.wait());
QVERIFY(progressSpy.size() >= 2);
int previousValue = -1;
@@ -3812,14 +3805,14 @@ void tst_QWebEnginePage::urlChange()
QUrl dataUrl("data:text/html,<h1>Test");
m_view->setUrl(dataUrl);
- ::waitForSignal(m_page, SIGNAL(urlChanged(QUrl)));
+ QVERIFY(urlSpy.wait());
QCOMPARE(urlSpy.size(), 1);
QUrl dataUrl2("data:text/html,<html><head><title>title</title></head><body><h1>Test</body></html>");
m_view->setUrl(dataUrl2);
- ::waitForSignal(m_page, SIGNAL(urlChanged(QUrl)));
+ QVERIFY(urlSpy.wait());
QCOMPARE(urlSpy.size(), 2);
}
@@ -3922,7 +3915,7 @@ void tst_QWebEnginePage::requestedUrlAfterSetAndLoadFailures()
const QUrl first("http://abcdef.abcdef/");
page.setUrl(first);
- ::waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QVERIFY(spy.wait());
QCOMPARE(spy.count(), 1);
QCOMPARE(page.url(), first);
QCOMPARE(page.requestedUrl(), first);
@@ -3932,7 +3925,7 @@ void tst_QWebEnginePage::requestedUrlAfterSetAndLoadFailures()
QVERIFY(first != second);
page.load(second);
- ::waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QVERIFY(spy.wait());
QCOMPARE(spy.count(), 2);
QCOMPARE(page.url(), first);
QCOMPARE(page.requestedUrl(), second);
@@ -3941,13 +3934,13 @@ void tst_QWebEnginePage::requestedUrlAfterSetAndLoadFailures()
void tst_QWebEnginePage::asyncAndDelete()
{
- QWebEnginePage *page = new QWebEnginePage;
+ QScopedPointer<QWebEnginePage> page(new QWebEnginePage);
CallbackSpy<QString> plainTextSpy;
CallbackSpy<QString> htmlSpy;
page->toPlainText(plainTextSpy.ref());
page->toHtml(htmlSpy.ref());
- delete page;
+ page.reset();
// Pending callbacks should be called with an empty value in the page's destructor.
QCOMPARE(plainTextSpy.waitForResult(), QString());
QVERIFY(plainTextSpy.wasCalled());
@@ -4016,14 +4009,15 @@ void tst_QWebEnginePage::setHtmlWithStylesheetResource()
QWebEngineElement webElement;
page.setHtml(html, QUrl(QLatin1String("qrc:///file")));
- waitForSignal(&page, SIGNAL(loadFinished(bool)), 200);
+ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
+ QVERIFY(spyFinished.wait(200));
webElement = page.documentElement().findFirst("p");
QCOMPARE(webElement.styleProperty("color", QWebEngineElement::CascadedStyle), QLatin1String("red"));
// Now we test the opposite: without a baseUrl as a local file, we cannot request local resources.
page.setHtml(html, QUrl(QLatin1String("http://www.example.com/")));
- waitForSignal(&page, SIGNAL(loadFinished(bool)), 200);
+ QVERIFY(spyFinished.wait(200));
webElement = page.documentElement().findFirst("p");
QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=118659", Continue);
QCOMPARE(webElement.styleProperty("color", QWebEngineElement::CascadedStyle), QString());
@@ -4048,7 +4042,8 @@ void tst_QWebEnginePage::setHtmlWithBaseURL()
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
page.setHtml(html, QUrl::fromLocalFile(TESTS_SOURCE_DIR));
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
+ QVERIFY(spyFinished.wait());
QCOMPARE(spy.count(), 1);
QCOMPARE(evaluateJavaScriptSync(&page, "document.images.length").toInt(), 1);
@@ -4079,7 +4074,8 @@ void tst_QWebEnginePage::setHtmlWithJSAlert()
QString html("<html><head></head><body><script>alert('foo');</script><p>hello world</p></body></html>");
MyPage page;
page.setHtml(html, QUrl(QStringLiteral("http://test.origin.com/path#fragment")));
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
+ QVERIFY(spyFinished.wait());
QCOMPARE(page.alerts, 1);
QCOMPARE(toHtmlSync(&page), html);
}
@@ -4259,9 +4255,9 @@ void tst_QWebEnginePage::scrollbarsOff()
"</body>");
- QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
+ QSignalSpy loadSpy(&view, &QWebEngineView::loadFinished);
view.setHtml(html);
- ::waitForSignal(&view, SIGNAL(loadFinished(bool)), 200);
+ QVERIFY(loadSpy.wait(200);
QCOMPARE(loadSpy.count(), 1);
mainFrame->evaluateJavaScript("checkScrollbar();");
@@ -4327,7 +4323,8 @@ void tst_QWebEnginePage::evaluateWillCauseRepaint()
QTRY_COMPARE(loadSpy.count(), 1);
evaluateJavaScriptSync(view.page(), "document.getElementById('junk').style.display = 'none';");
- ::waitForSignal(&view, SIGNAL(repaintRequested()));
+ QSignalSpy repaintSpy(&view, &WebView::repaintRequested);
+ QVERIFY(repaintSpy.wait());
}
void tst_QWebEnginePage::setContent_data()
@@ -4441,7 +4438,7 @@ void tst_QWebEnginePage::setUrlToEmpty()
// Set existing url
page.setUrl(url);
expectedLoadFinishedCount++;
- ::waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QVERIFY(spy.wait());
QCOMPARE(spy.count(), expectedLoadFinishedCount);
QCOMPARE(page.url(), url);
@@ -4602,7 +4599,8 @@ void tst_QWebEnginePage::setUrlUsingStateObject()
url = QUrl("qrc:/resources/test1.html");
m_page->setUrl(url);
- waitForSignal(m_page, SIGNAL(loadFinished(bool)));
+ QSignalSpy spyFinished(m_page, &QWebEnginePage::loadFinished);
+ QVERIFY(spyFinished.wait());
expectedUrlChangeCount++;
QCOMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
QCOMPARE(m_page->url(), url);
@@ -4802,39 +4800,37 @@ void tst_QWebEnginePage::loadInSignalHandlers()
URLSetter setter(m_page, signal, type, urlForSetter);
m_page->load(url);
- waitForSignal(&setter, SIGNAL(finished()));
+ QSignalSpy spy(&setter, &URLSetter::finished);
+ QVERIFY(spy.wait());
QCOMPARE(m_page->url(), urlForSetter);
}
void tst_QWebEnginePage::restoreHistory()
{
- QWebChannel *channel = new QWebChannel;
- QWebEnginePage *page = new QWebEnginePage;
- page->setWebChannel(channel);
+ QWebChannel channel;
+ QWebEnginePage page;
+ page.setWebChannel(&channel);
QWebEngineScript script;
script.setName(QStringLiteral("script"));
- page->scripts().insert(script);
+ page.scripts().insert(script);
- QSignalSpy spy(page, SIGNAL(loadFinished(bool)));
- page->load(QUrl(QStringLiteral("qrc:/resources/test1.html")));
+ QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
+ page.load(QUrl(QStringLiteral("qrc:/resources/test1.html")));
QTRY_COMPARE(spy.count(), 1);
- QCOMPARE(page->webChannel(), channel);
- QVERIFY(page->scripts().contains(script));
+ QCOMPARE(page.webChannel(), &channel);
+ QVERIFY(page.scripts().contains(script));
QByteArray data;
QDataStream out(&data, QIODevice::ReadWrite);
- out << *page->history();
+ out << *page.history();
QDataStream in(&data, QIODevice::ReadOnly);
- in >> *page->history();
+ in >> *page.history();
QTRY_COMPARE(spy.count(), 2);
- QCOMPARE(page->webChannel(), channel);
- QVERIFY(page->scripts().contains(script));
-
- delete page;
- delete channel;
+ QCOMPARE(page.webChannel(), &channel);
+ QVERIFY(page.scripts().contains(script));
}
void tst_QWebEnginePage::toPlainTextLoadFinishedRace_data()
@@ -4848,33 +4844,33 @@ void tst_QWebEnginePage::toPlainTextLoadFinishedRace()
{
QFETCH(bool, enableErrorPage);
- QWebEnginePage *page = new QWebEnginePage;
+ QScopedPointer<QWebEnginePage> page(new QWebEnginePage);
page->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, enableErrorPage);
- QSignalSpy spy(page, SIGNAL(loadFinished(bool)));
+ QSignalSpy spy(page.data(), SIGNAL(loadFinished(bool)));
page->load(QUrl("data:text/plain,foobarbaz"));
QTRY_VERIFY(spy.count() == 1);
- QCOMPARE(toPlainTextSync(page), QString("foobarbaz"));
+ QCOMPARE(toPlainTextSync(page.data()), QString("foobarbaz"));
page->load(QUrl("fail:unknown/scheme"));
QTRY_VERIFY(spy.count() == 2);
- QString s = toPlainTextSync(page);
+ QString s = toPlainTextSync(page.data());
QVERIFY(s.contains("foobarbaz") == !enableErrorPage);
page->load(QUrl("data:text/plain,lalala"));
QTRY_VERIFY(spy.count() == 3);
- QCOMPARE(toPlainTextSync(page), QString("lalala"));
- delete page;
+ QCOMPARE(toPlainTextSync(page.data()), QString("lalala"));
+ page.reset();
QVERIFY(spy.count() == 3);
}
void tst_QWebEnginePage::setZoomFactor()
{
- QWebEnginePage *page = new QWebEnginePage;
+ QWebEnginePage page;
- QVERIFY(qFuzzyCompare(page->zoomFactor(), 1.0));
- page->setZoomFactor(2.5);
- QVERIFY(qFuzzyCompare(page->zoomFactor(), 2.5));
+ QVERIFY(qFuzzyCompare(page.zoomFactor(), 1.0));
+ page.setZoomFactor(2.5);
+ QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));
const QUrl urlToLoad("qrc:/resources/test1.html");
@@ -4882,19 +4878,20 @@ void tst_QWebEnginePage::setZoomFactor()
m_page->setUrl(urlToLoad);
QTRY_COMPARE(finishedSpy.count(), 1);
QVERIFY(finishedSpy.at(0).first().toBool());
- QVERIFY(qFuzzyCompare(page->zoomFactor(), 2.5));
+ QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));
- page->setZoomFactor(5.5);
- QVERIFY(qFuzzyCompare(page->zoomFactor(), 2.5));
+ page.setZoomFactor(5.5);
+ QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));
- page->setZoomFactor(0.1);
- QVERIFY(qFuzzyCompare(page->zoomFactor(), 2.5));
-
- delete page;
+ page.setZoomFactor(0.1);
+ QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));
}
void tst_QWebEnginePage::printToPdf()
{
+#if !defined(QWEBENGINEPAGE_PDFPRINTINGENABLED)
+ QSKIP("QWEBENGINEPAGE_PDFPRINTINGENABLED");
+#else
QTemporaryDir tempDir(QDir::tempPath() + "/tst_qwebengineview-XXXXXX");
QVERIFY(tempDir.isValid());
QWebEnginePage page;
@@ -4922,14 +4919,15 @@ void tst_QWebEnginePage::printToPdf()
CallbackSpy<QByteArray> failedInvalidLayoutSpy;
page.printToPdf(failedInvalidLayoutSpy.ref(), QPageLayout());
QCOMPARE(failedInvalidLayoutSpy.waitForResult().length(), 0);
+#endif
}
void tst_QWebEnginePage::mouseButtonTranslation()
{
- QWebEngineView *view = new QWebEngineView;
+ QWebEngineView view;
- QSignalSpy spy(view, SIGNAL(loadFinished(bool)));
- view->setHtml(QStringLiteral(
+ QSignalSpy spy(&view, SIGNAL(loadFinished(bool)));
+ view.setHtml(QStringLiteral(
"<html><head><script>\
var lastEvent = { 'button' : -1 }; \
function saveLastEvent(event) { console.log(event); lastEvent = event; }; \
@@ -4938,25 +4936,23 @@ void tst_QWebEnginePage::mouseButtonTranslation()
<div style=\"height:600px;\" onmousedown=\"saveLastEvent(event)\">\
</div>\
</body></html>"));
- view->show();
- QTest::qWaitForWindowExposed(view);
+ view.show();
+ QTest::qWaitForWindowExposed(&view);
QTRY_VERIFY(spy.count() == 1);
- QVERIFY(view->focusProxy() != nullptr);
-
- QMouseEvent evpres(QEvent::MouseButtonPress, view->rect().center(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
- QGuiApplication::sendEvent(view->focusProxy(), &evpres);
+ QVERIFY(view.focusProxy() != nullptr);
- QTRY_COMPARE(evaluateJavaScriptSync(view->page(), "lastEvent.button").toInt(), 0);
- QCOMPARE(evaluateJavaScriptSync(view->page(), "lastEvent.buttons").toInt(), 1);
+ QMouseEvent evpres(QEvent::MouseButtonPress, view.rect().center(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+ QGuiApplication::sendEvent(view.focusProxy(), &evpres);
- QMouseEvent evpres2(QEvent::MouseButtonPress, view->rect().center(), Qt::RightButton, Qt::LeftButton | Qt::RightButton, Qt::NoModifier);
- QGuiApplication::sendEvent(view->focusProxy(), &evpres2);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "lastEvent.button").toInt(), 0);
+ QCOMPARE(evaluateJavaScriptSync(view.page(), "lastEvent.buttons").toInt(), 1);
- QTRY_COMPARE(evaluateJavaScriptSync(view->page(), "lastEvent.button").toInt(), 2);
- QCOMPARE(evaluateJavaScriptSync(view->page(), "lastEvent.buttons").toInt(), 3);
+ QMouseEvent evpres2(QEvent::MouseButtonPress, view.rect().center(), Qt::RightButton, Qt::LeftButton | Qt::RightButton, Qt::NoModifier);
+ QGuiApplication::sendEvent(view.focusProxy(), &evpres2);
- delete view;
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "lastEvent.button").toInt(), 2);
+ QCOMPARE(evaluateJavaScriptSync(view.page(), "lastEvent.buttons").toInt(), 3);
}
QPoint tst_QWebEnginePage::elementCenter(QWebEnginePage *page, const QString &id)
@@ -5035,20 +5031,18 @@ void tst_QWebEnginePage::viewSourceURL()
QFETCH(QUrl, requestedUrl);
QFETCH(QString, title);
- QWebEnginePage *page = new QWebEnginePage;
- QSignalSpy loadFinishedSpy(page, SIGNAL(loadFinished(bool)));
+ QWebEnginePage page;
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
- page->load(userInputUrl);
+ page.load(userInputUrl);
QTRY_COMPARE(loadFinishedSpy.count(), 1);
QList<QVariant> arguments = loadFinishedSpy.takeFirst();
QCOMPARE(arguments.at(0).toBool(), loadSucceed);
- QCOMPARE(page->url(), url);
- QCOMPARE(page->requestedUrl(), requestedUrl);
- QCOMPARE(page->title(), title);
- QVERIFY(!page->action(QWebEnginePage::ViewSource)->isEnabled());
-
- delete page;
+ QCOMPARE(page.url(), url);
+ QCOMPARE(page.requestedUrl(), requestedUrl);
+ QCOMPARE(page.title(), title);
+ QVERIFY(!page.action(QWebEnginePage::ViewSource)->isEnabled());
}
QTEST_MAIN(tst_QWebEnginePage)
diff --git a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
index d5ecd8841..c10ae2886 100644
--- a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
+++ b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
@@ -62,7 +62,8 @@ void tst_QWebEngineScript::domEditing()
page.scripts().insert(s);
page.load(QUrl("about:blank"));
view.show();
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
+ QVERIFY(spyFinished.wait());
QCOMPARE(evaluateJavaScriptSync(&page, "document.getElementById(\"banner\").innerText"), QVariant(QStringLiteral("Injected banner")));
// elementFromPoint only works for exposed elements
QTest::qWaitForWindowExposed(&view);
@@ -85,7 +86,8 @@ void tst_QWebEngineScript::injectionPoint()
document.body.innerText = contents;\
}, 550));\
</script></head><body></body></html>"));
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
+ QVERIFY(spyFinished.wait());
QTRY_COMPARE(evaluateJavaScriptSync(&page, "document.body.innerText"), QVariant::fromValue(QStringLiteral("SUCCESS")));
}
@@ -116,14 +118,15 @@ void tst_QWebEngineScript::scriptWorld()
script.setSourceCode(QStringLiteral("var userScriptTest = 1;"));
page.scripts().insert(script);
page.load(QUrl("about:blank"));
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
+ QVERIFY(spyFinished.wait());
QCOMPARE(evaluateJavaScriptSync(&page, "typeof(userScriptTest) != \"undefined\" && userScriptTest == 1;"), QVariant::fromValue(true));
QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "typeof(userScriptTest) == \"undefined\"", QWebEngineScript::ApplicationWorld), QVariant::fromValue(true));
script.setWorldId(QWebEngineScript::ApplicationWorld);
page.scripts().clear();
page.scripts().insert(script);
page.load(QUrl("about:blank"));
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QVERIFY(spyFinished.wait());
QCOMPARE(evaluateJavaScriptSync(&page, "typeof(userScriptTest) == \"undefined\""), QVariant::fromValue(true));
QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "typeof(userScriptTest) != \"undefined\" && userScriptTest == 1;", QWebEngineScript::ApplicationWorld), QVariant::fromValue(true));
}
@@ -141,11 +144,12 @@ void tst_QWebEngineScript::scriptModifications()
document.body.innerText = foo;});\
</script></head><body></body></html>"));
QVERIFY(page.scripts().count() == 1);
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
+ QVERIFY(spyFinished.wait());
QCOMPARE(evaluateJavaScriptSync(&page, "document.body.innerText"), QVariant::fromValue(QStringLiteral("SUCCESS")));
script.setSourceCode("var foo = \"FAILURE\"");
page.triggerAction(QWebEnginePage::ReloadAndBypassCache);
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QVERIFY(spyFinished.wait());
QCOMPARE(evaluateJavaScriptSync(&page, "document.body.innerText"), QVariant::fromValue(QStringLiteral("SUCCESS")));
QVERIFY(page.scripts().count() == 1);
QWebEngineScript s = page.scripts().findScript(QStringLiteral("String1"));
@@ -209,11 +213,12 @@ void tst_QWebEngineScript::webChannel()
script.setSourceCode(QString::fromLatin1(scriptSrc));
page.scripts().insert(script);
page.setHtml(QStringLiteral("<html><body></body></html>"));
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
+ QVERIFY(spyFinished.wait());
if (reloadFirst) {
// Check that the transport is also reinstalled on navigation
page.triggerAction(QWebEnginePage::Reload);
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QVERIFY(spyFinished.wait());
}
page.runJavaScript(QLatin1String(
"new QWebChannel(qt.webChannelTransport,"
@@ -221,7 +226,8 @@ void tst_QWebEngineScript::webChannel()
" channel.objects.object.text = 'test';"
" }"
");"), worldId);
- waitForSignal(&testObject, SIGNAL(textChanged(QString)));
+ QSignalSpy spyTextChanged(&testObject, &TestObject::textChanged);
+ QVERIFY(spyTextChanged.wait());
QCOMPARE(testObject.text(), QStringLiteral("test"));
if (worldId != QWebEngineScript::MainWorld)
@@ -235,7 +241,8 @@ void tst_QWebEngineScript::noTransportWithoutWebChannel()
QCOMPARE(evaluateJavaScriptSync(&page, "qt.webChannelTransport"), QVariant(QVariant::Invalid));
page.triggerAction(QWebEnginePage::Reload);
- waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
+ QVERIFY(spyFinished.wait());
QCOMPARE(evaluateJavaScriptSync(&page, "qt.webChannelTransport"), QVariant(QVariant::Invalid));
}
diff --git a/tests/auto/widgets/qwebenginespellcheck/tst_qwebenginespellcheck.cpp b/tests/auto/widgets/qwebenginespellcheck/tst_qwebenginespellcheck.cpp
index 4db5b9477..c7b083660 100644
--- a/tests/auto/widgets/qwebenginespellcheck/tst_qwebenginespellcheck.cpp
+++ b/tests/auto/widgets/qwebenginespellcheck/tst_qwebenginespellcheck.cpp
@@ -103,7 +103,9 @@ void tst_QWebEngineSpellcheck::load()
{
m_view->page()->load(QUrl("qrc:///resources/index.html"));
m_view->show();
- waitForSignal(m_view->page(), SIGNAL(loadFinished(bool)));
+ QSignalSpy spyFinished(m_view->page(), &QWebEnginePage::loadFinished);
+ QVERIFY(spyFinished.wait());
+
}
void tst_QWebEngineSpellcheck::cleanup()
@@ -170,7 +172,8 @@ void tst_QWebEngineSpellcheck::spellcheck()
// open menu on misspelled word
m_view->activateMenu(m_view->focusWidget(), rect.center());
- waitForSignal(m_view, SIGNAL(menuReady()));
+ QSignalSpy spyMenuReady(m_view, &WebView::menuReady);
+ QVERIFY(spyMenuReady.wait());
// check if menu is valid
QVERIFY(m_view->data().isValid());
diff --git a/tests/auto/widgets/qwebengineview/BLACKLIST b/tests/auto/widgets/qwebengineview/BLACKLIST
new file mode 100644
index 000000000..0a909d0f6
--- /dev/null
+++ b/tests/auto/widgets/qwebengineview/BLACKLIST
@@ -0,0 +1,2 @@
+[doNotSendMouseKeyboardEventsWhenDisabled]
+windows
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 9966ad9ee..2baadd869 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -31,8 +31,11 @@
#include <qdiriterator.h>
#include <qstackedlayout.h>
#include <qtemporarydir.h>
+#include <QCompleter>
#include <QLineEdit>
#include <QHBoxLayout>
+#include <QQuickItem>
+#include <QQuickWidget>
#define VERIFY_INPUTMETHOD_HINTS(actual, expect) \
QVERIFY(actual == expect);
@@ -83,6 +86,7 @@ private Q_SLOTS:
void inputMethodsTextFormat_data();
void inputMethodsTextFormat();
void keyboardEvents();
+ void keyboardFocusAfterPopup();
};
// This will be called before the first test function is executed.
@@ -177,7 +181,8 @@ void tst_QWebEngineView::reusePage()
page->setHtml(html, QUrl::fromLocalFile(TESTS_SOURCE_DIR));
if (html.contains("</embed>")) {
// some reasonable time for the PluginStream to feed test.swf to flash and start painting
- waitForSignal(view1, SIGNAL(loadFinished(bool)), 2000);
+ QSignalSpy spyFinished(view1, &QWebEngineView::loadFinished);
+ QVERIFY(spyFinished.wait(2000));
}
view1->show();
@@ -281,7 +286,8 @@ void tst_QWebEngineView::focusInputTypes()
webView.load(url);
mainFrame->setFocus();
- QVERIFY(waitForSignal(&webView, SIGNAL(loadFinished(bool))));
+ QSignalSpy spyFinished(webView, &QWebEngineView::loadFinished);
+ QVERIFY(spyFinished.wait());
// 'text' type
QWebEngineElement inputElement = mainFrame->documentElement().findFirst(QLatin1String("input[type=text]"));
@@ -400,7 +406,8 @@ void tst_QWebEngineView::horizontalScrollbarTest()
webView.page()->load(url);
webView.page()->setFocus();
- QVERIFY(waitForSignal(&webView, SIGNAL(loadFinished(bool))));
+ QSignalSpy spyFinished(webView, &QWebEngineView::loadFinished);
+ QVERIFY(spyFinished.wait());
QVERIFY(webView.page()->scrollPosition() == QPoint(0, 0));
@@ -562,7 +569,8 @@ void tst_QWebEngineView::renderingAfterMaxAndBack()
QWebEngineView view;
view.page()->load(url);
- QVERIFY(waitForSignal(&view, SIGNAL(loadFinished(bool))));
+ QSignalSpy spyFinished(&view, &QWebEngineView::loadFinished);
+ QVERIFY(spyFinished.wait());
view.show();
view.page()->settings()->setMaximumPagesInCache(3);
@@ -584,7 +592,7 @@ void tst_QWebEngineView::renderingAfterMaxAndBack()
"</html>");
view.page()->load(url2);
- QVERIFY(waitForSignal(&view, SIGNAL(loadFinished(bool))));
+ QVERIFY(spyFinished.wait());
view.showMaximized();
@@ -840,25 +848,29 @@ void tst_QWebEngineView::changeLocale()
QWebEngineView viewDE;
viewDE.setUrl(url);
- QVERIFY(waitForSignal(&viewDE, SIGNAL(titleChanged(QString))));
- QVERIFY(waitForSignal(&viewDE, SIGNAL(loadFinished(bool))));
+ QSignalSpy spyTitleChangedDE(&viewDE, &QWebEngineView::titleChanged);
+ QVERIFY(spyTitleChangedDE.wait());
+ QSignalSpy spyFinishedDE(&viewDE, &QWebEngineView::loadFinished);
+ QVERIFY(spyFinishedDE.wait());
QCOMPARE(viewDE.title(), QStringLiteral("Nicht verf\u00FCgbar: %1").arg(url.toString()));
QLocale::setDefault(QLocale("en"));
QWebEngineView viewEN;
viewEN.setUrl(url);
- QVERIFY(waitForSignal(&viewEN, SIGNAL(titleChanged(QString))));
- QVERIFY(waitForSignal(&viewEN, SIGNAL(loadFinished(bool))));
+ QSignalSpy spyTitleChangedEN(&viewEN, &QWebEngineView::titleChanged);
+ QVERIFY(spyTitleChangedEN.wait());
+ QSignalSpy spyFinishedEN(&viewEN, &QWebEngineView::loadFinished);
+ QVERIFY(spyFinishedEN.wait());
QCOMPARE(viewEN.title(), QStringLiteral("%1 is not available").arg(url.toString()));
viewDE.setUrl(QUrl("about:blank"));
- QVERIFY(waitForSignal(&viewDE, SIGNAL(loadFinished(bool))));
+ QVERIFY(spyFinishedDE.wait());
viewDE.setUrl(url);
- QVERIFY(waitForSignal(&viewDE, SIGNAL(titleChanged(QString))));
- QVERIFY(waitForSignal(&viewDE, SIGNAL(loadFinished(bool))));
+ QVERIFY(spyTitleChangedDE.wait());
+ QVERIFY(spyFinishedDE.wait());
QCOMPARE(viewDE.title(), QStringLiteral("Nicht verf\u00FCgbar: %1").arg(url.toString()));
}
@@ -1014,5 +1026,60 @@ void tst_QWebEngineView::keyboardEvents()
QVERIFY(loadFinishedSpy.wait());
}
+void tst_QWebEngineView::keyboardFocusAfterPopup()
+{
+ QScopedPointer<QWidget> containerWidget(new QWidget);
+
+ QLineEdit *urlLine = new QLineEdit(containerWidget.data());
+ QStringList urlList;
+ urlList << "test";
+ QCompleter *completer = new QCompleter(urlList, urlLine);
+ completer->setCompletionMode(QCompleter::PopupCompletion);
+ urlLine->setCompleter(completer);
+ urlLine->setFocus();
+
+ QWebEngineView *webView = new QWebEngineView(containerWidget.data());
+ QSignalSpy loadFinishedSpy(webView, SIGNAL(loadFinished(bool)));
+
+ connect(urlLine, &QLineEdit::editingFinished, [=] {
+ webView->setHtml("<html><body onload=\"document.getElementById('input1').focus()\">"
+ " <input type='text' id='input1' />"
+ "</body></html>");
+
+ // Check whether the RenderWidgetHostView has the keyboard focus
+ QQuickWidget *rwhv = qobject_cast<QQuickWidget *>(webView->focusProxy());
+ QVERIFY(rwhv);
+ QVERIFY(rwhv->hasFocus());
+ QVERIFY(rwhv->rootObject()->hasFocus());
+ QVERIFY(rwhv->window()->windowHandle()->isActive());
+ QVERIFY(rwhv->rootObject()->hasActiveFocus());
+ });
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(urlLine);
+ layout->addWidget(webView);
+
+ containerWidget->setLayout(layout);
+ containerWidget->show();
+ QTest::qWaitForWindowExposed(containerWidget.data());
+
+ // Trigger completer's popup and select the first suggestion
+ QTest::keyClick(urlLine, Qt::Key_T);
+ qApp->processEvents();
+ QTRY_VERIFY(qApp->activePopupWidget());
+ QTest::keyClick(qApp->activePopupWidget(), Qt::Key_Down);
+ qApp->processEvents();
+ QTest::keyClick(qApp->activePopupWidget(), Qt::Key_Enter);
+ qApp->processEvents();
+
+ // After the load the focused window should forward the keyboard events to the webView
+ QVERIFY(loadFinishedSpy.wait());
+ // Wait for active focus on the input field
+ QTRY_COMPARE(evaluateJavaScriptSync(webView->page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
+ QTest::keyClick(qApp->focusWindow(), Qt::Key_X);
+ qApp->processEvents();
+ QTRY_COMPARE(evaluateJavaScriptSync(webView->page(), "document.getElementById('input1').value").toString(), QStringLiteral("x"));
+}
+
QTEST_MAIN(tst_QWebEngineView)
#include "tst_qwebengineview.moc"
diff --git a/tests/auto/widgets/tests.pri b/tests/auto/widgets/tests.pri
index ca19a9496..14074cd08 100644
--- a/tests/auto/widgets/tests.pri
+++ b/tests/auto/widgets/tests.pri
@@ -12,7 +12,7 @@ INCLUDEPATH += $$PWD
RESOURCES += ../resources/tests.qrc
exists($$_PRO_FILE_PWD_/$${TARGET}.qrc): RESOURCES += $${TARGET}.qrc
-QT += testlib network webenginewidgets widgets
+QT += testlib network webenginewidgets widgets quick quickwidgets
macx: CONFIG -= app_bundle
# This define is used by some tests to look up resources in the source tree
diff --git a/tests/auto/widgets/util.h b/tests/auto/widgets/util.h
index 770579f1f..356cf6ebb 100644
--- a/tests/auto/widgets/util.h
+++ b/tests/auto/widgets/util.h
@@ -42,29 +42,6 @@
#endif
/**
- * Starts an event loop that runs until the given signal is received.
- * Optionally the event loop
- * can return earlier on a timeout.
- *
- * \return \p true if the requested signal was received
- * \p false on timeout
- */
-static inline bool waitForSignal(QObject* obj, const char* signal, int timeout = 10000)
-{
- QEventLoop loop;
- QObject::connect(obj, signal, &loop, SLOT(quit()));
- QTimer timer;
- QSignalSpy timeoutSpy(&timer, SIGNAL(timeout()));
- if (timeout > 0) {
- QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
- timer.setSingleShot(true);
- timer.start(timeout);
- }
- loop.exec();
- return timeoutSpy.isEmpty();
-}
-
-/**
* Just like QSignalSpy but facilitates sync and async
* signal emission. For example if you want to verify that
* page->foo() emitted a signal, it could be that the
diff --git a/tools/qmake/mkspecs/features/configure.prf b/tools/qmake/mkspecs/features/configure.prf
index c6f07e39d..bb4c56cae 100644
--- a/tools/qmake/mkspecs/features/configure.prf
+++ b/tools/qmake/mkspecs/features/configure.prf
@@ -78,6 +78,9 @@ defineTest(runConfigure) {
else: log("System NSS not found, BoringSSL will be used.$${EOL}")
}
}
+ !cross_compile {
+ WEBENGINE_CONFIG += enable_pdf
+ }
isQtMinimum(5, 8) {
include($$QTWEBENGINE_OUT_ROOT/qtwebengine-config.pri)
QT_FOR_CONFIG += webengine-private
diff --git a/tools/qmake/mkspecs/features/functions.prf b/tools/qmake/mkspecs/features/functions.prf
index fbd92b133..8191f7589 100644
--- a/tools/qmake/mkspecs/features/functions.prf
+++ b/tools/qmake/mkspecs/features/functions.prf
@@ -292,7 +292,7 @@ defineReplace(getConfigDir) {
}
defineReplace(getChromiumSrcDir) {
- git_chromium_src_dir = $$system("git config qtwebengine.chromiumsrcdir")
+ exists($$QTWEBENGINE_ROOT/.git): git_chromium_src_dir = $$system("git config qtwebengine.chromiumsrcdir")
# Fall back to the snapshot path if git does not know about chromium sources (i.e. init-repository.py has not been used)
isEmpty(git_chromium_src_dir): git_chromium_src_dir = "src/3rdparty/chromium"
return($$git_chromium_src_dir)