summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSzabolcs David <davidsz@inf.u-szeged.hu>2022-12-12 17:54:09 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-04-05 21:05:12 +0000
commita64c4bb59a6fb1f8b4e319d9aab32e8343b8486f (patch)
tree0acc43c8a39bf1bfbc3819b63e23aadc1248e48a
parent78ebfe3284955737deb7328e3fc059cedc5cfaff (diff)
downloadqtwebengine-a64c4bb59a6fb1f8b4e319d9aab32e8343b8486f.tar.gz
Better handling of interrupted PDF printing
- Document the fact Stop WebAction can interrupt the in-progress PDF generation. - Update PrintViewManagerQt::PrintPreviewDone(): Normally IsPrintRenderFrameConnected() implies IsRenderFrameLive(), but we have to check both to avoid crash when render process exits. (Like Chrome does.) - Update PrintViewManagerQt::RequestPrintPreview(): Handle that case when print preview params were sent between processes at the beginning, but it was interrupted before RequestPrintPreview() could start PDF generation. - Add a simple auto test to catch crashes Task-number: QTBUG-108154 Change-Id: I8a4f9cc97ddcf9a165d66a5981d93a023858fbc1 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> (cherry picked from commit c3ed0e176ccda503c968626010ca36f1f3961fce) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/core/api/qwebenginepage.cpp5
-rw-r--r--src/core/printing/print_view_manager_qt.cpp6
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp3
-rw-r--r--tests/auto/widgets/printing/tst_printing.cpp14
4 files changed, 27 insertions, 1 deletions
diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp
index ac44fad10..99edc7246 100644
--- a/src/core/api/qwebenginepage.cpp
+++ b/src/core/api/qwebenginepage.cpp
@@ -2248,6 +2248,9 @@ QSizeF QWebEnginePage::contentsSize() const
To be informed about the result of the request, connect to the signal
pdfPrintingFinished().
+ \note The \l QWebEnginePage::Stop web action can be used to interrupt
+ this asynchronous operation.
+
If a file already exists at the provided file path, it will be overwritten.
\sa pdfPrintingFinished()
*/
@@ -2273,6 +2276,8 @@ void QWebEnginePage::printToPdf(const QString &filePath, const QPageLayout &layo
The \a resultCallback must take a const reference to a QByteArray as parameter. If printing was successful, this byte array
will contain the PDF data, otherwise, the byte array will be empty.
+ \note The \l QWebEnginePage::Stop web action can be used to interrupt this operation.
+
\warning We guarantee that the callback (\a resultCallback) is always called, but it might be done
during page destruction. When QWebEnginePage is deleted, the callback is triggered with an invalid
value and it is not safe to use the corresponding QWebEnginePage or QWebEngineView instance inside it.
diff --git a/src/core/printing/print_view_manager_qt.cpp b/src/core/printing/print_view_manager_qt.cpp
index d8b6f1c1f..7d8a796f7 100644
--- a/src/core/printing/print_view_manager_qt.cpp
+++ b/src/core/printing/print_view_manager_qt.cpp
@@ -277,7 +277,7 @@ void PrintViewManagerQt::resetPdfState()
void PrintViewManagerQt::PrintPreviewDone()
{
- if (IsPrintRenderFrameConnected(m_printPreviewRfh))
+ if (m_printPreviewRfh->IsRenderFrameLive() && IsPrintRenderFrameConnected(m_printPreviewRfh))
GetPrintRenderFrame(m_printPreviewRfh)->OnPrintPreviewDialogClosed();
m_printPreviewRfh = nullptr;
}
@@ -338,6 +338,10 @@ void PrintViewManagerQt::ShowScriptedPrintPreview(bool /*source_is_modifiable*/)
void PrintViewManagerQt::RequestPrintPreview(printing::mojom::RequestPrintPreviewParamsPtr /*params*/)
{
+ if (m_printSettings.empty()) {
+ PrintPreviewDone();
+ return;
+ }
mojo::AssociatedRemote<printing::mojom::PrintRenderFrame> printRenderFrame;
m_printPreviewRfh->GetRemoteAssociatedInterfaces()->GetInterface(&printRenderFrame);
printRenderFrame->PrintPreview(m_printSettings.Clone());
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index fd74268f2..35fb98138 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -1408,6 +1408,9 @@ void QWebEngineView::printToPdf(const std::function<void(const QByteArray&)> &re
\note Printing runs on the browser process, which is by default not sandboxed.
+ \note The data generation step of printing can be interrupted for a short period of time using
+ the \l QWebEnginePage::Stop web action.
+
\note This function rasterizes the result when rendering onto \a printer. Please consider raising
the default resolution of \a printer to at least 300 DPI or using printToPdf() to produce
PDF file output more effectively.
diff --git a/tests/auto/widgets/printing/tst_printing.cpp b/tests/auto/widgets/printing/tst_printing.cpp
index 1c1e0615e..1f9b5059c 100644
--- a/tests/auto/widgets/printing/tst_printing.cpp
+++ b/tests/auto/widgets/printing/tst_printing.cpp
@@ -23,6 +23,7 @@ private slots:
#if QT_CONFIG(webengine_system_poppler)
void printToPdfPoppler();
#endif
+ void interruptPrinting();
};
void tst_Printing::printToPdfBasic()
@@ -117,6 +118,19 @@ void tst_Printing::printToPdfPoppler()
}
#endif
+void tst_Printing::interruptPrinting()
+{
+ QWebEngineView view;
+ QSignalSpy spy(&view, &QWebEngineView::loadFinished);
+ view.load(QUrl("qrc:///resources/basic_printing_page.html"));
+ QTRY_VERIFY(spy.size() == 1);
+
+ QTemporaryDir tempDir(QDir::tempPath() + "/tst_qwebengineview-XXXXXX");
+ QVERIFY(tempDir.isValid());
+ view.page()->printToPdf(tempDir.path() + "/file.pdf");
+ // Navigation stop interrupts print job, preferably do this without crash/assert
+ view.page()->triggerAction(QWebEnginePage::Stop);
+}
QTEST_MAIN(tst_Printing)
#include "tst_printing.moc"