From 04337275e4b66ba5853c24a79d7f61ebb2e7a247 Mon Sep 17 00:00:00 2001 From: Frank Richter Date: Mon, 12 Jun 2017 15:21:34 +0200 Subject: Fix incorrect GLX pbuffer attributes terminator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The glXCreatePbuffer() documentation states that the attributes list must be terminated with "None or NULL". However, GLX_NONE does not have a null value. Mesa is sensitive to this. Change-Id: I9606d95a6a0dadec446496abb8e0213950e3d700 Reviewed-by: Michael Brüning --- src/core/gl_surface_qt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/gl_surface_qt.cpp b/src/core/gl_surface_qt.cpp index a18e22b58..81d1b1cd5 100644 --- a/src/core/gl_surface_qt.cpp +++ b/src/core/gl_surface_qt.cpp @@ -257,7 +257,7 @@ bool GLSurfaceQtGLX::Initialize() GLX_PBUFFER_HEIGHT, m_size.height(), GLX_LARGEST_PBUFFER, False, GLX_PRESERVED_CONTENTS, False, - GLX_NONE + 0 }; m_surfaceBuffer = glXCreatePbuffer(display, static_cast(g_config), pbuffer_attributes); -- cgit v1.2.3 From f2d938962fe9a029ec0baf37ca7f478051125780 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCri=20Valdmann?= Date: Mon, 14 Aug 2017 10:25:56 +0200 Subject: Fix QWebEngineDownloadItem::type() Task-number: QTBUG-62640 Change-Id: I2b16f24533b38c20a7071319723382ba240e35f3 Reviewed-by: Peter Varga --- src/core/download_manager_delegate_qt.cpp | 21 ++++++++++++++------- src/core/download_manager_delegate_qt.h | 4 ++-- src/core/web_contents_adapter.cpp | 2 +- .../qwebenginedownloads/tst_qwebenginedownloads.cpp | 8 ++++---- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp index 77469a8ea..0eabd340c 100644 --- a/src/core/download_manager_delegate_qt.cpp +++ b/src/core/download_manager_delegate_qt.cpp @@ -65,7 +65,7 @@ DownloadManagerDelegateQt::DownloadManagerDelegateQt(BrowserContextAdapter *cont : m_contextAdapter(contextAdapter) , m_currentId(0) , m_weakPtrFactory(this) - , m_downloadType(BrowserContextAdapterClient::Attachment) + , m_nextDownloadIsUserRequested(false) { Q_ASSERT(m_contextAdapter); } @@ -107,10 +107,17 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(content::DownloadItem* i QString suggestedFilename = toQt(item->GetSuggestedFilename()); QString mimeTypeString = toQt(item->GetMimeType()); - bool isAttachment = net::HttpContentDisposition(item->GetContentDisposition(), std::string()).is_attachment(); - - if (!isAttachment || !BrowserContextAdapterClient::UserRequested) - m_downloadType = BrowserContextAdapterClient::DownloadAttribute; + int downloadType = 0; + if (m_nextDownloadIsUserRequested) { + downloadType = BrowserContextAdapterClient::UserRequested; + m_nextDownloadIsUserRequested = false; + } else { + bool isAttachment = net::HttpContentDisposition(item->GetContentDisposition(), std::string()).is_attachment(); + if (isAttachment) + downloadType = BrowserContextAdapterClient::Attachment; + else + downloadType = BrowserContextAdapterClient::DownloadAttribute; + } if (suggestedFilename.isEmpty()) suggestedFilename = toQt(net::HttpContentDisposition(item->GetContentDisposition(), std::string()).filename()); @@ -155,7 +162,7 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(content::DownloadItem* i suggestedFilePath, BrowserContextAdapterClient::UnknownSavePageFormat, false /* accepted */, - m_downloadType, + downloadType, item->GetLastReason() }; @@ -283,7 +290,7 @@ void DownloadManagerDelegateQt::OnDownloadUpdated(content::DownloadItem *downloa QString(), BrowserContextAdapterClient::UnknownSavePageFormat, true /* accepted */, - m_downloadType, + 0 /* downloadType (unused) */, download->GetLastReason() }; diff --git a/src/core/download_manager_delegate_qt.h b/src/core/download_manager_delegate_qt.h index cd21d330c..d23a78b0b 100644 --- a/src/core/download_manager_delegate_qt.h +++ b/src/core/download_manager_delegate_qt.h @@ -84,7 +84,7 @@ public: void cancelDownload(quint32 downloadId); - void setDownloadType(int downloadType) { m_downloadType = downloadType; } + void markNextDownloadAsUserRequested() { m_nextDownloadIsUserRequested = true; } // Inherited from content::DownloadItem::Observer void OnDownloadUpdated(content::DownloadItem *download) override; @@ -97,7 +97,7 @@ private: uint64_t m_currentId; base::WeakPtrFactory m_weakPtrFactory; - int m_downloadType; + bool m_nextDownloadIsUserRequested; friend class DownloadManagerDelegateInstance; DISALLOW_COPY_AND_ASSIGN(DownloadManagerDelegateQt); diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index ff4f09f0e..b301622d4 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -942,7 +942,7 @@ void WebContentsAdapter::download(const QUrl &url, const QString &suggestedFileN if (!dlm) return; - dlmd->setDownloadType(BrowserContextAdapterClient::UserRequested); + dlmd->markNextDownloadAsUserRequested(); dlm->SetDelegate(dlmd); GURL gurl = toGurl(url); diff --git a/tests/auto/widgets/qwebenginedownloads/tst_qwebenginedownloads.cpp b/tests/auto/widgets/qwebenginedownloads/tst_qwebenginedownloads.cpp index c25e82d41..aba5bdeb1 100644 --- a/tests/auto/widgets/qwebenginedownloads/tst_qwebenginedownloads.cpp +++ b/tests/auto/widgets/qwebenginedownloads/tst_qwebenginedownloads.cpp @@ -86,7 +86,7 @@ void tst_QWebEngineDownloads::downloadLink_data() /* fileDisposition */ << QByteArrayLiteral("") /* fileHasReferer */ << true /* fileAction */ << FileIsDownloaded - /* downloadType */ << QWebEngineDownloadItem::DownloadAttribute; + /* downloadType */ << QWebEngineDownloadItem::UserRequested; // SaveLink should always trigger a download, also for text files. QTest::newRow("save link to text file") @@ -99,7 +99,7 @@ void tst_QWebEngineDownloads::downloadLink_data() /* fileDisposition */ << QByteArrayLiteral("") /* fileHasReferer */ << true /* fileAction */ << FileIsDownloaded - /* downloadType */ << QWebEngineDownloadItem::DownloadAttribute; + /* downloadType */ << QWebEngineDownloadItem::UserRequested; // ... adding the "download" attribute should have no effect. QTest::newRow("save link to text file (attribute)") @@ -112,7 +112,7 @@ void tst_QWebEngineDownloads::downloadLink_data() /* fileDisposition */ << QByteArrayLiteral("") /* fileHasReferer */ << true /* fileAction */ << FileIsDownloaded - /* downloadType */ << QWebEngineDownloadItem::DownloadAttribute; + /* downloadType */ << QWebEngineDownloadItem::UserRequested; // ... adding the "attachment" content disposition should also have no effect. QTest::newRow("save link to text file (attachment)") @@ -508,7 +508,7 @@ void tst_QWebEngineDownloads::downloadTwoLinks() QCOMPARE(item->totalBytes(), -1); QCOMPARE(item->receivedBytes(), 0); QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason); - QCOMPARE(item->type(), QWebEngineDownloadItem::DownloadAttribute); + QCOMPARE(item->type(), QWebEngineDownloadItem::Attachment); QCOMPARE(item->mimeType(), QStringLiteral("text/plain")); QCOMPARE(item->path(), standardDir + QByteArrayLiteral("/file2")); QCOMPARE(item->savePageFormat(), QWebEngineDownloadItem::UnknownSaveFormat); -- cgit v1.2.3 From 14b58276822c12e8d21580f61869b5a9bbf43f22 Mon Sep 17 00:00:00 2001 From: Szabolcs David Date: Thu, 14 Dec 2017 12:37:28 +0100 Subject: Deselect text on each fourth click Triple click selects the entire paragraph and it should be deselected on a quadra click. Task-number: QTBUG-65649 Change-Id: I87c9405a202d8b6eacd7c19dbbcb051756c41220 Reviewed-by: Viktor Engelmann Reviewed-by: Allan Sandfeld Jensen --- src/core/render_widget_host_view_qt.cpp | 3 ++- tests/auto/quick/qmltests/data/tst_mouseClick.qml | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 6fc775535..cae2094fd 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -1197,7 +1197,8 @@ void RenderWidgetHostViewQt::handleMouseEvent(QMouseEvent* event) if (event->type() == QMouseEvent::MouseButtonPress) { if (event->button() != m_clickHelper.lastPressButton || (event->timestamp() - m_clickHelper.lastPressTimestamp > static_cast(qGuiApp->styleHints()->mouseDoubleClickInterval())) - || (event->pos() - m_clickHelper.lastPressPosition).manhattanLength() > qGuiApp->styleHints()->startDragDistance()) + || (event->pos() - m_clickHelper.lastPressPosition).manhattanLength() > qGuiApp->styleHints()->startDragDistance() + || m_clickHelper.clickCounter >= 3) m_clickHelper.clickCounter = 0; m_clickHelper.lastPressTimestamp = event->timestamp(); diff --git a/tests/auto/quick/qmltests/data/tst_mouseClick.qml b/tests/auto/quick/qmltests/data/tst_mouseClick.qml index bd6625a90..d81e690fd 100644 --- a/tests/auto/quick/qmltests/data/tst_mouseClick.qml +++ b/tests/auto/quick/qmltests/data/tst_mouseClick.qml @@ -57,6 +57,10 @@ TestWebEngineView { function mouseTripleClick(item, x, y) { mouseMultiClick(item, x, y, 3); } + + function mouseQuadraClick(item, x, y) { + mouseMultiClick(item, x, y, 4); + } } @@ -109,5 +113,18 @@ TestWebEngineView { mouseClick(webEngineView, center.x, center.y); tryVerify(function() { return getTextSelection() == "" }); } + + function test_quadraClick() { + webEngineView.settings.focusOnNavigationEnabled = true; + webEngineView.loadHtml("" + + "
" + + ""); + verify(webEngineView.waitForLoadSucceeded()); + + var center = getElementCenter("input"); + webEngineView.testSupport.mouseQuadraClick(webEngineView, center.x, center.y); + verifyElementHasFocus("input"); + tryVerify(function() { return getTextSelection() == "" }); + } } } -- cgit v1.2.3 From 3d53f2a26676d0c3f5e306f8b0f7d7ed413fc7cb Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 22 Jan 2018 16:22:02 +0100 Subject: Remove full blacklist of osx 10.11 It was added for a single test failure that was caused by a screen locker on the CI, a problem that has since been solved. This CI configuration is the only one that's running qmltests on osx. Change-Id: Ia6f11649ce2f63000488aa18080c5d149d04eac0 Reviewed-by: Alexandru Croitor --- tests/auto/quick/qmltests/BLACKLIST | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/auto/quick/qmltests/BLACKLIST b/tests/auto/quick/qmltests/BLACKLIST index f449f4949..f2ab9788d 100644 --- a/tests/auto/quick/qmltests/BLACKLIST +++ b/tests/auto/quick/qmltests/BLACKLIST @@ -1,4 +1,3 @@ -osx-10.11 ci [WebViewGeopermission::test_deniedGeolocationByUser] osx -- cgit v1.2.3 From 2971b796f455e95e58fd2b546d0a9853f5f8879e Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 4 Jan 2018 16:16:18 +0100 Subject: Fix FDL license header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I8d7cf992d1f51cc82168d5e01bbe4c062be09992 Reviewed-by: Michael Brüning --- .../stylesheetbrowser/doc/src/stylesheetbrowser.qdoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/webenginewidgets/stylesheetbrowser/doc/src/stylesheetbrowser.qdoc b/examples/webenginewidgets/stylesheetbrowser/doc/src/stylesheetbrowser.qdoc index c5506a623..f1fdf85d1 100644 --- a/examples/webenginewidgets/stylesheetbrowser/doc/src/stylesheetbrowser.qdoc +++ b/examples/webenginewidgets/stylesheetbrowser/doc/src/stylesheetbrowser.qdoc @@ -11,8 +11,8 @@ ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Free Documentation License Usage ** Alternatively, this file may be used under the terms of the GNU Free @@ -20,7 +20,7 @@ ** Foundation and appearing in the file included in the packaging of ** this file. Please review the following information to ensure ** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. ** $QT_END_LICENSE$ ** ****************************************************************************/ -- cgit v1.2.3 From d768d69de588c54ef224a7566e44fb06b51adbf4 Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Tue, 23 Jan 2018 11:41:11 +0100 Subject: Fix enable/disable precompiled headers Use 'enable_precompiled_headers' instead of 'disable_precompiled_headers' Change-Id: I23af6fe1c24a6ccc14d31f009710ebbc4cc2f716 Reviewed-by: Allan Sandfeld Jensen --- src/core/config/common.pri | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/config/common.pri b/src/core/config/common.pri index 60aba490c..8961e1cd3 100644 --- a/src/core/config/common.pri +++ b/src/core/config/common.pri @@ -47,7 +47,11 @@ qtConfig(webengine-webrtc) { qtConfig(webengine-proprietary-codecs): gn_args += proprietary_codecs=true ffmpeg_branding=\"Chrome\" -!precompile_header: gn_args += disable_precompiled_headers=true +precompile_header { + gn_args += enable_precompiled_headers=true +} else { + gn_args += enable_precompiled_headers=false +} CONFIG(release, debug|release) { force_debug_info { -- cgit v1.2.3 From dabc1069d6c39bd8342b446361226b63bd571cf9 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 23 Jan 2018 17:09:03 +0100 Subject: Re-enable setUrltoEmpty and setUrlHistory tests Have been skipped for years but appears to work. Change-Id: I461459b64fe3731b2fb50a3cc9c9d4ab75b135d4 Reviewed-by: Alexandru Croitor --- tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index 54cf27066..060645733 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -3750,8 +3750,6 @@ void tst_QWebEnginePage::setUrlWithPendingLoads() void tst_QWebEnginePage::setUrlToEmpty() { - QSKIP("FIXME: [0908/090526:FATAL:navigation_controller_impl.cc(927)] Check failed: active_entry->site_instance() == rfh->GetSiteInstance()."); - int expectedLoadFinishedCount = 0; const QUrl aboutBlank("about:blank"); const QUrl url("qrc:/resources/test2.html"); @@ -3759,7 +3757,8 @@ void tst_QWebEnginePage::setUrlToEmpty() QWebEnginePage page; QCOMPARE(page.url(), QUrl()); QCOMPARE(page.requestedUrl(), QUrl()); - QCOMPARE(baseUrlSync(&page), QUrl()); +// Chromium now returns about:blank as the base url here: +// QCOMPARE(baseUrlSync(&page), QUrl()); QSignalSpy spy(&page, SIGNAL(loadFinished(bool))); @@ -3926,8 +3925,6 @@ static QStringList collectHistoryUrls(QWebEngineHistory *history) void tst_QWebEnginePage::setUrlHistory() { - QSKIP("FIXME: [0908/090526:FATAL:navigation_controller_impl.cc(927)] Check failed: active_entry->site_instance() == rfh->GetSiteInstance()."); - const QUrl aboutBlank("about:blank"); QUrl url; int expectedLoadFinishedCount = 0; @@ -3943,10 +3940,10 @@ void tst_QWebEnginePage::setUrlHistory() // Chromium stores navigation entry for every successful loads. The load of the empty page is committed and stored as about:blank. QCOMPARE(collectHistoryUrls(m_page->history()), QStringList() << aboutBlank.toString()); - url = QUrl("http://non.existent/"); + url = QUrl("http://url.invalid/"); m_page->setUrl(url); expectedLoadFinishedCount++; - QTRY_COMPARE(spy.count(), expectedLoadFinishedCount); + QTRY_COMPARE_WITH_TIMEOUT(spy.count(), expectedLoadFinishedCount, 20000); // When error page is disabled in case of LoadFail the entry of the unavailable page is not stored. // We expect the url of the previously loaded page here. QCOMPARE(m_page->url(), aboutBlank); -- cgit v1.2.3 From 3cec2ccb0ffdd41a41ab55d4c1ba88d4866e71d1 Mon Sep 17 00:00:00 2001 From: Szabolcs David Date: Mon, 22 Jan 2018 15:49:16 +0100 Subject: Use correct margins when printing with QPrinter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Margins were applied two times: PrintViewManagerQt included them when rendering to a temporary PDF, then QPrinter applied them when printing. This patch changes the parameters of PDF generation to not contain the area of margins. This way the user-provided QPrinter can handle it without any kind of customization. Task-number: QTBUG-65715 Change-Id: Ie32785857e5195aa21c6e2ccb7ebd1e6f6ecd954 Reviewed-by: Michael Brüning --- src/core/print_view_manager_qt.cpp | 40 ++++++++++++++++++----------- src/webenginewidgets/api/qwebenginepage.cpp | 7 ++--- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/core/print_view_manager_qt.cpp b/src/core/print_view_manager_qt.cpp index b8df5a131..7c482b012 100644 --- a/src/core/print_view_manager_qt.cpp +++ b/src/core/print_view_manager_qt.cpp @@ -154,27 +154,37 @@ static base::DictionaryValue *createPrintSettings() return printSettings; } -static base::DictionaryValue *createPrintSettingsFromQPageLayout(const QPageLayout &pageLayout) +static base::DictionaryValue *createPrintSettingsFromQPageLayout(const QPageLayout &pageLayout, bool printToPdf) { base::DictionaryValue *printSettings = createPrintSettings(); //Set page size attributes, chromium expects these in micrometers - QSizeF pageSizeInMilimeter = pageLayout.pageSize().size(QPageSize::Millimeter); + QRectF pageSizeInMillimeter = pageLayout.pageSize().rect(QPageSize::Millimeter); + if (!printToPdf) { + // QPrinter will extend this size with its margins + QMarginsF margins = pageLayout.margins(QPageLayout::Millimeter); + pageSizeInMillimeter = pageSizeInMillimeter.marginsRemoved(margins); + } std::unique_ptr sizeDict(new base::DictionaryValue); - sizeDict->SetInteger(printing::kSettingMediaSizeWidthMicrons, pageSizeInMilimeter.width() * kMicronsToMillimeter); - sizeDict->SetInteger(printing::kSettingMediaSizeHeightMicrons, pageSizeInMilimeter.height() * kMicronsToMillimeter); + sizeDict->SetInteger(printing::kSettingMediaSizeWidthMicrons, pageSizeInMillimeter.width() * kMicronsToMillimeter); + sizeDict->SetInteger(printing::kSettingMediaSizeHeightMicrons, pageSizeInMillimeter.height() * kMicronsToMillimeter); printSettings->Set(printing::kSettingMediaSize, std::move(sizeDict)); - // Apply page margins - QMargins pageMarginsInPoints = pageLayout.marginsPoints(); - std::unique_ptr marginsDict(new base::DictionaryValue); - marginsDict->SetInteger(printing::kSettingMarginTop, pageMarginsInPoints.top()); - marginsDict->SetInteger(printing::kSettingMarginBottom, pageMarginsInPoints.bottom()); - marginsDict->SetInteger(printing::kSettingMarginLeft, pageMarginsInPoints.left()); - marginsDict->SetInteger(printing::kSettingMarginRight, pageMarginsInPoints.right()); - - printSettings->Set(printing::kSettingMarginsCustom, std::move(marginsDict)); - printSettings->SetInteger(printing::kSettingMarginsType, printing::CUSTOM_MARGINS); + if (printToPdf) { + // Apply page margins when printing to PDF + QMargins pageMarginsInPoints = pageLayout.marginsPoints(); + std::unique_ptr marginsDict(new base::DictionaryValue); + marginsDict->SetInteger(printing::kSettingMarginTop, pageMarginsInPoints.top()); + marginsDict->SetInteger(printing::kSettingMarginBottom, pageMarginsInPoints.bottom()); + marginsDict->SetInteger(printing::kSettingMarginLeft, pageMarginsInPoints.left()); + marginsDict->SetInteger(printing::kSettingMarginRight, pageMarginsInPoints.right()); + + printSettings->Set(printing::kSettingMarginsCustom, std::move(marginsDict)); + printSettings->SetInteger(printing::kSettingMarginsType, printing::CUSTOM_MARGINS); + } else { + // QPrinter will handle margins + printSettings->SetInteger(printing::kSettingMarginsType, printing::NO_MARGINS); + } printSettings->SetBoolean(printing::kSettingLandscape, pageLayout.orientation() == QPageLayout::Landscape); @@ -244,7 +254,7 @@ bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout, bool if (!pageLayout.isValid()) return false; - m_printSettings.reset(createPrintSettingsFromQPageLayout(pageLayout)); + m_printSettings.reset(createPrintSettingsFromQPageLayout(pageLayout, !m_pdfOutputPath.empty())); m_printSettings->SetBoolean(printing::kSettingShouldPrintBackgrounds , web_contents()->GetRenderViewHost()->GetWebkitPreferences().should_print_backgrounds); m_printSettings->SetInteger(printing::kSettingColor, diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index 438e3ea24..3f585cf78 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -106,8 +106,8 @@ static bool printPdfDataOnPrinter(const QByteArray& data, QPrinter& printer) return false; } - QRect printerPageRect = printer.pageRect(); - PdfiumDocumentWrapperQt pdfiumWrapper(data.constData(), data.size(), printerPageRect.size()); + QSize pageSize = printer.pageRect().size(); + PdfiumDocumentWrapperQt pdfiumWrapper(data.constData(), data.size(), pageSize); int toPage = printer.toPage(); int fromPage = printer.fromPage(); @@ -155,7 +155,8 @@ static bool printPdfDataOnPrinter(const QByteArray& data, QPrinter& printer) if (currentImage.isNull()) return false; - painter.drawImage(printerPageRect, currentImage, currentImage.rect()); + // Painting operations are automatically clipped to the bounds of the drawable part of the page. + painter.drawImage(QRect(0, 0, pageSize.width(), pageSize.height()), currentImage, currentImage.rect()); if (printedPages < pageCopies - 1) printer.newPage(); } -- cgit v1.2.3 From d502c6e9d09803dd268100f8c53cf7bc563e3d1d Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Fri, 15 Dec 2017 17:52:47 +0100 Subject: Add pkg-host wrapper script Currently we need pkg-config host for cross-builds to build build tools. Unfortunately if build environment exports PKG_CONFIG_* variables pkg-config will pick them up also for host builds, which can lead to compile errors. Create pkg-config-host_wrapper which explicitly unsets PKG_CONFIG_* variables. This is a temporary workaround till proper solution is implemented in qtbase. Task-number: QTBUG-65079 Change-Id: I9aff4a27ba62e096ed4c023cf022a41833260178 Reviewed-by: Allan Sandfeld Jensen --- configure.json | 18 ++++++++++++++++++ configure.pri | 14 ++++++++++++++ mkspecs/features/configure.prf | 6 ++++++ mkspecs/features/functions.prf | 15 +++++++++++++++ src/core/config/linux.pri | 9 ++++++++- 5 files changed, 61 insertions(+), 1 deletion(-) diff --git a/configure.json b/configure.json index 7ef1f5003..fecd83ed4 100644 --- a/configure.json +++ b/configure.json @@ -223,6 +223,11 @@ "type": "detectPython2", "log": "location" }, + "webengine-host-pkg-config": { + "label": "host pkg-config", + "type": "detectHostPkgConfig", + "log": "path" + }, "webengine-gperf": { "label": "gperf", "type": "detectGperf" @@ -355,6 +360,14 @@ { "type": "varAssign", "name": "QMAKE_PYTHON2", "value": "tests.webengine-python2.location" } ] }, + "webengine-host-pkg-config": { + "label": "host-pkg-config", + "condition": "config.unix && tests.webengine-host-pkg-config", + "output": [ + "privateFeature", + { "type": "varAssign", "name": "QMAKE_PKG_CONFIG_HOST", "value": "tests.webengine-host-pkg-config.path" } + ] + }, "webengine-gperf": { "label": "gperf", "condition": "tests.webengine-gperf", @@ -566,6 +579,11 @@ "type": "warning", "condition": "config.sanitizer && !tests.webengine-sanitizer && !features.webengine-sanitizer", "message": "Qt WebEngine cannot be built with the chosen sanitizer configuration. Check config.log for details or use -feature-webengine-sanitizer to force the build." + }, + { + "type": "warning", + "condition": "config.unix && !features.webengine-host-pkg-config", + "message": "host pkg-config not found" } ], diff --git a/configure.pri b/configure.pri index 497557262..ecf2ce4d3 100644 --- a/configure.pri +++ b/configure.pri @@ -157,6 +157,20 @@ defineTest(qtConfTest_detectIcuuc) { return(false) } +defineTest(qtConfTest_detectHostPkgConfig) { + PKG_CONFIG = $$qtConfPkgConfig(true) + isEmpty(PKG_CONFIG) { + qtLog("Could not find host pkg-config") + return(false) + } + qtLog("Found host pkg-config: $$PKG_CONFIG") + $${1}.path = $$PKG_CONFIG + export($${1}.path) + $${1}.cache += path + export($${1}.cache) + return(true) +} + defineTest(qtConfTest_isSanitizerSupported) { sanitizer_combo_supported = true diff --git a/mkspecs/features/configure.prf b/mkspecs/features/configure.prf index 8b8fd3efe..2c0908598 100644 --- a/mkspecs/features/configure.prf +++ b/mkspecs/features/configure.prf @@ -53,6 +53,12 @@ defineTest(runConfigure) { } linux { + + !qtConfig(webengine-host-pkg-config) { + skipBuild("Host pkg-config is required") + return(false) + } + !qtConfig(webengine-system-glibc) { skipBuild("A suitable version of libc could not be found. See: https://sourceware.org/bugzilla/show_bug.cgi?id=14898") return(false) diff --git a/mkspecs/features/functions.prf b/mkspecs/features/functions.prf index 3b9a400b1..8564bad8a 100644 --- a/mkspecs/features/functions.prf +++ b/mkspecs/features/functions.prf @@ -115,3 +115,18 @@ defineTest(skipBuild) { skipBuildReason = "$$skipBuildReason $${EOL}$$1" export(skipBuildReason) } + +defineReplace(pkgConfigHostExecutable) { + wrapper_name = $$OUT_PWD/pkg-config-host_wrapper.sh + wrapper_cmd = $$QMAKE_PKG_CONFIG_HOST + isEmpty(wrapper_cmd): wrapper_cmd = pkg-config + wrapper_content = \ + "$$LITERAL_HASH!/bin/sh" \ + "unset PKG_CONFIG_LIBDIR" \ + "unset PKG_CONFIG_SYSROOT_DIR" \ + "exec $$wrapper_cmd \"$@\"" + !build_pass:!write_file($$wrapper_name, wrapper_content, exe): error() + QMAKE_DISTCLEAN += $$wrapper_name + export(QMAKE_DISTCLEAN) + return($$system_quote($$system_path($$wrapper_name))) +} diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri index 6f7b27f10..d337f686f 100644 --- a/src/core/config/linux.pri +++ b/src/core/config/linux.pri @@ -113,7 +113,14 @@ host_build { PKGCONFIG = $$first($$list($$pkgConfigExecutable())) gn_args += pkg_config=\"$$PKGCONFIG\" PKG_CONFIG_HOST = $$(GN_PKG_CONFIG_HOST) - isEmpty(PKG_CONFIG_HOST): PKG_CONFIG_HOST = pkg-config + pkgConfigLibDir = $$(PKG_CONFIG_LIBDIR) + pkgConfigSysrootDir = $$(PKG_CONFIG_SYSROOT_DIR) + isEmpty(PKG_CONFIG_HOST): PKG_CONFIG_HOST = $$QMAKE_PKG_CONFIG_HOST + cross_compile { + !isEmpty(pkgConfigLibDir)|!isEmpty(pkgConfigSysrootDir) { + PKG_CONFIG_HOST = $$pkgConfigHostExecutable() + } + } gn_args += host_pkg_config=\"$$PKG_CONFIG_HOST\" } -- cgit v1.2.3 From 72103a55b1ac514fa0acbb9131610b26ee87d083 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 23 Jan 2018 16:23:40 +0100 Subject: Remove dead tests we will not be reusing We have no plans of implement QtWebKit still plugins. Change-Id: I9f7bb94cc240e2f0eda8c85c03fa5860435d52a3 Reviewed-by: Peter Varga --- .../widgets/qwebenginepage/tst_qwebenginepage.cpp | 360 --------------------- 1 file changed, 360 deletions(-) diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index 060645733..abebec03f 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -104,20 +104,12 @@ private Q_SLOTS: void modified(); void contextMenuCrash(); void updatePositionDependentActionsCrash(); - void createPluginWithPluginsEnabled(); - void createPluginWithPluginsDisabled(); void callbackSpyDeleted(); - void destroyPlugin_data(); - void destroyPlugin(); - void createViewlessPlugin_data(); - void createViewlessPlugin(); - void graphicsWidgetPlugin(); void multiplePageGroupsAndLocalStorage(); void cursorMovements(); void textSelection(); void textEditing(); void backActionUpdate(); - void protectBindingsRuntimeObjectsFromCollector(); void testOptionalJSObjects(); void testLocalStorageVisibility(); void testEnablePersistentStorage(); @@ -817,332 +809,6 @@ void tst_QWebEnginePage::contextMenuCrash() #endif } -#if defined(QWEBENGINEPAGE_CREATEPLUGIN) -class PluginPage : public QWebEnginePage -{ -public: - PluginPage(QObject *parent = 0) - : QWebEnginePage(parent) {} - - struct CallInfo - { - CallInfo(const QString &c, const QUrl &u, - const QStringList &pn, const QStringList &pv, - QObject *r) - : classid(c), url(u), paramNames(pn), - paramValues(pv), returnValue(r) - {} - QString classid; - QUrl url; - QStringList paramNames; - QStringList paramValues; - QObject *returnValue; - }; - - QList calls; - -protected: - virtual QObject *createPlugin(const QString &classid, const QUrl &url, - const QStringList ¶mNames, - const QStringList ¶mValues) - { - QObject *result = 0; - if (classid == "pushbutton") - result = new QPushButton(); -#ifndef QT_NO_INPUTDIALOG - else if (classid == "lineedit") - result = new QLineEdit(); -#endif - else if (classid == "graphicswidget") - result = new QGraphicsWidget(); - if (result) - result->setObjectName(classid); - calls.append(CallInfo(classid, url, paramNames, paramValues, result)); - return result; - } -}; - -static void createPlugin(QWebEngineView *view) -{ - QSignalSpy loadSpy(view, SIGNAL(loadFinished(bool))); - - PluginPage* newPage = new PluginPage(view); - view->setPage(newPage); - - // type has to be application/x-qt-plugin - view->setHtml(QString("")); - QTRY_COMPARE(loadSpy.count(), 1); - QCOMPARE(newPage->calls.count(), 0); - - view->setHtml(QString("")); - QTRY_COMPARE(loadSpy.count(), 2); - QCOMPARE(newPage->calls.count(), 1); - { - PluginPage::CallInfo ci = newPage->calls.takeFirst(); - QCOMPARE(ci.classid, QString::fromLatin1("pushbutton")); - QCOMPARE(ci.url, QUrl()); - QCOMPARE(ci.paramNames.count(), 3); - QCOMPARE(ci.paramValues.count(), 3); - QCOMPARE(ci.paramNames.at(0), QString::fromLatin1("type")); - QCOMPARE(ci.paramValues.at(0), QString::fromLatin1("application/x-qt-plugin")); - QCOMPARE(ci.paramNames.at(1), QString::fromLatin1("classid")); - QCOMPARE(ci.paramValues.at(1), QString::fromLatin1("pushbutton")); - QCOMPARE(ci.paramNames.at(2), QString::fromLatin1("id")); - QCOMPARE(ci.paramValues.at(2), QString::fromLatin1("mybutton")); - QVERIFY(ci.returnValue != 0); - QVERIFY(ci.returnValue->inherits("QPushButton")); - } - // test JS bindings - QCOMPARE(evaluateJavaScriptSync(newPage, "document.getElementById('mybutton').toString()").toString(), - QString::fromLatin1("[object HTMLObjectElement]")); - QCOMPARE(evaluateJavaScriptSync(newPage, "mybutton.toString()").toString(), - QString::fromLatin1("[object HTMLObjectElement]")); - QCOMPARE(evaluateJavaScriptSync(newPage, "typeof mybutton.objectName").toString(), - QString::fromLatin1("string")); - QCOMPARE(evaluateJavaScriptSync(newPage, "mybutton.objectName").toString(), - QString::fromLatin1("pushbutton")); - QCOMPARE(evaluateJavaScriptSync(newPage, "typeof mybutton.clicked").toString(), - QString::fromLatin1("function")); - QCOMPARE(evaluateJavaScriptSync(newPage, "mybutton.clicked.toString()").toString(), - QString::fromLatin1("function clicked() {\n [native code]\n}")); - - view->setHtml(QString("" - "" - "" - "
"), QUrl("http://foo.bar.baz")); - QTRY_COMPARE(loadSpy.count(), 3); - QCOMPARE(newPage->calls.count(), 2); - { - PluginPage::CallInfo ci = newPage->calls.takeFirst(); - QCOMPARE(ci.classid, QString::fromLatin1("lineedit")); - QCOMPARE(ci.url, QUrl()); - QCOMPARE(ci.paramNames.count(), 3); - QCOMPARE(ci.paramValues.count(), 3); - QCOMPARE(ci.paramNames.at(0), QString::fromLatin1("type")); - QCOMPARE(ci.paramValues.at(0), QString::fromLatin1("application/x-qt-plugin")); - QCOMPARE(ci.paramNames.at(1), QString::fromLatin1("classid")); - QCOMPARE(ci.paramValues.at(1), QString::fromLatin1("lineedit")); - QCOMPARE(ci.paramNames.at(2), QString::fromLatin1("id")); - QCOMPARE(ci.paramValues.at(2), QString::fromLatin1("myedit")); - QVERIFY(ci.returnValue != 0); - QVERIFY(ci.returnValue->inherits("QLineEdit")); - } - { - PluginPage::CallInfo ci = newPage->calls.takeFirst(); - QCOMPARE(ci.classid, QString::fromLatin1("pushbutton")); - QCOMPARE(ci.url, QUrl()); - QCOMPARE(ci.paramNames.count(), 3); - QCOMPARE(ci.paramValues.count(), 3); - QCOMPARE(ci.paramNames.at(0), QString::fromLatin1("type")); - QCOMPARE(ci.paramValues.at(0), QString::fromLatin1("application/x-qt-plugin")); - QCOMPARE(ci.paramNames.at(1), QString::fromLatin1("classid")); - QCOMPARE(ci.paramValues.at(1), QString::fromLatin1("pushbutton")); - QCOMPARE(ci.paramNames.at(2), QString::fromLatin1("id")); - QCOMPARE(ci.paramValues.at(2), QString::fromLatin1("mybutton")); - QVERIFY(ci.returnValue != 0); - QVERIFY(ci.returnValue->inherits("QPushButton")); - } -} -#endif - -void tst_QWebEnginePage::graphicsWidgetPlugin() -{ -#if !defined(QWEBENGINEPAGE_CREATEPLUGIN) - QSKIP("QWEBENGINEPAGE_CREATEPLUGIN"); -#else - m_view->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true); - QGraphicsWebView webView; - - QSignalSpy loadSpy(&webView, SIGNAL(loadFinished(bool))); - - PluginPage* newPage = new PluginPage(&webView); - webView.setPage(newPage); - - // type has to be application/x-qt-plugin - webView.setHtml(QString("")); - QTRY_COMPARE(loadSpy.count(), 1); - QCOMPARE(newPage->calls.count(), 0); - - webView.setHtml(QString("")); - QTRY_COMPARE(loadSpy.count(), 2); - QCOMPARE(newPage->calls.count(), 1); - { - PluginPage::CallInfo ci = newPage->calls.takeFirst(); - QCOMPARE(ci.classid, QString::fromLatin1("graphicswidget")); - QCOMPARE(ci.url, QUrl()); - QCOMPARE(ci.paramNames.count(), 3); - QCOMPARE(ci.paramValues.count(), 3); - QCOMPARE(ci.paramNames.at(0), QString::fromLatin1("type")); - QCOMPARE(ci.paramValues.at(0), QString::fromLatin1("application/x-qt-plugin")); - QCOMPARE(ci.paramNames.at(1), QString::fromLatin1("classid")); - QCOMPARE(ci.paramValues.at(1), QString::fromLatin1("graphicswidget")); - QCOMPARE(ci.paramNames.at(2), QString::fromLatin1("id")); - QCOMPARE(ci.paramValues.at(2), QString::fromLatin1("mygraphicswidget")); - QVERIFY(ci.returnValue); - QVERIFY(ci.returnValue->inherits("QGraphicsWidget")); - } - // test JS bindings - QCOMPARE(evaluateJavaScriptSync(newPage, "document.getElementById('mygraphicswidget').toString()").toString(), - QString::fromLatin1("[object HTMLObjectElement]")); - QCOMPARE(evaluateJavaScriptSync(newPage, "mygraphicswidget.toString()").toString(), - QString::fromLatin1("[object HTMLObjectElement]")); - QCOMPARE(evaluateJavaScriptSync(newPage, "typeof mygraphicswidget.objectName").toString(), - QString::fromLatin1("string")); - QCOMPARE(evaluateJavaScriptSync(newPage, "mygraphicswidget.objectName").toString(), - QString::fromLatin1("graphicswidget")); - QCOMPARE(evaluateJavaScriptSync(newPage, "typeof mygraphicswidget.geometryChanged").toString(), - QString::fromLatin1("function")); - QCOMPARE(evaluateJavaScriptSync(newPage, "mygraphicswidget.geometryChanged.toString()").toString(), - QString::fromLatin1("function geometryChanged() {\n [native code]\n}")); -#endif -} - -void tst_QWebEnginePage::createPluginWithPluginsEnabled() -{ -#if !defined(QWEBENGINEPAGE_CREATEPLUGIN) - QSKIP("QWEBENGINEPAGE_CREATEPLUGIN"); -#else - m_view->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true); - createPlugin(m_view); -#endif -} - -void tst_QWebEnginePage::createPluginWithPluginsDisabled() -{ -#if !defined(QWEBENGINEPAGE_CREATEPLUGIN) - QSKIP("QWEBENGINEPAGE_CREATEPLUGIN"); -#else - // Qt Plugins should be loaded by QtWebEngine even when PluginsEnabled is - // false. The client decides whether a Qt plugin is enabled or not when - // it decides whether or not to instantiate it. - m_view->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, false); - createPlugin(m_view); -#endif -} - -#if defined(QWEBENGINEPAGE_CREATEPLUGIN) -// Standard base class for template PluginTracerPage. In tests it is used as interface. -class PluginCounterPage : public QWebEnginePage { -public: - int m_count; - QPointer m_widget; - QObject* m_pluginParent; - PluginCounterPage(QObject* parent = 0) - : QWebEnginePage(parent) - , m_count(0) - , m_pluginParent(0) - { - settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true); - } - ~PluginCounterPage() - { - if (m_pluginParent) - m_pluginParent->deleteLater(); - } -}; - -template -class PluginTracerPage : public PluginCounterPage { -public: - PluginTracerPage(QObject* parent = 0) - : PluginCounterPage(parent) - { - // this is a dummy parent object for the created plugin - m_pluginParent = new T; - } - virtual QObject* createPlugin(const QString&, const QUrl&, const QStringList&, const QStringList&) - { - m_count++; - m_widget = new T; - // need a cast to the specific type, as QObject::setParent cannot be called, - // because it is not virtual. Instead it is necessary to call QWidget::setParent, - // which also takes a QWidget* instead of a QObject*. Therefore we need to - // upcast to T*, which is a QWidget. - static_cast(m_widget.data())->setParent(static_cast(m_pluginParent)); - return m_widget.data(); - } -}; - -class PluginFactory { -public: - enum FactoredType {QWidgetType, QGraphicsWidgetType}; - static PluginCounterPage* create(FactoredType type, QObject* parent = 0) - { - PluginCounterPage* result = 0; - switch (type) { - case QWidgetType: - result = new PluginTracerPage(parent); - break; - case QGraphicsWidgetType: - result = new PluginTracerPage(parent); - break; - default: {/*Oops*/}; - } - return result; - } - - static void prepareTestData() - { - QTest::addColumn("type"); - QTest::newRow("QWidget") << (int)PluginFactory::QWidgetType; - QTest::newRow("QGraphicsWidget") << (int)PluginFactory::QGraphicsWidgetType; - } -}; -#endif - -void tst_QWebEnginePage::destroyPlugin_data() -{ -#if defined(QWEBENGINEPAGE_CREATEPLUGIN) - PluginFactory::prepareTestData(); -#endif -} - -void tst_QWebEnginePage::destroyPlugin() -{ -#if !defined(QWEBENGINEPAGE_CREATEPLUGIN) - QSKIP("QWEBENGINEPAGE_CREATEPLUGIN"); -#else - QFETCH(int, type); - PluginCounterPage* page = PluginFactory::create((PluginFactory::FactoredType)type, m_view); - m_view->setPage(page); - - // we create the plugin, so the widget should be constructed - QString content(""); - m_view->setHtml(content); - QVERIFY(page->m_widget); - QCOMPARE(page->m_count, 1); - - // navigate away, the plugin widget should be destructed - m_view->setHtml("Hi"); - QTestEventLoop::instance().enterLoop(1); - QVERIFY(!page->m_widget); -#endif -} - -void tst_QWebEnginePage::createViewlessPlugin_data() -{ -#if defined(QWEBENGINEPAGE_CREATEPLUGIN) - PluginFactory::prepareTestData(); -#endif -} - -void tst_QWebEnginePage::createViewlessPlugin() -{ -#if !defined(QWEBENGINEPAGE_CREATEPLUGIN) - QSKIP("QWEBENGINEPAGE_CREATEPLUGIN"); -#else - QFETCH(int, type); - PluginCounterPage* page = PluginFactory::create((PluginFactory::FactoredType)type); - QString content(""); - page->setHtml(content); - QCOMPARE(page->m_count, 1); - QVERIFY(page->m_widget); - QVERIFY(page->m_pluginParent); - QVERIFY(page->m_widget.data()->parent() == page->m_pluginParent); - delete page; -#endif -} - void tst_QWebEnginePage::multiplePageGroupsAndLocalStorage() { #if !defined(QWEBENGINESETTINGS_SETLOCALSTORAGEPATH) @@ -1660,32 +1326,6 @@ void tst_QWebEnginePage::backActionUpdate() QVERIFY(action->isEnabled()); } -void tst_QWebEnginePage::protectBindingsRuntimeObjectsFromCollector() -{ -#if !defined(QWEBENGINEPAGE_CREATEPLUGIN) - QSKIP("QWEBENGINEPAGE_CREATEPLUGIN"); -#else - QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool))); - - PluginPage* newPage = new PluginPage(m_view); - m_view->setPage(newPage); - - m_view->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true); - - m_view->setHtml(QString("")); - QTRY_COMPARE(loadSpy.count(), 1); - - newPage->runJavaScript("function testme(text) { var lineedit = document.getElementById('mylineedit'); lineedit.setText(text); lineedit.selectAll(); }"); - - evaluateJavaScriptSync(newPage, "testme('foo')"); - - DumpRenderTreeSupportQt::garbageCollectorCollect(); - - // don't crash! - evaluateJavaScriptSync(newPage, "testme('bar')"); -#endif -} - #if defined(QWEBENGINEPAGE_SETTINGS) static inline bool testFlag(QWebEnginePage& webPage, QWebEngineSettings::WebAttribute settingAttribute, const QString& jsObjectName, bool settingValue) { -- cgit v1.2.3 From 3387809ba9e159f5179e3df5b9408bc34966cd4a Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 23 Jan 2018 16:24:55 +0100 Subject: Remove test relying on WebKit internals This test makes little sense for QtWebEngine Change-Id: I0177fb59ea23383a3c8135853f7e62b26ce5708a Reviewed-by: Peter Varga --- tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index abebec03f..279ce3902 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -100,7 +100,6 @@ private Q_SLOTS: void userStyleSheet(); void userStyleSheetFromLocalFileUrl(); void userStyleSheetFromQrcUrl(); - void loadHtml5Video(); void modified(); void contextMenuCrash(); void updatePositionDependentActionsCrash(); @@ -689,20 +688,6 @@ void tst_QWebEnginePage::userStyleSheetFromQrcUrl() #endif } -void tst_QWebEnginePage::loadHtml5Video() -{ -#if defined(WTF_USE_QT_MULTIMEDIA) && WTF_USE_QT_MULTIMEDIA - QByteArray url("http://does.not/exist?a=1%2Cb=2"); - m_view->setHtml("

"); - QTest::qWait(2000); - QUrl mUrl = DumpRenderTreeSupportQt::mediaContentUrlByElementId(m_page->mainFrame()->handle(), "video"); - QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=65452", Continue); - QCOMPARE(mUrl.toEncoded(), url); -#else - W_QSKIP("This test requires Qt Multimedia", SkipAll); -#endif -} - void tst_QWebEnginePage::modified() { #if !defined(QWEBENGINEPAGE_ISMODIFIED) -- cgit v1.2.3 From 7911a4f0480e3e5371515f211601b69606e32d50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCri=20Valdmann?= Date: Mon, 13 Nov 2017 12:49:02 +0100 Subject: Fix thread synchronization issue in tst_qwebengineprofile Change-Id: I7b7c4a6501387b1d657e55f222908365990b8fef Reviewed-by: Allan Sandfeld Jensen --- tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp index 6961f3b6d..c443ee114 100644 --- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp +++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp @@ -200,9 +200,13 @@ public: } bool isSequential() const override { return true; } qint64 bytesAvailable() const override - { return m_bytesAvailable; } + { + QMutexLocker lock(&m_mutex); + return m_bytesAvailable; + } bool atEnd() const override { + QMutexLocker lock(&m_mutex); return (m_data.size() >= 1000 && m_bytesRead >= 1000); } protected: @@ -237,7 +241,7 @@ protected: } private: - QMutex m_mutex; + mutable QMutex m_mutex{QMutex::Recursive}; QByteArray m_data; QBasicTimer m_timer; int m_bytesRead; -- cgit v1.2.3 From a96d1fdd51a5544bab52e5dbf176d31865f0542a Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Tue, 9 Jan 2018 16:15:43 +0100 Subject: Fix random crashes on exit Destroy WebContentsDelegateQt before WebContents, since it references already partly deleted WebContentsAdapterClient object. This prevents calls by navigation handling on already destructed web contents adapter client. Task-number: QTBUG-65647 Task-number: QTBUG-47945 Change-Id: I0ed5887b337a43ab89ecbfe05130691b5f1f37ec Reviewed-by: Allan Sandfeld Jensen --- src/core/web_contents_adapter.cpp | 2 -- src/core/web_contents_delegate_qt.cpp | 7 +++++++ src/core/web_contents_delegate_qt.h | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 5850b07b5..dc36b98c4 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -363,8 +363,6 @@ WebContentsAdapterPrivate::WebContentsAdapterPrivate() WebContentsAdapterPrivate::~WebContentsAdapterPrivate() { - // Destroy the WebContents first - webContents.reset(); } QSharedPointer WebContentsAdapter::createFromSerializedNavigationHistory(QDataStream &input, WebContentsAdapterClient *adapterClient) diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index f51a6dff3..db05fae4b 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -109,6 +109,13 @@ WebContentsDelegateQt::WebContentsDelegateQt(content::WebContents *webContents, Observe(webContents); } +WebContentsDelegateQt::~WebContentsDelegateQt() +{ + // The destruction of this object should take place before + // WebContents destruction since WebContentsAdapterClient + // might be already deleted. +} + content::WebContents *WebContentsDelegateQt::OpenURLFromTab(content::WebContents *source, const content::OpenURLParams ¶ms) { content::WebContents *target = source; diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h index 8440ec053..2ebdb2ffc 100644 --- a/src/core/web_contents_delegate_qt.h +++ b/src/core/web_contents_delegate_qt.h @@ -92,7 +92,7 @@ class WebContentsDelegateQt : public content::WebContentsDelegate { public: WebContentsDelegateQt(content::WebContents*, WebContentsAdapterClient *adapterClient); - ~WebContentsDelegateQt() { Q_ASSERT(m_loadingErrorFrameList.isEmpty()); } + ~WebContentsDelegateQt(); QString lastSearchedString() const { return m_lastSearchedString; } void setLastSearchedString(const QString &s) { m_lastSearchedString = s; } int lastReceivedFindReply() const { return m_lastReceivedFindReply; } -- cgit v1.2.3 From f0c5f3306fadc7dea7a13defd8b9cf20a6982493 Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Wed, 6 Dec 2017 16:08:12 +0100 Subject: Add 32bit host compiler test The 32bit compiler is required for creating v8 snapshots. Task-number: QTBUG-65004 Task-number: QTBUG-64869 Change-Id: I0a7a351208768f0b12900fac14d3abd5c8d99fa2 Reviewed-by: Allan Sandfeld Jensen --- config.tests/hostcompiler/hostcompiler.pro | 9 +++++++++ config.tests/hostcompiler/main.cpp | 6 ++++++ configure.json | 20 ++++++++++++++++++-- mkspecs/features/configure.prf | 7 +++++++ src/core/config/common.pri | 7 +++++++ 5 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 config.tests/hostcompiler/hostcompiler.pro create mode 100644 config.tests/hostcompiler/main.cpp diff --git a/config.tests/hostcompiler/hostcompiler.pro b/config.tests/hostcompiler/hostcompiler.pro new file mode 100644 index 000000000..5a80246ab --- /dev/null +++ b/config.tests/hostcompiler/hostcompiler.pro @@ -0,0 +1,9 @@ +option(host_build) + +gcc:equals(QT_ARCH, "x86_64"):contains(QT_TARGET_ARCH, "arm"):!contains(QT_TARGET_ARCH, "arm64") { + QMAKE_CXXFLAGS += -m32 + QMAKE_LFLAGS += -m32 +} + +SOURCES = main.cpp + diff --git a/config.tests/hostcompiler/main.cpp b/config.tests/hostcompiler/main.cpp new file mode 100644 index 000000000..96444ae8b --- /dev/null +++ b/config.tests/hostcompiler/main.cpp @@ -0,0 +1,6 @@ +#include +int main() +{ + printf("This works\n"); + return 0; +} diff --git a/configure.json b/configure.json index fecd83ed4..9c9285953 100644 --- a/configure.json +++ b/configure.json @@ -21,8 +21,8 @@ "webengine-spellchecker": "boolean", "webengine-native-spellchecker": "boolean", "webengine-webrtc": "boolean", - "webengine-geolocation" : "boolean", - + "webengine-geolocation": "boolean", + "webengine-v8-snapshot": "boolean", "alsa": { "type": "boolean", "name": "webengine-alsa" }, "pulseaudio": { "type": "boolean", "name": "webengine-pulseaudio" }, "ffmpeg": { "type": "enum", "name": "webengine-system-ffmpeg", "values": { "system": "yes", "qt": "no" } }, @@ -189,6 +189,11 @@ "test": "alsa", "type": "compile" }, + "webengine-host-compiler": { + "label": "host compiler", + "test": "hostcompiler", + "type": "compile" + }, "webengine-khr": { "label": "khr", "test": "khr", @@ -396,6 +401,16 @@ "condition": "config.unix && tests.alsa", "output": [ "privateFeature" ] }, + "webengine-v8-snapshot": { + "label" : "Use v8 snapshot", + "purpuse": "Enables the v8 snapshot, for fast v8 context creation", + "output": [ "privateFeature" ] + }, + "webengine-v8-snapshot-support": { + "autoDetect": "features.webengine-v8-snapshot", + "condition": "!config.unix || !features.webengine-embedded-build || tests.webengine-host-compiler", + "output": [ "privateFeature" ] + }, "webengine-system-khr" : { "label": "khr", "condition": "config.unix && tests.webengine-khr", @@ -600,6 +615,7 @@ "webengine-webrtc", "webengine-system-ninja", "webengine-geolocation", + "webengine-v8-snapshot-support", { "type": "feature", "args": "webengine-alsa", diff --git a/mkspecs/features/configure.prf b/mkspecs/features/configure.prf index 2c0908598..f8c154655 100644 --- a/mkspecs/features/configure.prf +++ b/mkspecs/features/configure.prf @@ -30,6 +30,13 @@ defineTest(runConfigure) { include($$QTWEBENGINE_OUT_ROOT/qtwebengine-config.pri) QT_FOR_CONFIG += webengine-private + !qtConfig(webengine-v8-snapshot-support):qtConfig(webengine-v8-snapshot) { + skipBuild("V8 snapshot cannot be built. Most likely, the 32-bit host compiler does not work."\ + "Please make sure you have 32-bit devel environment installed, or "\ + "configure webengine with '-no-webengine-v8-snapshot'") + return(false) + } + !qtConfig(webengine-gperf) { skipBuild("Required gperf could not be found.") return(false) diff --git a/src/core/config/common.pri b/src/core/config/common.pri index 8961e1cd3..ab2a60978 100644 --- a/src/core/config/common.pri +++ b/src/core/config/common.pri @@ -84,3 +84,10 @@ optimize_size: gn_args += optimize_for_size=true # rtti, linking would fail at build time. sanitize_undefined: gn_args += is_ubsan=true use_rtti=true } + +qtConfig(webengine-v8-snapshot) { + gn_args += v8_use_snapshot=true +} else { + gn_args += v8_use_snapshot=false +} + -- cgit v1.2.3 From 156024d840dee530def5c8ebe788978548b87c7d Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 23 Jan 2018 16:30:30 +0100 Subject: Rewrite and activate multiplePageGroupsAndLocalStorage Convert it to QtWebEngine. Change-Id: I7a453cd7544a20a9c461c3bb29b3a2fb78016d44 Reviewed-by: Joerg Bornemann --- .../widgets/qwebenginepage/tst_qwebenginepage.cpp | 81 +++++++++++----------- 1 file changed, 39 insertions(+), 42 deletions(-) diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index 279ce3902..098ac11e8 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -104,7 +104,7 @@ private Q_SLOTS: void contextMenuCrash(); void updatePositionDependentActionsCrash(); void callbackSpyDeleted(); - void multiplePageGroupsAndLocalStorage(); + void multipleProfilesAndLocalStorage(); void cursorMovements(); void textSelection(); void textEditing(); @@ -794,50 +794,47 @@ void tst_QWebEnginePage::contextMenuCrash() #endif } -void tst_QWebEnginePage::multiplePageGroupsAndLocalStorage() +void tst_QWebEnginePage::multipleProfilesAndLocalStorage() { -#if !defined(QWEBENGINESETTINGS_SETLOCALSTORAGEPATH) - QSKIP("QWEBENGINESETTINGS_SETLOCALSTORAGEPATH"); -#else QDir dir(tmpDirPath()); - dir.mkdir("path1"); - dir.mkdir("path2"); - - QWebEngineView view1; - QWebEngineView view2; - - view1.page()->settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true); - view1.page()->settings()->setLocalStoragePath(QDir::toNativeSeparators(tmpDirPath() + "/path1")); - DumpRenderTreeSupportQt::webPageSetGroupName(view1.page()->handle(), "group1"); - view2.page()->settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true); - view2.page()->settings()->setLocalStoragePath(QDir::toNativeSeparators(tmpDirPath() + "/path2")); - DumpRenderTreeSupportQt::webPageSetGroupName(view2.page()->handle(), "group2"); - QCOMPARE(DumpRenderTreeSupportQt::webPageGroupName(view1.page()->handle()), QString("group1")); - QCOMPARE(DumpRenderTreeSupportQt::webPageGroupName(view2.page()->handle()), QString("group2")); - - - view1.setHtml(QString(" "), QUrl("http://www.myexample.com")); - view2.setHtml(QString(" "), QUrl("http://www.myexample.com")); - - evaluateJavaScriptSync(view1.page(), "localStorage.test='value1';"); - evaluateJavaScriptSync(view2.page(), "localStorage.test='value2';"); - - view1.setHtml(QString(" "), QUrl("http://www.myexample.com")); - view2.setHtml(QString(" "), QUrl("http://www.myexample.com")); - - QVariant s1 = evaluateJavaScriptSync(view1.page(), "localStorage.test"); - QCOMPARE(s1.toString(), QString("value1")); - - QVariant s2 = evaluateJavaScriptSync(view2.page(), "localStorage.test"); - QCOMPARE(s2.toString(), QString("value2")); - + bool success = dir.mkpath("path1"); + success = success && dir.mkdir("path2"); + QVERIFY(success); + { + QWebEngineProfile profile1("test1"); + QWebEngineProfile profile2("test2"); + profile1.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true); + profile2.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true); + profile1.setPersistentStoragePath(QDir::toNativeSeparators(tmpDirPath() + "/path1")); + profile2.setPersistentStoragePath(QDir::toNativeSeparators(tmpDirPath() + "/path2")); + + QWebEnginePage page1(&profile1, nullptr); + QWebEnginePage page2(&profile2, nullptr); + QSignalSpy loadSpy1(&page1, SIGNAL(loadFinished(bool))); + QSignalSpy loadSpy2(&page2, SIGNAL(loadFinished(bool))); + + page1.setHtml(QString(" "), QUrl("http://wwww.example.com")); + page2.setHtml(QString(" "), QUrl("http://wwww.example.com")); + QTRY_COMPARE(loadSpy1.count(), 1); + QTRY_COMPARE(loadSpy2.count(), 1); + + evaluateJavaScriptSync(&page1, "localStorage.setItem('test', 'value1');"); + evaluateJavaScriptSync(&page2, "localStorage.setItem('test', 'value2');"); + + page1.setHtml(QString(" "), QUrl("http://wwww.example.com")); + page2.setHtml(QString(" "), QUrl("http://wwww.example.com")); + QTRY_COMPARE(loadSpy1.count(), 2); + QTRY_COMPARE(loadSpy2.count(), 2); + + QVariant s1 = evaluateJavaScriptSync(&page1, "localStorage.getItem('test')"); + QCOMPARE(s1.toString(), QString("value1")); + QVariant s2 = evaluateJavaScriptSync(&page2, "localStorage.getItem('test')"); + QCOMPARE(s2.toString(), QString("value2")); + } + // Avoid deleting on-disk dbs before the underlying browser-context has been asynchronously deleted QTest::qWait(1000); - - QFile::remove(QDir::toNativeSeparators(tmpDirPath() + "/path1/http_www.myexample.com_0.localstorage")); - QFile::remove(QDir::toNativeSeparators(tmpDirPath() + "/path2/http_www.myexample.com_0.localstorage")); - dir.rmdir(QDir::toNativeSeparators("./path1")); - dir.rmdir(QDir::toNativeSeparators("./path2")); -#endif + QDir(tmpDirPath() + "/path1").removeRecursively(); + QDir(tmpDirPath() + "/path2").removeRecursively(); } class CursorTrackedPage : public QWebEnginePage -- cgit v1.2.3 From 1661c8179989378d5cb03f9233ce2b72c582d8c1 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 26 Jan 2018 10:38:24 +0100 Subject: Fix configure overview of v8 snapshot Change-Id: Iad4dd57f5a86019290bc59187e60c9c1c3db917d Reviewed-by: Michal Klocek --- configure.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.json b/configure.json index 9c9285953..c44da9854 100644 --- a/configure.json +++ b/configure.json @@ -615,7 +615,7 @@ "webengine-webrtc", "webengine-system-ninja", "webengine-geolocation", - "webengine-v8-snapshot-support", + "webengine-v8-snapshot", { "type": "feature", "args": "webengine-alsa", -- cgit v1.2.3 From 7644564d754bbee640a091950b77e23586c2d283 Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Tue, 16 Jan 2018 18:44:01 +0100 Subject: Fix crashes of url load qml tests Currently we can get QuickWebEngineViewPrivate::loadFinished while still being in RenderFrameHostImpl::OnDidStopLoading, unfortunately if user connects onLoadingChanged signal with new url load request this will end up in DiscardUnusedFrame and delete on RenderFrameHostImpl which is still on the bottom of the stack. Use QTimer::singleShot to return to the event loop before emitting load handling signals. Post all load handling calls with singleShot to avoid out of order load "signals" delivery in some cases. Emitting signals should be done from WebContentsAdapterClient to make sure the destruction of WebConentAdapterClient prevents emitting signals on already deleted adapter. Task-numbmer: QTBUG-65813 Change-Id: I93263876fb14bd959ba951463c8aeb5155f04a4f Reviewed-by: Allan Sandfeld Jensen --- src/webengine/api/qquickwebenginetestsupport.cpp | 16 ++++++----- src/webengine/api/qquickwebengineview.cpp | 35 ++++++++++++++---------- src/webenginewidgets/api/qwebenginepage.cpp | 10 +++++-- 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/webengine/api/qquickwebenginetestsupport.cpp b/src/webengine/api/qquickwebenginetestsupport.cpp index b3290d3cc..b7b863125 100644 --- a/src/webengine/api/qquickwebenginetestsupport.cpp +++ b/src/webengine/api/qquickwebenginetestsupport.cpp @@ -42,6 +42,7 @@ #include "qquickwebengineloadrequest_p.h" #include #include +#include QT_BEGIN_NAMESPACE @@ -56,19 +57,20 @@ QQuickWebEngineErrorPage::QQuickWebEngineErrorPage() void QQuickWebEngineErrorPage::loadFinished(bool success, const QUrl &url) { Q_UNUSED(success); - - QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus); - Q_EMIT loadingChanged(&loadRequest); - return; + QTimer::singleShot(0, this, [this, url]() { + QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus); + emit loadingChanged(&loadRequest); + }); } void QQuickWebEngineErrorPage::loadStarted(const QUrl &provisionalUrl) { - QQuickWebEngineLoadRequest loadRequest(provisionalUrl, QQuickWebEngineView::LoadStartedStatus); - Q_EMIT loadingChanged(&loadRequest); + QTimer::singleShot(0, this, [this, provisionalUrl]() { + QQuickWebEngineLoadRequest loadRequest(provisionalUrl, QQuickWebEngineView::LoadStartedStatus); + emit loadingChanged(&loadRequest); + }); } - QQuickWebEngineTestInputContext::QQuickWebEngineTestInputContext() : m_visible(false) { diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index b4270a876..cb21f4b15 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -434,14 +434,14 @@ void QQuickWebEngineViewPrivate::iconChanged(const QUrl &url) iconUrl = faviconProvider->attach(q, url); m_history->reset(); - Q_EMIT q->iconChanged(); + QTimer::singleShot(0, q, &QQuickWebEngineView::iconChanged); } void QQuickWebEngineViewPrivate::loadProgressChanged(int progress) { Q_Q(QQuickWebEngineView); loadProgress = progress; - Q_EMIT q->loadProgressChanged(); + QTimer::singleShot(0, q, &QQuickWebEngineView::loadProgressChanged); } void QQuickWebEngineViewPrivate::didUpdateTargetURL(const QUrl &hoveredUrl) @@ -486,8 +486,11 @@ void QQuickWebEngineViewPrivate::loadStarted(const QUrl &provisionalUrl, bool is isLoading = true; m_history->reset(); m_certificateErrorControllers.clear(); - QQuickWebEngineLoadRequest loadRequest(provisionalUrl, QQuickWebEngineView::LoadStartedStatus); - Q_EMIT q->loadingChanged(&loadRequest); + + QTimer::singleShot(0, q, [q, provisionalUrl]() { + QQuickWebEngineLoadRequest loadRequest(provisionalUrl, QQuickWebEngineView::LoadStartedStatus); + emit q->loadingChanged(&loadRequest); + }); } void QQuickWebEngineViewPrivate::loadCommitted() @@ -522,25 +525,27 @@ void QQuickWebEngineViewPrivate::loadFinished(bool success, const QUrl &url, boo isLoading = false; m_history->reset(); if (errorCode == WebEngineError::UserAbortedError) { - QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadStoppedStatus); - Q_EMIT q->loadingChanged(&loadRequest); + QTimer::singleShot(0, q, [q, url]() { + QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadStoppedStatus); + emit q->loadingChanged(&loadRequest); + }); return; } if (success) { explicitUrl = QUrl(); - QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus); - Q_EMIT q->loadingChanged(&loadRequest); + QTimer::singleShot(0, q, [q, url]() { + QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus); + emit q->loadingChanged(&loadRequest); + }); return; } Q_ASSERT(errorCode); - QQuickWebEngineLoadRequest loadRequest( - url, - QQuickWebEngineView::LoadFailedStatus, - errorDescription, - errorCode, - static_cast(WebEngineError::toQtErrorDomain(errorCode))); - Q_EMIT q->loadingChanged(&loadRequest); + QQuickWebEngineView::ErrorDomain errorDomain = static_cast(WebEngineError::toQtErrorDomain(errorCode)); + QTimer::singleShot(0, q, [q, url, errorDescription, errorCode, errorDomain]() { + QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadFailedStatus,errorDescription, errorCode, errorDomain); + emit q->loadingChanged(&loadRequest); + }); return; } diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index 3f585cf78..ac8e9c667 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -328,7 +328,7 @@ void QWebEnginePagePrivate::loadStarted(const QUrl &provisionalUrl, bool isError return; isLoading = true; - Q_EMIT q->loadStarted(); + QTimer::singleShot(0, q, &QWebEnginePage::loadStarted); updateNavigationActions(); } @@ -346,7 +346,9 @@ void QWebEnginePagePrivate::loadFinished(bool success, const QUrl &url, bool isE if (isErrorPage) { Q_ASSERT(settings->testAttribute(QWebEngineSettings::ErrorPageEnabled)); - Q_EMIT q->loadFinished(false); + QTimer::singleShot(0, q, [q](){ + emit q->loadFinished(false); + }); return; } @@ -356,7 +358,9 @@ void QWebEnginePagePrivate::loadFinished(bool success, const QUrl &url, bool isE // Delay notifying failure until the error-page is done loading. // Error-pages are not loaded on failures due to abort. if (success || errorCode == -3 /* ERR_ABORTED*/ || !settings->testAttribute(QWebEngineSettings::ErrorPageEnabled)) { - Q_EMIT q->loadFinished(success); + QTimer::singleShot(0, q, [q, success](){ + emit q->loadFinished(success); + }); } updateNavigationActions(); } -- cgit v1.2.3