From b6fda272f56b147664970581fa84e68cbb736681 Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Mon, 27 May 2024 17:08:34 +0200
Subject: [PATCH 001/356] Add QWebEngineFrame::printToPdf

Provide API calls to (1) save to file (QString) and (2) get the bytes
in a callback.

Change-Id: I0ff44a25328b99080491b8c3b36a7b632c065131
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit ece3b065828bc6ca09dd2ad8654b48cdaddf1178)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebengineframe.cpp              |  63 ++++++++++
 src/core/api/qwebengineframe.h                |   4 +
 src/core/api/qwebenginepage.cpp               |  16 +--
 src/core/api/qwebenginepage_p.h               |   6 +-
 src/core/printing/print_view_manager_qt.cpp   |  41 +++---
 src/core/printing/print_view_manager_qt.h     |  15 +--
 src/core/web_contents_adapter.cpp             |  15 ++-
 src/core/web_contents_adapter.h               |   6 +-
 src/core/web_contents_adapter_client.h        |   5 +-
 .../api/qquickwebengineview.cpp               |  14 ++-
 .../api/qquickwebengineview_p_p.h             |   6 +-
 .../doc/src/webengineframe.qdoc               |  24 ++++
 src/webenginewidgets/api/qwebengineview.cpp   |   3 +-
 .../auto/core/qwebengineframe/CMakeLists.txt  |   2 +
 .../resources/printing-inner-document.html    |   7 ++
 .../resources/printing-outer-document.html    |   8 ++
 .../qwebengineframe/tst_qwebengineframe.cpp   | 119 ++++++++++++++++++
 tests/auto/quick/publicapi/tst_publicapi.cpp  |   2 +
 18 files changed, 299 insertions(+), 57 deletions(-)
 create mode 100644 tests/auto/core/qwebengineframe/resources/printing-inner-document.html
 create mode 100644 tests/auto/core/qwebengineframe/resources/printing-outer-document.html

diff --git a/src/core/api/qwebengineframe.cpp b/src/core/api/qwebengineframe.cpp
index 1eedc4b9254..52fd5e60273 100644
--- a/src/core/api/qwebengineframe.cpp
+++ b/src/core/api/qwebengineframe.cpp
@@ -5,6 +5,8 @@
 
 #include "qwebenginescript.h"
 #include <QtQml/qqmlengine.h>
+#include <QtGui/qpagelayout.h>
+#include <QtGui/qpageranges.h>
 
 #include "web_contents_adapter_client.h"
 #include "web_contents_adapter.h"
@@ -175,6 +177,67 @@ void QWebEngineFrame::runJavaScript(const QString &script, quint32 worldId,
     runJavaScript(script, worldId, wrappedCallback);
 }
 
+/*!
+    Renders the current content of the frame into a PDF document and saves it in the location
+    specified in \a filePath. Printing uses a page size of A4, portrait layout, and includes the
+    full range of pages.
+
+    This method issues an asynchronous request for printing the web page into a PDF and returns
+    immediately. To be informed about the result of the request, connect to the \l
+    QWebEnginePage::pdfPrintingFinished() signal.
+
+    \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 QWebEnginePage::pdfPrintingFinished()
+ */
+void QWebEngineFrame::printToPdf(const QString &filePath)
+{
+    QPageLayout layout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF());
+    m_adapterClient->printToPdf(filePath, layout, QPageRanges(), m_id);
+}
+
+/*!
+    Renders the current content of the frame into a PDF document and returns a byte array containing
+    the PDF data as parameter to \a callback. Printing uses a page size of A4, portrait layout, and
+    includes the full range of pages.
+
+    The \a callback 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.
+*/
+void QWebEngineFrame::printToPdf(const std::function<void(const QByteArray &)> &callback)
+{
+    std::function wrappedCallback = [callback](QSharedPointer<QByteArray> result) {
+        if (callback)
+            callback(result ? *result : QByteArray());
+    };
+    QPageLayout layout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF());
+    m_adapterClient->printToPdf(std::move(wrappedCallback), layout, QPageRanges(), m_id);
+}
+
+void QWebEngineFrame::printToPdf(const QJSValue &callback)
+{
+    std::function<void(QSharedPointer<QByteArray>)> wrappedCallback;
+    if (!callback.isUndefined()) {
+        const QObject *holdingObject = m_adapterClient->holdingQObject();
+        wrappedCallback = [holdingObject, callback](QSharedPointer<QByteArray> result) {
+            if (auto engine = qmlEngine(holdingObject)) {
+                QJSValueList args;
+                args.append(engine->toScriptValue(result ? *result : QByteArray()));
+                callback.call(args);
+            } else {
+                qWarning("No QML engine found to execute runJavaScript() callback");
+            }
+        };
+    }
+    QPageLayout layout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF());
+    m_adapterClient->printToPdf(std::move(wrappedCallback), layout, QPageRanges(), m_id);
+}
+
 /*! \fn bool QWebEngineFrame::operator==(const QWebEngineFrame &left, const QWebEngineFrame &right) noexcept
 
     Returns \c{true} if \a left and \a right represent the same frame in the same web page,
diff --git a/src/core/api/qwebengineframe.h b/src/core/api/qwebengineframe.h
index 3042fbae074..34b72e08ea1 100644
--- a/src/core/api/qwebengineframe.h
+++ b/src/core/api/qwebengineframe.h
@@ -49,6 +49,10 @@ class Q_WEBENGINECORE_EXPORT QWebEngineFrame
     Q_INVOKABLE void runJavaScript(const QString &script, quint32 worldId,
                                    const QJSValue &callback);
 
+    Q_INVOKABLE void printToPdf(const QString &filePath);
+    void printToPdf(const std::function<void(const QByteArray &)> &callback);
+    Q_INVOKABLE void printToPdf(const QJSValue &callback);
+
     friend inline bool comparesEqual(const QWebEngineFrame &lhs,
                                      const QWebEngineFrame &rhs) noexcept
     {
diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp
index 7c6a53d0f08..d7ab7030598 100644
--- a/src/core/api/qwebenginepage.cpp
+++ b/src/core/api/qwebenginepage.cpp
@@ -275,15 +275,17 @@ void QWebEnginePagePrivate::loadFinished(QWebEngineLoadingInfo info)
 }
 
 void QWebEnginePagePrivate::printToPdf(const QString &filePath, const QPageLayout &layout,
-                                       const QPageRanges &ranges)
+                                       const QPageRanges &ranges, quint64 frameId)
 {
-    adapter->printToPDF(layout, ranges, filePath);
+    adapter->printToPDF(layout, ranges, filePath, frameId);
 }
 
 void QWebEnginePagePrivate::printToPdf(std::function<void(QSharedPointer<QByteArray>)> &&callback,
-                                       const QPageLayout &layout, const QPageRanges &ranges)
+                                       const QPageLayout &layout, const QPageRanges &ranges,
+                                       quint64 frameId)
 {
-    adapter->printToPDFCallbackResult(std::move(callback), layout, ranges);
+    adapter->printToPDFCallbackResult(std::move(callback), layout, ranges, /*colorMode*/ true,
+                                      /*useCustomMargins*/ true, frameId);
 }
 
 void QWebEnginePagePrivate::didPrintPageToPdf(const QString &filePath, bool success)
@@ -1692,7 +1694,7 @@ void QWebEnginePagePrivate::printRequested()
     This signal is emitted when the JavaScript \c{window.print()} method is called on \a frame.
     If the frame is the main frame, \c{printRequested} is emitted instead.
 
-    \sa printRequested(), printToPdf()
+    \sa printRequested(), printToPdf(), QWebEngineFrame::printToPdf()
 */
 
 void QWebEnginePagePrivate::printRequestedByFrame(quint64 frameId)
@@ -2330,7 +2332,7 @@ void QWebEnginePage::printToPdf(const QString &filePath, const QPageLayout &layo
 #if QT_CONFIG(webengine_printing_and_pdf)
     Q_D(QWebEnginePage);
     d->ensureInitialized();
-    d->printToPdf(filePath, layout, ranges);
+    d->printToPdf(filePath, layout, ranges, WebContentsAdapter::kUseMainFrameId);
 #else
     Q_UNUSED(filePath);
     Q_UNUSED(layout);
@@ -2362,7 +2364,7 @@ void QWebEnginePage::printToPdf(const std::function<void(const QByteArray&)> &re
         if (resultCallback && result)
             resultCallback(*result);
     };
-    d->printToPdf(std::move(wrappedCallback), layout, ranges);
+    d->printToPdf(std::move(wrappedCallback), layout, ranges, WebContentsAdapter::kUseMainFrameId);
 #else
     Q_UNUSED(layout);
     Q_UNUSED(ranges);
diff --git a/src/core/api/qwebenginepage_p.h b/src/core/api/qwebenginepage_p.h
index 3aeda6711a1..6f536f3a622 100644
--- a/src/core/api/qwebenginepage_p.h
+++ b/src/core/api/qwebenginepage_p.h
@@ -136,10 +136,10 @@ class Q_WEBENGINECORE_EXPORT QWebEnginePagePrivate : public QtWebEngineCore::Web
                        const std::function<void(const QVariant &)> &callback) override;
     void didFetchDocumentMarkup(quint64 requestId, const QString &result) override;
     void didFetchDocumentInnerText(quint64 requestId, const QString &result) override;
-    void printToPdf(const QString &filePath, const QPageLayout &layout,
-                    const QPageRanges &ranges) override;
+    void printToPdf(const QString &filePath, const QPageLayout &layout, const QPageRanges &ranges,
+                    quint64 frameId) override;
     void printToPdf(std::function<void(QSharedPointer<QByteArray>)> &&callback,
-                    const QPageLayout &layout, const QPageRanges &ranges) override;
+                    const QPageLayout &layout, const QPageRanges &ranges, quint64 frameId) override;
     void didPrintPageToPdf(const QString &filePath, bool success) override;
     bool passOnFocus(bool reverse) override;
     void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message,
diff --git a/src/core/printing/print_view_manager_qt.cpp b/src/core/printing/print_view_manager_qt.cpp
index db9dc8743d1..42bade52bdd 100644
--- a/src/core/printing/print_view_manager_qt.cpp
+++ b/src/core/printing/print_view_manager_qt.cpp
@@ -11,6 +11,7 @@
 #include "pdf_util_qt.h"
 #include "type_conversion.h"
 #include "web_contents_adapter_client.h"
+#include "web_contents_adapter.h"
 #include "web_contents_view_qt.h"
 #include "web_engine_context.h"
 
@@ -173,8 +174,8 @@ PrintViewManagerQt::~PrintViewManagerQt()
 
 void PrintViewManagerQt::PrintToPDFFileWithCallback(const QPageLayout &pageLayout,
                                                     const QPageRanges &pageRanges,
-                                                    bool printInColor,
-                                                    const QString &filePath,
+                                                    bool printInColor, const QString &filePath,
+                                                    quint64 frameId,
                                                     PrintToPDFFileCallback callback)
 {
     if (callback.is_null())
@@ -188,7 +189,8 @@ void PrintViewManagerQt::PrintToPDFFileWithCallback(const QPageLayout &pageLayou
 
     m_pdfOutputPath = toFilePath(filePath);
     m_pdfSaveCallback = std::move(callback);
-    if (!PrintToPDFInternal(pageLayout, pageRanges, printInColor)) {
+    if (!PrintToPDFInternal(pageLayout, pageRanges, printInColor, /*useCustomMargins*/ true,
+                            frameId)) {
         content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
                        base::BindOnce(std::move(m_pdfSaveCallback), false));
         resetPdfState();
@@ -196,9 +198,8 @@ void PrintViewManagerQt::PrintToPDFFileWithCallback(const QPageLayout &pageLayou
 }
 
 void PrintViewManagerQt::PrintToPDFWithCallback(const QPageLayout &pageLayout,
-                                                const QPageRanges &pageRanges,
-                                                bool printInColor,
-                                                bool useCustomMargins,
+                                                const QPageRanges &pageRanges, bool printInColor,
+                                                bool useCustomMargins, quint64 frameId,
                                                 PrintToPDFCallback callback)
 {
     if (callback.is_null())
@@ -212,7 +213,7 @@ void PrintViewManagerQt::PrintToPDFWithCallback(const QPageLayout &pageLayout,
     }
 
     m_pdfPrintCallback = std::move(callback);
-    if (!PrintToPDFInternal(pageLayout, pageRanges, printInColor, useCustomMargins)) {
+    if (!PrintToPDFInternal(pageLayout, pageRanges, printInColor, useCustomMargins, frameId)) {
         content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
                        base::BindOnce(std::move(m_pdfPrintCallback), QSharedPointer<QByteArray>()));
 
@@ -221,9 +222,8 @@ void PrintViewManagerQt::PrintToPDFWithCallback(const QPageLayout &pageLayout,
 }
 
 bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout,
-                                            const QPageRanges &pageRanges,
-                                            const bool printInColor,
-                                            const bool useCustomMargins)
+                                            const QPageRanges &pageRanges, const bool printInColor,
+                                            const bool useCustomMargins, quint64 frameId)
 {
     if (!pageLayout.isValid())
         return false;
@@ -239,11 +239,22 @@ bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout,
     if (web_contents()->IsCrashed())
         return false;
 
-    content::RenderFrameHost *rfh = web_contents()->GetPrimaryMainFrame();
-    // Use the plugin frame for printing if web_contents() is a PDF viewer guest
-    content::RenderFrameHost *full_page_plugin = GetFullPagePlugin(web_contents());
-    if (content::RenderFrameHost *pdf_rfh = FindPdfChildFrame(full_page_plugin ? full_page_plugin : rfh))
-        rfh = pdf_rfh;
+    content::RenderFrameHost *rfh = nullptr;
+    if (frameId == WebContentsAdapter::kInvalidFrameId) {
+        return false;
+    } else if (frameId == WebContentsAdapter::kUseMainFrameId) {
+        rfh = web_contents()->GetPrimaryMainFrame();
+        // Use the plugin frame for printing if web_contents() is a PDF viewer guest
+        content::RenderFrameHost *full_page_plugin = GetFullPagePlugin(web_contents());
+        if (content::RenderFrameHost *pdf_rfh =
+                    FindPdfChildFrame(full_page_plugin ? full_page_plugin : rfh))
+            rfh = pdf_rfh;
+    } else {
+        auto *ftn = content::FrameTreeNode::GloballyFindByID(static_cast<int>(frameId));
+        if (!ftn)
+            return false;
+        rfh = ftn->current_frame_host();
+    }
     GetPrintRenderFrame(rfh)->InitiatePrintPreview(false);
 
     DCHECK(!m_printPreviewRfh);
diff --git a/src/core/printing/print_view_manager_qt.h b/src/core/printing/print_view_manager_qt.h
index 956849ef9ee..879a89ef000 100644
--- a/src/core/printing/print_view_manager_qt.h
+++ b/src/core/printing/print_view_manager_qt.h
@@ -41,21 +41,18 @@ class PrintViewManagerQt
     typedef base::OnceCallback<void(bool success)> PrintToPDFFileCallback;
 
     // Method to print a page to a Pdf document with page size \a pageSize in location \a filePath.
-    void PrintToPDFFileWithCallback(const QPageLayout &pageLayout,
-                                    const QPageRanges &pageRanges,
-                                    bool printInColor,
-                                    const QString &filePath,
+    void PrintToPDFFileWithCallback(const QPageLayout &pageLayout, const QPageRanges &pageRanges,
+                                    bool printInColor, const QString &filePath, quint64 frameId,
                                     PrintToPDFFileCallback callback);
-    void PrintToPDFWithCallback(const QPageLayout &pageLayout,
-                                const QPageRanges &pageRanges,
-                                bool printInColor,
-                                bool useCustomMargins,
+    void PrintToPDFWithCallback(const QPageLayout &pageLayout, const QPageRanges &pageRanges,
+                                bool printInColor, bool useCustomMargins, quint64 frameId,
                                 PrintToPDFCallback callback);
 
 protected:
     explicit PrintViewManagerQt(content::WebContents*);
 
-    bool PrintToPDFInternal(const QPageLayout &, const QPageRanges &, bool printInColor, bool useCustomMargins = true);
+    bool PrintToPDFInternal(const QPageLayout &, const QPageRanges &, bool printInColor,
+                            bool useCustomMargins, quint64 frameId);
 
     // content::WebContentsObserver implementation.
     // Cancels the print job.
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 4b21838a034..4774cf4dcc1 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -1346,7 +1346,8 @@ void WebContentsAdapter::wasHidden()
     m_webContents->WasHidden();
 }
 
-void WebContentsAdapter::printToPDF(const QPageLayout &pageLayout, const QPageRanges &pageRanges, const QString &filePath)
+void WebContentsAdapter::printToPDF(const QPageLayout &pageLayout, const QPageRanges &pageRanges,
+                                    const QString &filePath, quint64 frameId)
 {
 #if QT_CONFIG(webengine_printing_and_pdf)
     CHECK_INITIALIZED();
@@ -1356,17 +1357,15 @@ void WebContentsAdapter::printToPDF(const QPageLayout &pageLayout, const QPageRa
     content::WebContents *webContents = m_webContents.get();
     if (content::WebContents *guest = guestWebContents())
         webContents = guest;
-    PrintViewManagerQt::FromWebContents(webContents)->PrintToPDFFileWithCallback(pageLayout,
-                                                                                         pageRanges,
-                                                                                         true,
-                                                                                         filePath,
-                                                                                         std::move(callback));
+    PrintViewManagerQt::FromWebContents(webContents)
+            ->PrintToPDFFileWithCallback(pageLayout, pageRanges, true, filePath, frameId,
+                                         std::move(callback));
 #endif // QT_CONFIG(webengine_printing_and_pdf)
 }
 
 void WebContentsAdapter::printToPDFCallbackResult(
         std::function<void(QSharedPointer<QByteArray>)> &&callback, const QPageLayout &pageLayout,
-        const QPageRanges &pageRanges, bool colorMode, bool useCustomMargins)
+        const QPageRanges &pageRanges, bool colorMode, bool useCustomMargins, quint64 frameId)
 {
 #if QT_CONFIG(webengine_printing_and_pdf)
     CHECK_INITIALIZED();
@@ -1377,7 +1376,7 @@ void WebContentsAdapter::printToPDFCallbackResult(
     if (content::WebContents *guest = guestWebContents())
         webContents = guest;
     PrintViewManagerQt::FromWebContents(webContents)
-            ->PrintToPDFWithCallback(pageLayout, pageRanges, colorMode, useCustomMargins,
+            ->PrintToPDFWithCallback(pageLayout, pageRanges, colorMode, useCustomMargins, frameId,
                                      std::move(internalCallback));
     m_printCallbacks.emplace(m_nextRequestId++, std::move(callback));
 #else
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 9663c77eda7..61da0ba7bbe 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -206,10 +206,10 @@ class Q_WEBENGINECORE_EXPORT WebContentsAdapter : public QEnableSharedFromThis<W
     void endDragging(QDropEvent *e, const QPointF &screenPos);
     void leaveDrag();
 #endif // QT_CONFIG(draganddrop)
-    void printToPDF(const QPageLayout&, const QPageRanges &, const QString&);
+    void printToPDF(const QPageLayout &, const QPageRanges &, const QString &, quint64 frameId);
     void printToPDFCallbackResult(std::function<void(QSharedPointer<QByteArray>)> &&,
-                                  const QPageLayout &, const QPageRanges &, bool colorMode = true,
-                                  bool useCustomMargins = true);
+                                  const QPageLayout &, const QPageRanges &, bool colorMode,
+                                  bool useCustomMargins, quint64 frameId);
     void didPrintPage(quint64 requestId, QSharedPointer<QByteArray> result);
 
     void replaceMisspelling(const QString &word);
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 3c50ac84011..6cb07a32bc3 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -183,9 +183,10 @@ class Q_WEBENGINECORE_EXPORT WebContentsAdapterClient {
     virtual void didFetchDocumentMarkup(quint64 requestId, const QString& result) = 0;
     virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) = 0;
     virtual void printToPdf(const QString &filePath, const QPageLayout &layout,
-                            const QPageRanges &ranges) = 0;
+                            const QPageRanges &ranges, quint64 frameId) = 0;
     virtual void printToPdf(std::function<void(QSharedPointer<QByteArray>)> &&callback,
-                            const QPageLayout &layout, const QPageRanges &ranges) = 0;
+                            const QPageLayout &layout, const QPageRanges &ranges,
+                            quint64 frameId) = 0;
     virtual void didPrintPageToPdf(const QString &filePath, bool success) = 0;
     virtual bool passOnFocus(bool reverse) = 0;
     // returns the last QObject (QWidget/QQuickItem) based object in the accessibility
diff --git a/src/webenginequick/api/qquickwebengineview.cpp b/src/webenginequick/api/qquickwebengineview.cpp
index f6bd3878044..0ff182c7a3e 100644
--- a/src/webenginequick/api/qquickwebengineview.cpp
+++ b/src/webenginequick/api/qquickwebengineview.cpp
@@ -1318,16 +1318,17 @@ void QQuickWebEngineViewPrivate::runJavaScript(
 }
 
 void QQuickWebEngineViewPrivate::printToPdf(const QString &filePath, const QPageLayout &layout,
-                                            const QPageRanges &ranges)
+                                            const QPageRanges &ranges, quint64 frameId)
 {
-    adapter->printToPDF(layout, ranges, filePath);
+    adapter->printToPDF(layout, ranges, filePath, frameId);
 }
 
 void QQuickWebEngineViewPrivate::printToPdf(
         std::function<void(QSharedPointer<QByteArray>)> &&callback, const QPageLayout &layout,
-        const QPageRanges &ranges)
+        const QPageRanges &ranges, quint64 frameId)
 {
-    adapter->printToPDFCallbackResult(std::move(callback), layout, ranges);
+    adapter->printToPDFCallbackResult(std::move(callback), layout, ranges, /*colorMode*/ true,
+                                      /*useCustomMargins*/ true, frameId);
 }
 
 void QQuickWebEngineViewPrivate::didPrintPageToPdf(const QString &filePath, bool success)
@@ -1586,7 +1587,7 @@ void QQuickWebEngineView::printToPdf(const QString& filePath, PrintedPageSizeId
     QPageLayout pageLayout(layoutSize, layoutOrientation, QMarginsF(0.0, 0.0, 0.0, 0.0));
     QPageRanges ranges;
     d->ensureContentsAdapter();
-    d->adapter->printToPDF(pageLayout, ranges, filePath);
+    d->printToPdf(filePath, pageLayout, ranges, WebContentsAdapter::kUseMainFrameId);
 #else
     Q_UNUSED(filePath);
     Q_UNUSED(pageSizeId);
@@ -1613,7 +1614,8 @@ void QQuickWebEngineView::printToPdf(const QJSValue &callback, PrintedPageSizeId
         callback.call(args);
     };
 
-    d->printToPdf(std::move(wrappedCallback), pageLayout, ranges);
+    d->printToPdf(std::move(wrappedCallback), pageLayout, ranges,
+                  WebContentsAdapter::kUseMainFrameId);
 #else
     Q_UNUSED(pageSizeId);
     Q_UNUSED(orientation);
diff --git a/src/webenginequick/api/qquickwebengineview_p_p.h b/src/webenginequick/api/qquickwebengineview_p_p.h
index 5a968aaa44a..988a2f0b148 100644
--- a/src/webenginequick/api/qquickwebengineview_p_p.h
+++ b/src/webenginequick/api/qquickwebengineview_p_p.h
@@ -97,10 +97,10 @@ class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineViewPrivate : public QtWebEngineCor
                        const std::function<void(const QVariant &)> &callback) override;
     void didFetchDocumentMarkup(quint64, const QString&) override { }
     void didFetchDocumentInnerText(quint64, const QString&) override { }
-    void printToPdf(const QString &filePath, const QPageLayout &layout,
-                    const QPageRanges &ranges) override;
+    void printToPdf(const QString &filePath, const QPageLayout &layout, const QPageRanges &ranges,
+                    quint64 frameId) override;
     void printToPdf(std::function<void(QSharedPointer<QByteArray>)> &&callback,
-                    const QPageLayout &layout, const QPageRanges &ranges) override;
+                    const QPageLayout &layout, const QPageRanges &ranges, quint64 frameId) override;
     void didPrintPageToPdf(const QString &filePath, bool success) override;
     bool passOnFocus(bool reverse) override;
     void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) override;
diff --git a/src/webenginequick/doc/src/webengineframe.qdoc b/src/webenginequick/doc/src/webengineframe.qdoc
index a2368479a2f..7df4a1d2bfd 100644
--- a/src/webenginequick/doc/src/webengineframe.qdoc
+++ b/src/webenginequick/doc/src/webengineframe.qdoc
@@ -97,3 +97,27 @@
     For more information about injecting scripts, see \l {Script Injection}.
     For an alternative way to inject scripts, see WebEngineView::userScripts.
 */
+
+/*!
+    \qmlmethod void webEngineFrame::printToPdf(string filePath)
+
+    Prints the frame's current content to a PDF document and stores it
+    under \a filePath. The resulting document will have A4 page size and
+    portrait orientation.
+
+    This method issues an asynchronous request for printing the web page into a
+    PDF and returns immediately. To be informed about the result of the
+    request, connect to the signal \l WebEngineView::pdfPrintingFinished().
+
+    \sa WebEngineView::pdfPrintingFinished()
+*/
+
+/*!
+    \qmlmethod void webEngineFrame::printToPdf(variant callback)
+
+    Prints the frame's current content to a PDF document and returns it in a byte array. The
+    resulting document will have A4 page size and portrait orientation.
+
+    The \a callback must take a string parameter. This string will contain the document's data upon
+    successful printing and an empty string otherwise.
+*/
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index e72ad8fa96f..ebb818cbd71 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -1500,7 +1500,8 @@ void QWebEngineView::print(QPrinter *printer)
     };
     dPage->adapter->printToPDFCallbackResult(std::move(callback), printer->pageLayout(),
                                              printer->pageRanges(),
-                                             printer->colorMode() == QPrinter::Color, false);
+                                             printer->colorMode() == QPrinter::Color, false,
+                                             QtWebEngineCore::WebContentsAdapter::kUseMainFrameId);
 #else
     Q_UNUSED(printer);
     Q_EMIT printFinished(false);
diff --git a/tests/auto/core/qwebengineframe/CMakeLists.txt b/tests/auto/core/qwebengineframe/CMakeLists.txt
index d02b4307d2c..7d73e5a4aac 100644
--- a/tests/auto/core/qwebengineframe/CMakeLists.txt
+++ b/tests/auto/core/qwebengineframe/CMakeLists.txt
@@ -19,4 +19,6 @@ qt_internal_add_resource(tst_qwebengineframe "tst_qwebengineframe"
         "resources/frameset.html"
         "resources/iframes.html"
         "resources/nesting-iframe.html"
+        "resources/printing-inner-document.html"
+        "resources/printing-outer-document.html"
 )
diff --git a/tests/auto/core/qwebengineframe/resources/printing-inner-document.html b/tests/auto/core/qwebengineframe/resources/printing-inner-document.html
new file mode 100644
index 00000000000..2e5a53af5e0
--- /dev/null
+++ b/tests/auto/core/qwebengineframe/resources/printing-inner-document.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<html>
+    <head><title>Printing Inner Document</title></head>
+    <body>
+        <h1>Inner Header</h1>
+    </body>
+</html>
diff --git a/tests/auto/core/qwebengineframe/resources/printing-outer-document.html b/tests/auto/core/qwebengineframe/resources/printing-outer-document.html
new file mode 100644
index 00000000000..c5947371e2d
--- /dev/null
+++ b/tests/auto/core/qwebengineframe/resources/printing-outer-document.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<html>
+    <head><title>Printing Outer Document</title></head>
+    <body>
+        <h1>Outer Header</h1>
+        <iframe name="inner" src="printing-inner-document.html"></iframe>
+    </body>
+</html>
diff --git a/tests/auto/core/qwebengineframe/tst_qwebengineframe.cpp b/tests/auto/core/qwebengineframe/tst_qwebengineframe.cpp
index ce0b61ee27b..2fe0e27a265 100644
--- a/tests/auto/core/qwebengineframe/tst_qwebengineframe.cpp
+++ b/tests/auto/core/qwebengineframe/tst_qwebengineframe.cpp
@@ -39,6 +39,9 @@ private Q_SLOTS:
     void size();
     void runJavaScript();
     void printRequestedByFrame();
+    void printToPdfFile();
+    void printToPdfFileFailures();
+    void printToPdfFunction();
 
 private:
 };
@@ -208,6 +211,122 @@ void tst_QWebEngineFrame::printRequestedByFrame()
     QCOMPARE(*framePtr, *oFrame2);
 }
 
+void tst_QWebEngineFrame::printToPdfFile()
+{
+    QTemporaryDir tempDir(QDir::tempPath() + "/tst_qwebengineframe-XXXXXX");
+    QVERIFY(tempDir.isValid());
+
+    QWebEnginePage page;
+    QSignalSpy loadSpy{ &page, SIGNAL(loadFinished(bool)) };
+    page.load(QUrl("qrc:/resources/printing-outer-document.html"));
+    QTRY_COMPARE(loadSpy.size(), 1);
+
+    auto outerFrame = page.mainFrame();
+    auto maybeInnerFrame = page.findFrameByName("inner");
+    QVERIFY(maybeInnerFrame);
+    auto innerFrame = *maybeInnerFrame;
+
+    QSignalSpy savePdfSpy{ &page, SIGNAL(pdfPrintingFinished(QString, bool)) };
+
+    QString outerPath = tempDir.path() + "/outer.pdf";
+    outerFrame.printToPdf(outerPath);
+    QTRY_COMPARE(savePdfSpy.size(), 1);
+
+    QList<QVariant> outerArgs = savePdfSpy.takeFirst();
+    QCOMPARE(outerArgs.at(0).toString(), outerPath);
+    QVERIFY(outerArgs.at(1).toBool());
+
+    QString innerPath = tempDir.path() + "/inner.pdf";
+    innerFrame.printToPdf(innerPath);
+    QTRY_COMPARE(savePdfSpy.size(), 1);
+
+    QList<QVariant> innerArgs = savePdfSpy.takeFirst();
+    QCOMPARE(innerArgs.at(0).toString(), innerPath);
+    QVERIFY(innerArgs.at(1).toBool());
+
+    // The outer document encompasses more elements so its PDF should be larger. This is a
+    // roundabout way to check that we aren't just printing the same document twice.
+    auto outerSize = QFileInfo(outerPath).size();
+    auto innerSize = QFileInfo(innerPath).size();
+    QCOMPARE_GT(outerSize, innerSize);
+    QCOMPARE_GT(innerSize, 0);
+}
+
+void tst_QWebEngineFrame::printToPdfFileFailures()
+{
+    QTemporaryDir tempDir(QDir::tempPath() + "/tst_qwebengineframe-XXXXXX");
+    QVERIFY(tempDir.isValid());
+
+    QWebEnginePage page;
+    QSignalSpy loadSpy{ &page, SIGNAL(loadFinished(bool)) };
+    page.load(QUrl("qrc:/resources/printing-outer-document.html"));
+    QTRY_COMPARE(loadSpy.size(), 1);
+
+    auto maybeInnerFrame = page.findFrameByName("inner");
+    QVERIFY(maybeInnerFrame);
+    auto innerFrame = *maybeInnerFrame;
+
+    QSignalSpy savePdfSpy{ &page, SIGNAL(pdfPrintingFinished(QString, bool)) };
+
+#if !defined(Q_OS_WIN)
+    auto badPath = tempDir.path() + "/print_//2_failed.pdf";
+#else
+    auto badPath = tempDir.path() + "/print_|2_failed.pdf";
+#endif
+    innerFrame.printToPdf(badPath);
+    QTRY_COMPARE(savePdfSpy.size(), 1);
+
+    QList<QVariant> badPathArgs = savePdfSpy.takeFirst();
+    QCOMPARE(badPathArgs.at(0).toString(), badPath);
+    QVERIFY(!badPathArgs.at(1).toBool());
+
+    page.triggerAction(QWebEnginePage::WebAction::Reload);
+    QTRY_COMPARE(loadSpy.size(), 2);
+
+    QVERIFY(!innerFrame.isValid());
+    QString invalidFramePath = tempDir.path() + "/invalidFrame.pdf";
+    innerFrame.printToPdf(invalidFramePath);
+    QTRY_COMPARE(savePdfSpy.size(), 1);
+
+    QList<QVariant> invalidFrameArgs = savePdfSpy.takeFirst();
+    QCOMPARE(invalidFrameArgs.at(0).toString(), invalidFramePath);
+    QVERIFY(!invalidFrameArgs.at(1).toBool());
+}
+
+void tst_QWebEngineFrame::printToPdfFunction()
+{
+    QWebEnginePage page;
+    QSignalSpy loadSpy{ &page, SIGNAL(loadFinished(bool)) };
+    page.load(QUrl("qrc:/resources/printing-outer-document.html"));
+    QTRY_COMPARE(loadSpy.size(), 1);
+
+    auto outerFrame = page.mainFrame();
+    auto maybeInnerFrame = page.findFrameByName("inner");
+    QVERIFY(maybeInnerFrame);
+    auto innerFrame = *maybeInnerFrame;
+
+    CallbackSpy<QByteArray> outerSpy;
+    outerFrame.printToPdf(outerSpy.ref());
+    auto outerPdfData = outerSpy.waitForResult();
+    QCOMPARE_GT(outerPdfData.size(), 0);
+
+    CallbackSpy<QByteArray> innerSpy;
+    innerFrame.printToPdf(innerSpy.ref());
+    auto innerPdfData = innerSpy.waitForResult();
+    QCOMPARE_GT(innerPdfData.size(), 0);
+    QCOMPARE_GT(outerPdfData.size(), innerPdfData.size());
+
+    page.triggerAction(QWebEnginePage::WebAction::Reload);
+    QTRY_COMPARE(loadSpy.size(), 2);
+    QVERIFY(!innerFrame.isValid());
+
+    CallbackSpy<QByteArray> invalidSpy;
+    innerFrame.printToPdf(invalidSpy.ref());
+    auto invalidPdfData = invalidSpy.waitForResult();
+    QVERIFY(invalidSpy.wasCalled());
+    QCOMPARE(invalidPdfData.size(), 0);
+}
+
 QTEST_MAIN(tst_QWebEngineFrame)
 
 #include "tst_qwebengineframe.moc"
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index c95c45bb4ef..c4d889cbe8b 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -894,6 +894,8 @@ static const QStringList expectedAPI = QStringList()
     << "QWebEngineFrame.htmlName --> QString"
     << "QWebEngineFrame.isValid --> bool"
     << "QWebEngineFrame.name --> QString"
+    << "QWebEngineFrame.printToPdf(QJSValue) --> void"
+    << "QWebEngineFrame.printToPdf(QString) --> void"
     << "QWebEngineFrame.runJavaScript(QString) --> void"
     << "QWebEngineFrame.runJavaScript(QString,uint) --> void"
     << "QWebEngineFrame.runJavaScript(QString,QJSValue) --> void"

From c4acd649a825a0e3332143a90bba744ecc900db2 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Mon, 3 Jun 2024 14:13:44 +0000
Subject: [PATCH 002/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Ic4f09b4f1810a533476bdce49524d210c1115675
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index f6db2abacf1..37198aaddc8 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 4ad3d0c6096e6caefec74681eed86c2fa92149fd
+    ref: b241e3f8bc951dfbac152bbf58532170ed910756
     required: true
   ../qtpositioning:
-    ref: 413ede61f32da23c446654a98f285ce06ef035c8
+    ref: edda8a2bba1e447ba08f977f8156d45f19cb0b72
     required: false
   ../qttools:
-    ref: 49438275bdf6b08ba46e2ea2d89753f1f9c63d76
+    ref: f7d623d562d55b75eef0a43e1045a5da8d7609fc
     required: false
   ../qtwebchannel:
-    ref: 9f1ca1c6bdde6adedeb215e487ebdb05a17ad2d0
+    ref: 779185f6fa8e33bc183332c7e89b908904dea591
     required: false

From 3df5f39db2b5aff9494108dad96c6e9a744882d4 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Tue, 2 Apr 2024 16:08:15 +0200
Subject: [PATCH 003/356] Add QWebEnginePermission and rewrite permissions API

With the addition of permission persistence, it's now important for us
to have an API for querying previously granted/denied permissions, so
that they can be revoked at a later point. This change does the bulk
of the work to get us there, by introducing a new type representing
a single permission for a given URL/Feature pair.

This type holds no information about the permission's state; it is
simply an accessor object which allows its user to query the current
status of the permission, grant/deny it, or reset it back to its
initial state (so, delete it from storage). This provides application
developers an easy way to store/modify lists of permissions without
having to define their own custom types. A subsequent change will expand
the API to provide a list of all permissions for a given profile.

The current API (in QWebEnginePage and QQuickWebEngineView) has been
marked as deprecated, but has not been disabled to ensure a smooth
transition for developers.

[ChangeLog][QtWebEngineCore][QWebEnginePage] Deprecated old
permissions API
[ChangeLog][QtWebEngineQuick][WebEngineView] Deprecated old
permissions API
[ChangeLog][QtWebEngineCore] Added new API for querying and modifying
website permissions.
[ChangeLog][QtWebEngineQuick] Added new API for querying and modifying
website permissions.

Change-Id: I8661cdc26bbd6dcde6403d29cc083bcea1a49ccc
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 00d7de830a43a84a431511a55525f04c21b8ba49)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 .../quicknanobrowser/BrowserWindow.qml        |  44 ++-
 .../doc/src/quicknanobrowser.qdoc             |  21 +-
 .../webenginewidgets/maps/doc/src/maps.qdoc   |  11 +-
 examples/webenginewidgets/maps/mainwindow.cpp |  21 +-
 .../notifications/doc/src/notifications.qdoc  |   4 +-
 .../webenginewidgets/notifications/main.cpp   |   9 +-
 .../push-notifications/main.cpp               |   9 +-
 .../simplebrowser/webview.cpp                 |  39 +--
 .../webenginewidgets/simplebrowser/webview.h  |   4 +-
 src/core/api/CMakeLists.txt                   |   1 +
 src/core/api/qwebenginepage.cpp               | 260 ++++++++-------
 src/core/api/qwebenginepage.h                 |  38 ++-
 src/core/api/qwebenginepage_p.h               |   3 +-
 src/core/api/qwebenginepermission.cpp         | 307 ++++++++++++++++++
 src/core/api/qwebenginepermission.h           |  90 +++++
 src/core/api/qwebenginepermission_p.h         |  46 +++
 src/core/doc/src/qwebenginepage_lgpl.qdoc     |  15 +
 src/core/permission_manager_qt.cpp            | 177 ++++++----
 src/core/permission_manager_qt.h              |  10 +-
 src/core/profile_adapter.cpp                  |   8 +-
 src/core/profile_adapter.h                    |  21 +-
 src/core/web_contents_adapter.cpp             |  91 +++++-
 src/core/web_contents_adapter.h               |   9 +-
 src/core/web_contents_adapter_client.h        |   4 +-
 src/core/web_contents_delegate_qt.cpp         |   6 +-
 src/core/web_contents_delegate_qt.h           |   2 +-
 .../api/qquickwebengineforeigntypes_p.h       |  25 ++
 .../api/qquickwebenginesettings.cpp           |   4 +-
 .../api/qquickwebengineview.cpp               | 160 ++++++---
 .../api/qquickwebengineview_p.h               |  32 +-
 .../api/qquickwebengineview_p_p.h             |   3 +-
 .../doc/src/webengine_permission.qdoc         | 137 ++++++++
 .../doc/src/webengineview_lgpl.qdoc           |  19 +-
 tests/auto/quick/publicapi/tst_publicapi.cpp  |  50 ++-
 .../quick/qmltests/data/tst_geopermission.qml |  22 +-
 .../quick/qmltests/data/tst_getUserMedia.qml  |  30 +-
 .../quick/qmltests/data/tst_notification.qml  |  17 +-
 .../qwebenginepage/tst_qwebenginepage.cpp     | 235 +++++++++-----
 .../tst_qwebengineprofile.cpp                 |  14 +
 .../quick/geopermission/tst_geopermission.qml |   8 +-
 tests/manual/widgets/geolocation/main.cpp     |  13 +-
 tests/manual/widgets/webrtc/main.cpp          |   8 +-
 42 files changed, 1502 insertions(+), 525 deletions(-)
 create mode 100644 src/core/api/qwebenginepermission.cpp
 create mode 100644 src/core/api/qwebenginepermission.h
 create mode 100644 src/core/api/qwebenginepermission_p.h
 create mode 100644 src/webenginequick/doc/src/webengine_permission.qdoc

diff --git a/examples/webenginequick/quicknanobrowser/BrowserWindow.qml b/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
index e2cb71fb3ca..2c5b3d86e75 100644
--- a/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
+++ b/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
@@ -648,10 +648,9 @@ ApplicationWindow {
                         findBar.reset();
                 }
 
-                onFeaturePermissionRequested: function(securityOrigin, feature) {
-                    featurePermissionDialog.securityOrigin = securityOrigin;
-                    featurePermissionDialog.feature = feature;
-                    featurePermissionDialog.visible = true;
+                onPermissionRequested: function(permission) {
+                    permissionDialog.permission = permission;
+                    permissionDialog.visible = true;
                 }
                 onWebAuthUxRequested: function(request) {
                     webAuthDialog.init(request);
@@ -736,7 +735,7 @@ ApplicationWindow {
         }
     }
     Dialog {
-        id: featurePermissionDialog
+        id: permissionDialog
         anchors.centerIn: parent
         width: Math.min(browserWindow.width, browserWindow.height) / 3 * 2
         contentWidth: mainTextForPermissionDialog.width
@@ -744,59 +743,58 @@ ApplicationWindow {
         standardButtons: Dialog.No | Dialog.Yes
         title: "Permission Request"
 
-        property var feature;
-        property url securityOrigin;
+        property var permission;
 
         contentItem: Item {
             Label {
                 id: mainTextForPermissionDialog
-                text: featurePermissionDialog.questionForFeature()
+                text: permissionDialog.questionForFeature()
             }
         }
 
-        onAccepted: currentWebView && currentWebView.grantFeaturePermission(securityOrigin, feature, true)
-        onRejected: currentWebView && currentWebView.grantFeaturePermission(securityOrigin, feature, false)
+        onAccepted: permission.grant()
+        onRejected: permission.deny()
         onVisibleChanged: {
             if (visible)
                 width = contentWidth + 20;
         }
 
         function questionForFeature() {
-            var question = "Allow " + securityOrigin + " to "
+            var question = "Allow " + permission.origin + " to "
 
-            switch (feature) {
-            case WebEngineView.Geolocation:
+            switch (permission.feature) {
+            case WebEnginePermission.Geolocation:
                 question += "access your location information?";
                 break;
-            case WebEngineView.MediaAudioCapture:
+            case WebEnginePermission.MediaAudioCapture:
                 question += "access your microphone?";
                 break;
-            case WebEngineView.MediaVideoCapture:
+            case WebEnginePermission.MediaVideoCapture:
                 question += "access your webcam?";
                 break;
-            case WebEngineView.MediaVideoCapture:
+            case WebEnginePermission.MediaAudioVideoCapture:
                 question += "access your microphone and webcam?";
                 break;
-            case WebEngineView.MouseLock:
+            case WebEnginePermission.MouseLock:
                 question += "lock your mouse cursor?";
                 break;
-            case WebEngineView.DesktopVideoCapture:
+            case WebEnginePermission.DesktopVideoCapture:
                 question += "capture video of your desktop?";
                 break;
-            case WebEngineView.DesktopAudioVideoCapture:
+            case WebEnginePermission.DesktopAudioVideoCapture:
                 question += "capture audio and video of your desktop?";
                 break;
-            case WebEngineView.Notifications:
+            case WebEnginePermission.Notifications:
                 question += "show notification on your desktop?";
                 break;
-            case WebEngineView.ClipboardReadWrite:
+            case WebEnginePermission.ClipboardReadWrite:
                 question += "read from and write to your clipboard?";
                 break;
-            case WebEngineView.LocalFontsAccess:
+            case WebEnginePermission.LocalFontsAccess:
                 question += "access the fonts stored on your machine?";
                 break;
             default:
-                question += "access unknown or unsupported feature [" + feature + "] ?";
+                question += "access unknown or unsupported feature [" + permission.feature + "] ?";
                 break;
             }
 
diff --git a/examples/webenginequick/quicknanobrowser/doc/src/quicknanobrowser.qdoc b/examples/webenginequick/quicknanobrowser/doc/src/quicknanobrowser.qdoc
index 1e00402ff3f..cff4d3354e2 100644
--- a/examples/webenginequick/quicknanobrowser/doc/src/quicknanobrowser.qdoc
+++ b/examples/webenginequick/quicknanobrowser/doc/src/quicknanobrowser.qdoc
@@ -96,25 +96,22 @@
     \skipto Dialog {
     \printuntil /^\ {4}\}/
 
-    \section1 Handling Feature Permission Requests
+    \section1 Handling Permission Requests
 
-    We use the \c onFeaturePermissionRequested() signal handler to handle requests for
-    accessing a certain feature or device. The \c securityOrigin parameter identifies the
-    requester web site, and the \c feature parameter is the requested feature. We use these
-    to construct the message of the dialog:
+    We use the \c onPermissionRequested() signal handler to handle requests for
+    accessing a certain feature or device. The \c permission parameter is an object of the
+    WebEnginePermission type, which can be used to handle the incoming request. We temporarily store
+    this object, since we need to use it to construct the message of the dialog:
 
     \quotefromfile webenginequick/quicknanobrowser/BrowserWindow.qml
-    \skipto onFeaturePermissionRequested
+    \skipto onPermissionRequested
     \printuntil }
 
-    We show a dialog where the user is asked to grant or deny access. The custom
+    We display a dialog where the user is asked to grant or deny access. The custom
     \c questionForFeature() JavaScript function generates a human-readable question about
     the request.
-    If users select \uicontrol Yes, we call the \l{WebEngineView::}{grantFeaturePermission()}
-    method with a third \c true parameter to grant the \c securityOrigin web site the permission
-    to access the \c feature.
-    If users select \uicontrol No, we call the same method but with the \c false parameter to
-    deny access:
+    If user selects \uicontrol Yes, we call the \l{webEnginePermission::grant}{grant()}
+    method, and if they select \uicontrol No we call \l{webEnginePermission::deny}{deny()}.
 
     \skipto id: sslDialog
     \skipto Dialog {
diff --git a/examples/webenginewidgets/maps/doc/src/maps.qdoc b/examples/webenginewidgets/maps/doc/src/maps.qdoc
index 0175f8b6511..f9bd19bfcd8 100644
--- a/examples/webenginewidgets/maps/doc/src/maps.qdoc
+++ b/examples/webenginewidgets/maps/doc/src/maps.qdoc
@@ -48,10 +48,10 @@
     \printuntil setCentralWidget
 
     We then proceed to connect a lambda function to the \l
-    QWebEnginePage::featurePermissionRequested signal:
+    QWebEnginePage::permissionRequested signal:
 
     \skipto m_view->page()
-    \printuntil QWebEnginePage::Feature
+    \printuntil QWebEnginePermission permission
 
     This signal is emitted whenever a web page requests to make use of a certain
     feature or device, including not only location services but also audio
@@ -62,15 +62,14 @@
 
     Now comes the part where we actually ask the user for permission:
 
-    \printuntil securityOrigin
     \printuntil });
 
     Note that the question includes the host component of the web site's URI (\c
-    securityOrigin) to inform the user as to exactly which web site will be
+    permission.origin()) to inform the user as to exactly which web site will be
     receiving their location data.
 
-    We use the \l QWebEnginePage::setFeaturePermission method to communicate the
-    user's answer back to the web page.
+    We use the \l QWebEnginePermission::grant() and \l QWebEnginePermission::deny()
+    methods to communicate the user's answer back to the web page.
 
     Finally we ask the \l QWebEnginePage to load the web page that might want to
     use location services:
diff --git a/examples/webenginewidgets/maps/mainwindow.cpp b/examples/webenginewidgets/maps/mainwindow.cpp
index 0d2b499117c..ca98ca2630f 100644
--- a/examples/webenginewidgets/maps/mainwindow.cpp
+++ b/examples/webenginewidgets/maps/mainwindow.cpp
@@ -13,25 +13,22 @@ MainWindow::MainWindow(QWidget *parent)
 
     QWebEnginePage *page = m_view->page();
 
-    connect(page, &QWebEnginePage::featurePermissionRequested,
-            [this, page](const QUrl &securityOrigin, QWebEnginePage::Feature feature) {
-        if (feature != QWebEnginePage::Geolocation)
+    connect(page, &QWebEnginePage::permissionRequested,
+            [this, page](QWebEnginePermission permission) {
+        if (permission.feature() != QWebEnginePermission::Geolocation)
             return;
 
         QMessageBox msgBox(this);
-        msgBox.setText(tr("%1 wants to know your location").arg(securityOrigin.host()));
+        msgBox.setText(tr("%1 wants to know your location").arg(permission.origin().host()));
         msgBox.setInformativeText(tr("Do you want to send your current location to this website?"));
         msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
         msgBox.setDefaultButton(QMessageBox::Yes);
 
-        if (msgBox.exec() == QMessageBox::Yes) {
-            page->setFeaturePermission(
-                securityOrigin, feature, QWebEnginePage::PermissionGrantedByUser);
-        } else {
-            page->setFeaturePermission(
-                securityOrigin, feature, QWebEnginePage::PermissionDeniedByUser);
-        }
+        if (msgBox.exec() == QMessageBox::Yes)
+            permission.grant();
+        else
+            permission.deny();
     });
 
-    page->load(QUrl(QStringLiteral("https://maps.google.com")));
+    page->load(QUrl(QStringLiteral("https://bing.com/maps")));
 }
diff --git a/examples/webenginewidgets/notifications/doc/src/notifications.qdoc b/examples/webenginewidgets/notifications/doc/src/notifications.qdoc
index f4fe1818fe1..bd0def910a2 100644
--- a/examples/webenginewidgets/notifications/doc/src/notifications.qdoc
+++ b/examples/webenginewidgets/notifications/doc/src/notifications.qdoc
@@ -45,11 +45,11 @@
 
     \section2 Requesting Feature Permissions
 
-    We then use the \l QWebEnginePage::featurePermissionRequested() call to
+    We then use the \l QWebEnginePage::permissionRequested() call to
     request the user's permission to show notifications on their device.
 
     \quotefromfile webenginewidgets/notifications/main.cpp
-    \skipto featurePermissionRequested
+    \skipto permissionRequested
     \printuntil });
 
     \section2 Handling New Notifications
diff --git a/examples/webenginewidgets/notifications/main.cpp b/examples/webenginewidgets/notifications/main.cpp
index c754aff3f84..df9ebff73c8 100644
--- a/examples/webenginewidgets/notifications/main.cpp
+++ b/examples/webenginewidgets/notifications/main.cpp
@@ -33,11 +33,11 @@ int main(int argc, char *argv[])
     // set custom page to open all page's links for https scheme in system browser
     view.setPage(new WebEnginePage(&view));
 
-    QObject::connect(view.page(), &QWebEnginePage::featurePermissionRequested,
-                     [&] (const QUrl &origin, QWebEnginePage::Feature feature) {
-                         if (feature != QWebEnginePage::Notifications)
+    QObject::connect(view.page(), &QWebEnginePage::permissionRequested,
+                     [&] (QWebEnginePermission permission) {
+                         if (permission.feature() != QWebEnginePermission::Notifications)
                              return;
-                         view.page()->setFeaturePermission(origin, feature, QWebEnginePage::PermissionGrantedByUser);
+                         permission.grant();
                      });
 
     auto profile = view.page()->profile();
@@ -50,4 +50,3 @@ int main(int argc, char *argv[])
     view.setUrl(QStringLiteral("qrc:/index.html"));
     return app.exec();
 }
-
diff --git a/examples/webenginewidgets/push-notifications/main.cpp b/examples/webenginewidgets/push-notifications/main.cpp
index 18a862182b9..950ebfc9f14 100644
--- a/examples/webenginewidgets/push-notifications/main.cpp
+++ b/examples/webenginewidgets/push-notifications/main.cpp
@@ -20,13 +20,12 @@ int main(int argc, char *argv[])
     QWebEngineView view(profile.data());
     auto popup = new NotificationPopup(&view);
 
-    QObject::connect(view.page(), &QWebEnginePage::featurePermissionRequested,
-                     [&](const QUrl &origin, QWebEnginePage::Feature feature) {
-                         if (feature != QWebEnginePage::Notifications)
+    QObject::connect(view.page(), &QWebEnginePage::permissionRequested,
+                     [&](QWebEnginePermission permission) {
+                         if (permission.feature() != QWebEnginePage::Notifications)
                              return;
 
-                         view.page()->setFeaturePermission(origin, feature,
-                                                           QWebEnginePage::PermissionGrantedByUser);
+                         permission.grant();
                      });
 
     profile->setPushServiceEnabled(true);
diff --git a/examples/webenginewidgets/simplebrowser/webview.cpp b/examples/webenginewidgets/simplebrowser/webview.cpp
index 08e044f709e..3dcfc0c47c5 100644
--- a/examples/webenginewidgets/simplebrowser/webview.cpp
+++ b/examples/webenginewidgets/simplebrowser/webview.cpp
@@ -71,26 +71,26 @@ WebView::~WebView()
     m_imageAnimationGroup = nullptr;
 }
 
-inline QString questionForFeature(QWebEnginePage::Feature feature)
+inline QString questionForFeature(QWebEnginePermission::Feature feature)
 {
     switch (feature) {
-    case QWebEnginePage::Geolocation:
+    case QWebEnginePermission::Geolocation:
         return QObject::tr("Allow %1 to access your location information?");
-    case QWebEnginePage::MediaAudioCapture:
+    case QWebEnginePermission::MediaAudioCapture:
         return QObject::tr("Allow %1 to access your microphone?");
-    case QWebEnginePage::MediaVideoCapture:
+    case QWebEnginePermission::MediaVideoCapture:
         return QObject::tr("Allow %1 to access your webcam?");
-    case QWebEnginePage::MediaAudioVideoCapture:
+    case QWebEnginePermission::MediaAudioVideoCapture:
         return QObject::tr("Allow %1 to access your microphone and webcam?");
-    case QWebEnginePage::MouseLock:
+    case QWebEnginePermission::MouseLock:
         return QObject::tr("Allow %1 to lock your mouse cursor?");
-    case QWebEnginePage::DesktopVideoCapture:
+    case QWebEnginePermission::DesktopVideoCapture:
         return QObject::tr("Allow %1 to capture video of your desktop?");
-    case QWebEnginePage::DesktopAudioVideoCapture:
+    case QWebEnginePermission::DesktopAudioVideoCapture:
         return QObject::tr("Allow %1 to capture audio and video of your desktop?");
-    case QWebEnginePage::Notifications:
+    case QWebEnginePermission::Notifications:
         return QObject::tr("Allow %1 to show notification on your desktop?");
-    case QWebEnginePage::ClipboardReadWrite:
+    case QWebEnginePermission::ClipboardReadWrite:
         return QObject::tr("Allow %1 to read from and write to the clipboard?");
     }
     return QString();
@@ -103,8 +103,8 @@ void WebView::setPage(WebPage *page)
                    &WebView::handleCertificateError);
         disconnect(oldPage, &QWebEnginePage::authenticationRequired, this,
                    &WebView::handleAuthenticationRequired);
-        disconnect(oldPage, &QWebEnginePage::featurePermissionRequested, this,
-                   &WebView::handleFeaturePermissionRequested);
+        disconnect(oldPage, &QWebEnginePage::permissionRequested, this,
+                   &WebView::handlePermissionRequested);
         disconnect(oldPage, &QWebEnginePage::proxyAuthenticationRequired, this,
                    &WebView::handleProxyAuthenticationRequired);
         disconnect(oldPage, &QWebEnginePage::registerProtocolHandlerRequested, this,
@@ -124,8 +124,8 @@ void WebView::setPage(WebPage *page)
     connect(page, &WebPage::createCertificateErrorDialog, this, &WebView::handleCertificateError);
     connect(page, &QWebEnginePage::authenticationRequired, this,
             &WebView::handleAuthenticationRequired);
-    connect(page, &QWebEnginePage::featurePermissionRequested, this,
-            &WebView::handleFeaturePermissionRequested);
+    connect(page, &QWebEnginePage::permissionRequested, this,
+            &WebView::handlePermissionRequested);
     connect(page, &QWebEnginePage::proxyAuthenticationRequired, this,
             &WebView::handleProxyAuthenticationRequired);
     connect(page, &QWebEnginePage::registerProtocolHandlerRequested, this,
@@ -309,17 +309,14 @@ void WebView::handleAuthenticationRequired(const QUrl &requestUrl, QAuthenticato
     }
 }
 
-void WebView::handleFeaturePermissionRequested(const QUrl &securityOrigin,
-                                               QWebEnginePage::Feature feature)
+void WebView::handlePermissionRequested(QWebEnginePermission permission)
 {
     QString title = tr("Permission Request");
-    QString question = questionForFeature(feature).arg(securityOrigin.host());
+    QString question = questionForFeature(permission.feature()).arg(permission.origin().host());
     if (!question.isEmpty() && QMessageBox::question(window(), title, question) == QMessageBox::Yes)
-        page()->setFeaturePermission(securityOrigin, feature,
-                                     QWebEnginePage::PermissionGrantedByUser);
+        permission.grant();
     else
-        page()->setFeaturePermission(securityOrigin, feature,
-                                     QWebEnginePage::PermissionDeniedByUser);
+        permission.deny();
 }
 
 void WebView::handleProxyAuthenticationRequired(const QUrl &, QAuthenticator *auth,
diff --git a/examples/webenginewidgets/simplebrowser/webview.h b/examples/webenginewidgets/simplebrowser/webview.h
index c7e7f394c1b..d652fbdc9ac 100644
--- a/examples/webenginewidgets/simplebrowser/webview.h
+++ b/examples/webenginewidgets/simplebrowser/webview.h
@@ -14,6 +14,7 @@
 #include <QWebEngineRegisterProtocolHandlerRequest>
 #include <QWebEngineWebAuthUxRequest>
 #include <QWebEngineSettings>
+#include <QWebEnginePermission>
 #include <QActionGroup>
 
 class WebPage;
@@ -43,8 +44,7 @@ class WebView : public QWebEngineView
 private slots:
     void handleCertificateError(QWebEngineCertificateError error);
     void handleAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *auth);
-    void handleFeaturePermissionRequested(const QUrl &securityOrigin,
-                                          QWebEnginePage::Feature feature);
+    void handlePermissionRequested(QWebEnginePermission permission);
     void handleProxyAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *auth,
                                            const QString &proxyHost);
     void handleRegisterProtocolHandlerRequested(QWebEngineRegisterProtocolHandlerRequest request);
diff --git a/src/core/api/CMakeLists.txt b/src/core/api/CMakeLists.txt
index c06f5e4ce24..e14d0cd5c18 100644
--- a/src/core/api/CMakeLists.txt
+++ b/src/core/api/CMakeLists.txt
@@ -29,6 +29,7 @@ qt_internal_add_module(WebEngineCore
         qwebenginenewwindowrequest.cpp qwebenginenewwindowrequest.h qwebenginenewwindowrequest_p.h
         qwebenginenotification.cpp qwebenginenotification.h
         qwebenginepage.cpp qwebenginepage.h qwebenginepage_p.h
+        qwebenginepermission.cpp qwebenginepermission.h qwebenginepermission_p.h
         qwebengineprofile.cpp qwebengineprofile.h qwebengineprofile_p.h
         qwebenginequotarequest.cpp qwebenginequotarequest.h
         qwebengineregisterprotocolhandlerrequest.cpp qwebengineregisterprotocolhandlerrequest.h
diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp
index d7ab7030598..f0260fd0d31 100644
--- a/src/core/api/qwebenginepage.cpp
+++ b/src/core/api/qwebenginepage.cpp
@@ -24,6 +24,7 @@
 #include "qwebenginescriptcollection_p.h"
 #include "qwebenginesettings.h"
 #include "qwebenginewebauthuxrequest.h"
+#include "qwebenginepermission_p.h"
 
 #include "authentication_dialog_controller.h"
 #include "autofill_popup_controller.h"
@@ -589,50 +590,121 @@ void QWebEnginePagePrivate::showColorDialog(QSharedPointer<ColorChooserControlle
 void QWebEnginePagePrivate::runMediaAccessPermissionRequest(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags requestFlags)
 {
     Q_Q(QWebEnginePage);
-    QWebEnginePage::Feature feature;
-    if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture) &&
-        requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
-        feature = QWebEnginePage::MediaAudioVideoCapture;
+    QWebEnginePermission::Feature feature;
+
+    if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture)
+            && requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
+        feature = QWebEnginePermission::MediaAudioVideoCapture;
+    else if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture))
+        feature = QWebEnginePermission::MediaAudioCapture;
+    else if (requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
+        feature = QWebEnginePermission::MediaVideoCapture;
+    else if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopAudioCapture)
+            && requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture))
+        feature = QWebEnginePermission::DesktopAudioVideoCapture;
+    else // if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture))
+        feature = QWebEnginePermission::DesktopVideoCapture;
+
+    Q_EMIT q->permissionRequested(createFeaturePermissionObject(securityOrigin, feature));
+
+#if QT_DEPRECATED_SINCE(6, 8)
+    QT_WARNING_PUSH
+    QT_WARNING_DISABLE_DEPRECATED
+    QWebEnginePage::Feature deprecatedFeature;
+
+    if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture)
+            && requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
+        deprecatedFeature = QWebEnginePage::MediaAudioVideoCapture;
     else if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture))
-        feature = QWebEnginePage::MediaAudioCapture;
+        deprecatedFeature = QWebEnginePage::MediaAudioCapture;
     else if (requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
-        feature = QWebEnginePage::MediaVideoCapture;
-    else if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopAudioCapture) &&
-             requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture))
-        feature = QWebEnginePage::DesktopAudioVideoCapture;
+        deprecatedFeature = QWebEnginePage::MediaVideoCapture;
+    else if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopAudioCapture)
+            && requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture))
+        deprecatedFeature = QWebEnginePage::DesktopAudioVideoCapture;
     else // if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture))
-        feature = QWebEnginePage::DesktopVideoCapture;
-    Q_EMIT q->featurePermissionRequested(securityOrigin, feature);
+        deprecatedFeature = QWebEnginePage::DesktopVideoCapture;
+
+    Q_EMIT q->featurePermissionRequested(securityOrigin, deprecatedFeature);
+    QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 8)
 }
 
-static QWebEnginePage::Feature toFeature(QtWebEngineCore::ProfileAdapter::PermissionType type)
+#if QT_DEPRECATED_SINCE(6, 8)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+static QWebEnginePage::Feature toDeprecatedFeature(QWebEnginePermission::Feature feature)
 {
-    switch (type) {
-    case QtWebEngineCore::ProfileAdapter::NotificationPermission:
+    switch (feature) {
+    case QWebEnginePermission::Feature::Notifications:
         return QWebEnginePage::Notifications;
-    case QtWebEngineCore::ProfileAdapter::GeolocationPermission:
+    case QWebEnginePermission::Feature::Geolocation:
         return QWebEnginePage::Geolocation;
-    case QtWebEngineCore::ProfileAdapter::ClipboardReadWrite:
+    case QWebEnginePermission::Feature::ClipboardReadWrite:
         return QWebEnginePage::ClipboardReadWrite;
-    case QtWebEngineCore::ProfileAdapter::LocalFontsPermission:
+    case QWebEnginePermission::Feature::LocalFontsAccess:
         return QWebEnginePage::LocalFontsAccess;
-    default:
+    case QWebEnginePermission::Feature::MediaAudioCapture:
+        return QWebEnginePage::MediaAudioCapture;
+    case QWebEnginePermission::Feature::MediaVideoCapture:
+        return QWebEnginePage::MediaVideoCapture;
+    case QWebEnginePermission::Feature::MediaAudioVideoCapture:
+        return QWebEnginePage::MediaAudioVideoCapture;
+    case QWebEnginePermission::Feature::DesktopVideoCapture:
+        return QWebEnginePage::DesktopVideoCapture;
+    case QWebEnginePermission::Feature::DesktopAudioVideoCapture:
+        return QWebEnginePage::DesktopAudioVideoCapture;
+    case QWebEnginePermission::Feature::MouseLock:
+        return QWebEnginePage::MouseLock;
+    case QWebEnginePermission::Feature::Unsupported:
         break;
     }
+
     Q_UNREACHABLE();
     return QWebEnginePage::Feature(-1);
 }
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 8)
 
-void QWebEnginePagePrivate::runFeaturePermissionRequest(QtWebEngineCore::ProfileAdapter::PermissionType permission, const QUrl &securityOrigin)
+void QWebEnginePagePrivate::runFeaturePermissionRequest(QWebEnginePermission::Feature feature, const QUrl &securityOrigin)
 {
     Q_Q(QWebEnginePage);
-    Q_EMIT q->featurePermissionRequested(securityOrigin, toFeature(permission));
+    switch (feature) {
+    case QWebEnginePermission::Notifications:
+    case QWebEnginePermission::Geolocation:
+    case QWebEnginePermission::ClipboardReadWrite:
+    case QWebEnginePermission::LocalFontsAccess:
+        Q_EMIT q->permissionRequested(createFeaturePermissionObject(securityOrigin, feature));
+#if QT_DEPRECATED_SINCE(6, 8)
+        QT_WARNING_PUSH
+        QT_WARNING_DISABLE_DEPRECATED
+        Q_EMIT q->featurePermissionRequested(securityOrigin, toDeprecatedFeature(feature));
+        QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 8)
+        return;
+    case QWebEnginePermission::MouseLock:
+    case QWebEnginePermission::MediaAudioCapture:
+    case QWebEnginePermission::MediaVideoCapture:
+    case QWebEnginePermission::MediaAudioVideoCapture:
+    case QWebEnginePermission::DesktopAudioVideoCapture:
+    case QWebEnginePermission::DesktopVideoCapture:
+    case QWebEnginePermission::Unsupported:
+        Q_UNREACHABLE();
+        return;
+    }
 }
 
 void QWebEnginePagePrivate::runMouseLockPermissionRequest(const QUrl &securityOrigin)
 {
     Q_Q(QWebEnginePage);
+    Q_EMIT q->permissionRequested(createFeaturePermissionObject(securityOrigin, QWebEnginePermission::MouseLock));
+
+#if QT_DEPRECATED_SINCE(6, 8)
+    QT_WARNING_PUSH
+    QT_WARNING_DISABLE_DEPRECATED
     Q_EMIT q->featurePermissionRequested(securityOrigin, QWebEnginePage::MouseLock);
+    QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 8)
 }
 
 void QWebEnginePagePrivate::runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest request)
@@ -821,6 +893,12 @@ void QWebEnginePagePrivate::showWebAuthDialog(QWebEngineWebAuthUxRequest *reques
     Q_EMIT q->webAuthUxRequested(request);
 }
 
+QWebEnginePermission QWebEnginePagePrivate::createFeaturePermissionObject(const QUrl &securityOrigin, QWebEnginePermission::Feature feature)
+{
+    auto *returnPrivate = new QWebEnginePermissionPrivate{securityOrigin, feature, adapter, profileAdapter()};
+    return QWebEnginePermission(returnPrivate);
+}
+
 QWebEnginePage::QWebEnginePage(QObject* parent)
     : QObject(parent)
     , d_ptr(new QWebEnginePagePrivate())
@@ -1773,104 +1851,64 @@ void QWebEnginePage::setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *i
     d->adapter->setRequestInterceptor(interceptor);
 }
 
+#if QT_DEPRECATED_SINCE(6, 8)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
 void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEnginePage::Feature feature, QWebEnginePage::PermissionPolicy policy)
 {
     Q_D(QWebEnginePage);
-    if (policy == PermissionUnknown) {
-        switch (feature) {
-        case MediaAudioVideoCapture:
-        case MediaAudioCapture:
-        case MediaVideoCapture:
-        case DesktopAudioVideoCapture:
-        case DesktopVideoCapture:
-        case MouseLock:
-            break;
-        case Geolocation:
-            d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::GeolocationPermission, ProfileAdapter::AskPermission);
-            break;
-        case Notifications:
-            d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::NotificationPermission, ProfileAdapter::AskPermission);
-            break;
-        case ClipboardReadWrite:
-            d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::ClipboardReadWrite,
-                                               ProfileAdapter::AskPermission);
-            break;
-        case LocalFontsAccess:
-            d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::LocalFontsPermission, ProfileAdapter::AskPermission);
-            break;
-        }
-        return;
+    QWebEnginePermission::Feature f;
+    QWebEnginePermission::State s;
+
+    switch (feature) {
+    case QWebEnginePage::Notifications:
+        f = QWebEnginePermission::Notifications;
+        break;
+    case QWebEnginePage::Geolocation:
+        f = QWebEnginePermission::Geolocation;
+        break;
+    case QWebEnginePage::MediaAudioCapture:
+        f = QWebEnginePermission::MediaAudioCapture;
+        break;
+    case QWebEnginePage::MediaVideoCapture:
+        f = QWebEnginePermission::MediaVideoCapture;
+        break;
+    case QWebEnginePage::MediaAudioVideoCapture:
+        f = QWebEnginePermission::MediaAudioVideoCapture;
+        break;
+    case QWebEnginePage::MouseLock:
+        f = QWebEnginePermission::MouseLock;
+        break;
+    case QWebEnginePage::DesktopVideoCapture:
+        f = QWebEnginePermission::DesktopVideoCapture;
+        break;
+    case QWebEnginePage::DesktopAudioVideoCapture:
+        f = QWebEnginePermission::DesktopAudioVideoCapture;
+        break;
+    case QWebEnginePage::ClipboardReadWrite:
+        f = QWebEnginePermission::ClipboardReadWrite;
+        break;
+    case QWebEnginePage::LocalFontsAccess:
+        f = QWebEnginePermission::LocalFontsAccess;
+        break;
     }
 
-    const WebContentsAdapterClient::MediaRequestFlags audioVideoCaptureFlags(
-        WebContentsAdapterClient::MediaVideoCapture |
-        WebContentsAdapterClient::MediaAudioCapture);
-    const WebContentsAdapterClient::MediaRequestFlags desktopAudioVideoCaptureFlags(
-        WebContentsAdapterClient::MediaDesktopVideoCapture |
-        WebContentsAdapterClient::MediaDesktopAudioCapture);
-
-    if (policy == PermissionGrantedByUser) {
-        switch (feature) {
-        case MediaAudioVideoCapture:
-            d->adapter->grantMediaAccessPermission(securityOrigin, audioVideoCaptureFlags);
-            break;
-        case MediaAudioCapture:
-            d->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaAudioCapture);
-            break;
-        case MediaVideoCapture:
-            d->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaVideoCapture);
-            break;
-        case DesktopAudioVideoCapture:
-            d->adapter->grantMediaAccessPermission(securityOrigin, desktopAudioVideoCaptureFlags);
-            break;
-        case DesktopVideoCapture:
-            d->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaDesktopVideoCapture);
-            break;
-        case MouseLock:
-            d->adapter->grantMouseLockPermission(securityOrigin, true);
-            break;
-        case Geolocation:
-            d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::GeolocationPermission, ProfileAdapter::AllowedPermission);
-            break;
-        case Notifications:
-            d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::NotificationPermission, ProfileAdapter::AllowedPermission);
-            break;
-        case ClipboardReadWrite:
-            d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::ClipboardReadWrite,
-                                               ProfileAdapter::AllowedPermission);
-            break;
-        case LocalFontsAccess:
-            d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::LocalFontsPermission, ProfileAdapter::AllowedPermission);
-            break;
-        }
-    } else { // if (policy == PermissionDeniedByUser)
-        switch (feature) {
-        case MediaAudioVideoCapture:
-        case MediaAudioCapture:
-        case MediaVideoCapture:
-        case DesktopAudioVideoCapture:
-        case DesktopVideoCapture:
-            d->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaNone);
-            break;
-        case Geolocation:
-            d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::GeolocationPermission, ProfileAdapter::DeniedPermission);
-            break;
-        case MouseLock:
-            d->adapter->grantMouseLockPermission(securityOrigin, false);
-            break;
-        case Notifications:
-            d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::NotificationPermission, ProfileAdapter::DeniedPermission);
-            break;
-        case ClipboardReadWrite:
-            d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::ClipboardReadWrite,
-                                               ProfileAdapter::DeniedPermission);
-            break;
-        case LocalFontsAccess:
-            d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::LocalFontsPermission, ProfileAdapter::DeniedPermission);
-            break;
-        }
+    switch (policy) {
+    case QWebEnginePage::PermissionUnknown:
+        s = QWebEnginePermission::Ask;
+        break;
+    case QWebEnginePage::PermissionDeniedByUser:
+        s = QWebEnginePermission::Denied;
+        break;
+    case QWebEnginePage::PermissionGrantedByUser:
+        s = QWebEnginePermission::Granted;
+        break;
     }
+
+    d->adapter->setFeaturePermission(securityOrigin, f, s);
 }
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 8)
 
 static inline QWebEnginePage::FileSelectionMode toPublic(FilePickerController::FileChooserMode mode)
 {
diff --git a/src/core/api/qwebenginepage.h b/src/core/api/qwebenginepage.h
index 59eed2b9b4a..cca7c55e7a8 100644
--- a/src/core/api/qwebenginepage.h
+++ b/src/core/api/qwebenginepage.h
@@ -9,6 +9,7 @@
 #include <QtWebEngineCore/qwebenginedownloadrequest.h>
 #include <QtWebEngineCore/qwebenginequotarequest.h>
 #include <QtWebEngineCore/qwebengineframe.h>
+#include <QtWebEngineCore/qwebenginepermission.h>
 
 #include <QtCore/qobject.h>
 #include <QtCore/qurl.h>
@@ -147,12 +148,19 @@ class Q_WEBENGINECORE_EXPORT QWebEnginePage : public QObject
     };
     Q_ENUM(WebWindowType)
 
-    enum PermissionPolicy {
+#if QT_DEPRECATED_SINCE(6, 8)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+    enum QT_DEPRECATED_VERSION_X_6_8(
+        "QWebEnginePage::PermissionPolicy has been deprecated. "
+        "The updated permissions API uses QWebEnginePermission::State.")
+    PermissionPolicy {
         PermissionUnknown,
         PermissionGrantedByUser,
         PermissionDeniedByUser
     };
     Q_ENUM(PermissionPolicy)
+QT_WARNING_POP
+#endif
 
     // must match WebContentsAdapterClient::NavigationType
     enum NavigationType {
@@ -166,7 +174,12 @@ class Q_WEBENGINECORE_EXPORT QWebEnginePage : public QObject
     };
     Q_ENUM(NavigationType)
 
-    enum Feature {
+#if QT_DEPRECATED_SINCE(6, 8)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+    enum QT_DEPRECATED_VERSION_X_6_8(
+        "QWebEnginePage::Feature has been deprecated. "
+        "The updated permissions API uses QWebEnginePermission::Feature.")
+    Feature {
         Notifications = 0,
         Geolocation = 1,
         MediaAudioCapture = 2,
@@ -179,6 +192,8 @@ class Q_WEBENGINECORE_EXPORT QWebEnginePage : public QObject
         LocalFontsAccess,
     };
     Q_ENUM(Feature)
+QT_WARNING_POP
+#endif
 
     // Ex-QWebFrame enum
 
@@ -236,7 +251,12 @@ class Q_WEBENGINECORE_EXPORT QWebEnginePage : public QObject
 
     void findText(const QString &subString, FindFlags options = {}, const std::function<void(const QWebEngineFindTextResult &)> &resultCallback = std::function<void(const QWebEngineFindTextResult &)>());
 
+#if QT_DEPRECATED_SINCE(6, 8)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+    QT_DEPRECATED_VERSION_X_6_8("Setting permissions through QWebEnginePage has been deprecated. Please use QWebEnginePermission instead.")
     void setFeaturePermission(const QUrl &securityOrigin, Feature feature, PermissionPolicy policy);
+QT_WARNING_POP
+#endif
 
     bool isLoading() const;
 
@@ -319,9 +339,23 @@ class Q_WEBENGINECORE_EXPORT QWebEnginePage : public QObject
     void geometryChangeRequested(const QRect &geom);
     void windowCloseRequested();
 
+#if QT_DEPRECATED_SINCE(6, 8)
+#if !defined(Q_MOC_RUN)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+#endif // !defined(Q_MOC_RUN)
+    QT_MOC_COMPAT QT_DEPRECATED_VERSION_X_6_8("The signal has been deprecated; please use permissionRequested instead.")
     void featurePermissionRequested(const QUrl &securityOrigin, QWebEnginePage::Feature feature);
+    QT_MOC_COMPAT QT_DEPRECATED_VERSION_X_6_8("The signal has been deprecated, and no longer functions.")
     void featurePermissionRequestCanceled(const QUrl &securityOrigin, QWebEnginePage::Feature feature);
+#if !defined(Q_MOC_RUN)
+QT_WARNING_POP
+#endif // !defined(Q_MOC_RUN)
+#endif // QT_DEPRECATED_SINCE(6, 8)
+
     void fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest);
+    void permissionRequested(QWebEnginePermission permissionRequest);
+
 #if QT_DEPRECATED_SINCE(6, 5)
     QT_DEPRECATED_VERSION_X_6_5("Requesting host quota is no longer supported.")
     void quotaRequested(QWebEngineQuotaRequest quotaRequest);
diff --git a/src/core/api/qwebenginepage_p.h b/src/core/api/qwebenginepage_p.h
index 6f536f3a622..77d3dd8c247 100644
--- a/src/core/api/qwebenginepage_p.h
+++ b/src/core/api/qwebenginepage_p.h
@@ -148,7 +148,7 @@ class Q_WEBENGINECORE_EXPORT QWebEnginePagePrivate : public QtWebEngineCore::Web
             QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) override;
     void releaseProfile() override;
     void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) override;
-    void runFeaturePermissionRequest(QtWebEngineCore::ProfileAdapter::PermissionType permission, const QUrl &securityOrigin) override;
+    void runFeaturePermissionRequest(QWebEnginePermission::Feature feature, const QUrl &securityOrigin) override;
     void runMouseLockPermissionRequest(const QUrl &securityOrigin) override;
     void runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest) override;
     void runFileSystemAccessRequest(QWebEngineFileSystemAccessRequest) override;
@@ -180,6 +180,7 @@ class Q_WEBENGINECORE_EXPORT QWebEnginePagePrivate : public QtWebEngineCore::Web
                            const QRect &bounds, bool autoselectFirstSuggestion) override;
     void hideAutofillPopup() override;
     void showWebAuthDialog(QWebEngineWebAuthUxRequest *controller) override;
+    QWebEnginePermission createFeaturePermissionObject(const QUrl &securityOrigin, QWebEnginePermission::Feature feature) override;
 
     QtWebEngineCore::ProfileAdapter *profileAdapter() override;
     QtWebEngineCore::WebContentsAdapter *webContentsAdapter() override;
diff --git a/src/core/api/qwebenginepermission.cpp b/src/core/api/qwebenginepermission.cpp
new file mode 100644
index 00000000000..d898b8c7e59
--- /dev/null
+++ b/src/core/api/qwebenginepermission.cpp
@@ -0,0 +1,307 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qwebenginepermission.h"
+#include "qwebenginepermission_p.h"
+#include "web_contents_adapter.h"
+#include "profile_adapter.h"
+
+QT_BEGIN_NAMESPACE
+
+QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QWebEnginePermissionPrivate)
+
+QWebEnginePermissionPrivate::QWebEnginePermissionPrivate()
+    : QSharedData()
+    , feature(QWebEnginePermission::Unsupported)
+{
+}
+
+QWebEnginePermissionPrivate::QWebEnginePermissionPrivate(const QUrl &origin_, QWebEnginePermission::Feature feature_,
+        QSharedPointer<QtWebEngineCore::WebContentsAdapter> webContentsAdapter_, QtWebEngineCore::ProfileAdapter *profileAdapter_)
+    : QSharedData()
+    , origin(origin_)
+    , feature(feature_)
+    , webContentsAdapter(webContentsAdapter_)
+    , profileAdapter(profileAdapter_)
+{
+}
+
+/*!
+    \class QWebEnginePermission
+    \inmodule QtWebEngineCore
+    \since 6.8
+    \brief A QWebEnginePermission is an object used to access and modify the state of a single permission that's been
+    granted or denied to a specific origin URL.
+
+    The typical usage pattern is as follows:
+    \list 1
+        \li A website requests a specific feature, triggering the QWebEnginePage::permissionRequested() signal;
+        \li The signal handler triggers a prompt asking the user whether they want to grant the permission;
+        \li When the user has made their decision, the application calls \l grant() or \l deny();
+    \endlist
+
+    Alternatively, an application interested in modifying already granted permissions may use QWebEngineProfile::listPermissions()
+    to get a list of existing permissions associated with a profile, or QWebEngineProfile::getPermission() to get
+    a QWebEnginePermission object for a specific permission.
+
+    The \l origin() property can be used to query which origin the QWebEnginePermission is associated with, while the
+    \l feature() property describes the associated feature. A website origin is the combination of its scheme, hostname,
+    and port. Permissions are granted on a per-origin basis; thus, if the web page \c{https://www.example.com:12345/some/page.html}
+    requests a permission, it will be granted to the origin \c{https://www.example.com:12345/}.
+
+    \l QWebEnginePermission::Feature describes all the feature types Qt WebEngine supports. Some Features are transient;
+    in practice, this means that they are never remembered, and a website that uses them will trigger a permission
+    prompt every time the Feature is needed. Transient Features cannot be granted in advance.
+
+    The usability lifetime of a QWebEnginePermission is tied either to its associated QWebEnginePage
+    (for transient feature types), or QWebEngineProfile (for permanent feature types). A transient permission is one which
+    needs to be explicitly granted or denied every time it's needed (e.g. webcam/screen sharing permission), whereas a permanent
+    one might be stored inside the current profile, depending on the value of QWebEngineProfile::persistentPermissionsPolicy().
+    You can check whether a QWebEnginePermission is in a valid state using its \l isValid() property. For invalid objects, calls to \l grant(),
+    \l deny(), or \l reset() will do nothing, while calls to \l state() will always return QWebEnginePermission::Invalid.
+
+    \sa QWebEnginePage::permissionRequested(), QWebEngineProfile::getPermission(), QWebEngineProfile::listPermissions()
+*/
+
+/*! \fn QWebEnginePermission::QWebEnginePermission()
+    \internal
+*/
+
+/*! \internal */
+QWebEnginePermission::QWebEnginePermission()
+    : d_ptr(new QWebEnginePermissionPrivate())
+{
+}
+
+/*! \internal */
+QWebEnginePermission::QWebEnginePermission(QWebEnginePermissionPrivate *pvt)
+    : d_ptr(pvt)
+{
+}
+
+QWebEnginePermission::QWebEnginePermission(const QWebEnginePermission &other)
+    : d_ptr(new QWebEnginePermissionPrivate(*other.d_ptr))
+{
+}
+
+QWebEnginePermission::~QWebEnginePermission() = default;
+
+QWebEnginePermission &QWebEnginePermission::operator=(const QWebEnginePermission &other)
+{
+    if (this == &other)
+        return *this;
+
+    d_ptr.reset(new QWebEnginePermissionPrivate(*other.d_ptr));
+    return *this;
+}
+
+bool QWebEnginePermission::comparesEqual(const QWebEnginePermission &other) const
+{
+    if (this == &other)
+        return true;
+
+    if (d_ptr->feature != other.d_ptr->feature || d_ptr->origin != other.d_ptr->origin)
+        return false;
+
+    if (isTransient(d_ptr->feature)) {
+        if (d_ptr->webContentsAdapter != other.d_ptr->webContentsAdapter)
+            return false;
+    } else {
+        QtWebEngineCore::ProfileAdapter *thisProfile = d_ptr->webContentsAdapter
+            ? d_ptr->webContentsAdapter.toStrongRef()->profileAdapter()
+            : d_ptr->profileAdapter.get();
+        QtWebEngineCore::ProfileAdapter *otherProfile = d_ptr->webContentsAdapter
+            ? other.d_ptr->webContentsAdapter.toStrongRef()->profileAdapter()
+            : other.d_ptr->profileAdapter.get();
+
+        if (thisProfile != otherProfile)
+            return false;
+    }
+
+    return true;
+}
+
+/*!
+    \property QWebEnginePermission::origin
+    \brief The URL of the permission's associated origin.
+
+    A website origin is the combination of its scheme, hostname, and port. Permissions are granted on a
+    per-origin basis; thus, if the web page \c{https://www.example.com:12345/some/page.html}
+    requests a permission, it will be granted to the origin \c{https://www.example.com:12345/}.
+*/
+const QUrl QWebEnginePermission::origin() const
+{
+    return d_ptr->origin;
+}
+
+/*!
+    \enum QWebEnginePermission::Feature
+
+    This enum type holds the type of the requested feature:
+
+    \value MediaAudioCapture Access to a microphone, or another audio source. This feature is transient.
+    \value MediaVideoCapture Access to a webcam, or another video source. This feature is transient.
+    \value MediaAudioVideoCapture Combination of \l MediaAudioCapture and \l MediaVideoCapture. This feature is transient.
+    \value DesktopVideoCapture Access to the contents of the user's screen. This feature is transient.
+    \value DesktopAudioVideoCapture Access to the contents of the user's screen, and application audio. This feature is transient.
+    \value MouseLock Locks the pointer inside an element on the web page. This feature is transient.
+    \value Notifications Allows the website to send notifications to the user.
+    \value Geolocation Access to the user's physical location.
+    \value ClipboardReadWrite Access to the user's clipboard.
+    \value LocalFontsAccess Access to the fonts installed on the user's machine. Only available on desktops.
+    \value Unsupported An unsupported feature type.
+
+    \note Transient feature types are ones that will never be remembered by the underlying storage, and will trigger
+    a permission request every time a website tries to use them. Transient Features can only be denied/granted
+    as they're needed; any attempts to pre-grant a transient Feature will fail.
+*/
+
+/*!
+    \property QWebEnginePermission::feature
+    \brief The feature type associated with this permission.
+*/
+QWebEnginePermission::Feature QWebEnginePermission::feature() const
+{
+    return d_ptr->feature;
+}
+
+/*!
+    \enum QWebEnginePermission::State
+
+    This enum type holds the current state of the requested feature:
+
+    \value Invalid Object is in an invalid state, and any attempts to modify the described permission will fail.
+    \value Ask Either the permission has not been requested before, or the feature() is transient.
+    \value Granted Permission has already been granted.
+    \value Denied Permission has already been denied.
+*/
+
+/*!
+    \property QWebEnginePermission::state
+    \brief The current state of the permission.
+
+    If a permission for the specified \l feature() and \l origin() has already been granted or denied,
+    the return value is QWebEnginePermission::Granted, or QWebEnginePermission::Denied, respectively.
+    When this is the first time the permission is requested, or if the \l feature() is transient,
+    the return value is QWebEnginePermission::Ask. If the object is in an invalid state, the returned
+    value is QWebEnginePermission::Invalid.
+
+    \sa isValid(), isTransient()
+*/
+QWebEnginePermission::State QWebEnginePermission::state() const
+{
+    if (!isValid())
+        return Invalid;
+    if (d_ptr->webContentsAdapter)
+        return d_ptr->webContentsAdapter.toStrongRef()->getPermissionState(origin(), feature());
+    if (d_ptr->profileAdapter)
+        return d_ptr->profileAdapter->getPermissionState(origin(), feature());
+    Q_UNREACHABLE();
+    return Ask;
+}
+
+/*!
+    \property QWebEnginePermission::isValid
+    \brief Indicates whether attempts to change the permission's state will be successful.
+
+    An invalid QWebEnginePermission is either:
+    \list
+        \li One whose \l feature() is unsupported;
+        \li One whose \l feature() is transient, and the associated page/view has been destroyed;
+        \li One whose \l feature() is permanent, but the associated profile has been destroyed;
+        \li One whose \l origin() is invalid.
+    \endlist
+
+    \sa isTransient()
+*/
+bool QWebEnginePermission::isValid() const
+{
+    if (feature() == Unsupported)
+        return false;
+    if (isTransient(feature()) && !d_ptr->webContentsAdapter)
+        return false;
+    if (!d_ptr->profileAdapter)
+        return false;
+    if (!d_ptr->origin.isValid())
+        return false;
+    return true;
+}
+
+/*!
+    Allows the associated origin to access the requested feature. Does nothing when \l isValid() evaluates to false.
+
+    \sa deny(), reset(), isValid()
+*/
+void QWebEnginePermission::grant() const
+{
+    if (!isValid())
+        return;
+    if (d_ptr->webContentsAdapter)
+        d_ptr->webContentsAdapter.toStrongRef()->setFeaturePermission(origin(), feature(), Granted);
+    else if (d_ptr->profileAdapter)
+        d_ptr->profileAdapter->setPermission(origin(), feature(), Granted);
+}
+
+/*!
+    Stops the associated origin from accessing the requested feature. Does nothing when \l isValid() evaluates to false.
+
+    \sa grant(), reset(), isValid()
+*/
+void QWebEnginePermission::deny() const
+{
+    if (!isValid())
+        return;
+    if (d_ptr->webContentsAdapter)
+        d_ptr->webContentsAdapter.toStrongRef()->setFeaturePermission(origin(), feature(), Denied);
+    else if (d_ptr->profileAdapter)
+        d_ptr->profileAdapter->setPermission(origin(), feature(), Denied);
+}
+
+/*!
+    Removes the permission from the profile's underlying storage. By default, permissions are stored on disk (except for
+    off-the-record profiles, where permissions are stored in memory and are destroyed with the profile).
+    This means that an already granted/denied permission will not be requested twice, but will get automatically
+    granted/denied every subsequent time a website requests it. Calling reset() allows the query to be asked
+    again the next time the website requests it.
+
+    Does nothing when \l isValid() evaluates to false.
+
+    \sa grant(), deny(), isValid(), QWebEngineProfile::persistentPermissionsPolicy()
+*/
+void QWebEnginePermission::reset() const
+{
+    if (!isValid())
+        return;
+    if (d_ptr->webContentsAdapter)
+        d_ptr->webContentsAdapter.toStrongRef()->setFeaturePermission(origin(), feature(), Ask);
+    else if (d_ptr->profileAdapter)
+        d_ptr->profileAdapter->setPermission(origin(), feature(), Ask);
+}
+
+/*!
+    Returns whether \a feature is transient, meaning that a permission will be requested
+    every time the associated functionality is used by a web page.
+*/
+bool QWebEnginePermission::isTransient(QWebEnginePermission::Feature feature)
+{
+    switch (feature) {
+    case QWebEnginePermission::MediaAudioCapture:
+    case QWebEnginePermission::MediaVideoCapture:
+    case QWebEnginePermission::MediaAudioVideoCapture:
+    case QWebEnginePermission::DesktopVideoCapture:
+    case QWebEnginePermission::DesktopAudioVideoCapture:
+    case QWebEnginePermission::MouseLock:
+        return true;
+    case QWebEnginePermission::Notifications:
+    case QWebEnginePermission::Geolocation:
+    case QWebEnginePermission::ClipboardReadWrite:
+    case QWebEnginePermission::LocalFontsAccess:
+        return false;
+    case QWebEnginePermission::Unsupported:
+        return false;
+    }
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qwebenginepermission.cpp"
diff --git a/src/core/api/qwebenginepermission.h b/src/core/api/qwebenginepermission.h
new file mode 100644
index 00000000000..09db8ce363d
--- /dev/null
+++ b/src/core/api/qwebenginepermission.h
@@ -0,0 +1,90 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QWEBENGINEPERMISSION_H
+#define QWEBENGINEPERMISSION_H
+
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qshareddata.h>
+
+QT_BEGIN_NAMESPACE
+
+struct QWebEnginePermissionPrivate;
+QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QWebEnginePermissionPrivate,
+                                                 Q_WEBENGINECORE_EXPORT)
+
+class QWebEnginePermission
+{
+    Q_GADGET_EXPORT(Q_WEBENGINECORE_EXPORT)
+    Q_PROPERTY(QUrl origin READ origin CONSTANT FINAL)
+    Q_PROPERTY(Feature feature READ feature CONSTANT FINAL)
+    Q_PROPERTY(State state READ state CONSTANT FINAL)
+    Q_PROPERTY(bool isValid READ isValid CONSTANT FINAL)
+    Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
+
+public:
+    Q_WEBENGINECORE_EXPORT QWebEnginePermission();
+
+    Q_WEBENGINECORE_EXPORT QWebEnginePermission(const QWebEnginePermission &other);
+    Q_WEBENGINECORE_EXPORT QWebEnginePermission(QWebEnginePermissionPrivate *pvt);
+    Q_WEBENGINECORE_EXPORT ~QWebEnginePermission();
+
+    Q_WEBENGINECORE_EXPORT QWebEnginePermission &operator=(const QWebEnginePermission &other);
+    QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QWebEnginePermission)
+    void swap(QWebEnginePermission &other) noexcept { d_ptr.swap(other.d_ptr); }
+
+    enum Feature : quint8 {
+        Unsupported,
+        MediaAudioCapture,
+        MediaVideoCapture,
+        MediaAudioVideoCapture,
+        DesktopVideoCapture,
+        DesktopAudioVideoCapture,
+        MouseLock,
+        Notifications,
+        Geolocation,
+        ClipboardReadWrite,
+        LocalFontsAccess,
+    };
+    Q_ENUM(Feature)
+
+    enum State : quint8 {
+        Invalid,
+        Ask,
+        Granted,
+        Denied
+    };
+    Q_ENUM(State)
+
+    Q_WEBENGINECORE_EXPORT const QUrl origin() const;
+    Q_WEBENGINECORE_EXPORT Feature feature() const;
+    Q_WEBENGINECORE_EXPORT State state() const;
+    Q_WEBENGINECORE_EXPORT bool isValid() const;
+
+    Q_WEBENGINECORE_EXPORT Q_INVOKABLE void grant() const;
+    Q_WEBENGINECORE_EXPORT Q_INVOKABLE void deny() const;
+    Q_WEBENGINECORE_EXPORT Q_INVOKABLE void reset() const;
+
+    Q_WEBENGINECORE_EXPORT Q_INVOKABLE static bool isTransient(QWebEnginePermission::Feature feature);
+
+private:
+    inline friend bool operator==(const QWebEnginePermission &lhs, const QWebEnginePermission &rhs)
+        { return lhs.comparesEqual(rhs); };
+    inline friend bool operator!=(const QWebEnginePermission &lhs, const QWebEnginePermission &rhs)
+        { return !lhs.comparesEqual(rhs); };
+
+    Q_WEBENGINECORE_EXPORT bool comparesEqual(const QWebEnginePermission &other) const;
+
+protected:
+    QExplicitlySharedDataPointer<QWebEnginePermissionPrivate> d_ptr;
+};
+
+
+
+Q_DECLARE_SHARED(QWebEnginePermission)
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINEPERMISSION_H
diff --git a/src/core/api/qwebenginepermission_p.h b/src/core/api/qwebenginepermission_p.h
new file mode 100644
index 00000000000..94c89887391
--- /dev/null
+++ b/src/core/api/qwebenginepermission_p.h
@@ -0,0 +1,46 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QWEBENGINEPERMISSION_P_H
+#define QWEBENGINEPERMISSION_P_H
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API.  It exists purely as an
+// implementation detail.  This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qwebenginepermission.h"
+
+#include <QtCore/qpointer.h>
+#include <QtCore/qsharedpointer.h>
+#include <QtCore/qshareddata.h>
+
+namespace QtWebEngineCore {
+class WebContentsAdapter;
+class ProfileAdapter;
+}
+
+QT_BEGIN_NAMESPACE
+
+struct QWebEnginePermissionPrivate : public QSharedData
+{
+    Q_WEBENGINECORE_EXPORT QWebEnginePermissionPrivate();
+    Q_WEBENGINECORE_EXPORT QWebEnginePermissionPrivate(const QUrl &, QWebEnginePermission::Feature,
+        QSharedPointer<QtWebEngineCore::WebContentsAdapter>, QtWebEngineCore::ProfileAdapter *);
+
+    QUrl origin;
+    QWebEnginePermission::Feature feature;
+
+    QWeakPointer<QtWebEngineCore::WebContentsAdapter> webContentsAdapter;
+    QPointer<QtWebEngineCore::ProfileAdapter> profileAdapter;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINEPERMISSION_P_H
diff --git a/src/core/doc/src/qwebenginepage_lgpl.qdoc b/src/core/doc/src/qwebenginepage_lgpl.qdoc
index 1640ca8be37..630ea507e26 100644
--- a/src/core/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/core/doc/src/qwebenginepage_lgpl.qdoc
@@ -245,6 +245,7 @@
 
 /*!
     \enum QWebEnginePage::PermissionPolicy
+    \deprecated [6.8] Replaced by QWebEnginePermission::State.
 
     This enum describes the permission policies that the user may set for data or device access:
 
@@ -273,6 +274,7 @@
 
 /*!
     \enum QWebEnginePage::Feature
+    \deprecated [6.8] Replaced by QWebEnginePermission::Feature.
 
     This enum describes the platform feature access categories that the user may be asked to grant
     or deny access to:
@@ -779,6 +781,8 @@
 
 /*!
     \fn void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, Feature feature, PermissionPolicy policy)
+    \deprecated [6.8] Use QWebEnginePermission's \l {QWebEnginePermission::grant} {grant}(),
+    \l {QWebEnginePermission::deny} {deny}(), and \l {QWebEnginePermission::reset} {reset}() functions instead.
 
     Sets the permission for the web site identified by \a securityOrigin to use \a feature to \a policy.
 
@@ -792,6 +796,7 @@
 
 /*!
     \fn void QWebEnginePage::featurePermissionRequested(const QUrl &securityOrigin, Feature feature)
+    \deprecated [6.8] Use permissionRequested() instead.
 
     This signal is emitted when the web site identified by \a securityOrigin requests to make use of
     the resource or device identified by \a feature.
@@ -801,6 +806,7 @@
 
 /*!
     \fn void QWebEnginePage::featurePermissionRequestCanceled(const QUrl &securityOrigin, Feature feature)
+    \deprecated [6.8] This signal is no longer emitted.
 
     This signal is emitted when the web site identified by \a securityOrigin cancels a previously issued
     request to make use of \a feature.
@@ -809,6 +815,15 @@
 
 */
 
+/*!
+    \fn void QWebEnginePage::permissionRequested(QWebEnginePermission permission)
+    \since 6.8
+
+    This signal is emitted when a web site requests to make use of a feature (e.g. geolocation access,
+    permission to send notifications). The \a permission object can queried for the requesting URL
+    and the \c{QWebEnginePermission::Feature} it's asking for, as well as to grant or deny permission.
+*/
+
 /*!
     \fn void QWebEnginePage::titleChanged(const QString &title)
 
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index 100b7eb7cb2..6883d222404 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -27,28 +27,30 @@
 
 namespace QtWebEngineCore {
 
-static ProfileAdapter::PermissionType toQt(blink::PermissionType type)
+static QWebEnginePermission::Feature toQt(blink::PermissionType type)
 {
     switch (type) {
     case blink::PermissionType::GEOLOCATION:
-        return ProfileAdapter::GeolocationPermission;
+        return QWebEnginePermission::Geolocation;
     case blink::PermissionType::AUDIO_CAPTURE:
-        return ProfileAdapter::AudioCapturePermission;
+        return QWebEnginePermission::MediaAudioCapture;
     case blink::PermissionType::VIDEO_CAPTURE:
-        return ProfileAdapter::VideoCapturePermission;
+        return QWebEnginePermission::MediaVideoCapture;
+    case blink::PermissionType::DISPLAY_CAPTURE:
+        return QWebEnginePermission::DesktopAudioVideoCapture;
         // We treat these both as read/write since we do not currently have a
         // ClipboardSanitizedWrite feature.
     case blink::PermissionType::CLIPBOARD_READ_WRITE:
     case blink::PermissionType::CLIPBOARD_SANITIZED_WRITE:
-        return ProfileAdapter::ClipboardReadWrite;
+        return QWebEnginePermission::ClipboardReadWrite;
     case blink::PermissionType::NOTIFICATIONS:
-        return ProfileAdapter::NotificationPermission;
+        return QWebEnginePermission::Notifications;
     case blink::PermissionType::LOCAL_FONTS:
-        return ProfileAdapter::LocalFontsPermission;
+        return QWebEnginePermission::LocalFontsAccess;
     case blink::PermissionType::ACCESSIBILITY_EVENTS:
     case blink::PermissionType::CAMERA_PAN_TILT_ZOOM:
     case blink::PermissionType::WINDOW_MANAGEMENT:
-        return ProfileAdapter::UnsupportedPermission;
+        return QWebEnginePermission::Unsupported;
     case blink::PermissionType::MIDI_SYSEX:
     case blink::PermissionType::PROTECTED_MEDIA_IDENTIFIER:
     case blink::PermissionType::MIDI:
@@ -65,62 +67,92 @@ static ProfileAdapter::PermissionType toQt(blink::PermissionType type)
     case blink::PermissionType::AR:
     case blink::PermissionType::VR:
     case blink::PermissionType::STORAGE_ACCESS_GRANT:
-    case blink::PermissionType::DISPLAY_CAPTURE:
     case blink::PermissionType::TOP_LEVEL_STORAGE_ACCESS:
     case blink::PermissionType::NUM:
-        LOG(INFO) << "Unexpected unsupported WebEngine permission type: " << static_cast<int>(type);
+        LOG(INFO) << "Unexpected unsupported Blink permission type: " << static_cast<int>(type);
         break;
     }
-    return ProfileAdapter::UnsupportedPermission;
+    return QWebEnginePermission::Unsupported;
 }
 
-static blink::PermissionType toBlink(ProfileAdapter::PermissionType type)
+static blink::PermissionType toBlink(QWebEnginePermission::Feature feature)
 {
-    switch (type) {
-    case ProfileAdapter::GeolocationPermission:
+    switch (feature) {
+    case QWebEnginePermission::Notifications:
+        return blink::PermissionType::NOTIFICATIONS;
+    case QWebEnginePermission::Geolocation:
         return blink::PermissionType::GEOLOCATION;
-    case ProfileAdapter::AudioCapturePermission:
+    case QWebEnginePermission::MediaAudioCapture:
         return blink::PermissionType::AUDIO_CAPTURE;
-    case ProfileAdapter::VideoCapturePermission:
+    case QWebEnginePermission::MediaVideoCapture:
         return blink::PermissionType::VIDEO_CAPTURE;
-    case ProfileAdapter::ClipboardReadWrite:
+    case QWebEnginePermission::DesktopVideoCapture:
+    case QWebEnginePermission::DesktopAudioVideoCapture:
+        return blink::PermissionType::DISPLAY_CAPTURE;
+    case QWebEnginePermission::ClipboardReadWrite:
         return blink::PermissionType::CLIPBOARD_READ_WRITE;
-    case ProfileAdapter::NotificationPermission:
-        return blink::PermissionType::NOTIFICATIONS;
-    case ProfileAdapter::LocalFontsPermission:
+    case QWebEnginePermission::LocalFontsAccess:
         return blink::PermissionType::LOCAL_FONTS;
+    case QWebEnginePermission::MediaAudioVideoCapture:
+    case QWebEnginePermission::Unsupported:
+        LOG(INFO) << "Unexpected unsupported WebEngine permission type: " << static_cast<int>(feature);
+        return blink::PermissionType::NUM;
     }
 
-    LOG(INFO) << "Unexpected unsupported Blink permission type: " << static_cast<int>(type);
-    return blink::PermissionType::NUM;
+    Q_UNREACHABLE();
 }
 
-static bool canRequestPermissionFor(ProfileAdapter::PermissionType type)
+static QWebEnginePermission::State toQt(blink::mojom::PermissionStatus state)
 {
-    switch (type) {
-    case ProfileAdapter::GeolocationPermission:
-    case ProfileAdapter::NotificationPermission:
-    case ProfileAdapter::ClipboardReadWrite:
-    case ProfileAdapter::LocalFontsPermission:
-        return true;
-    default:
-        break;
+    switch (state) {
+    case blink::mojom::PermissionStatus::ASK:
+        return QWebEnginePermission::Ask;
+    case blink::mojom::PermissionStatus::GRANTED:
+        return QWebEnginePermission::Granted;
+    case blink::mojom::PermissionStatus::DENIED:
+        return QWebEnginePermission::Denied;
     }
-    return false;
 }
 
-static blink::mojom::PermissionStatus toBlink(ProfileAdapter::PermissionState reply)
+static blink::mojom::PermissionStatus toBlink(QWebEnginePermission::State state)
 {
-    switch (reply) {
-    case ProfileAdapter::AskPermission:
+    switch (state) {
+    case QWebEnginePermission::Invalid:
+    case QWebEnginePermission::Ask:
         return blink::mojom::PermissionStatus::ASK;
-    case ProfileAdapter::AllowedPermission:
+    case QWebEnginePermission::Granted:
         return blink::mojom::PermissionStatus::GRANTED;
-    case ProfileAdapter::DeniedPermission:
+    case QWebEnginePermission::Denied:
         return blink::mojom::PermissionStatus::DENIED;
     }
 }
 
+std::string featureString(QWebEnginePermission::Feature feature)
+{
+    // This is separate from blink::featureString() for the sake of future-proofing;
+    // e.g. in case we add extra Features that do not correspond to a PermissionType, and
+    // we need to store them.
+    switch (feature) {
+    case QWebEnginePermission::Notifications:
+        return "Notifications";
+    case QWebEnginePermission::Geolocation:
+        return "Geolocation";
+    case QWebEnginePermission::ClipboardReadWrite:
+        return "ClipboardReadWrite";
+    case QWebEnginePermission::LocalFontsAccess:
+        return "LocalFontsAccess";
+    case QWebEnginePermission::MediaAudioCapture:
+        return "MediaAudioCapture";
+    case QWebEnginePermission::MediaVideoCapture:
+        return "MediaVideoCapture";
+    case QWebEnginePermission::DesktopAudioVideoCapture:
+        return "DesktopAudioVideoCapture";
+    default:
+        Q_UNREACHABLE();
+        return nullptr;
+    }
+}
+
 static blink::mojom::PermissionStatus getStatusFromSettings(blink::PermissionType type, WebEngineSettings *settings)
 {
     switch (type) {
@@ -159,12 +191,12 @@ PermissionManagerQt::PermissionManagerQt(ProfileAdapter *profileAdapter)
     }
 
     // Register all preference types as keys prior to doing anything else
-    prefRegistry->RegisterDictionaryPref(GetPermissionString(toBlink(ProfileAdapter::GeolocationPermission)));
-    prefRegistry->RegisterDictionaryPref(GetPermissionString(toBlink(ProfileAdapter::AudioCapturePermission)));
-    prefRegistry->RegisterDictionaryPref(GetPermissionString(toBlink(ProfileAdapter::VideoCapturePermission)));
-    prefRegistry->RegisterDictionaryPref(GetPermissionString(toBlink(ProfileAdapter::ClipboardReadWrite)));
-    prefRegistry->RegisterDictionaryPref(GetPermissionString(toBlink(ProfileAdapter::NotificationPermission)));
-    prefRegistry->RegisterDictionaryPref(GetPermissionString(toBlink(ProfileAdapter::LocalFontsPermission)));
+    prefRegistry->RegisterDictionaryPref(featureString(QWebEnginePermission::Geolocation));
+    prefRegistry->RegisterDictionaryPref(featureString(QWebEnginePermission::ClipboardReadWrite));
+    prefRegistry->RegisterDictionaryPref(featureString(QWebEnginePermission::Notifications));
+    prefRegistry->RegisterDictionaryPref(featureString(QWebEnginePermission::LocalFontsAccess));
+    prefRegistry->RegisterDictionaryPref(featureString(QWebEnginePermission::MediaAudioCapture));
+    prefRegistry->RegisterDictionaryPref(featureString(QWebEnginePermission::MediaVideoCapture));
     PrefProxyConfigTrackerImpl::RegisterPrefs(prefRegistry.get());
 
     if (policy == ProfileAdapter::NoPersistentPermissions)
@@ -181,34 +213,35 @@ PermissionManagerQt::~PermissionManagerQt()
     commit();
 }
 
-void PermissionManagerQt::permissionRequestReply(const QUrl &url, ProfileAdapter::PermissionType type, ProfileAdapter::PermissionState reply)
+void PermissionManagerQt::setPermission(const QUrl &url, QWebEnginePermission::Feature feature, QWebEnginePermission::State state)
 {
     // Normalize the QUrl to Chromium origin form.
     const GURL gorigin = toGurl(url).DeprecatedGetOriginAsURL();
     const QUrl origin = gorigin.is_empty() ? url : toQt(gorigin);
     if (origin.isEmpty())
         return;
-    if (reply == ProfileAdapter::AskPermission)
-        ResetPermission(toBlink(type), gorigin, gorigin);
+    if (state == QWebEnginePermission::Ask)
+        ResetPermission(toBlink(feature), gorigin, gorigin);
     else
-        setPermission(toBlink(type), gorigin, reply == ProfileAdapter::AllowedPermission);
-    blink::mojom::PermissionStatus status = toBlink(reply);
-    if (reply != ProfileAdapter::AskPermission) {
+        setPermission(toBlink(feature), gorigin, state == QWebEnginePermission::Granted);
+    blink::mojom::PermissionStatus status = toBlink(state);
+    if (state != QWebEnginePermission::Ask) {
         auto it = m_requests.begin();
         while (it != m_requests.end()) {
-            if (it->origin == origin && it->type == type) {
+            if (it->origin == origin && it->type == feature) {
                 std::move(it->callback).Run(status);
                 it = m_requests.erase(it);
             } else
                 ++it;
         }
     }
+
     for (const auto &it: m_subscribers) {
-        if (it.second.origin == origin && it.second.type == type)
+        if (it.second.origin == origin && it.second.type == feature)
             it.second.callback.Run(status);
     }
 
-    if (reply == ProfileAdapter::AskPermission)
+    if (state == QWebEnginePermission::Ask)
         return;
 
     auto it = m_multiRequests.begin();
@@ -218,13 +251,13 @@ void PermissionManagerQt::permissionRequestReply(const QUrl &url, ProfileAdapter
             std::vector<blink::mojom::PermissionStatus> result;
             result.reserve(it->types.size());
             for (blink::PermissionType permission : it->types) {
-                if (toQt(permission) == ProfileAdapter::UnsupportedPermission) {
+                if (toQt(permission) == QWebEnginePermission::Unsupported) {
                     result.push_back(blink::mojom::PermissionStatus::DENIED);
                     continue;
                 }
 
                 blink::mojom::PermissionStatus permissionStatus = GetPermissionStatus(permission, gorigin, GURL());
-                if (permissionStatus == toBlink(reply)) {
+                if (permissionStatus == toBlink(state)) {
                     if (permissionStatus == blink::mojom::PermissionStatus::ASK) {
                         answerable = false;
                         break;
@@ -233,7 +266,7 @@ void PermissionManagerQt::permissionRequestReply(const QUrl &url, ProfileAdapter
                     result.push_back(permissionStatus);
                 } else {
                     // Reached when the PersistentPermissionsPolicy is set to NoPersistentPermissions
-                    result.push_back(toBlink(reply));
+                    result.push_back(toBlink(state));
                 }
             }
             if (answerable) {
@@ -246,9 +279,9 @@ void PermissionManagerQt::permissionRequestReply(const QUrl &url, ProfileAdapter
     }
 }
 
-bool PermissionManagerQt::checkPermission(const QUrl &origin, ProfileAdapter::PermissionType type)
+QWebEnginePermission::State PermissionManagerQt::getPermissionState(const QUrl &origin, QWebEnginePermission::Feature feature)
 {
-    return GetPermissionStatus(toBlink(type), toGurl(origin), GURL()) == blink::mojom::PermissionStatus::GRANTED;
+    return toQt(GetPermissionStatus(toBlink(feature), toGurl(origin), GURL()));
 }
 
 void PermissionManagerQt::commit()
@@ -275,8 +308,8 @@ void PermissionManagerQt::RequestPermissions(content::RenderFrameHost *frameHost
     std::vector<content::PermissionStatus> result;
     result.reserve(requestDescription.permissions.size());
     for (blink::PermissionType permission : requestDescription.permissions) {
-        const ProfileAdapter::PermissionType permissionType = toQt(permission);
-        if (permissionType == ProfileAdapter::UnsupportedPermission) {
+        const QWebEnginePermission::Feature feature = toQt(permission);
+        if (feature == QWebEnginePermission::Unsupported) {
             result.push_back(blink::mojom::PermissionStatus::DENIED);
             continue;
         }
@@ -306,9 +339,9 @@ void PermissionManagerQt::RequestPermissions(content::RenderFrameHost *frameHost
     auto requestOrigin = toQt(requestDescription.requesting_origin);
     m_multiRequests.push_back({ request_id, requestDescription.permissions, requestOrigin, std::move(callback) });
     for (blink::PermissionType permission : requestDescription.permissions) {
-        const ProfileAdapter::PermissionType permissionType = toQt(permission);
-        if (canRequestPermissionFor(permissionType))
-            contentsDelegate->requestFeaturePermission(permissionType, requestOrigin);
+        const QWebEnginePermission::Feature feature = toQt(permission);
+        if (!QWebEnginePermission::isTransient(feature))
+            contentsDelegate->requestFeaturePermission(feature, requestOrigin);
     }
 }
 
@@ -324,12 +357,12 @@ blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatus(
     const GURL& requesting_origin,
     const GURL& /*embedding_origin*/)
 {
-    const ProfileAdapter::PermissionType permissionType = toQt(permission);
-    if (permissionType == ProfileAdapter::UnsupportedPermission)
+    const QWebEnginePermission::Feature feature = toQt(permission);
+    if (feature == QWebEnginePermission::Unsupported)
         return blink::mojom::PermissionStatus::DENIED;
 
     permission = toBlink(toQt(permission)); // Filter out merged/unsupported permissions (e.g. clipboard)
-    auto *pref = m_prefService->FindPreference(GetPermissionString(permission));
+    auto *pref = m_prefService->FindPreference(featureString(toQt(permission)));
     if (!pref)
         return blink::mojom::PermissionStatus::ASK; // Permission type not in database
 
@@ -405,11 +438,11 @@ void PermissionManagerQt::ResetPermission(
     const GURL& requesting_origin,
     const GURL& /*embedding_origin*/)
 {
-    const ProfileAdapter::PermissionType permissionType = toQt(permission);
-    if (permissionType == ProfileAdapter::UnsupportedPermission)
+    const QWebEnginePermission::Feature feature = toQt(permission);
+    if (feature == QWebEnginePermission::Unsupported)
         return;
 
-    ScopedDictPrefUpdate updater(m_prefService.get(), GetPermissionString(permission));
+    ScopedDictPrefUpdate updater(m_prefService.get(), featureString(feature));
     updater.Get().Remove(requesting_origin.spec());
 }
 
@@ -437,14 +470,14 @@ void PermissionManagerQt::setPermission(
     const GURL& requesting_origin,
     bool granted)
 {
-    const ProfileAdapter::PermissionType permissionType = toQt(permission);
-    if (permissionType == ProfileAdapter::UnsupportedPermission)
+    const QWebEnginePermission::Feature feature = toQt(permission);
+    if (feature == QWebEnginePermission::Unsupported)
         return;
 
-    if (!m_prefService->FindPreference(GetPermissionString(permission)))
+    if (!m_prefService->FindPreference(featureString(feature)))
         return;
 
-    ScopedDictPrefUpdate updater(m_prefService.get(), GetPermissionString(permission));
+    ScopedDictPrefUpdate updater(m_prefService.get(), featureString(feature));
     updater.Get().Set(requesting_origin.spec(), granted);
 }
 
diff --git a/src/core/permission_manager_qt.h b/src/core/permission_manager_qt.h
index 5dedaa612fb..e74a3fba126 100644
--- a/src/core/permission_manager_qt.h
+++ b/src/core/permission_manager_qt.h
@@ -7,6 +7,7 @@
 #include "base/functional/callback.h"
 #include "content/public/browser/permission_controller_delegate.h"
 
+#include <QtWebEngineCore/qwebenginepermission.h>
 #include "profile_adapter.h"
 
 #include <map>
@@ -21,8 +22,9 @@ class PermissionManagerQt : public content::PermissionControllerDelegate
     PermissionManagerQt(ProfileAdapter *adapter);
     ~PermissionManagerQt();
 
-    void permissionRequestReply(const QUrl &origin, ProfileAdapter::PermissionType type, ProfileAdapter::PermissionState reply);
-    bool checkPermission(const QUrl &origin, ProfileAdapter::PermissionType type);
+    void setPermission(const QUrl &origin, QWebEnginePermission::Feature feature, QWebEnginePermission::State state);
+    QWebEnginePermission::State getPermissionState(const QUrl &origin, QWebEnginePermission::Feature feature);
+
     void commit();
 
     // content::PermissionManager implementation:
@@ -66,7 +68,7 @@ class PermissionManagerQt : public content::PermissionControllerDelegate
 private:
     struct Request {
         int id;
-        ProfileAdapter::PermissionType type;
+        QWebEnginePermission::Feature type;
         QUrl origin;
         base::OnceCallback<void(blink::mojom::PermissionStatus)> callback;
     };
@@ -77,7 +79,7 @@ class PermissionManagerQt : public content::PermissionControllerDelegate
         base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus>&)> callback;
     };
     struct Subscription {
-        ProfileAdapter::PermissionType type;
+        QWebEnginePermission::Feature type;
         QUrl origin;
         base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback;
     };
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index 6fec8aa2879..4b337e8ed3c 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -569,14 +569,14 @@ UserResourceControllerHost *ProfileAdapter::userResourceController()
     return m_userResourceController.data();
 }
 
-void ProfileAdapter::permissionRequestReply(const QUrl &origin, PermissionType type, PermissionState reply)
+void ProfileAdapter::setPermission(const QUrl &origin, QWebEnginePermission::Feature feature, QWebEnginePermission::State state)
 {
-    static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->permissionRequestReply(origin, type, reply);
+    static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->setPermission(origin, feature, state);
 }
 
-bool ProfileAdapter::checkPermission(const QUrl &origin, PermissionType type)
+QWebEnginePermission::State ProfileAdapter::getPermissionState(const QUrl &origin, QWebEnginePermission::Feature feature)
 {
-    return static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->checkPermission(origin, type);
+    return static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->getPermissionState(origin, feature);
 }
 
 QString ProfileAdapter::httpAcceptLanguageWithoutQualities() const
diff --git a/src/core/profile_adapter.h b/src/core/profile_adapter.h
index 18d82ba9631..644d7e03c32 100644
--- a/src/core/profile_adapter.h
+++ b/src/core/profile_adapter.h
@@ -28,6 +28,7 @@
 #include <QtWebEngineCore/qwebenginecookiestore.h>
 #include <QtWebEngineCore/qwebengineurlrequestinterceptor.h>
 #include <QtWebEngineCore/qwebengineurlschemehandler.h>
+#include <QtWebEngineCore/qwebenginepermission.h>
 #include "net/qrc_url_scheme_handler.h"
 
 QT_FORWARD_DECLARE_CLASS(QObject)
@@ -133,22 +134,6 @@ class Q_WEBENGINECORE_EXPORT ProfileAdapter : public QObject
         PersistentPermissionsOnDisk,
     };
 
-    enum PermissionType {
-        UnsupportedPermission = 0,
-        GeolocationPermission = 1,
-        NotificationPermission = 2,
-        AudioCapturePermission = 3,
-        VideoCapturePermission = 4,
-        ClipboardReadWrite = 5,
-        LocalFontsPermission = 6,
-    };
-
-    enum PermissionState {
-        AskPermission = 0,
-        AllowedPermission = 1,
-        DeniedPermission = 2
-    };
-
     enum ClientHint : uchar {
         UAArchitecture,
         UAPlatform,
@@ -187,8 +172,8 @@ class Q_WEBENGINECORE_EXPORT ProfileAdapter : public QObject
     const QList<QByteArray> customUrlSchemes() const;
     UserResourceControllerHost *userResourceController();
 
-    void permissionRequestReply(const QUrl &origin, PermissionType type, PermissionState reply);
-    bool checkPermission(const QUrl &origin, PermissionType type);
+    void setPermission(const QUrl &origin, QWebEnginePermission::Feature feature, QWebEnginePermission::State state);
+    QWebEnginePermission::State getPermissionState(const QUrl &origin, QWebEnginePermission::Feature feature);
 
     QString httpAcceptLanguageWithoutQualities() const;
     QString httpAcceptLanguage() const;
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 4774cf4dcc1..7d9e119e94a 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -1411,21 +1411,92 @@ QSizeF WebContentsAdapter::lastContentsSize() const
     return QSizeF();
 }
 
-void WebContentsAdapter::grantMediaAccessPermission(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags flags)
+void WebContentsAdapter::setFeaturePermission(const QUrl &origin, QWebEnginePermission::Feature feature, QWebEnginePermission::State state)
 {
+    if (!QWebEnginePermission::isTransient(feature)) {
+        // Do not check for initialization in this path so permissions can be set before first navigation
+        Q_ASSERT(m_profileAdapter);
+        m_profileAdapter->setPermission(origin, feature, state);
+        return;
+    }
+
     CHECK_INITIALIZED();
-    // Let the permission manager remember the reply.
-    if (flags & WebContentsAdapterClient::MediaAudioCapture)
-        m_profileAdapter->permissionRequestReply(securityOrigin, ProfileAdapter::AudioCapturePermission, ProfileAdapter::AllowedPermission);
-    if (flags & WebContentsAdapterClient::MediaVideoCapture)
-        m_profileAdapter->permissionRequestReply(securityOrigin, ProfileAdapter::VideoCapturePermission, ProfileAdapter::AllowedPermission);
-    MediaCaptureDevicesDispatcher::GetInstance()->handleMediaAccessPermissionResponse(m_webContents.get(), securityOrigin, flags);
+    if (feature == QWebEnginePermission::MouseLock) {
+        switch (state) {
+        case QWebEnginePermission::Ask:
+            // Do nothing
+            break;
+        case QWebEnginePermission::Denied:
+            grantMouseLockPermission(origin, false);
+            break;
+        case QWebEnginePermission::Granted:
+            grantMouseLockPermission(origin, true);
+            break;
+        }
+
+        return;
+    }
+
+    const WebContentsAdapterClient::MediaRequestFlags audioVideoCaptureFlags(
+        WebContentsAdapterClient::MediaVideoCapture |
+        WebContentsAdapterClient::MediaAudioCapture);
+    const WebContentsAdapterClient::MediaRequestFlags desktopAudioVideoCaptureFlags(
+        WebContentsAdapterClient::MediaDesktopVideoCapture |
+        WebContentsAdapterClient::MediaDesktopAudioCapture);
+
+    switch (state) {
+    case QWebEnginePermission::Ask:
+        // Do nothing
+        return;
+    case QWebEnginePermission::Denied:
+        // Deny all media access
+        grantMediaAccessPermission(origin, WebContentsAdapterClient::MediaNone);
+        return;
+    case QWebEnginePermission::Granted:
+        // Enable only the requested capture type
+        break;
+    }
+
+    switch (feature) {
+    case QWebEnginePermission::MediaAudioVideoCapture:
+        grantMediaAccessPermission(origin, audioVideoCaptureFlags);
+        break;
+    case QWebEnginePermission::MediaAudioCapture:
+        grantMediaAccessPermission(origin, WebContentsAdapterClient::MediaAudioCapture);
+        break;
+    case QWebEnginePermission::MediaVideoCapture:
+        grantMediaAccessPermission(origin, WebContentsAdapterClient::MediaVideoCapture);
+        break;
+    case QWebEnginePermission::DesktopAudioVideoCapture:
+        grantMediaAccessPermission(origin, desktopAudioVideoCaptureFlags);
+        break;
+    case QWebEnginePermission::DesktopVideoCapture:
+        grantMediaAccessPermission(origin, WebContentsAdapterClient::MediaDesktopVideoCapture);
+        break;
+    default:
+        Q_UNREACHABLE();
+        break;
+    }
 }
 
-void WebContentsAdapter::grantFeaturePermission(const QUrl &securityOrigin, ProfileAdapter::PermissionType feature, ProfileAdapter::PermissionState allowed)
+QWebEnginePermission::State WebContentsAdapter::getPermissionState(const QUrl &origin, QWebEnginePermission::Feature feature)
 {
-    Q_ASSERT(m_profileAdapter);
-    m_profileAdapter->permissionRequestReply(securityOrigin, feature, allowed);
+    // For now, we just return Ask for transient Features
+    if (QWebEnginePermission::isTransient(feature))
+        return QWebEnginePermission::Ask;
+
+    return m_profileAdapter->getPermissionState(origin, feature);
+}
+
+void WebContentsAdapter::grantMediaAccessPermission(const QUrl &origin, WebContentsAdapterClient::MediaRequestFlags flags)
+{
+    CHECK_INITIALIZED();
+    // Let the permission manager remember the reply.
+    if (flags & WebContentsAdapterClient::MediaAudioCapture)
+        m_profileAdapter->setPermission(origin, QWebEnginePermission::MediaAudioCapture, QWebEnginePermission::Granted);
+    if (flags & WebContentsAdapterClient::MediaVideoCapture)
+        m_profileAdapter->setPermission(origin, QWebEnginePermission::MediaVideoCapture, QWebEnginePermission::Granted);
+    MediaCaptureDevicesDispatcher::GetInstance()->handleMediaAccessPermissionResponse(m_webContents.get(), origin, flags);
 }
 
 void WebContentsAdapter::grantMouseLockPermission(const QUrl &securityOrigin, bool granted)
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 61da0ba7bbe..66736dd2151 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -26,6 +26,7 @@
 #include <QtWebEngineCore/qwebenginecontextmenurequest.h>
 #include <QtWebEngineCore/qwebenginehttprequest.h>
 #include <QtWebEngineCore/qwebengineframe.h>
+#include <QtWebEngineCore/qwebenginepermission.h>
 
 #include "web_contents_adapter_client.h"
 
@@ -178,10 +179,12 @@ class Q_WEBENGINECORE_EXPORT WebContentsAdapter : public QEnableSharedFromThis<W
     void devToolsFrontendDestroyed(DevToolsFrontendQt *frontend);
     QString devToolsId();
 
-    void grantMediaAccessPermission(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags flags);
-    void grantMouseLockPermission(const QUrl &securityOrigin, bool granted);
+    void setFeaturePermission(const QUrl &origin, QWebEnginePermission::Feature feature, QWebEnginePermission::State state);
+    QWebEnginePermission::State getPermissionState(const QUrl &origin, QWebEnginePermission::Feature feature);
+
+    void grantMediaAccessPermission(const QUrl &origin, WebContentsAdapterClient::MediaRequestFlags flags);
+    void grantMouseLockPermission(const QUrl &origin, bool granted);
     void handlePendingMouseLockPermission();
-    void grantFeaturePermission(const QUrl &securityOrigin, ProfileAdapter::PermissionType feature, ProfileAdapter::PermissionState allowed);
 
     void setBackgroundColor(const QColor &color);
     QAccessibleInterface *browserAccessible();
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 6cb07a32bc3..ca162833c81 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -16,6 +16,7 @@
 #define WEB_CONTENTS_ADAPTER_CLIENT_H
 
 #include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
+#include <QtWebEngineCore/qwebenginepermission.h>
 
 #include "profile_adapter.h"
 
@@ -194,7 +195,7 @@ class Q_WEBENGINECORE_EXPORT WebContentsAdapterClient {
     virtual QObject *accessibilityParentObject() = 0;
     virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) = 0;
     virtual void authenticationRequired(QSharedPointer<AuthenticationDialogController>) = 0;
-    virtual void runFeaturePermissionRequest(ProfileAdapter::PermissionType, const QUrl &securityOrigin) = 0;
+    virtual void runFeaturePermissionRequest(QWebEnginePermission::Feature, const QUrl &securityOrigin) = 0;
     virtual void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) = 0;
     virtual void runMouseLockPermissionRequest(const QUrl &securityOrigin) = 0;
     virtual void runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest) = 0;
@@ -228,6 +229,7 @@ class Q_WEBENGINECORE_EXPORT WebContentsAdapterClient {
     virtual WebContentsAdapter* webContentsAdapter() = 0;
     virtual void releaseProfile() = 0;
     virtual void showWebAuthDialog(QWebEngineWebAuthUxRequest *request) = 0;
+    virtual QWebEnginePermission createFeaturePermissionObject(const QUrl &securityOrigin, QWebEnginePermission::Feature feature) = 0;
 };
 
 } // namespace QtWebEngineCore
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 4df73fb6999..e16f5d769a2 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -733,7 +733,7 @@ void WebContentsDelegateQt::selectClientCert(const QSharedPointer<ClientCertSele
     m_viewClient->selectClientCert(selectController);
 }
 
-void WebContentsDelegateQt::requestFeaturePermission(ProfileAdapter::PermissionType feature, const QUrl &requestingOrigin)
+void WebContentsDelegateQt::requestFeaturePermission(QWebEnginePermission::Feature feature, const QUrl &requestingOrigin)
 {
     m_viewClient->runFeaturePermissionRequest(feature, requestingOrigin);
 }
@@ -790,9 +790,9 @@ bool WebContentsDelegateQt::CheckMediaAccessPermission(content::RenderFrameHost
 {
     switch (type) {
     case blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE:
-        return m_viewClient->profileAdapter()->checkPermission(toQt(security_origin), ProfileAdapter::AudioCapturePermission);
+        return m_viewClient->profileAdapter()->getPermissionState(toQt(security_origin), QWebEnginePermission::MediaAudioCapture);
     case blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE:
-        return m_viewClient->profileAdapter()->checkPermission(toQt(security_origin), ProfileAdapter::VideoCapturePermission);
+        return m_viewClient->profileAdapter()->getPermissionState(toQt(security_origin), QWebEnginePermission::MediaVideoCapture);
     default:
         LOG(INFO) << "WebContentsDelegateQt::CheckMediaAccessPermission: "
                   << "Unsupported media stream type checked " << type;
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index 51004878d65..88056c3ca36 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -136,7 +136,7 @@ class WebContentsDelegateQt : public content::WebContentsDelegate
     void overrideWebPreferences(content::WebContents *, blink::web_pref::WebPreferences*);
     void allowCertificateError(const QSharedPointer<CertificateErrorController> &);
     void selectClientCert(const QSharedPointer<ClientCertSelectController> &);
-    void requestFeaturePermission(ProfileAdapter::PermissionType feature, const QUrl &requestingOrigin);
+    void requestFeaturePermission(QWebEnginePermission::Feature feature, const QUrl &requestingOrigin);
     void launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame, bool has_user_gesture);
     FindTextHelper *findTextHelper();
 
diff --git a/src/webenginequick/api/qquickwebengineforeigntypes_p.h b/src/webenginequick/api/qquickwebengineforeigntypes_p.h
index 7ba3a412114..58dee066ffb 100644
--- a/src/webenginequick/api/qquickwebengineforeigntypes_p.h
+++ b/src/webenginequick/api/qquickwebengineforeigntypes_p.h
@@ -32,6 +32,7 @@
 #include <QtWebEngineCore/qwebengineregisterprotocolhandlerrequest.h>
 #include <QtWebEngineCore/qwebenginefilesystemaccessrequest.h>
 #include <QtWebEngineCore/qwebenginewebauthuxrequest.h>
+#include <QtWebEngineCore/qwebenginepermission.h>
 
 QT_BEGIN_NAMESPACE
 
@@ -240,6 +241,30 @@ struct ForeginWebEngineWebAuthPinRequest
     QML_UNCREATABLE("")
 };
 
+// To prevent the same type from being exported twice into qmltypes
+// (for value type and for the enums)
+class QWebEnginePermissionDerived : public QWebEnginePermission
+{
+    Q_GADGET
+};
+
+namespace ForeignWebEnginePermissionNamespace
+{
+    Q_NAMESPACE
+    QML_FOREIGN_NAMESPACE(QWebEnginePermissionDerived)
+    QML_NAMED_ELEMENT(WebEnginePermission)
+    QML_ADDED_IN_VERSION(6, 8)
+}
+
+struct ForeignWebEnginePermission
+{
+    Q_GADGET
+    QML_FOREIGN(QWebEnginePermission)
+    QML_VALUE_TYPE(webEnginePermission)
+    QML_ADDED_IN_VERSION(6, 8)
+    QML_UNCREATABLE("")
+};
+
 QT_END_NAMESPACE
 
 #endif // QQUICKWEBENGINEFOREIGNTYPES_H
diff --git a/src/webenginequick/api/qquickwebenginesettings.cpp b/src/webenginequick/api/qquickwebenginesettings.cpp
index 31ed7a661b0..5dc093a4472 100644
--- a/src/webenginequick/api/qquickwebenginesettings.cpp
+++ b/src/webenginequick/api/qquickwebenginesettings.cpp
@@ -79,7 +79,7 @@ bool QQuickWebEngineSettings::javascriptCanOpenWindows() const
 
     Since unrestricted clipboard access is a potential security concern, it is
     recommended that applications leave this disabled and instead respond to
-    \l{WebEngineView::ClipboardReadWrite}{ClipboardReadWrite} feature permission requests.
+    \l{WebEnginePermission::ClipboardReadWrite}{ClipboardReadWrite} feature permission requests.
 
     Disabled by default.
 */
@@ -389,7 +389,7 @@ bool QQuickWebEngineSettings::webRTCPublicInterfacesOnly() const
 
     Since unrestricted clipboard access is a potential security concern, it is
     recommended that applications leave this disabled and instead respond to
-    \l{WebEngineView::ClipboardReadWrite}{ClipboardReadWrite} feature permission requests.
+    \l{WebEnginePermission::ClipboardReadWrite}{ClipboardReadWrite} feature permission requests.
 
     Disabled by default.
 */
diff --git a/src/webenginequick/api/qquickwebengineview.cpp b/src/webenginequick/api/qquickwebengineview.cpp
index 0ff182c7a3e..852d00c7642 100644
--- a/src/webenginequick/api/qquickwebengineview.cpp
+++ b/src/webenginequick/api/qquickwebengineview.cpp
@@ -41,6 +41,7 @@
 #include <QtWebEngineCore/qwebengineregisterprotocolhandlerrequest.h>
 #include <QtWebEngineCore/qwebenginescriptcollection.h>
 #include <QtWebEngineCore/qwebenginewebauthuxrequest.h>
+#include <QtWebEngineCore/qwebenginepermission.h>
 #include <QtWebEngineCore/private/qwebenginecontextmenurequest_p.h>
 #include <QtWebEngineCore/private/qwebenginedesktopmediarequest_p.h>
 #include <QtWebEngineCore/private/qwebenginehistory_p.h>
@@ -48,6 +49,7 @@
 #include <QtWebEngineCore/private/qwebenginescriptcollection_p.h>
 #include <QtWebEngineCore/private/qwebenginepage_p.h>
 #include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
+#include <QtWebEngineCore/private/qwebenginepermission_p.h>
 
 #include <QtCore/qloggingcategory.h>
 #include <QtCore/qmimedata.h>
@@ -484,29 +486,67 @@ void QQuickWebEngineViewPrivate::selectClientCert(
     Q_EMIT q->selectClientCertificate(certSelection);
 }
 
-static QQuickWebEngineView::Feature toFeature(QtWebEngineCore::ProfileAdapter::PermissionType type)
+#if QT_DEPRECATED_SINCE(6, 8)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+static QQuickWebEngineView::Feature toDeprecatedFeature(QWebEnginePermission::Feature feature)
 {
-    switch (type) {
-    case QtWebEngineCore::ProfileAdapter::NotificationPermission:
+    switch (feature) {
+    case QWebEnginePermission::Feature::Notifications:
         return QQuickWebEngineView::Notifications;
-    case QtWebEngineCore::ProfileAdapter::GeolocationPermission:
+    case QWebEnginePermission::Feature::Geolocation:
         return QQuickWebEngineView::Geolocation;
-    case QtWebEngineCore::ProfileAdapter::ClipboardReadWrite:
+    case QWebEnginePermission::Feature::ClipboardReadWrite:
         return QQuickWebEngineView::ClipboardReadWrite;
-    case QtWebEngineCore::ProfileAdapter::LocalFontsPermission:
+    case QWebEnginePermission::Feature::LocalFontsAccess:
         return QQuickWebEngineView::LocalFontsAccess;
-    default:
+    case QWebEnginePermission::Feature::MediaAudioCapture:
+        return QQuickWebEngineView::MediaAudioCapture;
+    case QWebEnginePermission::Feature::MediaVideoCapture:
+        return QQuickWebEngineView::MediaVideoCapture;
+    case QWebEnginePermission::Feature::MediaAudioVideoCapture:
+        return QQuickWebEngineView::MediaAudioVideoCapture;
+    case QWebEnginePermission::Feature::DesktopVideoCapture:
+        return QQuickWebEngineView::DesktopVideoCapture;
+    case QWebEnginePermission::Feature::DesktopAudioVideoCapture:
+        return QQuickWebEngineView::DesktopAudioVideoCapture;
+    case QWebEnginePermission::Feature::MouseLock:
+    case QWebEnginePermission::Feature::Unsupported:
         break;
     }
+
     Q_UNREACHABLE();
     return QQuickWebEngineView::Feature(-1);
 }
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 8)
 
-
-void QQuickWebEngineViewPrivate::runFeaturePermissionRequest(QtWebEngineCore::ProfileAdapter::PermissionType permission, const QUrl &url)
+void QQuickWebEngineViewPrivate::runFeaturePermissionRequest(QWebEnginePermission::Feature feature, const QUrl &url)
 {
     Q_Q(QQuickWebEngineView);
-    Q_EMIT q->featurePermissionRequested(url, toFeature(permission));
+    switch (feature) {
+    case QWebEnginePermission::Notifications:
+    case QWebEnginePermission::Geolocation:
+    case QWebEnginePermission::ClipboardReadWrite:
+    case QWebEnginePermission::LocalFontsAccess:
+        Q_EMIT q->permissionRequested(createFeaturePermissionObject(url, feature));
+#if QT_DEPRECATED_SINCE(6, 8)
+        QT_WARNING_PUSH
+        QT_WARNING_DISABLE_DEPRECATED
+        Q_EMIT q->featurePermissionRequested(url, toDeprecatedFeature(feature));
+        QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 8)
+        return;
+    case QWebEnginePermission::MouseLock:
+    case QWebEnginePermission::MediaAudioCapture:
+    case QWebEnginePermission::MediaVideoCapture:
+    case QWebEnginePermission::MediaAudioVideoCapture:
+    case QWebEnginePermission::DesktopAudioVideoCapture:
+    case QWebEnginePermission::DesktopVideoCapture:
+    case QWebEnginePermission::Unsupported:
+        Q_UNREACHABLE();
+        return;
+    }
 }
 
 void QQuickWebEngineViewPrivate::showColorDialog(QSharedPointer<ColorChooserController> controller)
@@ -784,19 +824,41 @@ void QQuickWebEngineViewPrivate::runMediaAccessPermissionRequest(const QUrl &sec
     Q_Q(QQuickWebEngineView);
     if (!requestFlags)
         return;
-    QQuickWebEngineView::Feature feature;
+    QWebEnginePermission::Feature feature;
     if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture) && requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
-        feature = QQuickWebEngineView::MediaAudioVideoCapture;
+        feature = QWebEnginePermission::MediaAudioVideoCapture;
     else if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture))
-        feature = QQuickWebEngineView::MediaAudioCapture;
+        feature = QWebEnginePermission::MediaAudioCapture;
     else if (requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
-        feature = QQuickWebEngineView::MediaVideoCapture;
+        feature = QWebEnginePermission::MediaVideoCapture;
     else if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopAudioCapture) &&
              requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture))
-        feature = QQuickWebEngineView::DesktopAudioVideoCapture;
+        feature = QWebEnginePermission::DesktopAudioVideoCapture;
+    else // if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture))
+        feature = QWebEnginePermission::DesktopVideoCapture;
+    Q_EMIT q->permissionRequested(createFeaturePermissionObject(securityOrigin, feature));
+
+#if QT_DEPRECATED_SINCE(6, 8)
+    QT_WARNING_PUSH
+    QT_WARNING_DISABLE_DEPRECATED
+    QQuickWebEngineView::Feature deprecatedFeature;
+
+    if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture)
+            && requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
+        deprecatedFeature = QQuickWebEngineView::MediaAudioVideoCapture;
+    else if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture))
+        deprecatedFeature = QQuickWebEngineView::MediaAudioCapture;
+    else if (requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
+        deprecatedFeature = QQuickWebEngineView::MediaVideoCapture;
+    else if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopAudioCapture)
+            && requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture))
+        deprecatedFeature = QQuickWebEngineView::DesktopAudioVideoCapture;
     else // if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture))
-        feature = QQuickWebEngineView::DesktopVideoCapture;
-    Q_EMIT q->featurePermissionRequested(securityOrigin, feature);
+        deprecatedFeature = QQuickWebEngineView::DesktopVideoCapture;
+
+    Q_EMIT q->featurePermissionRequested(securityOrigin, deprecatedFeature);
+    QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 8)
 }
 
 void QQuickWebEngineViewPrivate::runMouseLockPermissionRequest(const QUrl &securityOrigin)
@@ -1466,6 +1528,12 @@ void QQuickWebEngineViewPrivate::showWebAuthDialog(QWebEngineWebAuthUxRequest *r
     Q_EMIT q->webAuthUxRequested(request);
 }
 
+QWebEnginePermission QQuickWebEngineViewPrivate::createFeaturePermissionObject(const QUrl &securityOrigin, QWebEnginePermission::Feature feature)
+{
+    auto *returnPrivate = new QWebEnginePermissionPrivate(securityOrigin, feature, adapter, profileAdapter());
+    return QWebEnginePermission(returnPrivate);
+}
+
 bool QQuickWebEngineView::isLoading() const
 {
     Q_D(const QQuickWebEngineView);
@@ -1761,55 +1829,49 @@ void QQuickWebEngineView::setDevToolsView(QQuickWebEngineView *devToolsView)
     Q_EMIT devToolsViewChanged();
 }
 
+#if QT_DEPRECATED_SINCE(6, 8)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
 void QQuickWebEngineView::grantFeaturePermission(const QUrl &securityOrigin, QQuickWebEngineView::Feature feature, bool granted)
 {
-    if (!granted && ((feature >= MediaAudioCapture && feature <= MediaAudioVideoCapture) ||
-                     (feature >= DesktopVideoCapture && feature <= DesktopAudioVideoCapture))) {
-         d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaNone);
-         return;
-    }
+    Q_D(QQuickWebEngineView);
+    QWebEnginePermission::Feature f;
 
     switch (feature) {
-    case MediaAudioCapture:
-        d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaAudioCapture);
+    case QQuickWebEngineView::Notifications:
+        f = QWebEnginePermission::Notifications;
         break;
-    case MediaVideoCapture:
-        d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaVideoCapture);
+    case QQuickWebEngineView::Geolocation:
+        f = QWebEnginePermission::Geolocation;
         break;
-    case MediaAudioVideoCapture:
-        d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaRequestFlags(WebContentsAdapterClient::MediaAudioCapture                                                                                                               | WebContentsAdapterClient::MediaVideoCapture));
+    case QQuickWebEngineView::MediaAudioCapture:
+        f = QWebEnginePermission::MediaAudioCapture;
         break;
-    case DesktopVideoCapture:
-        d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaDesktopVideoCapture);
+    case QQuickWebEngineView::MediaVideoCapture:
+        f = QWebEnginePermission::MediaVideoCapture;
         break;
-    case DesktopAudioVideoCapture:
-        d_ptr->adapter->grantMediaAccessPermission(
-            securityOrigin,
-            WebContentsAdapterClient::MediaRequestFlags(
-                WebContentsAdapterClient::MediaDesktopAudioCapture |
-                WebContentsAdapterClient::MediaDesktopVideoCapture));
+    case QQuickWebEngineView::MediaAudioVideoCapture:
+        f = QWebEnginePermission::MediaAudioVideoCapture;
         break;
-    case Geolocation:
-        d_ptr->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::GeolocationPermission,
-                                               granted ? ProfileAdapter::AllowedPermission : ProfileAdapter::DeniedPermission);
+    case QQuickWebEngineView::DesktopVideoCapture:
+        f = QWebEnginePermission::DesktopVideoCapture;
         break;
-    case Notifications:
-        d_ptr->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::NotificationPermission,
-                                               granted ? ProfileAdapter::AllowedPermission : ProfileAdapter::DeniedPermission);
+    case QQuickWebEngineView::DesktopAudioVideoCapture:
+        f = QWebEnginePermission::DesktopAudioVideoCapture;
         break;
-    case ClipboardReadWrite:
-        d_ptr->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::ClipboardReadWrite,
-                                               granted ? ProfileAdapter::AllowedPermission
-                                                       : ProfileAdapter::DeniedPermission);
+    case QQuickWebEngineView::ClipboardReadWrite:
+        f = QWebEnginePermission::ClipboardReadWrite;
         break;
-    case LocalFontsAccess:
-        d_ptr->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::LocalFontsPermission,
-                                               granted ? ProfileAdapter::AllowedPermission : ProfileAdapter::DeniedPermission);
+    case QQuickWebEngineView::LocalFontsAccess:
+        f = QWebEnginePermission::LocalFontsAccess;
         break;
     default:
         Q_UNREACHABLE();
     }
+
+    d->adapter->setFeaturePermission(securityOrigin, f, granted ? QWebEnginePermission::Granted : QWebEnginePermission::Denied);
 }
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 8)
 
 void QQuickWebEngineView::setActiveFocusOnPress(bool arg)
 {
diff --git a/src/webenginequick/api/qquickwebengineview_p.h b/src/webenginequick/api/qquickwebengineview_p.h
index a310e09345b..ea09dff9faf 100644
--- a/src/webenginequick/api/qquickwebengineview_p.h
+++ b/src/webenginequick/api/qquickwebengineview_p.h
@@ -20,6 +20,7 @@
 #include <QtWebEngineCore/qwebenginedesktopmediarequest.h>
 #include <QtWebEngineCore/qwebenginedownloadrequest.h>
 #include <QtWebEngineCore/qwebengineframe.h>
+#include <QtWebEngineCore/qwebenginepermission.h>
 #include <QtWebEngineQuick/private/qtwebenginequickglobal_p.h>
 #include <QtGui/qcolor.h>
 #include <QtQml/qqmlregistration.h>
@@ -166,8 +167,12 @@ QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
     Q_ENUM(NewViewDestination)
 QT_WARNING_POP
 #endif
-
-    enum Feature {
+#if QT_DEPRECATED_SINCE(6, 8)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+    enum QT_DEPRECATED_VERSION_X_6_8(
+        "WebEnginePage::Feature has been deprecated. "
+        "The updated permissions API uses WebEnginePermission::Feature.")
+    Feature {
         MediaAudioCapture,
         MediaVideoCapture,
         MediaAudioVideoCapture,
@@ -179,6 +184,8 @@ QT_WARNING_POP
         LocalFontsAccess,
     };
     Q_ENUM(Feature)
+QT_WARNING_POP
+#endif
 
     enum WebAction {
         NoWebAction = - 1,
@@ -489,7 +496,17 @@ public Q_SLOTS:
     void stop();
     Q_REVISION(1,1) void findText(const QString &subString, FindFlags options = { }, const QJSValue &callback = QJSValue());
     Q_REVISION(1,1) void fullScreenCancelled();
+#if QT_DEPRECATED_SINCE(6, 8)
+#if !defined(Q_MOC_RUN)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+#endif // !defined(Q_MOC_RUN)
+    QT_DEPRECATED_VERSION_X_6_8("Setting permissions through WebEngineView has been deprecated. Please use WebEnginePermission instead.")
     Q_REVISION(1,1) void grantFeaturePermission(const QUrl &securityOrigin, QQuickWebEngineView::Feature, bool granted);
+#if !defined(Q_MOC_RUN)
+QT_WARNING_POP
+#endif // !defined(Q_MOC_RUN)
+#endif // QT_DEPRECATED_SINCE(6, 8)
     Q_REVISION(1,2) void setActiveFocusOnPress(bool arg);
     Q_REVISION(1,2) void triggerWebAction(WebAction action);
     Q_REVISION(1,3) void printToPdf(const QString &filePath, PrintedPageSizeId pageSizeId = PrintedPageSizeId::A4, PrintedPageOrientation orientation = PrintedPageOrientation::Portrait);
@@ -515,9 +532,19 @@ private Q_SLOTS:
     Q_REVISION(1,1) void certificateError(const QWebEngineCertificateError &error);
     Q_REVISION(1,1) void fullScreenRequested(const QWebEngineFullScreenRequest &request);
     Q_REVISION(1,1) void isFullScreenChanged();
+#if QT_DEPRECATED_SINCE(6, 8)
+#if !defined(Q_MOC_RUN)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+#endif // !defined(Q_MOC_RUN)
+    QT_MOC_COMPAT QT_DEPRECATED_VERSION_X_6_8("The signal has been deprecated; please use permissionRequested instead.")
     Q_REVISION(1, 1)
     void featurePermissionRequested(const QUrl &securityOrigin,
                                     QQuickWebEngineView::Feature feature);
+#if !defined(Q_MOC_RUN)
+QT_WARNING_POP
+#endif // !defined(Q_MOC_RUN)
+#endif // QT_DEPRECATED_SINCE(6, 8)
     Q_REVISION(1,1) void zoomFactorChanged(qreal arg);
     Q_REVISION(1,1) void profileChanged();
     Q_REVISION(1,1) void webChannelChanged();
@@ -562,6 +589,7 @@ private Q_SLOTS:
     Q_REVISION(6, 7) void webAuthUxRequested(QWebEngineWebAuthUxRequest *request);
     Q_REVISION(6,7) void desktopMediaRequested(const QWebEngineDesktopMediaRequest &request);
     Q_REVISION(6, 8) void printRequestedByFrame(QWebEngineFrame frame);
+    Q_REVISION(6,8) void permissionRequested(QWebEnginePermission permissionRequest);
 
 protected:
     void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
diff --git a/src/webenginequick/api/qquickwebengineview_p_p.h b/src/webenginequick/api/qquickwebengineview_p_p.h
index 988a2f0b148..e61f32bcb09 100644
--- a/src/webenginequick/api/qquickwebengineview_p_p.h
+++ b/src/webenginequick/api/qquickwebengineview_p_p.h
@@ -114,7 +114,7 @@ class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineViewPrivate : public QtWebEngineCor
     void allowCertificateError(const QWebEngineCertificateError &error) override;
     void selectClientCert(const QSharedPointer<QtWebEngineCore::ClientCertSelectController>
                                   &selectController) override;
-    void runFeaturePermissionRequest(QtWebEngineCore::ProfileAdapter::PermissionType permission, const QUrl &securityOrigin) override;
+    void runFeaturePermissionRequest(QWebEnginePermission::Feature feature, const QUrl &securityOrigin) override;
     void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode) override;
     void requestGeometryChange(const QRect &geometry, const QRect &frameGeometry) override;
     void updateScrollPosition(const QPointF &position) override;
@@ -139,6 +139,7 @@ class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineViewPrivate : public QtWebEngineCor
                            const QRect &bounds, bool autoselectFirstSuggestion) override;
     void hideAutofillPopup() override;
     void showWebAuthDialog(QWebEngineWebAuthUxRequest *request) override;
+    QWebEnginePermission createFeaturePermissionObject(const QUrl &securityOrigin, QWebEnginePermission::Feature feature) override;
 
     void updateAction(QQuickWebEngineView::WebAction) const;
     bool adoptWebContents(QtWebEngineCore::WebContentsAdapter *webContents);
diff --git a/src/webenginequick/doc/src/webengine_permission.qdoc b/src/webenginequick/doc/src/webengine_permission.qdoc
new file mode 100644
index 00000000000..f59f57fa07f
--- /dev/null
+++ b/src/webenginequick/doc/src/webengine_permission.qdoc
@@ -0,0 +1,137 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+    \qmltype webEnginePermission
+    \instantiates QWebEnginePermission
+    \inqmlmodule QtWebEngine
+    \brief An object used to access and modify the state of a single permission that's been
+    granted or denied to a specific origin URL.
+
+    The typical usage pattern is as follows:
+    \list 1
+        \li A website requests a specific feature, triggering the WebEngineView::permissionRequested signal;
+        \li The signal handler triggers a prompt asking the user whether they want to grant the permission;
+        \li When the user has made their decision, the application calls \l grant() or \l deny();
+    \endlist
+
+    Alternatively, an application interested in modifying already granted permissions may use WebEngineProfile::listPermissions()
+    to get a list of existing permissions associated with a profile, or WebEngineProfile::getPermission() to get
+    a webEnginePermission object for a specific permission.
+
+    The \l origin property can be used to query which origin the webEnginePermission is associated with, while the
+    \l feature property describes the associated feature. A website origin is the combination of its scheme, hostname,
+    and port. Permissions are granted on a per-origin basis; thus, if the web page \c{https://www.example.com:12345/some/page.html}
+    requests a permission, it will be granted to the origin \c{https://www.example.com:12345/}.
+
+    The usability lifetime of a webEnginePermission is tied either to its associated WebEngineView
+    (for transient feature types), or WebEngineProfile (for permanent feature types). A transient permission is one which
+    needs to be explicitly granted or denied every time it's needed (e.g. webcam/screen sharing permission), whereas a permanent
+    one might be stored inside the current profile, depending on the value of WebEngineProfile::persistentPermissionsPolicy.
+    You can check whether a webEnginePermission is in a valid state using its \l isValid() property. For invalid objects, calls to \l grant(),
+    \l deny(), or \l reset() will do nothing, and their \l state() will always be WebEnginePermission.Invalid.
+
+    The feature types Qt WebEngine supports are described in \l feature.
+
+    \sa WebEngineView::permissionRequested, WebEngineProfile::getPermission(),
+    WebEngineProfile::listPermissions()
+*/
+
+/*!
+    \qmlproperty url webEnginePermission::origin
+    \brief The URL of the permission's associated origin.
+
+    A website origin is the combination of its scheme, hostname, and port. Permissions are granted on a
+    per-origin basis; thus, if the web page \c{https://www.example.com:12345/some/page.html}
+    requests a permission, it will be granted to the origin \c{https://www.example.com:12345/}.
+*/
+
+/*!
+    \qmlproperty enumeration webEnginePermission::feature
+    \brief The feature type associated with this permission.
+
+    \value WebEnginePermission.MediaAudioCapture Access to a microphone, or another audio source. This feature is transient.
+    \value WebEnginePermission.MediaVideoCapture Access to a webcam, or another video source. This feature is transient.
+    \value WebEnginePermission.MediaAudioVideoCapture Combination of \l MediaAudioCapture and \l MediaVideoCapture. This feature is transient.
+    \value WebEnginePermission.DesktopVideoCapture Access to the contents of the user's screen. This feature is transient.
+    \value WebEnginePermission.DesktopAudioVideoCapture Access to the contents of the user's screen, and application audio. This feature is transient.
+    \value WebEnginePermission.MouseLock Locks the pointer inside an element on the web page. This feature is transient.
+    \value WebEnginePermission.Notifications Allows the website to send notifications to the user.
+    \value WebEnginePermission.Geolocation Access to the user's physical location.
+    \value WebEnginePermission.ClipboardReadWrite Access to the user's clipboard.
+    \value WebEnginePermission.LocalFontsAccess Access to the fonts installed on the user's machine. Only available on desktops.
+    \value WebEnginePermission.Unsupported An unsupported feature type.
+
+    \note Transient feature types are ones that will never be remembered by the underlying storage, and will trigger
+    a permission request every time a website tries to use them.
+*/
+
+/*!
+    \qmlproperty enumeration webEnginePermission::state
+    \brief The current state of the permission.
+
+    \value WebEnginePermission.Invalid Object is in an invalid state, and any attempts to modify the described permission will fail.
+    \value WebEnginePermission.Ask Either the permission has not been requested before, or the feature() is transient.
+    \value WebEnginePermission.Granted Permission has already been granted.
+    \value WebEnginePermission.Denied Permission has already been denied.
+
+    If a permission for the specified \l feature and \l origin has already been granted or denied,
+    the return value is WebEnginePermission.Granted, or WebEnginePermission.Denied, respectively.
+    When this is the first time the permission is requested, or if the \l feature is transient,
+    the return value is WebEnginePermission.Ask. If the object is in an invalid state, the returned
+    value is WebEnginePermission.Invalid.
+
+    \sa isValid, isTransient
+*/
+
+/*!
+    \qmlproperty bool webEnginePermission::isValid
+    \brief Indicates whether attempts to change the permission's state will be successful.
+
+    An invalid webEnginePermission is either:
+    \list
+        \li One whose \l feature is unsupported;
+        \li One whose \l feature is transient, and the associated page/view has been destroyed;
+        \li One whose \l feature is permanent, but the associated profile has been destroyed;
+        \li One whose \l origin is invalid.
+    \endlist
+
+    \sa isTransient
+*/
+
+/*!
+    \qmlmethod void webEnginePermission::grant()
+
+    Allows the associated origin to access the requested feature. Does nothing when \l isValid evaluates to false.
+
+    \sa deny, reset, isValid
+*/
+
+/*!
+    \qmlmethod void webEnginePermission::deny()
+
+    Stops the associated origin from accessing the requested feature. Does nothing when \l isValid evaluates to false.
+
+    \sa grant, reset, isValid
+*/
+
+/*!
+    \qmlmethod void webEnginePermission::reset()
+
+    Removes the permission from the profile's underlying storage. By default, permissions are stored on disk (except for
+    off-the-record profiles, where permissions are stored in memory and are destroyed with the profile).
+    This means that an already granted/denied permission will not be requested twice, but will get automatically
+    granted/denied every subsequent time a website requests it. Calling reset() allows the query to be asked
+    again the next time the website requests it.
+
+    Does nothing when \l isValid evaluates to false.
+
+    \sa grant, deny, isValid, WebEngineProfile::persistentPermissionsPolicy
+*/
+
+/*!
+    \qmlmethod void webEnginePermission::isTransient(WebEnginePermission.Feature feature)
+
+    Returns whether \a feature is transient, meaning that a permission will be requested
+    every time the associated functionality is used by a web page.
+*/
diff --git a/src/webenginequick/doc/src/webengineview_lgpl.qdoc b/src/webenginequick/doc/src/webengineview_lgpl.qdoc
index 82bf605ca86..f7b17fa7b62 100644
--- a/src/webenginequick/doc/src/webengineview_lgpl.qdoc
+++ b/src/webenginequick/doc/src/webengineview_lgpl.qdoc
@@ -111,10 +111,9 @@
     \section2 Platform Features
 
     Web pages can request access to platform features, such as geolocation or audio and video
-    capture devices. The \l featurePermissionRequested() signal is emitted when a web page requests
-    to make use of a resource. The supported platform features are described by the \l Feature
-    property. If users grant the permission, the \l grantFeaturePermission() method is used to set
-    it to \e granted.
+    capture devices. The \l permissionRequested() signal is emitted when a web page requests
+    to make use of a resource. The supported platform features are described by the QWebEnginePermission::Feature
+    property.
 
     \section2 Rendering to OpenGL Surface
 
@@ -445,6 +444,7 @@
 /*!
     \qmlmethod void WebEngineView::grantFeaturePermission(url securityOrigin, Feature feature, bool granted)
     \since QtWebEngine 1.1
+    \deprecated [6.8] Use webEnginePermission.grant() or webEnginePermission.deny() instead.
 
     Sets or unsets the permission, depending on \a granted, for the web site
     identified by \a securityOrigin to use \a feature.
@@ -501,6 +501,7 @@
 /*!
     \qmlsignal WebEngineView::featurePermissionRequested(url securityOrigin, Feature feature)
     \since QtWebEngine 1.1
+    \deprecated [6.8] Use \l permissionRequested() instead.
 
     This signal is emitted when the web site identified by \a securityOrigin requests
     to make use of the resource or device identified by \a feature.
@@ -508,6 +509,15 @@
     \sa grantFeaturePermission()
 */
 
+/*!
+    \qmlsignal WebEngineView::permissionRequested(webEnginePermission permission)
+    \since QtWebEngine 6.8
+
+    This signal is emitted when a web site requests to make use of a feature (e.g. geolocation access,
+    permission to send notifications). The \a permission object can queried for the requesting URL
+    and the \c{WebEnginePermission.Feature} it's asking for, as well as to grant or deny permission.
+*/
+
 /*!
     \qmlsignal WebEngineView::loadingChanged(WebEngineLoadingInfo loadingInfo)
 
@@ -844,6 +854,7 @@
 
 /*!
     \qmlproperty enumeration WebEngineView::Feature
+    \deprecated [6.8] Replaced by WebEnginePermission.Feature.
 
     Describes the platform feature access categories that the user may be asked to grant or deny
     access to:
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index c4d889cbe8b..cf0e59274df 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -26,6 +26,7 @@
 #include <QtWebEngineCore/QWebEngineLoadingInfo>
 #include <QtWebEngineCore/QWebEngineWebAuthUxRequest>
 #include <QtWebEngineCore/QWebEngineFrame>
+#include <QtWebEngineCore/QWebEnginePermission>
 #include <private/qquickwebengineview_p.h>
 #include <private/qquickwebengineaction_p.h>
 #include <private/qquickwebengineclientcertificateselection_p.h>
@@ -72,6 +73,7 @@ static const QList<const QMetaObject *> typesToCheck = QList<const QMetaObject *
     << &QWebEngineNavigationRequest::staticMetaObject
     << &QWebEngineNewWindowRequest::staticMetaObject
     << &QWebEngineNotification::staticMetaObject
+    << &QWebEnginePermission::staticMetaObject
     << &QWebEngineQuotaRequest::staticMetaObject
     << &QWebEngineRegisterProtocolHandlerRequest::staticMetaObject
     << &QQuickWebEngineTouchSelectionMenuRequest::staticMetaObject
@@ -82,6 +84,7 @@ static const QList<const QMetaObject *> typesToCheck = QList<const QMetaObject *
 
 static QList<QMetaEnum> knownEnumNames = QList<QMetaEnum>()
     << QWebEngineDownloadRequest::staticMetaObject.enumerator(QWebEngineDownloadRequest::staticMetaObject.indexOfEnumerator("SavePageFormat"))
+    << QWebEnginePermission::staticMetaObject.enumerator(QWebEnginePermission::staticMetaObject.indexOfEnumerator("Feature"))
     ;
 
 static const QStringList hardcodedTypes = QStringList()
@@ -353,6 +356,29 @@ static const QStringList expectedAPI = QStringList()
     << "QWebEngineNewWindowRequest.InNewDialog --> DestinationType"
     << "QWebEngineNewWindowRequest.InNewTab --> DestinationType"
     << "QWebEngineNewWindowRequest.InNewWindow --> DestinationType"
+    << "QWebEnginePermission.Unsupported --> Feature"
+    << "QWebEnginePermission.MediaAudioCapture --> Feature"
+    << "QWebEnginePermission.MediaVideoCapture --> Feature"
+    << "QWebEnginePermission.MediaAudioVideoCapture --> Feature"
+    << "QWebEnginePermission.DesktopVideoCapture --> Feature"
+    << "QWebEnginePermission.DesktopAudioVideoCapture --> Feature"
+    << "QWebEnginePermission.MouseLock --> Feature"
+    << "QWebEnginePermission.Notifications --> Feature"
+    << "QWebEnginePermission.Geolocation --> Feature"
+    << "QWebEnginePermission.ClipboardReadWrite --> Feature"
+    << "QWebEnginePermission.LocalFontsAccess --> Feature"
+    << "QWebEnginePermission.Invalid --> State"
+    << "QWebEnginePermission.Ask --> State"
+    << "QWebEnginePermission.Granted --> State"
+    << "QWebEnginePermission.Denied --> State"
+    << "QWebEnginePermission.origin --> QUrl"
+    << "QWebEnginePermission.feature --> QWebEnginePermission::Feature"
+    << "QWebEnginePermission.state --> QWebEnginePermission::State"
+    << "QWebEnginePermission.isValid --> bool"
+    << "QWebEnginePermission.grant() --> void"
+    << "QWebEnginePermission.deny() --> void"
+    << "QWebEnginePermission.reset() --> void"
+    << "QWebEnginePermission.isTransient(QWebEnginePermission::Feature) --> bool"
     << "QQuickWebEngineNewWindowRequest.openIn(QQuickWebEngineView*) --> void"
     << "QQuickWebEngineProfile.AllowPersistentCookies --> PersistentCookiesPolicy"
     << "QQuickWebEngineProfile.DiskHttpCache --> HttpCacheType"
@@ -537,10 +563,20 @@ static const QStringList expectedAPI = QStringList()
     << "QQuickWebEngineView.B10 --> PrintedPageSizeId"
     << "QQuickWebEngineView.Back --> WebAction"
     << "QQuickWebEngineView.C5E --> PrintedPageSizeId"
+#if QT_DEPRECATED_SINCE(6, 8)
+    << "QQuickWebEngineView.ClipboardReadWrite --> Feature"
+    << "QQuickWebEngineView.DesktopAudioVideoCapture --> Feature"
+    << "QQuickWebEngineView.DesktopVideoCapture --> Feature"
+    << "QQuickWebEngineView.Geolocation --> Feature"
+    << "QQuickWebEngineView.LocalFontsAccess --> Feature"
+    << "QQuickWebEngineView.MediaAudioCapture --> Feature"
+    << "QQuickWebEngineView.MediaAudioVideoCapture --> Feature"
+    << "QQuickWebEngineView.MediaVideoCapture --> Feature"
+    << "QQuickWebEngineView.Notifications --> Feature"
+#endif
     << "QQuickWebEngineView.CertificateErrorDomain --> ErrorDomain"
     << "QQuickWebEngineView.ChangeTextDirectionLTR --> WebAction"
     << "QQuickWebEngineView.ChangeTextDirectionRTL --> WebAction"
-    << "QQuickWebEngineView.ClipboardReadWrite --> Feature"
     << "QQuickWebEngineView.Comm10E --> PrintedPageSizeId"
     << "QQuickWebEngineView.ConnectionErrorDomain --> ErrorDomain"
     << "QQuickWebEngineView.Copy --> WebAction"
@@ -552,8 +588,6 @@ static const QStringList expectedAPI = QStringList()
     << "QQuickWebEngineView.Custom --> PrintedPageSizeId"
     << "QQuickWebEngineView.Cut --> WebAction"
     << "QQuickWebEngineView.DLE --> PrintedPageSizeId"
-    << "QQuickWebEngineView.DesktopAudioVideoCapture --> Feature"
-    << "QQuickWebEngineView.DesktopVideoCapture --> Feature"
     << "QQuickWebEngineView.DnsErrorDomain --> ErrorDomain"
     << "QQuickWebEngineView.DoublePostcard --> PrintedPageSizeId"
     << "QQuickWebEngineView.DownloadImageToDisk --> WebAction"
@@ -608,7 +642,6 @@ static const QStringList expectedAPI = QStringList()
     << "QQuickWebEngineView.Folio --> PrintedPageSizeId"
     << "QQuickWebEngineView.Forward --> WebAction"
     << "QQuickWebEngineView.FtpErrorDomain --> ErrorDomain"
-    << "QQuickWebEngineView.Geolocation --> Feature"
     << "QQuickWebEngineView.HttpErrorDomain --> ErrorDomain"
     << "QQuickWebEngineView.Imperial10x11 --> PrintedPageSizeId"
     << "QQuickWebEngineView.Imperial10x13 --> PrintedPageSizeId"
@@ -653,12 +686,7 @@ static const QStringList expectedAPI = QStringList()
     << "QQuickWebEngineView.LoadStartedStatus --> LoadStatus"
     << "QQuickWebEngineView.LoadStoppedStatus --> LoadStatus"
     << "QQuickWebEngineView.LoadSucceededStatus --> LoadStatus"
-    << "QQuickWebEngineView.LocalFontsAccess --> Feature"
-    << "QQuickWebEngineView.MediaAudioCapture --> Feature"
-    << "QQuickWebEngineView.MediaAudioVideoCapture --> Feature"
-    << "QQuickWebEngineView.MediaVideoCapture --> Feature"
     << "QQuickWebEngineView.NoErrorDomain --> ErrorDomain"
-    << "QQuickWebEngineView.Notifications --> Feature"
     << "QQuickWebEngineView.NoWebAction --> WebAction"
     << "QQuickWebEngineView.NormalTerminationStatus --> RenderProcessTerminationStatus"
     << "QQuickWebEngineView.Note --> PrintedPageSizeId"
@@ -734,7 +762,9 @@ static const QStringList expectedAPI = QStringList()
     << "QQuickWebEngineView.goBack() --> void"
     << "QQuickWebEngineView.goBackOrForward(int) --> void"
     << "QQuickWebEngineView.goForward() --> void"
+#if QT_DEPRECATED_SINCE(6, 8)
     << "QQuickWebEngineView.grantFeaturePermission(QUrl,QQuickWebEngineView::Feature,bool) --> void"
+#endif
     << "QQuickWebEngineView.history --> QWebEngineHistory*"
     << "QQuickWebEngineView.icon --> QUrl"
     << "QQuickWebEngineView.iconChanged() --> void"
@@ -769,6 +799,7 @@ static const QStringList expectedAPI = QStringList()
     << "QQuickWebEngineView.NewViewInDialog --> NewViewDestination"
     << "QQuickWebEngineView.NewViewInTab --> NewViewDestination"
     << "QQuickWebEngineView.NewViewInWindow --> NewViewDestination"
+    << "QQuickWebEngineView.permissionRequested(QWebEnginePermission) --> void"
     << "QQuickWebEngineView.pdfPrintingFinished(QString,bool) --> void"
     << "QQuickWebEngineView.printRequested() --> void"
     << "QQuickWebEngineView.printRequestedByFrame(QWebEngineFrame) --> void"
@@ -1020,4 +1051,3 @@ void tst_publicapi::publicAPI()
 QTEST_MAIN(tst_publicapi)
 
 #include "tst_publicapi.moc"
-
diff --git a/tests/auto/quick/qmltests/data/tst_geopermission.qml b/tests/auto/quick/qmltests/data/tst_geopermission.qml
index c474033a977..e425a82c742 100644
--- a/tests/auto/quick/qmltests/data/tst_geopermission.qml
+++ b/tests/auto/quick/qmltests/data/tst_geopermission.qml
@@ -16,19 +16,19 @@ TestWebEngineView {
     profile.persistentPermissionsPolicy: WebEngineProfile.NoPersistentPermissions
 
     SignalSpy {
-        id: featurePermissionSpy
+        id: permissionSpy
         target: webEngineView
-        signalName: "featurePermissionRequested"
+        signalName: "permissionRequested"
     }
 
-    onFeaturePermissionRequested: function(securityOrigin, feature) {
-        if (feature === WebEngineView.Geolocation) {
+    onPermissionRequested: function(perm) {
+        if (perm.feature === WebEnginePermission.Geolocation) {
             geoPermissionRequested = true
             if (deniedGeolocation) {
-                webEngineView.grantFeaturePermission(securityOrigin, feature, false)
+                perm.deny()
             }
             else {
-                webEngineView.grantFeaturePermission(securityOrigin, feature, true)
+                perm.grant()
             }
         }
     }
@@ -57,15 +57,15 @@ TestWebEngineView {
 
         function init() {
             deniedGeolocation = false
-            featurePermissionSpy.clear()
+            permissionSpy.clear()
         }
 
         function test_geoPermissionRequest() {
-            compare(featurePermissionSpy.count, 0)
+            compare(permissionSpy.count, 0)
             webEngineView.url = Qt.resolvedUrl("geolocation.html")
-            featurePermissionSpy.wait()
+            permissionSpy.wait()
             verify(geoPermissionRequested)
-            compare(featurePermissionSpy.count, 1)
+            compare(permissionSpy.count, 1)
             tryVerify(isHandled, 5000)
             verify(getErrorMessage() === "")
         }
@@ -73,7 +73,7 @@ TestWebEngineView {
         function test_deniedGeolocationByUser() {
             deniedGeolocation = true
             webEngineView.url = Qt.resolvedUrl("geolocation.html")
-            featurePermissionSpy.wait()
+            permissionSpy.wait()
             tryVerify(isHandled, 5000)
             compare(getErrorMessage(), "User denied Geolocation")
         }
diff --git a/tests/auto/quick/qmltests/data/tst_getUserMedia.qml b/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
index 653f7a5df3d..9a876778b37 100644
--- a/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
+++ b/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
@@ -22,17 +22,17 @@ TestWebEngineView {
                 {
                     tag: "device audio",
                     constraints: { audio: true },
-                    feature: WebEngineView.MediaAudioCapture,
+                    feature: WebEnginePermission.MediaAudioCapture,
                 },
                 {
                     tag: "device video",
                     constraints: { video: true },
-                    feature: WebEngineView.MediaVideoCapture,
+                    feature: WebEnginePermission.MediaVideoCapture,
                 },
                 {
                     tag: "device audio+video",
                     constraints: { audio: true, video: true },
-                    feature: WebEngineView.MediaAudioVideoCapture,
+                    feature: WebEnginePermission.MediaAudioVideoCapture,
                 },
                 {
                     tag: "desktop video",
@@ -43,7 +43,7 @@ TestWebEngineView {
                             }
                         }
                     },
-                    feature: WebEngineView.DesktopVideoCapture,
+                    feature: WebEnginePermission.DesktopVideoCapture,
                 },
                 {
                     tag: "desktop audio+video",
@@ -59,7 +59,7 @@ TestWebEngineView {
                             }
                         }
                     },
-                    feature: WebEngineView.DesktopAudioVideoCapture,
+                    feature: WebEnginePermission.DesktopAudioVideoCapture,
                 }
             ]
         }
@@ -116,28 +116,24 @@ TestWebEngineView {
     ////
     // synchronous permission requests
 
-    property variant requestedFeature
-    property variant requestedSecurityOrigin
+    property variant permissionObject
 
-    onFeaturePermissionRequested: function(securityOrigin, feature) {
-        requestedFeature = feature
-        requestedSecurityOrigin = securityOrigin
+    onPermissionRequested: function(perm) {
+        permissionObject = perm
     }
 
     function gotFeatureRequest(expectedFeature) {
-        return requestedFeature == expectedFeature
+        return permissionObject && permissionObject.feature == expectedFeature
     }
 
     function acceptPendingRequest() {
-        webEngineView.grantFeaturePermission(requestedSecurityOrigin, requestedFeature, true)
-        requestedFeature = undefined
-        requestedSecurityOrigin = undefined
+        permissionObject.grant()
+        permissionObject = undefined
     }
 
     function rejectPendingRequest() {
-        webEngineView.grantFeaturePermission(requestedSecurityOrigin, requestedFeature, false)
-        requestedFeature = undefined
-        requestedSecurityOrigin = undefined
+        permissionObject.deny()
+        permissionObject = undefined
     }
 
     ////
diff --git a/tests/auto/quick/qmltests/data/tst_notification.qml b/tests/auto/quick/qmltests/data/tst_notification.qml
index 0bb33b41ebd..5defbff4b6f 100644
--- a/tests/auto/quick/qmltests/data/tst_notification.qml
+++ b/tests/auto/quick/qmltests/data/tst_notification.qml
@@ -13,7 +13,7 @@ TestWebEngineView {
 
     property bool permissionRequested: false
     property bool grantPermission: false
-    property url securityOrigin: ''
+    property var permissionObject
 
     profile.persistentPermissionsPolicy: WebEngineProfile.NoPersistentPermissions
 
@@ -22,14 +22,17 @@ TestWebEngineView {
     SignalSpy {
         id: spyRequest
         target: view
-        signalName: 'featurePermissionRequested'
+        signalName: 'permissionRequested'
     }
 
-    onFeaturePermissionRequested: function(securityOrigin, feature) {
-        if (feature === WebEngineView.Notifications) {
+    onPermissionRequested: function(perm) {
+        if (perm.feature === WebEnginePermission.Notifications) {
             view.permissionRequested = true
-            view.securityOrigin = securityOrigin
-            view.grantFeaturePermission(securityOrigin, feature, grantPermission)
+            view.permissionObject = perm
+            if (grantPermission)
+                perm.grant()
+            else
+                perm.deny()
         }
     }
 
@@ -93,7 +96,7 @@ TestWebEngineView {
             compare(notification.title, title)
             compare(notification.message, message)
             compare(notification.direction, Qt.RightToLeft)
-            compare(notification.origin, securityOrigin)
+            compare(notification.origin, permissionObject.origin)
             compare(notification.tag, 'tst')
             compare(notification.language, 'de')
         }
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index f6eac2880b5..8b6ea31fd41 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -72,6 +72,7 @@
 #include <qwebengineurlscheme.h>
 #include <qwebengineurlschemehandler.h>
 #include <qwebengineview.h>
+#include <qwebenginepermission.h>
 #include <qimagewriter.h>
 #include <QColorSpace>
 #include <QQuickRenderControl>
@@ -451,12 +452,12 @@ Q_OBJECT
         return true;
     }
 public Q_SLOTS:
-    void requestPermission(const QUrl &origin, QWebEnginePage::Feature feature)
+    void requestPermission(QWebEnginePermission permission)
     {
         if (m_allowGeolocation)
-            setFeaturePermission(origin, feature, PermissionGrantedByUser);
+            permission.grant();
         else
-            setFeaturePermission(origin, feature, PermissionDeniedByUser);
+            permission.deny();
     }
 
 public:
@@ -488,8 +489,8 @@ void tst_QWebEnginePage::geolocationRequestJS()
     newPage->profile()->setPersistentPermissionsPolicy(QWebEngineProfile::NoPersistentPermissions);
     newPage->setGeolocationPermission(allowed);
 
-    connect(newPage, SIGNAL(featurePermissionRequested(const QUrl&, QWebEnginePage::Feature)),
-            newPage, SLOT(requestPermission(const QUrl&, QWebEnginePage::Feature)));
+    connect(newPage, SIGNAL(permissionRequested(QWebEnginePermission)),
+            newPage, SLOT(requestPermission(QWebEnginePermission)));
 
     QSignalSpy spyLoadFinished(newPage, SIGNAL(loadFinished(bool)));
     newPage->setHtml(QString("<html><body>test</body></html>"), QUrl("qrc://secure/origin"));
@@ -1656,8 +1657,9 @@ Q_OBJECT
     GetUserMediaTestPage()
         : m_gotRequest(false)
         , m_loadSucceeded(false)
+        , m_permission(nullptr)
     {
-        connect(this, &QWebEnginePage::featurePermissionRequested, this, &GetUserMediaTestPage::onFeaturePermissionRequested);
+        connect(this, &QWebEnginePage::permissionRequested, this, &GetUserMediaTestPage::onPermissionRequested);
         connect(this, &QWebEnginePage::loadFinished, [this](bool success){
             m_loadSucceeded = success;
         });
@@ -1695,18 +1697,20 @@ Q_OBJECT
 
     void rejectPendingRequest()
     {
-        setFeaturePermission(m_requestSecurityOrigin, m_requestedFeature, QWebEnginePage::PermissionDeniedByUser);
+        QVERIFY(m_permission);
+        m_permission->deny();
         m_gotRequest = false;
     }
     void acceptPendingRequest()
     {
-        setFeaturePermission(m_requestSecurityOrigin, m_requestedFeature, QWebEnginePage::PermissionGrantedByUser);
+        QVERIFY(m_permission);
+        m_permission->grant();
         m_gotRequest = false;
     }
 
-    bool gotFeatureRequest(QWebEnginePage::Feature feature)
+    bool gotFeatureRequest(QWebEnginePermission::Feature feature)
     {
-        return m_gotRequest && m_requestedFeature == feature;
+        return m_gotRequest && m_permission && m_permission->feature() == feature;
     }
 
     bool gotFeatureRequest() const
@@ -1720,50 +1724,47 @@ Q_OBJECT
     }
 
 private Q_SLOTS:
-    void onFeaturePermissionRequested(const QUrl &securityOrigin, QWebEnginePage::Feature feature)
+    void onPermissionRequested(QWebEnginePermission permission)
     {
-        m_requestedFeature = feature;
-        m_requestSecurityOrigin = securityOrigin;
+        m_permission.reset(new QWebEnginePermission(permission));
         m_gotRequest = true;
     }
 
 private:
     bool m_gotRequest;
     bool m_loadSucceeded;
-    QWebEnginePage::Feature m_requestedFeature;
-    QUrl m_requestSecurityOrigin;
-
+    std::unique_ptr<QWebEnginePermission> m_permission;
 };
 
 void tst_QWebEnginePage::getUserMediaRequest_data()
 {
     QTest::addColumn<QString>("call");
-    QTest::addColumn<QWebEnginePage::Feature>("feature");
+    QTest::addColumn<QWebEnginePermission::Feature>("feature");
 
     QTest::addRow("device audio")
-        << "getUserMedia({audio: true})" << QWebEnginePage::MediaAudioCapture;
+        << "getUserMedia({audio: true})" << QWebEnginePermission::MediaAudioCapture;
     QTest::addRow("device video")
-        << "getUserMedia({video: true})" << QWebEnginePage::MediaVideoCapture;
+        << "getUserMedia({video: true})" << QWebEnginePermission::MediaVideoCapture;
     QTest::addRow("device audio+video")
-        << "getUserMedia({audio: true, video: true})" << QWebEnginePage::MediaAudioVideoCapture;
+        << "getUserMedia({audio: true, video: true})" << QWebEnginePermission::MediaAudioVideoCapture;
     QTest::addRow("desktop video")
         << "getUserMedia({video: { mandatory: { chromeMediaSource: 'desktop' }}})"
-        << QWebEnginePage::DesktopVideoCapture;
+        << QWebEnginePermission::DesktopVideoCapture;
     QTest::addRow("desktop audio+video")
         << "getUserMedia({audio: { mandatory: { chromeMediaSource: 'desktop' }}, video: { mandatory: { chromeMediaSource: 'desktop' }}})"
-        << QWebEnginePage::DesktopAudioVideoCapture;
+        << QWebEnginePermission::DesktopAudioVideoCapture;
     QTest::addRow("display video")
-        << "getDisplayMedia()" << QWebEnginePage::DesktopVideoCapture;
+        << "getDisplayMedia()" << QWebEnginePermission::DesktopVideoCapture;
 }
 
 void tst_QWebEnginePage::getUserMediaRequest()
 {
     QFETCH(QString, call);
-    QFETCH(QWebEnginePage::Feature, feature);
+    QFETCH(QWebEnginePermission::Feature, feature);
 
     GetUserMediaTestPage page;
     QWebEngineView view;
-    if (feature == QWebEnginePage::DesktopVideoCapture || feature == QWebEnginePage::DesktopAudioVideoCapture) {
+    if (feature == QWebEnginePermission::DesktopVideoCapture || feature == QWebEnginePermission::DesktopAudioVideoCapture) {
         // Desktop capture needs to be on a desktop.
         view.setPage(&page);
         view.resize(640, 480);
@@ -1833,7 +1834,7 @@ void tst_QWebEnginePage::getUserMediaRequestSettingDisabled()
 void tst_QWebEnginePage::getUserMediaRequestDesktopVideoManyPages()
 {
     const QString constraints = QStringLiteral("{video: { mandatory: { chromeMediaSource: 'desktop' }}}");
-    const QWebEnginePage::Feature feature = QWebEnginePage::DesktopVideoCapture;
+    const QWebEnginePermission::Feature feature = QWebEnginePermission::DesktopVideoCapture;
     std::vector<GetUserMediaTestPage> pages(10);
 
     // Desktop capture needs to be on a desktop
@@ -1866,7 +1867,7 @@ void tst_QWebEnginePage::getUserMediaRequestDesktopVideoManyPages()
 void tst_QWebEnginePage::getUserMediaRequestDesktopVideoManyRequests()
 {
     const QString constraints = QStringLiteral("{video: { mandatory: { chromeMediaSource: 'desktop' }}}");
-    const QWebEnginePage::Feature feature = QWebEnginePage::DesktopVideoCapture;
+    const QWebEnginePermission::Feature feature = QWebEnginePermission::DesktopVideoCapture;
     GetUserMediaTestPage page;
 
     // Desktop capture needs to be on a desktop
@@ -3795,20 +3796,30 @@ void tst_QWebEnginePage::dynamicFrame()
 
 struct NotificationPage : ConsolePage {
     Q_OBJECT
-    const QWebEnginePage::PermissionPolicy policy;
+    const QWebEnginePermission::State policy;
 
 public:
-    NotificationPage(QWebEnginePage::PermissionPolicy ppolicy) : policy(ppolicy) {
+    NotificationPage(QWebEnginePermission::State ppolicy) : policy(ppolicy) {
         connect(this, &QWebEnginePage::loadFinished, [load = spyLoad.ref()] (bool result) mutable { load(result); });
 
-        connect(this, &QWebEnginePage::featurePermissionRequested,
-                [this] (const QUrl &origin, QWebEnginePage::Feature feature) {
-            if (feature != QWebEnginePage::Notifications)
+        connect(this, &QWebEnginePage::permissionRequested,
+                [this] (QWebEnginePermission permission) {
+            if (permission.feature() != QWebEnginePermission::Notifications)
                 return;
             if (spyRequest.wasCalled())
                 QFAIL("request executed twise!");
-            setFeaturePermission(origin, feature, policy);
-            spyRequest.ref()(origin);
+            switch (policy) {
+            case QWebEnginePermission::Granted:
+                permission.grant();
+                break;
+            case QWebEnginePermission::Denied:
+                permission.deny();
+                break;
+            case QWebEnginePermission::Ask:
+                permission.reset();
+                break;
+            }
+            spyRequest.ref()(permission.origin());
         });
 
         load(QStringLiteral("qrc:///shared/notification.html"));
@@ -3828,18 +3839,18 @@ struct NotificationPage : ConsolePage {
 void tst_QWebEnginePage::notificationPermission_data()
 {
     QTest::addColumn<bool>("setOnInit");
-    QTest::addColumn<QWebEnginePage::PermissionPolicy>("policy");
+    QTest::addColumn<QWebEnginePermission::State>("policy");
     QTest::addColumn<QString>("permission");
-    QTest::newRow("denyOnInit")  << true  << QWebEnginePage::PermissionDeniedByUser << "denied";
-    QTest::newRow("deny")        << false << QWebEnginePage::PermissionDeniedByUser << "denied";
-    QTest::newRow("grant")       << false << QWebEnginePage::PermissionGrantedByUser << "granted";
-    QTest::newRow("grantOnInit") << true  << QWebEnginePage::PermissionGrantedByUser << "granted";
+    QTest::newRow("denyOnInit")  << true  << QWebEnginePermission::Denied << "denied";
+    QTest::newRow("deny")        << false << QWebEnginePermission::Denied << "denied";
+    QTest::newRow("grant")       << false << QWebEnginePermission::Granted << "granted";
+    QTest::newRow("grantOnInit") << true  << QWebEnginePermission::Granted << "granted";
 }
 
 void tst_QWebEnginePage::notificationPermission()
 {
     QFETCH(bool, setOnInit);
-    QFETCH(QWebEnginePage::PermissionPolicy, policy);
+    QFETCH(QWebEnginePermission::State, policy);
     QFETCH(QString, permission);
 
     QWebEngineProfile otr;
@@ -3849,20 +3860,33 @@ void tst_QWebEnginePage::notificationPermission()
     QUrl baseUrl("https://www.example.com/somepage.html");
 
     bool permissionRequested = false, errorState = false;
-    connect(&page, &QWebEnginePage::featurePermissionRequested, &page, [&] (const QUrl &o, QWebEnginePage::Feature f) {
-        if (f != QWebEnginePage::Notifications)
+    connect(&page, &QWebEnginePage::permissionRequested, &page, [&] (QWebEnginePermission permission) {
+        if (permission.feature() != QWebEnginePermission::Notifications)
             return;
-        if (permissionRequested || o != baseUrl.url(QUrl::RemoveFilename)) {
-            qWarning() << "Unexpected case. Can't proceed." << setOnInit << permissionRequested << o;
+        if (permissionRequested || permission.origin() != baseUrl.url(QUrl::RemoveFilename)) {
+            qWarning() << "Unexpected case. Can't proceed." << setOnInit << permissionRequested << permission.origin();
             errorState = true;
             return;
         }
         permissionRequested = true;
-        page.setFeaturePermission(o, f, policy);
+
+        if (policy == QWebEnginePermission::Granted)
+            permission.grant();
+        else
+            permission.deny();
     });
 
     if (setOnInit)
-        page.setFeaturePermission(baseUrl, QWebEnginePage::Notifications, policy);
+#if QT_DEPRECATED_SINCE(6, 8)
+        QT_WARNING_PUSH
+        QT_WARNING_DISABLE_DEPRECATED
+        // FIXME: Replace with QWebEngineProfile permission API when that's implemented
+        page.setFeaturePermission(baseUrl, QWebEnginePage::Notifications,
+            policy == QWebEnginePermission::Granted ? QWebEnginePage::PermissionGrantedByUser : QWebEnginePage::PermissionDeniedByUser);
+        QT_WARNING_POP
+#else
+        W_QSKIP("Compiled without deprecated APIs", SkipSingle);
+#endif // QT_DEPRECATED_SINCE(6, 8)
 
     QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
     page.setHtml(QString("<html><body>Test</body></html>"), baseUrl);
@@ -3871,8 +3895,17 @@ void tst_QWebEnginePage::notificationPermission()
     QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("Notification.permission")), setOnInit ? permission : QLatin1String("default"));
 
     if (!setOnInit) {
-        page.setFeaturePermission(baseUrl, QWebEnginePage::Notifications, policy);
+#if QT_DEPRECATED_SINCE(6, 8)
+        QT_WARNING_PUSH
+        QT_WARNING_DISABLE_DEPRECATED
+        // FIXME: Replace with QWebEngineProfile permission API when that's implemented
+        page.setFeaturePermission(baseUrl, QWebEnginePage::Notifications,
+            policy == QWebEnginePermission::Granted ? QWebEnginePage::PermissionGrantedByUser : QWebEnginePage::PermissionDeniedByUser);
         QTRY_COMPARE(evaluateJavaScriptSync(&page, QStringLiteral("Notification.permission")), permission);
+        QT_WARNING_POP
+#else
+        W_QSKIP("Compiled without deprecated APIs", SkipSingle);
+#endif // QT_DEPRECATED_SINCE(6, 8)
     }
 
     auto js = QStringLiteral("var permission; Notification.requestPermission().then(p => { permission = p })");
@@ -3885,7 +3918,7 @@ void tst_QWebEnginePage::notificationPermission()
 
 void tst_QWebEnginePage::sendNotification()
 {
-    NotificationPage page(QWebEnginePage::PermissionGrantedByUser);
+    NotificationPage page(QWebEnginePermission::Granted);
     QVERIFY(page.spyLoad.waitForResult());
 
     page.resetPermission();
@@ -3973,42 +4006,42 @@ void tst_QWebEnginePage::clipboardReadWritePermissionInitialState()
 void tst_QWebEnginePage::clipboardReadWritePermission_data()
 {
     QTest::addColumn<bool>("canAccessClipboard");
-    QTest::addColumn<QWebEnginePage::PermissionPolicy>("initialPolicy");
+    QTest::addColumn<QWebEnginePermission::State>("initialPolicy");
     QTest::addColumn<QString>("initialPermission");
-    QTest::addColumn<QWebEnginePage::PermissionPolicy>("requestPolicy");
+    QTest::addColumn<QWebEnginePermission::State>("requestPolicy");
     QTest::addColumn<QString>("finalPermission");
 
     QTest::newRow("noAccessGrantGrant")
-            << false << QWebEnginePage::PermissionGrantedByUser << "granted"
-            << QWebEnginePage::PermissionGrantedByUser << "granted";
+            << false << QWebEnginePermission::Granted << "granted"
+            << QWebEnginePermission::Granted << "granted";
     QTest::newRow("noAccessGrantDeny")
-            << false << QWebEnginePage::PermissionGrantedByUser << "granted"
-            << QWebEnginePage::PermissionDeniedByUser << "denied";
+            << false << QWebEnginePermission::Granted << "granted"
+            << QWebEnginePermission::Denied << "denied";
     QTest::newRow("noAccessDenyGrant")
-            << false << QWebEnginePage::PermissionDeniedByUser << "denied"
-            << QWebEnginePage::PermissionGrantedByUser << "granted";
-    QTest::newRow("noAccessDenyDeny") << false << QWebEnginePage::PermissionDeniedByUser << "denied"
-                                      << QWebEnginePage::PermissionDeniedByUser << "denied";
-    QTest::newRow("noAccessAskGrant") << false << QWebEnginePage::PermissionUnknown << "prompt"
-                                      << QWebEnginePage::PermissionGrantedByUser << "granted";
+            << false << QWebEnginePermission::Denied << "denied"
+            << QWebEnginePermission::Granted << "granted";
+    QTest::newRow("noAccessDenyDeny") << false << QWebEnginePermission::Denied << "denied"
+                                      << QWebEnginePermission::Denied << "denied";
+    QTest::newRow("noAccessAskGrant") << false << QWebEnginePermission::Ask << "prompt"
+                                      << QWebEnginePermission::Granted << "granted";
 
     // All policies are ignored and overridden by setting JsCanAccessClipboard and JsCanPaste to
     // true
     QTest::newRow("accessGrantGrant")
-            << true << QWebEnginePage::PermissionGrantedByUser << "granted"
-            << QWebEnginePage::PermissionGrantedByUser << "granted";
-    QTest::newRow("accessDenyDeny") << true << QWebEnginePage::PermissionDeniedByUser << "granted"
-                                    << QWebEnginePage::PermissionDeniedByUser << "granted";
-    QTest::newRow("accessAskAsk") << true << QWebEnginePage::PermissionUnknown << "granted"
-                                  << QWebEnginePage::PermissionUnknown << "granted";
+            << true << QWebEnginePermission::Granted << "granted"
+            << QWebEnginePermission::Granted << "granted";
+    QTest::newRow("accessDenyDeny") << true << QWebEnginePermission::Denied << "granted"
+                                    << QWebEnginePermission::Denied << "granted";
+    QTest::newRow("accessAskAsk") << true << QWebEnginePermission::Ask << "granted"
+                                  << QWebEnginePermission::Ask << "granted";
 }
 
 void tst_QWebEnginePage::clipboardReadWritePermission()
 {
     QFETCH(bool, canAccessClipboard);
-    QFETCH(QWebEnginePage::PermissionPolicy, initialPolicy);
+    QFETCH(QWebEnginePermission::State, initialPolicy);
     QFETCH(QString, initialPermission);
-    QFETCH(QWebEnginePage::PermissionPolicy, requestPolicy);
+    QFETCH(QWebEnginePermission::State, requestPolicy);
     QFETCH(QString, finalPermission);
 
     QWebEngineProfile otr;
@@ -4026,20 +4059,43 @@ void tst_QWebEnginePage::clipboardReadWritePermission()
     bool errorState = false;
 
     // if JavascriptCanAccessClipboard is true, this never fires
-    connect(&page, &QWebEnginePage::featurePermissionRequested, &page,
-            [&](const QUrl &o, QWebEnginePage::Feature f) {
-                if (f != QWebEnginePage::ClipboardReadWrite)
+    connect(&page, &QWebEnginePage::permissionRequested, &page,
+            [&](QWebEnginePermission permission) {
+                if (permission.feature() != QWebEnginePermission::ClipboardReadWrite)
                     return;
-                if (o != baseUrl.url(QUrl::RemoveFilename)) {
-                    qWarning() << "Unexpected case. Can't proceed." << o;
+                if (permission.origin() != baseUrl.url(QUrl::RemoveFilename)) {
+                    qWarning() << "Unexpected case. Can't proceed." << permission.origin();
                     errorState = true;
                     return;
                 }
                 permissionRequestCount++;
-                page.setFeaturePermission(o, f, requestPolicy);
+                switch (requestPolicy) {
+                case QWebEnginePermission::Granted:
+                    permission.grant();
+                    break;
+                case QWebEnginePermission::Denied:
+                    permission.deny();
+                    break;
+                case QWebEnginePermission::Ask:
+                    permission.reset();
+                    break;
+                default:
+                    break;
+                }
             });
 
-    page.setFeaturePermission(baseUrl, QWebEnginePage::ClipboardReadWrite, initialPolicy);
+    // FIXME: Replace with QWebEngineProfile permission API when that's implemented
+#if QT_DEPRECATED_SINCE(6, 8)
+    QT_WARNING_PUSH
+    QT_WARNING_DISABLE_DEPRECATED
+    QWebEnginePage::PermissionPolicy deprecatedPolicy =
+        initialPolicy == QWebEnginePermission::Granted ? QWebEnginePage::PermissionGrantedByUser
+        : (initialPolicy == QWebEnginePermission::Denied ? QWebEnginePage::PermissionDeniedByUser : QWebEnginePage::PermissionUnknown);
+    page.setFeaturePermission(baseUrl, QWebEnginePage::ClipboardReadWrite, deprecatedPolicy);
+    QT_WARNING_POP
+#else
+    W_QSKIP("Compiled without deprecated APIs", SkipSingle);
+#endif // QT_DEPRECATED_SINCE(6, 8)
 
     QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
     page.setHtml(QString("<html><body>Test</body></html>"), baseUrl);
@@ -4099,17 +4155,17 @@ void tst_QWebEnginePage::contentsSize()
 
 void tst_QWebEnginePage::localFontAccessPermission_data()
 {
-    QTest::addColumn<QWebEnginePage::PermissionPolicy>("policy");
+    QTest::addColumn<QWebEnginePermission::State>("policy");
     QTest::addColumn<bool>("ignore");
     QTest::addColumn<bool>("shouldBeEmpty");
 
-    QTest::newRow("ignore")         << QWebEnginePage::PermissionDeniedByUser  << true  << true;
-    QTest::newRow("setDeny")        << QWebEnginePage::PermissionDeniedByUser  << false << true;
-    QTest::newRow("setGrant")       << QWebEnginePage::PermissionGrantedByUser << false << false;
+    QTest::newRow("ignore")   << QWebEnginePermission::Denied  << true  << true;
+    QTest::newRow("setDeny")  << QWebEnginePermission::Denied  << false << true;
+    QTest::newRow("setGrant") << QWebEnginePermission::Granted << false << false;
 }
 
 void tst_QWebEnginePage::localFontAccessPermission() {
-    QFETCH(QWebEnginePage::PermissionPolicy, policy);
+    QFETCH(QWebEnginePermission::State, policy);
     QFETCH(bool, ignore);
     QFETCH(bool, shouldBeEmpty);
 
@@ -4118,12 +4174,16 @@ void tst_QWebEnginePage::localFontAccessPermission() {
     page.profile()->setPersistentPermissionsPolicy(QWebEngineProfile::NoPersistentPermissions);
     view.setPage(&page);
 
-    connect(&page, &QWebEnginePage::featurePermissionRequested, &page, [&] (const QUrl &o, QWebEnginePage::Feature f) {
-        if (f != QWebEnginePage::LocalFontsAccess)
+    connect(&page, &QWebEnginePage::permissionRequested, &page, [&] (QWebEnginePermission permission) {
+        if (permission.feature() != QWebEnginePermission::LocalFontsAccess)
             return;
 
-        if (!ignore)
-            page.setFeaturePermission(o, f, policy);
+        if (!ignore) {
+            if (policy == QWebEnginePermission::Granted)
+                permission.grant();
+            else
+                permission.deny();
+        }
     });
 
     QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
@@ -5734,12 +5794,11 @@ void tst_QWebEnginePage::chooseDesktopMedia()
                 desktopMediaRequested = true;
             });
 
-    connect(&page, &QWebEnginePage::featurePermissionRequested,
-            [&](const QUrl &securityOrigin, QWebEnginePage::Feature feature) {
+    connect(&page, &QWebEnginePage::permissionRequested,
+            [&](QWebEnginePermission permission) {
                 permissionRequested = true;
                 // Handle permission to 'complete' the media request
-                page.setFeaturePermission(securityOrigin, feature,
-                                          QWebEnginePage::PermissionGrantedByUser);
+                permission.grant();
             });
 
     page.load(QUrl(server.url()));
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index ef069ac1c69..81800658650 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -1051,8 +1051,15 @@ void tst_QWebEngineProfile::permissionPersistence()
 
     QVariant variant = granted ? "granted" : "denied";
     QVariant defaultVariant = "default";
+#if QT_DEPRECATED_SINCE(6, 8)
+    QT_WARNING_PUSH
+    QT_WARNING_DISABLE_DEPRECATED
     page->setFeaturePermission(server.url("/hedgehog.html"), QWebEnginePage::Notifications,
         granted ? QWebEnginePage::PermissionGrantedByUser : QWebEnginePage::PermissionDeniedByUser);
+    QT_WARNING_POP
+#else
+    W_QSKIP("Compiled without deprecated APIs", SkipSingle);
+#endif // QT_DEPRECATED_SINCE(6, 8)
     QCOMPARE(evaluateJavaScriptSync(page.get(), "Notification.permission"), variant);
 
     page.reset();
@@ -1077,7 +1084,14 @@ void tst_QWebEngineProfile::permissionPersistence()
     QTRY_COMPARE(evaluateJavaScriptSync(page.get(), "Notification.permission"),
         expectSame ? variant : defaultVariant);
 
+#if QT_DEPRECATED_SINCE(6, 8)
+    QT_WARNING_PUSH
+    QT_WARNING_DISABLE_DEPRECATED
     page->setFeaturePermission(server.url("/hedgehog.html"), QWebEnginePage::Notifications, QWebEnginePage::PermissionUnknown);
+    QT_WARNING_POP
+#else
+    W_QSKIP("Compiled without deprecated APIs", SkipSingle);
+#endif // QT_DEPRECATED_SINCE(6, 8)
     QCOMPARE(evaluateJavaScriptSync(page.get(), "Notification.permission"), defaultVariant);
 
     page.reset();
diff --git a/tests/manual/quick/geopermission/tst_geopermission.qml b/tests/manual/quick/geopermission/tst_geopermission.qml
index 36317c176ae..ace48d464d4 100644
--- a/tests/manual/quick/geopermission/tst_geopermission.qml
+++ b/tests/manual/quick/geopermission/tst_geopermission.qml
@@ -13,14 +13,14 @@ WebEngineView {
     property bool deniedGeolocation: false
     property bool geoPermissionRequested: false
 
-    onFeaturePermissionRequested: function(securityOrigin, feature) {
-        if (feature === WebEngineView.Geolocation) {
+    onPermissionRequested: function(perm) {
+        if (perm.feature === WebEnginePermission.Geolocation) {
             geoPermissionRequested = true
             if (deniedGeolocation) {
-                webEngineView.grantFeaturePermission(securityOrigin, feature, false)
+                perm.deny()
             }
             else {
-                webEngineView.grantFeaturePermission(securityOrigin, feature, true)
+                perm.grant()
             }
         }
     }
diff --git a/tests/manual/widgets/geolocation/main.cpp b/tests/manual/widgets/geolocation/main.cpp
index f33cf5798b7..1f4cefe54e4 100644
--- a/tests/manual/widgets/geolocation/main.cpp
+++ b/tests/manual/widgets/geolocation/main.cpp
@@ -16,18 +16,15 @@ class GeoPermissionWebView : public QWebEngineView {
   Q_OBJECT
 
 public slots:
-    void handleFeaturePermissionRequested(const QUrl &securityOrigin,
-                                               QWebEnginePage::Feature feature)
+    void handlePermissionRequested(QWebEnginePermission permission)
     {
         qWarning("Feature Permission");
         QString title = tr("Permission Request");
         QString question = QLatin1String("Allow access to geolocation?");
         if (!question.isEmpty() && QMessageBox::question(window(), title, question) == QMessageBox::Yes)
-            page()->setFeaturePermission(securityOrigin, feature,
-                                         QWebEnginePage::PermissionGrantedByUser);
+            permission.grant();
         else
-            page()->setFeaturePermission(securityOrigin, feature,
-                                         QWebEnginePage::PermissionDeniedByUser);
+            permission.deny();
     }
 
 };
@@ -38,8 +35,8 @@ int main(int argc, char *argv[])
     QMainWindow w;
     GeoPermissionWebView webview;
     QWebEnginePage page;
-    QObject::connect(&page, &QWebEnginePage::featurePermissionRequested, &webview,
-            &GeoPermissionWebView::handleFeaturePermissionRequested);
+    QObject::connect(&page, &QWebEnginePage::permissionRequested, &webview,
+            &GeoPermissionWebView::handlePermissionRequested);
     webview.setPage(&page);
     page.load(QUrl("qrc:/geolocation.html"));
     w.setCentralWidget(&webview);
diff --git a/tests/manual/widgets/webrtc/main.cpp b/tests/manual/widgets/webrtc/main.cpp
index 328e4ae3674..b5718159c8b 100644
--- a/tests/manual/widgets/webrtc/main.cpp
+++ b/tests/manual/widgets/webrtc/main.cpp
@@ -35,19 +35,19 @@ private slots:
 Page::Page(QWebEngineProfile *profile, QObject *parent) : QWebEnginePage(profile, parent)
 {
     settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true);
-    connect(this, &QWebEnginePage::featurePermissionRequested, this,
+    connect(this, &QWebEnginePage::permissionRequested, this,
             &Page::handlePermissionRequest);
     connect(this, &QWebEnginePage::desktopMediaRequested, this, &Page::handleDesktopMediaRequest);
 }
 
-void Page::handlePermissionRequest(const QUrl &origin, Feature feature)
+void Page::handlePermissionRequest(QWebEnginePermission permission)
 {
     if (QMessageBox::question(QApplication::activeWindow(), tr("Permission request"),
                               tr("allow access?"))
         == QMessageBox::Yes)
-        setFeaturePermission(origin, feature, PermissionGrantedByUser);
+        permission.grant();
     else
-        setFeaturePermission(origin, feature, PermissionDeniedByUser);
+        permission.deny();
 }
 
 void Page::handleDesktopMediaRequest(const QWebEngineDesktopMediaRequest &request)

From ec2391243e3e6772fe1c87c72427148fae28cbe1 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Wed, 3 Apr 2024 16:46:57 +0200
Subject: [PATCH 004/356] Implement API for listing existing permissions in a
 profile

QWebEngineProfile and QQuickWebEngineProfile now have methods for
either getting one specific permission object, or for getting a list
of all the permissions currently stored. The methods for listing also
have overloads for filtering based on origin or Feature type.

Change-Id: I07241bcb3ff171fa8b82547c2b5f094071bebe44
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 7ad9ee5c5ef109a91fbc83e86b351f399e96d194)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebengineprofile.cpp            |  90 +++++++++++
 src/core/api/qwebengineprofile.h              |   6 +
 src/core/permission_manager_qt.cpp            |  60 +++++++-
 src/core/permission_manager_qt.h              |   2 +
 src/core/profile_adapter.cpp                  |  11 ++
 src/core/profile_adapter.h                    |   2 +
 .../api/qquickwebengineprofile.cpp            | 142 ++++++++++++++++++
 .../api/qquickwebengineprofile.h              |   6 +
 tests/auto/quick/publicapi/tst_publicapi.cpp  |   8 +-
 .../qwebenginepage/tst_qwebenginepage.cpp     |  60 ++++----
 .../tst_qwebengineprofile.cpp                 | 128 +++++++++++++---
 11 files changed, 458 insertions(+), 57 deletions(-)

diff --git a/src/core/api/qwebengineprofile.cpp b/src/core/api/qwebengineprofile.cpp
index a9477929ba9..5d7bb5559b2 100644
--- a/src/core/api/qwebengineprofile.cpp
+++ b/src/core/api/qwebengineprofile.cpp
@@ -11,6 +11,7 @@
 #include "qwebenginesettings.h"
 #include "qwebenginescriptcollection.h"
 #include "qwebenginescriptcollection_p.h"
+#include "qwebenginepermission_p.h"
 #include "qtwebenginecoreglobal.h"
 #include "profile_adapter.h"
 #include "visited_links_manager_qt.h"
@@ -976,6 +977,95 @@ void QWebEngineProfile::requestIconForIconURL(const QUrl &url, int desiredSizeIn
                                                iconAvailableCallback);
 }
 
+/*!
+ * Returns a QWebEnginePermission object corresponding to a single permission for the provided \a securityOrigin and
+ * \a feature. The object may be used to query for the current state of the permission, or to change it. It is not required
+ * for a permission to already exist; the returned object may also be used to pre-grant a permission if a website is
+ * known to use it.
+ *
+ * \note This may only be used for permanent feature types. Calling it with a transient \a feature will return an invalid object.
+ * \since 6.8
+ * \sa listPermissions(), QWebEnginePermission::Feature
+ */
+QWebEnginePermission QWebEngineProfile::getPermission(const QUrl &securityOrigin, QWebEnginePermission::Feature feature) const
+{
+    Q_D(const QWebEngineProfile);
+
+    if (feature == QWebEnginePermission::Unsupported) {
+        qWarning("Attempting to get unsupported permission. Returned object will be in an invalid state.");
+        return QWebEnginePermission(new QWebEnginePermissionPrivate());
+    }
+
+    if (QWebEnginePermission::isTransient(feature)) {
+        qWarning() << "Attempting to get permission for feature" << feature << ". Returned object will be in an invalid state.";
+        return QWebEnginePermission(new QWebEnginePermissionPrivate());
+    }
+
+    auto *pvt = new QWebEnginePermissionPrivate(securityOrigin, feature, nullptr, d->profileAdapter());
+    return QWebEnginePermission(pvt);
+}
+
+/*!
+ * Returns a QList of QWebEnginePermission objects, each one representing a single permission currently
+ * present in the permissions store. The returned list contains all previously granted/denied permissions for this profile,
+ * except for those of a transient feature type.
+ *
+ * \since 6.8
+ * \sa getPermission(), QWebEnginePermission::Feature
+ */
+QList<QWebEnginePermission> QWebEngineProfile::listPermissions() const
+{
+    Q_D(const QWebEngineProfile);
+    if (persistentPermissionsPolicy() == NoPersistentPermissions)
+        return QList<QWebEnginePermission>();
+    return d->profileAdapter()->listPermissions();
+}
+
+/*!
+ * Returns a QList of QWebEnginePermission objects, each one representing a single permission currently
+ * present in the permissions store. The returned list contains all previously granted/denied permissions associated with a
+ * specific \a securityOrigin for this profile, except for those of a transient feature type.
+ *
+ * \note Since permissions are granted on a per-origin basis, the provided \a securityOrigin will be stripped to its
+ * origin form, and the returned list will contain all permissions for the origin. Thus, passing https://www.example.com/some/page.html
+ * is the same as passing just https://www.example.com/.
+ * \since 6.8
+ * \sa getPermission(), QWebEnginePermission::Feature
+ */
+QList<QWebEnginePermission> QWebEngineProfile::listPermissions(const QUrl &securityOrigin) const
+{
+    Q_D(const QWebEngineProfile);
+    if (persistentPermissionsPolicy() == NoPersistentPermissions)
+        return QList<QWebEnginePermission>();
+    return d->profileAdapter()->listPermissions(securityOrigin);
+}
+
+/*!
+ * Returns a QList of QWebEnginePermission objects, each one representing a single permission currently
+ * present in the permissions store. The returned list contains all previously granted/denied permissions of the \a feature
+ * type for this profile. If the feature is of a transient or unsupported type, the list will be empty.
+ * \since 6.8
+ * \sa getPermission(), QWebEnginePermission::Feature
+ */
+QList<QWebEnginePermission> QWebEngineProfile::listPermissions(QWebEnginePermission::Feature feature) const
+{
+    Q_D(const QWebEngineProfile);
+    if (persistentPermissionsPolicy() == NoPersistentPermissions)
+        return QList<QWebEnginePermission>();
+
+    if (feature == QWebEnginePermission::Unsupported) {
+        qWarning("Attempting to get permission list for an unsupported type. Returned list will be empty.");
+        return QList<QWebEnginePermission>();
+    }
+
+    if (QWebEnginePermission::isTransient(feature)) {
+        qWarning() << "Attempting to get permission list for feature" << feature << ". Returned list will be empty.";
+        return QList<QWebEnginePermission>();
+    }
+
+    return d->profileAdapter()->listPermissions(QUrl(), feature);
+}
+
 /*!
     Return the Client Hints settings associated with this browsing context.
 
diff --git a/src/core/api/qwebengineprofile.h b/src/core/api/qwebengineprofile.h
index 259de4bff4f..573f39e7dd3 100644
--- a/src/core/api/qwebengineprofile.h
+++ b/src/core/api/qwebengineprofile.h
@@ -5,6 +5,7 @@
 #define QWEBENGINEPROFILE_H
 
 #include <QtWebEngineCore/qtwebenginecoreglobal.h>
+#include <QtWebEngineCore/qwebenginepermission.h>
 
 #include <QtCore/qobject.h>
 #include <QtCore/qscopedpointer.h>
@@ -120,6 +121,11 @@ class Q_WEBENGINECORE_EXPORT QWebEngineProfile : public QObject
     void requestIconForPageURL(const QUrl &url, int desiredSizeInPixel, std::function<void(const QIcon &, const QUrl &, const QUrl &)> iconAvailableCallback) const;
     void requestIconForIconURL(const QUrl &url, int desiredSizeInPixel, std::function<void(const QIcon &, const QUrl &)> iconAvailableCallback) const;
 
+    QWebEnginePermission getPermission(const QUrl &securityOrigin, QWebEnginePermission::Feature feature) const;
+    QList<QWebEnginePermission> listPermissions() const;
+    QList<QWebEnginePermission> listPermissions(const QUrl &securityOrigin) const;
+    QList<QWebEnginePermission> listPermissions(QWebEnginePermission::Feature feature) const;
+
     static QWebEngineProfile *defaultProfile();
 
 Q_SIGNALS:
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index 6883d222404..63189c1d7a0 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -21,6 +21,7 @@
 #include "components/proxy_config/pref_proxy_config_tracker_impl.h"
 #include "components/prefs/pref_service.h"
 
+#include <QtWebEngineCore/private/qwebenginepermission_p.h>
 #include "type_conversion.h"
 #include "web_contents_delegate_qt.h"
 #include "web_engine_settings.h"
@@ -190,13 +191,19 @@ PermissionManagerQt::PermissionManagerQt(ProfileAdapter *profileAdapter)
         factory.set_user_prefs(new InMemoryPrefStore);
     }
 
+    m_featureTypes.push_back(QWebEnginePermission::Notifications);
+    m_featureTypes.push_back(QWebEnginePermission::Geolocation);
+    m_featureTypes.push_back(QWebEnginePermission::ClipboardReadWrite);
+    m_featureTypes.push_back(QWebEnginePermission::LocalFontsAccess);
+
+    // Transient, but the implementation relies on them being written to storage
+    m_featureTypes.push_back(QWebEnginePermission::MediaAudioCapture);
+    m_featureTypes.push_back(QWebEnginePermission::MediaVideoCapture);
+
     // Register all preference types as keys prior to doing anything else
-    prefRegistry->RegisterDictionaryPref(featureString(QWebEnginePermission::Geolocation));
-    prefRegistry->RegisterDictionaryPref(featureString(QWebEnginePermission::ClipboardReadWrite));
-    prefRegistry->RegisterDictionaryPref(featureString(QWebEnginePermission::Notifications));
-    prefRegistry->RegisterDictionaryPref(featureString(QWebEnginePermission::LocalFontsAccess));
-    prefRegistry->RegisterDictionaryPref(featureString(QWebEnginePermission::MediaAudioCapture));
-    prefRegistry->RegisterDictionaryPref(featureString(QWebEnginePermission::MediaVideoCapture));
+    for (auto &type : m_featureTypes) {
+        prefRegistry->RegisterDictionaryPref(featureString(type));
+    }
     PrefProxyConfigTrackerImpl::RegisterPrefs(prefRegistry.get());
 
     if (policy == ProfileAdapter::NoPersistentPermissions)
@@ -284,6 +291,47 @@ QWebEnginePermission::State PermissionManagerQt::getPermissionState(const QUrl &
     return toQt(GetPermissionStatus(toBlink(feature), toGurl(origin), GURL()));
 }
 
+QList<QWebEnginePermission> PermissionManagerQt::listPermissions(const QUrl &origin, QWebEnginePermission::Feature feature)
+{
+    Q_ASSERT(origin.isEmpty() || feature == QWebEnginePermission::Unsupported);
+    QList<QWebEnginePermission> returnList;
+    GURL gorigin = toGurl(origin).DeprecatedGetOriginAsURL();
+    std::string originSpec = gorigin.spec();
+
+    if (!origin.isEmpty() && !gorigin.is_valid())
+        return returnList;
+
+    std::vector<QWebEnginePermission::Feature> types;
+    if (feature == QWebEnginePermission::Unsupported)
+        types = m_featureTypes;
+    else
+        types.push_back(feature);
+
+    for (auto &type : types) {
+        // Transient types may end up in the permission store as an implementation detail,
+        // but we do not want to expose them to callers.
+        if (QWebEnginePermission::isTransient(type))
+            continue;
+
+        auto *pref = m_prefService->FindPreference(featureString(type));
+        if (!pref)
+            continue;
+
+        auto *prefDict = pref->GetValue()->GetIfDict();
+        Q_ASSERT(prefDict);
+
+        for (const auto &entry : *prefDict) {
+            if (!originSpec.empty() && entry.first != originSpec)
+                continue;
+
+            auto *pvt = new QWebEnginePermissionPrivate(toQt(GURL(std::string_view(entry.first))), type, nullptr, m_profileAdapter.get());
+            returnList.push_back(QWebEnginePermission(pvt));
+        }
+    }
+
+    return returnList;
+}
+
 void PermissionManagerQt::commit()
 {
     DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
diff --git a/src/core/permission_manager_qt.h b/src/core/permission_manager_qt.h
index e74a3fba126..ebab613d616 100644
--- a/src/core/permission_manager_qt.h
+++ b/src/core/permission_manager_qt.h
@@ -24,6 +24,7 @@ class PermissionManagerQt : public content::PermissionControllerDelegate
 
     void setPermission(const QUrl &origin, QWebEnginePermission::Feature feature, QWebEnginePermission::State state);
     QWebEnginePermission::State getPermissionState(const QUrl &origin, QWebEnginePermission::Feature feature);
+    QList<QWebEnginePermission> listPermissions(const QUrl &origin, QWebEnginePermission::Feature feature);
 
     void commit();
 
@@ -90,6 +91,7 @@ class PermissionManagerQt : public content::PermissionControllerDelegate
 
     std::vector<Request> m_requests;
     std::vector<MultiRequest> m_multiRequests;
+    std::vector<QWebEnginePermission::Feature> m_featureTypes;
     std::map<content::PermissionControllerDelegate::SubscriptionId, Subscription> m_subscribers;
     content::PermissionControllerDelegate::SubscriptionId::Generator subscription_id_generator_;
     int m_requestIdCount;
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index 4b337e8ed3c..c0906003acb 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -576,9 +576,20 @@ void ProfileAdapter::setPermission(const QUrl &origin, QWebEnginePermission::Fea
 
 QWebEnginePermission::State ProfileAdapter::getPermissionState(const QUrl &origin, QWebEnginePermission::Feature feature)
 {
+    if (persistentPermissionsPolicy() == ProfileAdapter::NoPersistentPermissions)
+        return QWebEnginePermission::Ask;
+
     return static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->getPermissionState(origin, feature);
 }
 
+QList<QWebEnginePermission> ProfileAdapter::listPermissions(const QUrl &origin, QWebEnginePermission::Feature feature)
+{
+    if (persistentPermissionsPolicy() == ProfileAdapter::NoPersistentPermissions)
+        return QList<QWebEnginePermission>();
+
+    return static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->listPermissions(origin, feature);
+}
+
 QString ProfileAdapter::httpAcceptLanguageWithoutQualities() const
 {
     const QStringList list = m_httpAcceptLanguage.split(QLatin1Char(','));
diff --git a/src/core/profile_adapter.h b/src/core/profile_adapter.h
index 644d7e03c32..6550e617696 100644
--- a/src/core/profile_adapter.h
+++ b/src/core/profile_adapter.h
@@ -174,6 +174,7 @@ class Q_WEBENGINECORE_EXPORT ProfileAdapter : public QObject
 
     void setPermission(const QUrl &origin, QWebEnginePermission::Feature feature, QWebEnginePermission::State state);
     QWebEnginePermission::State getPermissionState(const QUrl &origin, QWebEnginePermission::Feature feature);
+    QList<QWebEnginePermission> listPermissions(const QUrl &origin = QUrl(), QWebEnginePermission::Feature feature = QWebEnginePermission::Unsupported);
 
     QString httpAcceptLanguageWithoutQualities() const;
     QString httpAcceptLanguage() const;
@@ -185,6 +186,7 @@ class Q_WEBENGINECORE_EXPORT ProfileAdapter : public QObject
     void setClientHintsEnabled(bool enabled);
     void resetClientHints();
 
+
     void clearHttpCache();
 
 #if QT_CONFIG(ssl)
diff --git a/src/webenginequick/api/qquickwebengineprofile.cpp b/src/webenginequick/api/qquickwebengineprofile.cpp
index ae55bb1bd96..d3373d0b9b7 100644
--- a/src/webenginequick/api/qquickwebengineprofile.cpp
+++ b/src/webenginequick/api/qquickwebengineprofile.cpp
@@ -19,6 +19,7 @@
 #include <QtWebEngineCore/qwebenginenotification.h>
 #include <QtWebEngineCore/private/qwebenginedownloadrequest_p.h>
 #include <QtWebEngineCore/qwebengineurlscheme.h>
+#include <QtWebEngineCore/private/qwebenginepermission_p.h>
 
 #include <QtCore/qdir.h>
 #include <QtCore/qfileinfo.h>
@@ -1113,6 +1114,147 @@ QWebEngineClientHints *QQuickWebEngineProfile::clientHints() const
     return d->m_clientHints.data();
 }
 
+/*!
+    \fn QQuickWebEngineProfile::getPermission(const QUrl &securityOrigin, QWebEnginePermission::Feature feature) const
+
+    Returns a QWebEnginePermission object corresponding to a single permission for the provided \a securityOrigin and
+    \a feature. The object may be used to query for the current state of the permission, or to change it. It is not required
+    for a permission to already exist; the returned object may also be used to pre-grant a permission if a website is
+    known to use it.
+
+    \note This may only be used for permanent feature types. Calling it with a transient \a feature will return an invalid object.
+    \since 6.8
+    \sa listPermissions(), QWebEnginePermission::Feature
+ */
+
+/*!
+    \qmlmethod void WebEngineProfile::getPermission(url securityOrigin, WebEnginePermission.Feature feature) const
+
+    Returns a webEnginePermission object corresponding to a single permission for the provided \a securityOrigin and
+    \a feature. The object may be used to query for the current state of the permission, or to change it. It is not required
+    for a permission to already exist; the returned object may also be used to pre-grant a permission if a website is
+    known to use it.
+
+    \note This may only be used for permanent feature types. Calling it with a transient \a feature will return an invalid object.
+    \since 6.8
+    \sa listPermissions()
+ */
+QWebEnginePermission QQuickWebEngineProfile::getPermission(const QUrl &securityOrigin, QWebEnginePermission::Feature feature) const
+{
+    Q_D(const QQuickWebEngineProfile);
+
+    if (feature == QWebEnginePermission::Unsupported) {
+        qWarning("Attempting to get unsupported permission. Returned object will be in an invalid state.");
+        return QWebEnginePermission(new QWebEnginePermissionPrivate());
+    }
+
+    if (QWebEnginePermission::isTransient(feature)) {
+        qWarning() << "Attempting to get permission for feature" << feature << ". Returned object will be in an invalid state.";
+        return QWebEnginePermission(new QWebEnginePermissionPrivate());
+    }
+
+    auto *pvt = new QWebEnginePermissionPrivate(securityOrigin, feature, nullptr, d->profileAdapter());
+    return QWebEnginePermission(pvt);
+}
+
+/*!
+    \qmlmethod list<webEnginePermission> WebEngineProfile::listPermissions() const
+
+    Returns a \l list of webEnginePermission objects, each one representing a single permission currently
+    present in the permissions store. The returned list contains all previously granted/denied permissions for this profile,
+    except for those of a transient feature type.
+
+    \since 6.8
+    \sa getPermission()
+ */
+
+/*!
+    Returns a QList of QWebEnginePermission objects, each one representing a single permission currently
+    present in the permissions store. The returned list contains all previously granted/denied permissions for this profile,
+    except for those of a transient feature type.
+
+    \since 6.8
+    \sa getPermission()
+ */
+QList<QWebEnginePermission> QQuickWebEngineProfile::listPermissions() const
+{
+    Q_D(const QQuickWebEngineProfile);
+    if (persistentPermissionsPolicy() == NoPersistentPermissions)
+        return QList<QWebEnginePermission>();
+    return d->profileAdapter()->listPermissions();
+}
+
+/*!
+    \qmlmethod list<webEnginePermission> WebEngineProfile::listPermissions(url securityOrigin) const
+
+    Returns a \l list of webEnginePermission objects, each one representing a single permission currently
+    present in the permissions store. The returned list contains all previously granted/denied permissions associated with a
+    specific \a securityOrigin for this profile, except for those of a transient feature type.
+
+    \note Since permissions are granted on a per-origin basis, the provided \a securityOrigin will be stripped to its
+    origin form, and the returned list will contain all permissions for the origin. Thus, passing https://www.example.com/some/page.html
+    is the same as passing just https://www.example.com/.
+    \since 6.8
+    \sa getPermission()
+ */
+
+/*!
+    Returns a QList of QWebEnginePermission objects, each one representing a single permission currently
+    present in the permissions store. The returned list contains all previously granted/denied permissions associated with a
+    specific \a securityOrigin for this profile, except for those of a transient feature type.
+
+    \note Since permissions are granted on a per-origin basis, the provided \a securityOrigin will be stripped to its
+    origin form, and the returned list will contain all permissions for the origin. Thus, passing https://www.example.com/some/page.html
+    is the same as passing just https://www.example.com/.
+    \since 6.8
+    \sa getPermission()
+ */
+QList<QWebEnginePermission> QQuickWebEngineProfile::listPermissions(const QUrl &securityOrigin) const
+{
+    Q_D(const QQuickWebEngineProfile);
+    if (persistentPermissionsPolicy() == NoPersistentPermissions)
+        return QList<QWebEnginePermission>();
+    return d->profileAdapter()->listPermissions(securityOrigin);
+}
+
+/*!
+    \qmlmethod list<webEnginePermission> WebEngineProfile::listPermissions(WebEnginePermission.Feature feature) const
+
+    Returns a \l list of webEnginePermission objects, each one representing a single permission currently
+    present in the permissions store. The returned list contains all previously granted/denied permissions of the \a feature
+    type for this profile. If the feature is of a transient or unsupported type, the list will be empty.
+
+    \since 6.8
+    \sa getPermission()
+ */
+
+/*!
+    Returns a QList of QWebEnginePermission objects, each one representing a single permission currently
+    present in the permissions store. The returned list contains all previously granted/denied permissions of the \a feature
+    type for this profile. If the feature is of a transient or unsupported type, the list will be empty.
+
+    \since 6.8
+    \sa getPermission(), QWebEnginePermission::Feature
+ */
+QList<QWebEnginePermission> QQuickWebEngineProfile::listPermissions(QWebEnginePermission::Feature feature) const
+{
+    Q_D(const QQuickWebEngineProfile);
+    if (persistentPermissionsPolicy() == NoPersistentPermissions)
+        return QList<QWebEnginePermission>();
+
+    if (feature == QWebEnginePermission::Unsupported) {
+        qWarning("Attempting to get permission list for an unsupported type. Returned list will be empty.");
+        return QList<QWebEnginePermission>();
+    }
+
+    if (QWebEnginePermission::isTransient(feature)) {
+        qWarning() << "Attempting to get permission list for feature" << feature << ". Returned list will be empty.";
+        return QList<QWebEnginePermission>();
+    }
+
+    return d->profileAdapter()->listPermissions(QUrl(), feature);
+}
+
 void QQuickWebEngineProfile::ensureQmlContext(const QObject *object)
 {
     if (!qmlContext(this)) {
diff --git a/src/webenginequick/api/qquickwebengineprofile.h b/src/webenginequick/api/qquickwebengineprofile.h
index 7ba9105ffa9..186a11d7bc4 100644
--- a/src/webenginequick/api/qquickwebengineprofile.h
+++ b/src/webenginequick/api/qquickwebengineprofile.h
@@ -5,6 +5,7 @@
 #define QQUICKWEBENGINEPROFILE_H
 
 #include <QtWebEngineQuick/qtwebenginequickglobal.h>
+#include <QtWebEngineCore/qwebenginepermission.h>
 #include <QtCore/qobject.h>
 #include <QtCore/qscopedpointer.h>
 #include <QtCore/qstring.h>
@@ -127,6 +128,11 @@ class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineProfile : public QObject {
     QWebEngineClientCertificateStore *clientCertificateStore();
     QWebEngineClientHints *clientHints() const;
 
+    Q_REVISION(6,8) Q_INVOKABLE QWebEnginePermission getPermission(const QUrl &securityOrigin, QWebEnginePermission::Feature feature) const;
+    Q_REVISION(6,8) Q_INVOKABLE QList<QWebEnginePermission> listPermissions() const;
+    Q_REVISION(6,8) Q_INVOKABLE QList<QWebEnginePermission> listPermissions(const QUrl &securityOrigin) const;
+    Q_REVISION(6,8) Q_INVOKABLE QList<QWebEnginePermission> listPermissions(QWebEnginePermission::Feature feature) const;
+
     static QQuickWebEngineProfile *defaultProfile();
 
 Q_SIGNALS:
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index cf0e59274df..dbe9513f20e 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -98,7 +98,9 @@ static const QStringList hardcodedTypes = QStringList()
     << "Qt::LayoutDirection"
     << "QQuickWebEngineScriptCollection*"
     << "QQmlComponent*"
-    << "QMultiMap<QByteArray,QByteArray>";
+    << "QMultiMap<QByteArray,QByteArray>"
+    << "QList<QWebEnginePermission>"
+    ;
 
 static const QStringList expectedAPI = QStringList()
     << "QQuickWebEngineAction.text --> QString"
@@ -397,6 +399,10 @@ static const QStringList expectedAPI = QStringList()
     << "QQuickWebEngineProfile.downloadRequested(QQuickWebEngineDownloadRequest*) --> void"
     << "QQuickWebEngineProfile.downloadPath --> QString"
     << "QQuickWebEngineProfile.downloadPathChanged() --> void"
+    << "QQuickWebEngineProfile.getPermission(QUrl,QWebEnginePermission::Feature) --> QWebEnginePermission"
+    << "QQuickWebEngineProfile.listPermissions() --> QList<QWebEnginePermission>"
+    << "QQuickWebEngineProfile.listPermissions(QUrl) --> QList<QWebEnginePermission>"
+    << "QQuickWebEngineProfile.listPermissions(QWebEnginePermission::Feature) --> QList<QWebEnginePermission>"
     << "QQuickWebEngineProfile.persistentPermissionsPolicy --> QQuickWebEngineProfile::PersistentPermissionsPolicy"
     << "QQuickWebEngineProfile.persistentPermissionsPolicyChanged() --> void"
     << "QQuickWebEngineProfile.presentNotification(QWebEngineNotification*) --> void"
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 8b6ea31fd41..e7f2ce1cd7a 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -3818,6 +3818,8 @@ struct NotificationPage : ConsolePage {
             case QWebEnginePermission::Ask:
                 permission.reset();
                 break;
+            default:
+                break;
             }
             spyRequest.ref()(permission.origin());
         });
@@ -3876,17 +3878,13 @@ void tst_QWebEnginePage::notificationPermission()
             permission.deny();
     });
 
-    if (setOnInit)
-#if QT_DEPRECATED_SINCE(6, 8)
-        QT_WARNING_PUSH
-        QT_WARNING_DISABLE_DEPRECATED
-        // FIXME: Replace with QWebEngineProfile permission API when that's implemented
-        page.setFeaturePermission(baseUrl, QWebEnginePage::Notifications,
-            policy == QWebEnginePermission::Granted ? QWebEnginePage::PermissionGrantedByUser : QWebEnginePage::PermissionDeniedByUser);
-        QT_WARNING_POP
-#else
-        W_QSKIP("Compiled without deprecated APIs", SkipSingle);
-#endif // QT_DEPRECATED_SINCE(6, 8)
+    QWebEnginePermission permissionObject = otr.getPermission(baseUrl, QWebEnginePermission::Notifications);
+    if (setOnInit) {
+        if (policy == QWebEnginePermission::Granted)
+            permissionObject.grant();
+        else
+            permissionObject.deny();
+    }
 
     QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
     page.setHtml(QString("<html><body>Test</body></html>"), baseUrl);
@@ -3895,17 +3893,11 @@ void tst_QWebEnginePage::notificationPermission()
     QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("Notification.permission")), setOnInit ? permission : QLatin1String("default"));
 
     if (!setOnInit) {
-#if QT_DEPRECATED_SINCE(6, 8)
-        QT_WARNING_PUSH
-        QT_WARNING_DISABLE_DEPRECATED
-        // FIXME: Replace with QWebEngineProfile permission API when that's implemented
-        page.setFeaturePermission(baseUrl, QWebEnginePage::Notifications,
-            policy == QWebEnginePermission::Granted ? QWebEnginePage::PermissionGrantedByUser : QWebEnginePage::PermissionDeniedByUser);
+        if (policy == QWebEnginePermission::Granted)
+            permissionObject.grant();
+        else
+            permissionObject.deny();
         QTRY_COMPARE(evaluateJavaScriptSync(&page, QStringLiteral("Notification.permission")), permission);
-        QT_WARNING_POP
-#else
-        W_QSKIP("Compiled without deprecated APIs", SkipSingle);
-#endif // QT_DEPRECATED_SINCE(6, 8)
     }
 
     auto js = QStringLiteral("var permission; Notification.requestPermission().then(p => { permission = p })");
@@ -4084,18 +4076,20 @@ void tst_QWebEnginePage::clipboardReadWritePermission()
                 }
             });
 
-    // FIXME: Replace with QWebEngineProfile permission API when that's implemented
-#if QT_DEPRECATED_SINCE(6, 8)
-    QT_WARNING_PUSH
-    QT_WARNING_DISABLE_DEPRECATED
-    QWebEnginePage::PermissionPolicy deprecatedPolicy =
-        initialPolicy == QWebEnginePermission::Granted ? QWebEnginePage::PermissionGrantedByUser
-        : (initialPolicy == QWebEnginePermission::Denied ? QWebEnginePage::PermissionDeniedByUser : QWebEnginePage::PermissionUnknown);
-    page.setFeaturePermission(baseUrl, QWebEnginePage::ClipboardReadWrite, deprecatedPolicy);
-    QT_WARNING_POP
-#else
-    W_QSKIP("Compiled without deprecated APIs", SkipSingle);
-#endif // QT_DEPRECATED_SINCE(6, 8)
+    QWebEnginePermission permissionObject = otr.getPermission(baseUrl, QWebEnginePermission::ClipboardReadWrite);
+    switch (initialPolicy) {
+    case QWebEnginePermission::Granted:
+        permissionObject.grant();
+        break;
+    case QWebEnginePermission::Denied:
+        permissionObject.deny();
+        break;
+    case QWebEnginePermission::Ask:
+        permissionObject.reset();
+        break;
+    default:
+        break;
+    }
 
     QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
     page.setHtml(QString("<html><body>Test</body></html>"), baseUrl);
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index 81800658650..6245a6c7a23 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -58,6 +58,9 @@ private Q_SLOTS:
     void badDeleteOrder();
     void permissionPersistence_data();
     void permissionPersistence();
+    void getPermission_data();
+    void getPermission();
+    void listPermissions();
     void qtbug_71895(); // this should be the last test
 };
 
@@ -1051,15 +1054,12 @@ void tst_QWebEngineProfile::permissionPersistence()
 
     QVariant variant = granted ? "granted" : "denied";
     QVariant defaultVariant = "default";
-#if QT_DEPRECATED_SINCE(6, 8)
-    QT_WARNING_PUSH
-    QT_WARNING_DISABLE_DEPRECATED
-    page->setFeaturePermission(server.url("/hedgehog.html"), QWebEnginePage::Notifications,
-        granted ? QWebEnginePage::PermissionGrantedByUser : QWebEnginePage::PermissionDeniedByUser);
-    QT_WARNING_POP
-#else
-    W_QSKIP("Compiled without deprecated APIs", SkipSingle);
-#endif // QT_DEPRECATED_SINCE(6, 8)
+
+    QWebEnginePermission permissionObject = profile->getPermission(server.url("/hedgehog.html"), QWebEnginePermission::Notifications);
+    if (granted)
+        permissionObject.grant();
+    else
+        permissionObject.deny();
     QCOMPARE(evaluateJavaScriptSync(page.get(), "Notification.permission"), variant);
 
     page.reset();
@@ -1084,14 +1084,9 @@ void tst_QWebEngineProfile::permissionPersistence()
     QTRY_COMPARE(evaluateJavaScriptSync(page.get(), "Notification.permission"),
         expectSame ? variant : defaultVariant);
 
-#if QT_DEPRECATED_SINCE(6, 8)
-    QT_WARNING_PUSH
-    QT_WARNING_DISABLE_DEPRECATED
-    page->setFeaturePermission(server.url("/hedgehog.html"), QWebEnginePage::Notifications, QWebEnginePage::PermissionUnknown);
-    QT_WARNING_POP
-#else
-    W_QSKIP("Compiled without deprecated APIs", SkipSingle);
-#endif // QT_DEPRECATED_SINCE(6, 8)
+    // Re-acquire the permission, since deleting the Profile makes it invalid
+    permissionObject = profile->getPermission(server.url("/hedgehog.html"), QWebEnginePermission::Notifications);
+    permissionObject.reset();
     QCOMPARE(evaluateJavaScriptSync(page.get(), "Notification.permission"), defaultVariant);
 
     page.reset();
@@ -1107,6 +1102,105 @@ void tst_QWebEngineProfile::permissionPersistence()
     QVERIFY(server.stop());
 }
 
+void tst_QWebEngineProfile::getPermission_data()
+{
+    QTest::addColumn<QWebEnginePermission::Feature>("feature");
+    QTest::addColumn<QUrl>("url");
+    QTest::addColumn<bool>("expectedValid");
+
+    QTest::newRow("badUrl") << QWebEnginePermission::Notifications << QUrl(QStringLiteral("//:bad-url")) << false;
+    QTest::newRow("badFeature") << QWebEnginePermission::Unsupported << QUrl(QStringLiteral("qrc:/resources/hedgehog.html")) << false;
+    QTest::newRow("transientFeature") << QWebEnginePermission::MouseLock << QUrl(QStringLiteral("qrc:/resources/hedgehog.html")) << false;
+    QTest::newRow("good") << QWebEnginePermission::Notifications << QUrl(QStringLiteral("qrc:/resources/hedgehog.html")) << true;
+}
+
+void tst_QWebEngineProfile::getPermission()
+{
+    QFETCH(QWebEnginePermission::Feature, feature);
+    QFETCH(QUrl, url);
+    QFETCH(bool, expectedValid);
+
+    QWebEngineProfile profile;
+    // In-memory is the default for otr profiles
+    QVERIFY(profile.persistentPermissionsPolicy() == QWebEngineProfile::PersistentPermissionsInMemory);
+
+    QWebEnginePermission permission = profile.getPermission(url, feature);
+    bool valid = permission.isValid();
+    QVERIFY(valid == expectedValid);
+    if (!valid)
+        QVERIFY(permission.state() == QWebEnginePermission::Invalid);
+
+    // Verify that we can grant a valid permission, and we can't grant an invalid one...
+    permission.grant();
+    QVERIFY(permission.state() == (valid ? QWebEnginePermission::Granted : QWebEnginePermission::Invalid));
+
+    // ...and that doing so twice doesn't mess up the state...
+    permission.grant();
+    QVERIFY(permission.state() == (valid ? QWebEnginePermission::Granted : QWebEnginePermission::Invalid));
+
+    // ...and that the same thing applies to denying them...
+    permission.deny();
+    QVERIFY(permission.state() == (valid ? QWebEnginePermission::Denied : QWebEnginePermission::Invalid));
+    permission.deny();
+    QVERIFY(permission.state() == (valid ? QWebEnginePermission::Denied : QWebEnginePermission::Invalid));
+
+    // ...and that resetting works
+    permission.reset();
+    QVERIFY(permission.state() == (valid ? QWebEnginePermission::Ask : QWebEnginePermission::Invalid));
+    permission.reset();
+    QVERIFY(permission.state() == (valid ? QWebEnginePermission::Ask : QWebEnginePermission::Invalid));
+}
+
+void tst_QWebEngineProfile::listPermissions()
+{
+    QWebEngineProfile profile;
+    // In-memory is the default for otr profiles
+    QVERIFY(profile.persistentPermissionsPolicy() == QWebEngineProfile::PersistentPermissionsInMemory);
+
+    QUrl commonUrl = QUrl(QStringLiteral("http://www.bing.com/maps"));
+    QWebEnginePermission::Feature commonFeature = QWebEnginePermission::Notifications;
+
+    // First, set several permissions at once
+    profile.getPermission(commonUrl, QWebEnginePermission::Geolocation).deny();
+    profile.getPermission(commonUrl, QWebEnginePermission::Unsupported).grant(); // Invalid
+    profile.getPermission(commonUrl, commonFeature).grant();
+    profile.getPermission(QUrl(QStringLiteral("http://www.google.com/translate")), commonFeature).grant();
+
+    QList<QWebEnginePermission> permissionsListAll = profile.listPermissions();
+    QList<QWebEnginePermission> permissionsListUrl = profile.listPermissions(commonUrl);
+    QList<QWebEnginePermission> permissionsListFeature = profile.listPermissions(commonFeature);
+
+    // Order of returned permissions is not guaranteed, so we must iterate until we find the one we need
+    auto findInList = [](QList<QWebEnginePermission> list, const QUrl &url,
+        QWebEnginePermission::Feature feature, QWebEnginePermission::State state)
+    {
+        bool found = false;
+        for (auto &permission : list) {
+            if (permission.origin().adjusted(QUrl::RemovePath) == url.adjusted(QUrl::RemovePath) && permission.feature() == feature && permission.state() == state) {
+                found = true;
+                break;
+            }
+        }
+        return found;
+    };
+
+    // Check full list
+    QVERIFY(permissionsListAll.size() == 3);
+    QVERIFY(findInList(permissionsListAll, commonUrl, QWebEnginePermission::Geolocation, QWebEnginePermission::Denied));
+    QVERIFY(findInList(permissionsListAll, commonUrl, commonFeature, QWebEnginePermission::Granted));
+    QVERIFY(findInList(permissionsListAll, QUrl(QStringLiteral("http://www.google.com")), commonFeature, QWebEnginePermission::Granted));
+
+    // Check list filtered by URL
+    QVERIFY(permissionsListUrl.size() == 2);
+    QVERIFY(findInList(permissionsListUrl, commonUrl, QWebEnginePermission::Geolocation, QWebEnginePermission::Denied));
+    QVERIFY(findInList(permissionsListAll, commonUrl, commonFeature, QWebEnginePermission::Granted));
+
+    // Check list filtered by feature
+    QVERIFY(permissionsListFeature.size() == 2);
+    QVERIFY(findInList(permissionsListAll, commonUrl, commonFeature, QWebEnginePermission::Granted));
+    QVERIFY(findInList(permissionsListAll, QUrl(QStringLiteral("http://www.google.com")), commonFeature, QWebEnginePermission::Granted));
+}
+
 void tst_QWebEngineProfile::qtbug_71895()
 {
     QWebEngineView view;

From 5ab15e1ce3f4168de0380a23a242ff934d777008 Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Fri, 31 May 2024 11:17:38 +0200
Subject: [PATCH 005/356] Add QWebEngineFrame::isMainFrame()

Change-Id: I5360ebc88aeff2189071c971e4f24a69e765686d
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 91abf8036329a6e8830fa616d11cf27bd62a2a8d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebengineframe.cpp                   |  8 ++++++++
 src/core/api/qwebengineframe.h                     |  2 ++
 src/webenginequick/doc/src/webengineframe.qdoc     |  6 ++++++
 .../core/qwebengineframe/tst_qwebengineframe.cpp   | 14 ++++++++++++++
 tests/auto/quick/publicapi/tst_publicapi.cpp       |  1 +
 5 files changed, 31 insertions(+)

diff --git a/src/core/api/qwebengineframe.cpp b/src/core/api/qwebengineframe.cpp
index 52fd5e60273..fa2cbb507b3 100644
--- a/src/core/api/qwebengineframe.cpp
+++ b/src/core/api/qwebengineframe.cpp
@@ -106,6 +106,14 @@ QSizeF QWebEngineFrame::size() const
     return m_adapterClient->webContentsAdapter()->frameSize(m_id);
 }
 
+/*!
+    Returns \c{true} if this object represents the page's main frame; \c{false} otherwise.
+*/
+bool QWebEngineFrame::isMainFrame() const
+{
+    return m_adapterClient->webContentsAdapter()->mainFrameId() == m_id;
+}
+
 /*! \fn void QWebEngineFrame::runJavaScript(const QString &script, const std::function<void(const QVariant &)> &callback)
     \fn void QWebEngineFrame::runJavaScript(const QString &script, quint32 worldId)
     \fn void QWebEngineFrame::runJavaScript(const QString &script, quint32 worldId, const
diff --git a/src/core/api/qwebengineframe.h b/src/core/api/qwebengineframe.h
index 34b72e08ea1..b6953cdd21f 100644
--- a/src/core/api/qwebengineframe.h
+++ b/src/core/api/qwebengineframe.h
@@ -28,6 +28,7 @@ class Q_WEBENGINECORE_EXPORT QWebEngineFrame
     Q_PROPERTY(QString htmlName READ htmlName FINAL)
     Q_PROPERTY(QUrl url READ url FINAL)
     Q_PROPERTY(QSizeF size READ size FINAL)
+    Q_PROPERTY(bool isMainFrame READ isMainFrame FINAL)
 
 public:
     QML_VALUE_TYPE(webEngineFrame)
@@ -39,6 +40,7 @@ class Q_WEBENGINECORE_EXPORT QWebEngineFrame
     QList<QWebEngineFrame> children() const;
     QUrl url() const;
     QSizeF size() const;
+    bool isMainFrame() const;
 
     void runJavaScript(const QString &script,
                        const std::function<void(const QVariant &)> &callback);
diff --git a/src/webenginequick/doc/src/webengineframe.qdoc b/src/webenginequick/doc/src/webengineframe.qdoc
index 7df4a1d2bfd..8f852501ef8 100644
--- a/src/webenginequick/doc/src/webengineframe.qdoc
+++ b/src/webenginequick/doc/src/webengineframe.qdoc
@@ -64,6 +64,12 @@
     If the frame could not be found, returns a default size with dimensions (-1, -1).
 */
 
+/*!
+    \qmlproperty bool webEngineFrame::isMainFrame
+
+    Returns \c{true} if this object represents the page's main frame; \c{false} otherwise.
+*/
+
 /*!
     \qmlmethod void webEngineFrame::runJavaScript(string script, variant callback)
     \qmlmethod void webEngineFrame::runJavaScript(string script, uint worldId, variant callback)
diff --git a/tests/auto/core/qwebengineframe/tst_qwebengineframe.cpp b/tests/auto/core/qwebengineframe/tst_qwebengineframe.cpp
index 2fe0e27a265..8bbefd5f58a 100644
--- a/tests/auto/core/qwebengineframe/tst_qwebengineframe.cpp
+++ b/tests/auto/core/qwebengineframe/tst_qwebengineframe.cpp
@@ -37,6 +37,7 @@ private Q_SLOTS:
     void childrenOfInvalidFrame();
     void url();
     void size();
+    void isMainFrame();
     void runJavaScript();
     void printRequestedByFrame();
     void printToPdfFile();
@@ -180,6 +181,19 @@ void tst_QWebEngineFrame::size()
     QCOMPARE(frame1.size(), QSizeF());
 }
 
+void tst_QWebEngineFrame::isMainFrame()
+{
+    QWebEnginePage page;
+    QSignalSpy loadSpy{ &page, SIGNAL(loadFinished(bool)) };
+    page.load(QUrl("qrc:/resources/frameset.html"));
+    QTRY_COMPARE(loadSpy.size(), 1);
+    auto frame = page.mainFrame();
+    QVERIFY(frame.isMainFrame());
+    for (auto child : frame.children()) {
+        QVERIFY(!child.isMainFrame());
+    }
+}
+
 void tst_QWebEngineFrame::runJavaScript()
 {
     QWebEnginePage page;
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index dbe9513f20e..e6605dc4103 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -929,6 +929,7 @@ static const QStringList expectedAPI = QStringList()
     << "QQuickWebEngineSettings.imageAnimationPolicy --> QQuickWebEngineSettings::ImageAnimationPolicy"
     << "QQuickWebEngineSettings.imageAnimationPolicyChanged() --> void"
     << "QWebEngineFrame.htmlName --> QString"
+    << "QWebEngineFrame.isMainFrame --> bool"
     << "QWebEngineFrame.isValid --> bool"
     << "QWebEngineFrame.name --> QString"
     << "QWebEngineFrame.printToPdf(QJSValue) --> void"

From bb988763684ae3e52f8274905e97a396d81f0975 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Fri, 12 Apr 2024 11:07:06 +0200
Subject: [PATCH 006/356] Add PermissionBrowser example

The example demonstrates how to properly use the new
QWebEnginePermission API to manage incoming and existing
website permissions.

Change-Id: I21fd01879f7bd89fc2239fde38f5b6456f193578
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 754160cc0951315fd7d4e712e151dd617910644b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 examples/webenginewidgets/CMakeLists.txt      |   1 +
 .../permissionbrowser/CMakeLists.txt          |  84 +++++
 .../permissionbrowser/Info.cmake.macos.plist  |  36 ++
 .../doc/images/permissionbrowser-example.png  | Bin 0 -> 50311 bytes
 .../doc/src/permissionbrowser.qdoc            | 221 +++++++++++
 .../permissionbrowser/main.cpp                |  18 +
 .../permissionbrowser/mainwindow.cpp          | 270 +++++++++++++
 .../permissionbrowser/mainwindow.h            |  74 ++++
 .../permissionbrowser/mainwindow.ui           | 356 ++++++++++++++++++
 .../permissionbrowser.exe.manifest            |  17 +
 .../permissionbrowser/permissionbrowser.qrc   |   7 +
 .../permissionbrowser/permissiondialog.ui     | 117 ++++++
 .../permissionbrowser/permissionwidget.ui     | 119 ++++++
 .../resources/3rdparty/COPYING                |   1 +
 .../resources/3rdparty/go-next.png            | Bin 0 -> 1219 bytes
 .../resources/3rdparty/go-previous.png        | Bin 0 -> 1200 bytes
 .../resources/3rdparty/qt_attribution.json    |  24 ++
 .../resources/3rdparty/view-refresh.png       | Bin 0 -> 1364 bytes
 .../resources/AppLogoColor.png                | Bin 0 -> 6113 bytes
 .../permissionbrowser/resources/landing.html  |  88 +++++
 20 files changed, 1433 insertions(+)
 create mode 100644 examples/webenginewidgets/permissionbrowser/CMakeLists.txt
 create mode 100644 examples/webenginewidgets/permissionbrowser/Info.cmake.macos.plist
 create mode 100644 examples/webenginewidgets/permissionbrowser/doc/images/permissionbrowser-example.png
 create mode 100644 examples/webenginewidgets/permissionbrowser/doc/src/permissionbrowser.qdoc
 create mode 100644 examples/webenginewidgets/permissionbrowser/main.cpp
 create mode 100644 examples/webenginewidgets/permissionbrowser/mainwindow.cpp
 create mode 100644 examples/webenginewidgets/permissionbrowser/mainwindow.h
 create mode 100644 examples/webenginewidgets/permissionbrowser/mainwindow.ui
 create mode 100644 examples/webenginewidgets/permissionbrowser/permissionbrowser.exe.manifest
 create mode 100644 examples/webenginewidgets/permissionbrowser/permissionbrowser.qrc
 create mode 100644 examples/webenginewidgets/permissionbrowser/permissiondialog.ui
 create mode 100644 examples/webenginewidgets/permissionbrowser/permissionwidget.ui
 create mode 100644 examples/webenginewidgets/permissionbrowser/resources/3rdparty/COPYING
 create mode 100644 examples/webenginewidgets/permissionbrowser/resources/3rdparty/go-next.png
 create mode 100644 examples/webenginewidgets/permissionbrowser/resources/3rdparty/go-previous.png
 create mode 100644 examples/webenginewidgets/permissionbrowser/resources/3rdparty/qt_attribution.json
 create mode 100644 examples/webenginewidgets/permissionbrowser/resources/3rdparty/view-refresh.png
 create mode 100644 examples/webenginewidgets/permissionbrowser/resources/AppLogoColor.png
 create mode 100644 examples/webenginewidgets/permissionbrowser/resources/landing.html

diff --git a/examples/webenginewidgets/CMakeLists.txt b/examples/webenginewidgets/CMakeLists.txt
index 3ce666d7293..ebe34d668fa 100644
--- a/examples/webenginewidgets/CMakeLists.txt
+++ b/examples/webenginewidgets/CMakeLists.txt
@@ -3,6 +3,7 @@
 
 qt_internal_add_example(contentmanipulation)
 qt_internal_add_example(cookiebrowser)
+qt_internal_add_example(permissionbrowser)
 qt_internal_add_example(notifications)
 qt_internal_add_example(simplebrowser)
 qt_internal_add_example(push-notifications)
diff --git a/examples/webenginewidgets/permissionbrowser/CMakeLists.txt b/examples/webenginewidgets/permissionbrowser/CMakeLists.txt
new file mode 100644
index 00000000000..0a92691ba1f
--- /dev/null
+++ b/examples/webenginewidgets/permissionbrowser/CMakeLists.txt
@@ -0,0 +1,84 @@
+# Copyright (C) 2024 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.5)
+project(permissionbrowser LANGUAGES CXX)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+    set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/permissionbrowser")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineWidgets)
+
+qt_add_executable(permissionbrowser
+    permissiondialog.ui
+    permissionwidget.ui
+    main.cpp
+    mainwindow.cpp mainwindow.h mainwindow.ui
+)
+
+if(WIN32)
+    set_property(
+        TARGET permissionbrowser
+        APPEND PROPERTY
+            SOURCES permissionbrowser.exe.manifest)
+endif()
+
+set_target_properties(permissionbrowser PROPERTIES
+    WIN32_EXECUTABLE TRUE
+    MACOSX_BUNDLE TRUE
+    MACOSX_BUNDLE_GUI_IDENTIFIER "io.qt.examples.webenginewidgets.permissionbrowser"
+)
+
+target_link_libraries(permissionbrowser PUBLIC
+    Qt::Core
+    Qt::Gui
+    Qt::WebEngineWidgets
+)
+
+# Resources:
+set(permissionbrowser_resource_files
+    "resources/3rdparty/view-refresh.png"
+    "resources/3rdparty/go-next.png"
+    "resources/3rdparty/go-previous.png"
+    "resources/AppLogoColor.png"
+    "resources/landing.html"
+)
+
+qt_add_resources(permissionbrowser "permissionbrowser"
+    PREFIX
+        "/"
+    BASE
+        "resources"
+    FILES
+        ${permissionbrowser_resource_files}
+)
+
+if (APPLE)
+    set_target_properties(permissionbrowser PROPERTIES
+        MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.cmake.macos.plist"
+    )
+
+    if (NOT CMAKE_GENERATOR STREQUAL "Xcode")
+        # Need to sign application for location permissions to work
+        if(QT_FEATURE_debug_and_release)
+            set(exe_path "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/")
+        else()
+            unset(exe_path)
+        endif()
+        add_custom_command(TARGET permissionbrowser
+            POST_BUILD COMMAND codesign --force -s - ${exe_path}permissionbrowser.app
+        )
+    endif()
+endif()
+
+install(TARGETS permissionbrowser
+    RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+    BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+    LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/examples/webenginewidgets/permissionbrowser/Info.cmake.macos.plist b/examples/webenginewidgets/permissionbrowser/Info.cmake.macos.plist
new file mode 100644
index 00000000000..48ddaadc650
--- /dev/null
+++ b/examples/webenginewidgets/permissionbrowser/Info.cmake.macos.plist
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+    <key>CFBundleInfoDictionaryVersion</key>
+    <string>6.0</string>
+    <key>CFBundlePackageType</key>
+    <string>APPL</string>
+    <key>CFBundleName</key>
+    <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
+    <key>CFBundleIdentifier</key>
+    <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
+    <key>CFBundleExecutable</key>
+    <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
+    <key>CFBundleVersion</key>
+    <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
+    <key>CFBundleShortVersionString</key>
+    <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
+    <key>LSMinimumSystemVersion</key>
+    <string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
+    <key>NSHumanReadableCopyright</key>
+    <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
+    <key>CFBundleIconFile</key>
+    <string>${MACOSX_BUNDLE_ICON_FILE}</string>
+    <key>CFBundleDevelopmentRegion</key>
+    <string>English</string>
+    <key>NSSupportsAutomaticGraphicsSwitching</key>
+    <true/>
+    <key>NSLocationUsageDescription</key>
+    <string>Permission Browser would like to give web sites access to your location for demo purposes.</string>
+    <key>NSMicrophoneUsageDescription</key>
+    <string>Permission Browser would like to give web sites access to your computer's microphone for demo purposes.</string>
+    <key>NSCameraUsageDescription</key>
+    <string>Permission Browser would like to give web sites access to your computer's camera for demo purposes.</string>
+</dict>
+</plist>
diff --git a/examples/webenginewidgets/permissionbrowser/doc/images/permissionbrowser-example.png b/examples/webenginewidgets/permissionbrowser/doc/images/permissionbrowser-example.png
new file mode 100644
index 0000000000000000000000000000000000000000..56ea60025ded508dcc93f2bfecf9ae08b4f84d1b
GIT binary patch
diff --git a/examples/webenginewidgets/permissionbrowser/doc/src/permissionbrowser.qdoc b/examples/webenginewidgets/permissionbrowser/doc/src/permissionbrowser.qdoc
new file mode 100644
index 00000000000..a266ec62a2a
--- /dev/null
+++ b/examples/webenginewidgets/permissionbrowser/doc/src/permissionbrowser.qdoc
@@ -0,0 +1,221 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+    \example webenginewidgets/permissionbrowser
+    \examplecategory {Web Technologies}
+    \title WebEngine Widgets Permission Browser Example
+    \ingroup webengine-widgetexamples
+    \brief Demonstrates how to handle website permission requests, and manage
+    existing permissions.
+
+    \image permissionbrowser-example.png
+
+    Permission Browser demonstrates how to use the \l{QWebEnginePermission} class
+    to manage website permissions. The example includes code for handling incoming
+    permission requests, as well as modifying already existing permissions. Also
+    demonstrated are the effects of the different permission persistence policies
+    defined within the \l{QWebEngineProfile} class.
+
+    \include examples-run.qdocinc
+
+    \section1 Class Definitions
+
+    \section2 MainWindow
+
+    The \c MainWindow class inherits \l QMainWindow. Inside, we declare a convenience
+    pointer to the \l QVBoxLayout which will lay out the widgets used to manipulate
+    individual permissions, as well as another convenience pointer to the widget
+    displaying the currently pending permission request. We also declare a
+    \l QWebEngineView, which will be used to display the actual webpage contents.
+
+    \quotefromfile webenginewidgets/permissionbrowser/mainwindow.h
+    \skipto class MainWindow :
+    \printuntil /^\}/
+
+    The rest of the layout for the application is defined inside mainwindow.ui,
+    and was created using Qt Creator's Design mode. \c MainWindow is a child class
+    of Ui_MainWindow, which is a C++ class generated at compile time from the
+    definitions found inside mainwindow.ui.
+
+    \section2 PermissionWidget and PermissionDialog
+
+    The \c PermissionWidget class defines a widget corresponding to a single
+    \l QWebEnginePermission instance. For convenience, the \l QWebEnginePermission
+    object is stored within. The widget itself has controls for granting, denying,
+    or deleting the permission; all of this is defined inside \c PermissionWidget.ui.
+
+    \quotefromfile webenginewidgets/permissionbrowser/mainwindow.h
+    \skipto class PermissionWidget :
+    \printuntil /^\}/
+
+    When clicking the "New" button in the main window's UI, a pop-up window will
+    appear, allowing the user to pre-grant permission to a known origin. That
+    pop-up is defined by the \c PermissionDialog class:
+
+    \quotefromfile webenginewidgets/permissionbrowser/mainwindow.h
+    \skipto class PermissionDialog :
+    \printuntil /^\}/
+
+    \section1 Handling incoming permission requests
+
+    Whenever a website uses an API that might compromise the user's privacy, the
+    browser is expected to show them a prompt asking to either grant or deny permission.
+    The PermissionBrowser example has a dedicated section at the bottom right, which
+    gets populated with a \c PermissionWidget whenever that happens.
+
+    The \c PermissionWidget displays the permission's origin, the requested
+    \l QWebEnginePermission::Feature, as well as the current status of that permission.
+    It also has buttons for granting and denying the permission. Since the permission status
+    is (by default) remembered, the delete button allows the user to remove the permission
+    from the underlying storage.
+
+    To achieve all this, we first connect QWebEnginePage's \c permissionRequested signal
+    to \c MainWindow's \c handlePermissionRequested slot:
+
+    \quotefromfile webenginewidgets/permissionbrowser/mainwindow.cpp
+    \skipto connect(m_webview->page(),
+    \printline connect(m_webview->page(),
+
+    The signal handler is relatively simple: it attempts to create a \c PermissionWidget
+    instance for the provided QWebEnginePermission object, and if it succeeds it
+    plugs that widget into the QFrame designated for pending permissions. We also
+    subscribe to \c PermissionWidget's \c permissionModified signal so that we can later move
+    the \c PermissionWidget from the bottom right to the list of existing widgets above.
+
+    \quotefromfile webenginewidgets/permissionbrowser/mainwindow.cpp
+    \skipto void MainWindow::handlePermissionRequested
+    \printuntil /^\}/
+
+    We only create a new \c PermissionWidget if we don't already have an existing one:
+
+    \quotefromfile webenginewidgets/permissionbrowser/mainwindow.cpp
+    \skipto PermissionWidget *MainWindow::create PermissionWidget
+    \printuntil /^\}/
+
+    \target PermissionWidgetConstructor
+    \section1 Modifying a permission and displaying it to the user
+
+    The QWebEnginePermission interface provides the \l {QWebEnginePermission::grant}{grant}()
+    and {QWebEnginePermission::deny}{deny}() functions, which are all that's needed to
+    change the status of a permission. If the application needs to forget about a permission,
+    we use the {QWebEnginePermission::reset}{reset}() function.
+
+    Inside the \c PermissionWidget constructor, we hook those function up to the buttons'
+    \c clicked signal, so that we can execute the relevant functionality on the
+    QWebEnginePermission object.
+
+    Whenever a button is pressed, we emit the \c permissionModified signal, which
+    \c MainWindow uses to know when it needs to move the widget from the bottom-right
+    to the list of existing permissions. We also make sure to call \c updateState(), which
+    handles visual updates to the widget. When the delete button is pressed, we also make
+    sure mark the widget for deletion, since we only want to display existing permissions to
+    the user.
+
+    \quotefromfile webenginewidgets/permissionbrowser/mainwindow.cpp
+    \skipto PermissionWidget::PermissionWidget
+    \printuntil /^\}/
+
+    The \c updateState() function displays the data supplied by QWebEnginePermission
+    to the user. It also makes sure that, when a permission is in the
+    \l QWebEnginePermission::Invalid state, the buttons for granting or denying it
+    are disabled.
+
+    \quotefromfile webenginewidgets/permissionbrowser/mainwindow.cpp
+    \skipto void PermissionWidget::updateState()
+    \printuntil /^\}/
+
+    When a pending permission is granted or denied, we want to move the associated
+    widget to the list above, which contains all currently existing permissions.
+    We do this in the MainWindow::handlePermissionModified slot.
+
+    \quotefromfile webenginewidgets/permissionbrowser/mainwindow.cpp
+    \skipto void MainWindow::handlePermissionModified
+    \printuntil /^\}/
+
+    Notably, we only do this in cases where we know the permission is remembered.
+    This is not true for transient \c Features,
+    which require a permission prompt be shown to the user every time they're needed.
+    We also exclude permissions with a \l QWebEnginePermission::Ask state, which
+    indicates that the permission was \l {QWebEnginePermission::reset}{reset}(),
+    and we don't add anything to the list of existing permissions when
+    \l QWebEngineProfile::persistentPermissionsPolicy is set to
+    \c NoPersistentPermissions.
+
+    \note Check the \l QWebEnginePermission::Feature documentation to see which
+    \c Features are transient.
+
+    \section1 Displaying and modifying existing permissions
+
+    By default, permissions are stored to disk and retrieved again on application
+    startup. To get a list of all existing website permissions, we call
+    \l QWebEngineProfile::listPermissions():
+
+    \quotefromfile webenginewidgets/permissionbrowser/mainwindow.cpp
+    \skipto void MainWindow::loadStoredPermissions()
+    \printuntil /^\}/
+
+    For every permission in the list, we simply construct a new \c PermissionWidget, and
+    add it to the list on the right-hand side of the screen. Existing permissions
+    are modified \l {PermissionWidgetConstructor}{using the exact same API as pending ones}.
+
+    \section1 Pre-granting permissions
+
+    Certain permissions may be granted in advance, provided the origin and Feature type
+    are known. Clicking on the "New" button in the top right will create a pop-up
+    dialog that allows you to do just that. The dialog is implemented by the
+    \c PermissionDialog class:
+
+    \quotefromfile webenginewidgets/permissionbrowser/mainwindow.cpp
+    \skipto PermissionDialog::PermissionDialog
+    \printuntil /^\}/
+
+    We populate the \l QComboBox using the QMetaEnum type associated with
+    \l QWebEnginePermission::Feature. We make sure to filter out transient
+    features, since pre-granting these is not supported.
+
+    We display the dialog and add show the resulting \c PermissionWidget
+    in the UI inside the \c MainWindow::handleNewClicked slot. The new
+    permission is handled the same way we would if a website requested it:
+    by calling \c handlePermissionRequested().
+
+    \quotefromfile webenginewidgets/permissionbrowser/mainwindow.cpp
+    \skipto void MainWindow::handleNewClicked()
+    \printuntil /^\}/
+
+    \section1 Changing the permission persistence policy
+
+    By default, permissions are stored to disk for every named QWebEngineProfile,
+    and in memory for every unnamed/off-the-record one. Normally, this setting
+    won't be changed at runtime, but this example explores the effects
+    of each option.
+
+    \list
+        \li \l QWebEngineProfile::PersistentPermissionsOnDisk is the default, and it ensures
+        that any permissions that have been granted in the current application run will be
+        loaded back up at next startup. A permission onlycneeds to be granted once, and
+        subsequent uses of the API that triggered the request will automatically be granted,
+        until the application calls QWebEnginePermission::reset().
+        li \l QWebEngineProfile::PersistentPermissionsInMemory Has the same behavior as above,
+        except that permissions will be destroyed at application exit, and not committed
+        to disk.
+        li \l QWebEngineProfile::NoPersistentPermissions makes sure permissions are never
+        remembered, and all act as if they're transient. Thus, every time a web API needs
+        a permission, a new prompt will be shown to the user. This option is intended for
+        backwards compatibility and applications which implement their own permission storage.
+    \endlist
+
+    To ensure the user will be shown previously existing permissions, we need to call
+    \l QWebEngineProfile::listPermissions():
+
+    \quotefromfile webenginewidgets/permissionbrowser/mainwindow.cpp
+    \skipto void MainWindow::loadStoredPermissions()
+    \printuntil /^\}/
+
+    This is done one time at startup, as well as whenever the user changes the policy
+    from the \l QComboBox from the top right.
+
+    \quotefromfile webenginewidgets/permissionbrowser/mainwindow.cpp
+    \skipto void MainWindow::handlePolicyComboBoxIndexChanged
+    \printuntil /^\}/
+*/
diff --git a/examples/webenginewidgets/permissionbrowser/main.cpp b/examples/webenginewidgets/permissionbrowser/main.cpp
new file mode 100644
index 00000000000..c1e2c25660e
--- /dev/null
+++ b/examples/webenginewidgets/permissionbrowser/main.cpp
@@ -0,0 +1,18 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "mainwindow.h"
+#include <QApplication>
+#include <QLoggingCategory>
+#include <QUrl>
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication::setOrganizationName("QtExamples");
+    QApplication app(argc, argv);
+    app.setWindowIcon(QIcon(QString(u":AppLogoColor.png")));
+    MainWindow window(QUrl("qrc:/landing.html"));
+    window.resize(1024, 768);
+    window.show();
+    return app.exec();
+}
diff --git a/examples/webenginewidgets/permissionbrowser/mainwindow.cpp b/examples/webenginewidgets/permissionbrowser/mainwindow.cpp
new file mode 100644
index 00000000000..2fe3c3b1706
--- /dev/null
+++ b/examples/webenginewidgets/permissionbrowser/mainwindow.cpp
@@ -0,0 +1,270 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "mainwindow.h"
+#include <QWebEngineProfile>
+#include <QWebEnginePermission>
+#include <QWebEngineSettings>
+#include <QMetaEnum>
+#include <QUrl>
+
+PermissionDialog::PermissionDialog(const QWebEngineProfile *profile, QWidget *parent)
+    : QDialog(parent)
+    , m_profile(profile)
+    , m_permission(nullptr)
+{
+    setupUi(this);
+
+    auto metaEnum = QMetaEnum::fromType<QWebEnginePermission::Feature>();
+    Q_ASSERT(metaEnum.value(QWebEnginePermission::Unsupported) == 0);
+    for (int i = 1; i < metaEnum.keyCount(); ++i) {
+        QWebEnginePermission::Feature feature = QWebEnginePermission::Feature(metaEnum.value(i));
+        if (!QWebEnginePermission::isTransient(feature))
+            m_featureComboBox->addItem(metaEnum.valueToKey(feature), QVariant(feature));
+    }
+}
+
+PermissionDialog::~PermissionDialog()
+{
+    delete m_permission;
+}
+
+QWebEnginePermission PermissionDialog::permission()
+{
+    return m_profile->getPermission(QUrl(m_originLineEdit->text()),
+        QWebEnginePermission::Feature(m_featureComboBox->itemData(m_featureComboBox->currentIndex()).toInt()));
+}
+
+PermissionWidget::PermissionWidget(const QWebEnginePermission &permission, QWidget *parent)
+    : QWidget(parent)
+    , m_permission(permission)
+{
+    setupUi(this);
+    connect(m_deleteButton, &QPushButton::clicked, [this]() {
+        m_permission.reset();
+        emit permissionModified(this);
+        deleteLater();
+    });
+
+    connect(m_grantButton, &QPushButton::clicked, [this]() {
+        m_permission.grant();
+        updateState();
+        emit permissionModified(this);
+    });
+
+    connect(m_denyButton, &QPushButton::clicked, [this]() {
+        m_permission.deny();
+        updateState();
+        emit permissionModified(this);
+    });
+
+    updateState();
+}
+
+void PermissionWidget::updateState()
+{
+    switch (m_permission.state()) {
+    case QWebEnginePermission::Invalid:
+        m_stateLabel->setText("<font color='gray'>Invalid</font>");
+        m_grantButton->setEnabled(false);
+        m_denyButton->setEnabled(false);
+        break;
+    case QWebEnginePermission::Ask:
+        m_stateLabel->setText("<font color='yellow'>Waiting for response</font>");
+        break;
+    case QWebEnginePermission::Granted:
+        m_stateLabel->setText("<font color='green'>Granted</font>");
+        break;
+    case QWebEnginePermission::Denied:
+        m_stateLabel->setText("<font color='red'>Denied</font>");
+        break;
+    }
+
+    m_typeLabel->setText(QMetaEnum::fromType<QWebEnginePermission::Feature>().valueToKey(m_permission.feature()));
+    m_originLabel->setText(m_permission.origin().toDisplayString());
+}
+
+MainWindow::MainWindow(const QUrl &url)
+    : QMainWindow()
+    , m_layout(new QVBoxLayout)
+    , m_profile(new QWebEngineProfile("permissionbrowser"))
+    , m_webview(new QWebEngineView(m_profile, this))
+    , m_pendingWidget(nullptr)
+{
+    setupUi(this);
+    m_urlLineEdit->setText(url.toString());
+
+    m_layout->addItem(new QSpacerItem(0,0, QSizePolicy::Minimum, QSizePolicy::Expanding));
+    m_layout->setContentsMargins(0, 0, 0, 0);
+    m_layout->setSpacing(0);
+
+    QWidget *w = new QWidget();
+    w->setLayout(m_layout);
+
+    m_storedScrollArea->setWidget(w);
+    m_storedScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+    (new QVBoxLayout(m_pendingFrame))->setContentsMargins(0, 0, 0, 0);
+
+    loadStoredPermissions();
+
+    connect(m_deleteAllButton, &QPushButton::clicked, this, &MainWindow::handleDeleteAllClicked);
+    connect(m_newButton, &QPushButton::clicked, this, &MainWindow::handleNewClicked);
+    connect(m_refreshButton, &QPushButton::clicked, this, &MainWindow::handleRefreshClicked);
+    connect(m_backButton, &QPushButton::clicked, this, &MainWindow::handleBackClicked);
+    connect(m_forwardButton, &QPushButton::clicked, this, &MainWindow::handleForwardClicked);
+    connect(m_policyComboBox, &QComboBox::currentIndexChanged, this, &MainWindow::handlePolicyComboBoxIndexChanged);
+    connect(m_webview, &QWebEngineView::urlChanged, this, &MainWindow::handleUrlChanged);
+    connect(m_webview->page(), &QWebEnginePage::permissionRequested, this, &MainWindow::handlePermissionRequested);
+
+    m_profile->settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true);
+    m_profile->settings()->setAttribute(QWebEngineSettings::JavascriptCanAccessClipboard, true);
+
+    m_frame->layout()->addWidget(m_webview);
+    static_cast<QVBoxLayout *>(m_frame->layout())->setStretchFactor(m_webview, 1);
+    m_webview->load(url);
+}
+
+MainWindow::~MainWindow()
+{
+    delete m_webview;
+    delete m_profile;
+}
+
+void MainWindow::handlePermissionRequested(QWebEnginePermission permission)
+{
+    PermissionWidget *widget = createPermissionWidget(permission);
+    if (widget) {
+        m_pendingFrame->layout()->addWidget(widget);
+        connect(widget, &PermissionWidget::permissionModified, this, &MainWindow::handlePermissionModified);
+
+        if (m_pendingWidget)
+            m_pendingWidget->deleteLater();
+
+        m_pendingWidget = widget;
+    }
+}
+
+void MainWindow::handlePermissionModified(PermissionWidget *widget)
+{
+    if (!m_pendingWidget || m_pendingWidget != widget)
+        return;
+
+    m_pendingFrame->layout()->removeWidget(widget);
+    m_pendingWidget = nullptr;
+
+    if (QWebEnginePermission::isTransient(widget->m_permission.feature())
+        || widget->m_permission.state() == QWebEnginePermission::Ask
+        || m_profile->persistentPermissionsPolicy() == QWebEngineProfile::NoPersistentPermissions) {
+
+        widget->deleteLater();
+        return;
+    }
+
+    m_layout->insertWidget(0, widget);
+}
+
+void MainWindow::handleUrlChanged(const QUrl &url)
+{
+    m_urlLineEdit->setText(url.toString());
+}
+
+void MainWindow::handleDeleteAllClicked()
+{
+    for (int i = m_layout->count() - 1; i >= 0; i--) {
+        PermissionWidget *widget = qobject_cast<PermissionWidget *>(m_layout->itemAt(i)->widget());
+        if (!widget)
+            continue;
+
+        widget->m_permission.reset();
+        widget->deleteLater();
+    }
+}
+
+void MainWindow::handleNewClicked()
+{
+    PermissionDialog dialog(m_profile);
+    if (dialog.exec() == QDialog::Accepted) {
+        handlePermissionRequested(dialog.permission());
+    }
+}
+
+void MainWindow::handleRefreshClicked()
+{
+    m_webview->load(QUrl::fromUserInput(m_urlLineEdit->text()));
+}
+
+void MainWindow::handleBackClicked()
+{
+    m_webview->triggerPageAction(QWebEnginePage::Back);
+}
+
+void MainWindow::handleForwardClicked()
+{
+    m_webview->triggerPageAction(QWebEnginePage::Forward);
+}
+
+void MainWindow::handlePolicyComboBoxIndexChanged(int index)
+{
+    QWebEngineProfile::PersistentPermissionsPolicy policy;
+    switch (index) {
+    case 0:
+        policy = QWebEngineProfile::PersistentPermissionsOnDisk;
+        break;
+    case 1:
+        policy = QWebEngineProfile::PersistentPermissionsInMemory;
+        break;
+    case 2:
+        policy = QWebEngineProfile::NoPersistentPermissions;
+        break;
+    }
+
+    if (policy == m_profile->persistentPermissionsPolicy())
+        return;
+
+    for (int i = m_layout->count() - 1; i >= 0; i--) {
+        PermissionWidget *widget = qobject_cast<PermissionWidget *>(m_layout->itemAt(i)->widget());
+        if (!widget)
+            continue;
+
+        widget->deleteLater();
+    }
+
+    m_profile->setPersistentPermissionsPolicy(policy);
+    loadStoredPermissions();
+}
+
+bool MainWindow::containsPermission(const QWebEnginePermission &permission)
+{
+    for (const auto *w: std::as_const(m_storedScrollArea->widget()->children())) {
+        const PermissionWidget *widget = qobject_cast<const PermissionWidget *>(w);
+        if (!widget)
+            continue;
+        const QWebEnginePermission &widgetPermission = widget->m_permission;
+        if (widgetPermission == permission)
+            return true;
+    }
+
+    if (m_pendingWidget && m_pendingWidget->m_permission == permission)
+        return true;
+
+    return false;
+}
+
+PermissionWidget *MainWindow::createPermissionWidget(const QWebEnginePermission &permission)
+{
+    if (containsPermission(permission))
+        return nullptr;
+
+    return new PermissionWidget(permission, this);
+}
+
+void MainWindow::loadStoredPermissions()
+{
+    QList<QWebEnginePermission> permissionsList = m_profile->listPermissions();
+    for (QWebEnginePermission &permission : permissionsList) {
+        PermissionWidget *widget = createPermissionWidget(permission);
+        if (widget)
+            m_layout->insertWidget(0, widget);
+    }
+}
diff --git a/examples/webenginewidgets/permissionbrowser/mainwindow.h b/examples/webenginewidgets/permissionbrowser/mainwindow.h
new file mode 100644
index 00000000000..8f7a0945035
--- /dev/null
+++ b/examples/webenginewidgets/permissionbrowser/mainwindow.h
@@ -0,0 +1,74 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "ui_mainwindow.h"
+#include "ui_permissiondialog.h"
+#include "ui_permissionwidget.h"
+#include <QDialog>
+#include <QMainWindow>
+#include <QWebEngineView>
+#include <QWebEnginePermission>
+
+QT_BEGIN_NAMESPACE
+class QWebEngineView;
+class QWebEngineProfile;
+class QLineEdit;
+QT_END_NAMESPACE
+
+class PermissionDialog : public QDialog, public Ui_PermissionDialog
+{
+    Q_OBJECT
+public:
+    PermissionDialog(const QWebEngineProfile *profile, QWidget *parent = nullptr);
+    ~PermissionDialog();
+    QWebEnginePermission permission();
+
+private:
+    const QWebEngineProfile *m_profile;
+    QWebEnginePermission *m_permission;
+};
+
+class PermissionWidget : public QWidget, public Ui_PermissionWidget
+{
+    Q_OBJECT
+public:
+    PermissionWidget(const QWebEnginePermission &permission, QWidget *parent = nullptr);
+
+    QWebEnginePermission m_permission;
+
+signals:
+    void permissionModified(PermissionWidget *widget);
+
+private:
+    void updateState();
+};
+
+class MainWindow : public QMainWindow, public Ui_MainWindow
+{
+    Q_OBJECT
+public:
+    explicit MainWindow(const QUrl &url);
+    ~MainWindow();
+
+private slots:
+    void handlePermissionRequested(QWebEnginePermission permission);
+    void handleUrlChanged(const QUrl &url);
+
+    void handlePermissionModified(PermissionWidget *widget);
+    void handleDeleteAllClicked();
+    void handleNewClicked();
+    void handleRefreshClicked();
+    void handleBackClicked();
+    void handleForwardClicked();
+    void handlePolicyComboBoxIndexChanged(int index);
+
+private:
+    bool containsPermission(const QWebEnginePermission &permission);
+    PermissionWidget *createPermissionWidget(const QWebEnginePermission &permission);
+    void loadStoredPermissions();
+
+    QVBoxLayout *m_layout;
+    QWebEngineProfile *m_profile;
+    QWebEngineView *m_webview;
+    PermissionWidget *m_pendingWidget;
+};
diff --git a/examples/webenginewidgets/permissionbrowser/mainwindow.ui b/examples/webenginewidgets/permissionbrowser/mainwindow.ui
new file mode 100644
index 00000000000..4496b8c0782
--- /dev/null
+++ b/examples/webenginewidgets/permissionbrowser/mainwindow.ui
@@ -0,0 +1,356 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>1600</width>
+    <height>900</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Permission Browser</string>
+  </property>
+  <widget class="QWidget" name="centralWidget">
+   <layout class="QHBoxLayout" name="horizontalLayout_2">
+    <item>
+     <widget class="QFrame" name="m_frame">
+      <property name="frameShape">
+       <enum>QFrame::StyledPanel</enum>
+      </property>
+      <property name="frameShadow">
+       <enum>QFrame::Raised</enum>
+      </property>
+      <layout class="QVBoxLayout" name="verticalLayout" stretch="0">
+       <item>
+        <widget class="QWidget" name="widget" native="true">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <layout class="QHBoxLayout" name="horizontalLayout">
+          <property name="leftMargin">
+           <number>0</number>
+          </property>
+          <property name="topMargin">
+           <number>0</number>
+          </property>
+          <property name="rightMargin">
+           <number>0</number>
+          </property>
+          <property name="bottomMargin">
+           <number>0</number>
+          </property>
+          <item>
+           <widget class="QPushButton" name="m_backButton">
+            <property name="text">
+             <string/>
+            </property>
+            <property name="icon">
+             <iconset resource="permissionbrowser.qrc">
+              <normaloff>:3rdparty/go-previous.png</normaloff>:3rdparty/go-previous.png</iconset>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="m_forwardButton">
+            <property name="text">
+             <string/>
+            </property>
+            <property name="icon">
+             <iconset resource="permissionbrowser.qrc">
+              <normaloff>:3rdparty/go-next.png</normaloff>:3rdparty/go-next.png</iconset>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="m_refreshButton">
+            <property name="text">
+             <string/>
+            </property>
+            <property name="icon">
+             <iconset resource="permissionbrowser.qrc">
+              <normaloff>:3rdparty/view-refresh.png</normaloff>:3rdparty/view-refresh.png</iconset>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QLineEdit" name="m_urlLineEdit"/>
+          </item>
+         </layout>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+    </item>
+    <item>
+     <widget class="QFrame" name="frame_2">
+      <property name="maximumSize">
+       <size>
+        <width>336</width>
+        <height>16777215</height>
+       </size>
+      </property>
+      <property name="frameShape">
+       <enum>QFrame::StyledPanel</enum>
+      </property>
+      <property name="frameShadow">
+       <enum>QFrame::Raised</enum>
+      </property>
+      <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,0,0,0,1,0,0,0">
+       <item>
+        <widget class="QWidget" name="widget_2" native="true">
+         <layout class="QHBoxLayout" name="horizontalLayout_3">
+          <property name="leftMargin">
+           <number>0</number>
+          </property>
+          <property name="topMargin">
+           <number>0</number>
+          </property>
+          <property name="rightMargin">
+           <number>0</number>
+          </property>
+          <property name="bottomMargin">
+           <number>0</number>
+          </property>
+          <item>
+           <widget class="QLabel" name="label">
+            <property name="text">
+             <string>Permissions:</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <spacer name="horizontalSpacer">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>87</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item>
+           <widget class="QPushButton" name="m_newButton">
+            <property name="text">
+             <string>New</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="m_deleteAllButton">
+            <property name="text">
+             <string>Delete All</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item>
+        <widget class="QWidget" name="widget_3" native="true">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <layout class="QHBoxLayout" name="horizontalLayout_6">
+          <property name="leftMargin">
+           <number>0</number>
+          </property>
+          <property name="topMargin">
+           <number>0</number>
+          </property>
+          <property name="rightMargin">
+           <number>0</number>
+          </property>
+          <property name="bottomMargin">
+           <number>0</number>
+          </property>
+          <item>
+           <widget class="QLabel" name="label_2">
+            <property name="text">
+             <string>Persistence policy:</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <spacer name="horizontalSpacer_2">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>40</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item>
+           <widget class="QComboBox" name="m_policyComboBox">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="minimumSize">
+             <size>
+              <width>0</width>
+              <height>25</height>
+             </size>
+            </property>
+            <property name="currentIndex">
+             <number>0</number>
+            </property>
+            <property name="sizeAdjustPolicy">
+             <enum>QComboBox::AdjustToContents</enum>
+            </property>
+            <item>
+             <property name="text">
+              <string>Persist on disk</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>Persist in memory</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>Do not persist</string>
+             </property>
+            </item>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item>
+        <widget class="Line" name="line">
+         <property name="minimumSize">
+          <size>
+           <width>0</width>
+           <height>10</height>
+          </size>
+         </property>
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLabel" name="label_3">
+         <property name="text">
+          <string>Stored permissions</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QScrollArea" name="m_storedScrollArea">
+         <property name="minimumSize">
+          <size>
+           <width>320</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>320</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="frameShape">
+          <enum>QFrame::StyledPanel</enum>
+         </property>
+         <property name="lineWidth">
+          <number>2</number>
+         </property>
+         <property name="verticalScrollBarPolicy">
+          <enum>Qt::ScrollBarAlwaysOff</enum>
+         </property>
+         <property name="horizontalScrollBarPolicy">
+          <enum>Qt::ScrollBarAlwaysOff</enum>
+         </property>
+         <property name="widgetResizable">
+          <bool>true</bool>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="Line" name="line_2">
+         <property name="minimumSize">
+          <size>
+           <width>0</width>
+           <height>10</height>
+          </size>
+         </property>
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLabel" name="label_4">
+         <property name="text">
+          <string>Pending permission</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QFrame" name="m_pendingFrame">
+         <property name="minimumSize">
+          <size>
+           <width>0</width>
+           <height>104</height>
+          </size>
+         </property>
+         <property name="frameShape">
+          <enum>QFrame::StyledPanel</enum>
+         </property>
+         <property name="frameShadow">
+          <enum>QFrame::Sunken</enum>
+         </property>
+         <property name="lineWidth">
+          <number>2</number>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources>
+  <include location="permissionbrowser.qrc"/>
+ </resources>
+ <connections>
+  <connection>
+   <sender>m_urlLineEdit</sender>
+   <signal>returnPressed()</signal>
+   <receiver>m_refreshButton</receiver>
+   <slot>click()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>509</x>
+     <y>28</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>1024</x>
+     <y>27</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/examples/webenginewidgets/permissionbrowser/permissionbrowser.exe.manifest b/examples/webenginewidgets/permissionbrowser/permissionbrowser.exe.manifest
new file mode 100644
index 00000000000..acc40177692
--- /dev/null
+++ b/examples/webenginewidgets/permissionbrowser/permissionbrowser.exe.manifest
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+    <application>
+    <!--The ID below indicates application support for Windows Vista -->
+    <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+    <!--The ID below indicates application support for Windows 7 -->
+    <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+    <!--The ID below indicates application support for Windows 8 -->
+    <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
+    <!--The ID below indicates application support for Windows 8.1 -->
+    <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
+    <!--The ID below indicates application support for Windows 10/11 -->
+    <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
+    </application>
+</compatibility>
+</assembly>
diff --git a/examples/webenginewidgets/permissionbrowser/permissionbrowser.qrc b/examples/webenginewidgets/permissionbrowser/permissionbrowser.qrc
new file mode 100644
index 00000000000..80a7d20f254
--- /dev/null
+++ b/examples/webenginewidgets/permissionbrowser/permissionbrowser.qrc
@@ -0,0 +1,7 @@
+<RCC>
+    <qresource prefix="/">
+        <file alias="view-refresh.png">resources/3rdparty/view-refresh.png</file>
+        <file alias="go-next.png">resources/3rdparty/go-next.png</file>
+        <file alias="go-previous.png">resources/3rdparty/go-previous.png</file>
+    </qresource>
+</RCC>
diff --git a/examples/webenginewidgets/permissionbrowser/permissiondialog.ui b/examples/webenginewidgets/permissionbrowser/permissiondialog.ui
new file mode 100644
index 00000000000..a98432131a1
--- /dev/null
+++ b/examples/webenginewidgets/permissionbrowser/permissiondialog.ui
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PermissionDialog</class>
+ <widget class="QDialog" name="PermissionDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>110</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Permission</string>
+  </property>
+  <layout class="QFormLayout" name="formLayout">
+   <item row="0" column="0">
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Origin</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1">
+    <widget class="QLineEdit" name="m_originLineEdit">
+     <property name="readOnly">
+      <bool>false</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="QLabel" name="label_2">
+     <property name="text">
+      <string>Feature</string>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="1">
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="m_addButton">
+       <property name="enabled">
+        <bool>true</bool>
+       </property>
+       <property name="text">
+        <string>Add</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="m_cancelButton">
+       <property name="text">
+        <string>Cancel</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="1" column="1">
+    <widget class="QComboBox" name="m_featureComboBox"/>
+   </item>
+  </layout>
+ </widget>
+ <tabstops>
+  <tabstop>m_originLineEdit</tabstop>
+  <tabstop>m_addButton</tabstop>
+  <tabstop>m_cancelButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>m_cancelButton</sender>
+   <signal>clicked()</signal>
+   <receiver>PermissionDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>349</x>
+     <y>89</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>334</x>
+     <y>67</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>m_addButton</sender>
+   <signal>clicked()</signal>
+   <receiver>PermissionDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>264</x>
+     <y>88</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>218</x>
+     <y>68</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/examples/webenginewidgets/permissionbrowser/permissionwidget.ui b/examples/webenginewidgets/permissionbrowser/permissionwidget.ui
new file mode 100644
index 00000000000..0a09da5d3f0
--- /dev/null
+++ b/examples/webenginewidgets/permissionbrowser/permissionwidget.ui
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PermissionWidget</class>
+ <widget class="QWidget" name="PermissionWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>300</width>
+    <height>104</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>300</width>
+    <height>0</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>310</width>
+    <height>16777215</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0">
+   <item>
+    <layout class="QFormLayout" name="formLayout">
+     <property name="sizeConstraint">
+      <enum>QLayout::SetDefaultConstraint</enum>
+     </property>
+     <property name="formAlignment">
+      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+     </property>
+     <property name="verticalSpacing">
+      <number>10</number>
+     </property>
+     <item row="0" column="0">
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>Origin:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <widget class="QLabel" name="m_originLabel">
+       <property name="text">
+        <string>Empty</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>Type:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="QLabel" name="m_typeLabel">
+       <property name="text">
+        <string>Empty</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="0">
+      <widget class="QLabel" name="label_3">
+       <property name="text">
+        <string>State:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="1">
+      <widget class="QLabel" name="m_stateLabel">
+       <property name="text">
+        <string>Empty</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QVBoxLayout" name="verticalLayout">
+     <item>
+      <widget class="QPushButton" name="m_grantButton">
+       <property name="text">
+        <string>Grant</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="m_denyButton">
+       <property name="text">
+        <string>Deny</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="m_deleteButton">
+       <property name="text">
+        <string>Delete</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/webenginewidgets/permissionbrowser/resources/3rdparty/COPYING b/examples/webenginewidgets/permissionbrowser/resources/3rdparty/COPYING
new file mode 100644
index 00000000000..220881da67d
--- /dev/null
+++ b/examples/webenginewidgets/permissionbrowser/resources/3rdparty/COPYING
@@ -0,0 +1 @@
+The icons in this repository are herefore released into the Public Domain.
diff --git a/examples/webenginewidgets/permissionbrowser/resources/3rdparty/go-next.png b/examples/webenginewidgets/permissionbrowser/resources/3rdparty/go-next.png
new file mode 100644
index 0000000000000000000000000000000000000000..a68e2db77531cb15a2cddd62f567f030513b60fa
GIT binary patch
diff --git a/examples/webenginewidgets/permissionbrowser/resources/3rdparty/go-previous.png b/examples/webenginewidgets/permissionbrowser/resources/3rdparty/go-previous.png
new file mode 100644
index 0000000000000000000000000000000000000000..c37bc0414c24b6e4f34096d0c0f20fbe0bf84045
GIT binary patch
diff --git a/examples/webenginewidgets/permissionbrowser/resources/3rdparty/qt_attribution.json b/examples/webenginewidgets/permissionbrowser/resources/3rdparty/qt_attribution.json
new file mode 100644
index 00000000000..e11663d5e41
--- /dev/null
+++ b/examples/webenginewidgets/permissionbrowser/resources/3rdparty/qt_attribution.json
@@ -0,0 +1,24 @@
+{
+    "Id": "permissionbrowser-tango",
+    "Name": "Tango Icon Library",
+    "QDocModule": "qtwebengine",
+    "QtUsage": "Used in WebEngine Permission Browser example.",
+
+    "QtParts": [ "examples" ],
+    "Description": "Selected icons from the Tango Icon Library",
+    "Homepage": "http://tango.freedesktop.org/Tango_Icon_Library",
+    "Version": "0.8.90",
+    "DownloadLocation": "http://tango.freedesktop.org/releases/tango-icon-theme-0.8.90.tar.gz",
+    "LicenseId": "urn:dje:license:public-domain",
+    "License": "Public Domain",
+    "LicenseFile": "COPYING",
+    "Copyright": ["Ulisse Perusin <uli.peru@gmail.com>",
+    "Steven Garrity <sgarrity@silverorange.com>",
+    "Lapo Calamandrei <calamandrei@gmail.com>",
+    "Ryan Collier <rcollier@novell.com>",
+    "Rodney Dawes <dobey@novell.com>",
+    "Andreas Nilsson <nisses.mail@home.se>",
+    "Tuomas Kuosmanen <tigert@tigert.com>",
+    "Garrett LeSage <garrett@novell.com>",
+    "Jakub Steiner <jimmac@novell.com>"]
+}
diff --git a/examples/webenginewidgets/permissionbrowser/resources/3rdparty/view-refresh.png b/examples/webenginewidgets/permissionbrowser/resources/3rdparty/view-refresh.png
new file mode 100644
index 0000000000000000000000000000000000000000..cab4d02c756502f922bbff34df34c0056406bd96
GIT binary patch
diff --git a/examples/webenginewidgets/permissionbrowser/resources/AppLogoColor.png b/examples/webenginewidgets/permissionbrowser/resources/AppLogoColor.png
new file mode 100644
index 0000000000000000000000000000000000000000..2a49717828ba3977b2b49eb13a690ce1777ab6c0
GIT binary patch
diff --git a/examples/webenginewidgets/permissionbrowser/resources/landing.html b/examples/webenginewidgets/permissionbrowser/resources/landing.html
new file mode 100644
index 00000000000..5d921671fcb
--- /dev/null
+++ b/examples/webenginewidgets/permissionbrowser/resources/landing.html
@@ -0,0 +1,88 @@
+<!doctype html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8">
+        <title>Permissions example page</title>
+        <script>
+            function copyText() {
+                navigator.clipboard.writeText(document.getElementById("copyTextInput").value);
+            }
+
+            function pasteText() {
+                navigator.clipboard.readText()
+                    .then((text) => (
+                        document.getElementById("pasteTextInput").value = text
+                    ))
+                    .catch((err) => (
+                        document.getElementById("pasteTextInput").value = "<permission denied>"
+                    ));
+            }
+
+            function showNotification() {
+                new Notification("Example notification", {
+                    body: "Notification contents",
+                    tag: "notifTag",
+                    lang: "",
+                    dir: "auto",
+                    icon: "./3rdparty/go-next.png"
+                });
+            }
+
+            function tryShowNotification() {
+                if (Notification.permission !== "granted") {
+                    Notification.requestPermission()
+                        .then((permission) => {
+                            if (permission === "granted") { showNotification() }
+
+                        })
+                        .catch((err) => (
+                            document.getElementById("pasteTextInput").value = err
+                        ));
+                } else {
+                    showNotification();
+                }
+            }
+
+            function listFonts() {
+                var fontSelect = document.getElementById("fontSelect");
+                var i, length = fontSelect.options.length - 1;
+                for (i = length; i >= 0; i--) {
+                    fontSelect.remove(i);
+                }
+
+                window.queryLocalFonts()
+                    .then((fontsList) => {
+                        for (const font of fontsList) {
+                            fontSelect.add(new Option(text = font.fullName));
+                        }
+                    })
+                    .catch()
+            }
+        </script>
+    </head>
+    <body>
+        <h1>Permission Browser Example</h1>
+        <div>
+            <h2>Clipboard</h2>
+            <div>
+                <button onclick="copyText()">Copy text</button>
+                <input id="copyTextInput" value="Example text"></input>
+            </div>
+            <div>
+                <button onclick="pasteText()">Paste text</button>
+                <input id="pasteTextInput" placeholder="Text will be pasted here"></input>
+            </div>
+        </div>
+        <div>
+            <h2>Notifications</h2>
+            <div>
+                <button onclick="tryShowNotification()">Show notification</button>
+            </div>
+        </div>
+        <div>
+            <h2>Local fonts</h2>
+            <button onclick="listFonts()">List fonts</button>
+            <select id="fontSelect"></select>
+        </div>
+    </body>
+</html>

From 3fad66045a4482945d223916097b80fbc917b81b Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Fri, 24 May 2024 09:56:05 +0200
Subject: [PATCH 007/356] Ensure Chromium features are propagated to child
 processes

With the 118 update, the fallback code path that passed Chromium
feature flags via the command line was completely removed in favor
of a shared memory model. Correctly initializing this requires
having a FieldTrialList instance alive somewhere, but some fixups
when integrating 118 rendered that code path unreachable. As a result,
Chromium features were never getting sent to the render process,
and were only visible on the main WebEngine process.

This change adds a FieldTrialList instance inside WebEngineContext,
which allows the FeaturesList class to work correctly, and thus
correctly propagate features to the render process.

Pick-to: 6.7
Change-Id: I6d07ea4a7c87db83e526ea62ca4d86526463ad1a
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 1e0c7155877a4cf81c6a3c5d26b02c939b0dd049)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/web_engine_context.cpp | 5 +++++
 src/core/web_engine_context.h   | 2 ++
 2 files changed, 7 insertions(+)

diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index faf9bd54229..e38d8af8917 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -11,6 +11,7 @@
 #include "base/functional/bind.h"
 #include "base/command_line.h"
 #include "base/files/file_path.h"
+#include "base/metrics/field_trial.h"
 #include "base/power_monitor/power_monitor.h"
 #include "base/power_monitor/power_monitor_device_source.h"
 #include "base/run_loop.h"
@@ -970,6 +971,10 @@ WebEngineContext::WebEngineContext()
             parsedCommandLine->AppendSwitchASCII(switches::kUseAdapterLuid, luid.toStdString());
     }
 #endif
+    // We need the FieldTrialList to make sure Chromium features are provided to child processes
+    if (!base::FieldTrialList::GetInstance()) {
+        m_fieldTrialList.reset(new base::FieldTrialList());
+    }
 
     initializeFeatureList(parsedCommandLine, enableFeatures, disableFeatures);
 
diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h
index 50b080db100..faed5866180 100644
--- a/src/core/web_engine_context.h
+++ b/src/core/web_engine_context.h
@@ -16,6 +16,7 @@
 namespace base {
 class RunLoop;
 class CommandLine;
+class FieldTrialList;
 }
 
 namespace content {
@@ -102,6 +103,7 @@ class WebEngineContext : public base::RefCounted<WebEngineContext> {
     std::unique_ptr<ProfileAdapter> m_defaultProfileAdapter;
     std::unique_ptr<DevToolsServerQt> m_devtoolsServer;
     QList<ProfileAdapter*> m_profileAdapters;
+    std::unique_ptr<base::FieldTrialList> m_fieldTrialList;
 #if QT_CONFIG(accessibility)
     std::unique_ptr<AccessibilityActivationObserver> m_accessibilityActivationObserver;
 #endif

From 012b99c60ecf1398442f72697115eff17bb910ec Mon Sep 17 00:00:00 2001
From: Szabolcs David <davidsz@inf.u-szeged.hu>
Date: Mon, 3 Jun 2024 12:23:33 +0200
Subject: [PATCH 008/356] Remove anonymus namespace from QWebEngineLoadingInfo
 header

Fix code checker warning.

Change-Id: I3f3fb2c6a3c08679dde2515066f7423d890b5a8e
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 6a02b2fc67f1fdffd28472008b76db8d291d6f9a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebengineloadinginfo.h       | 4 ----
 src/core/net/custom_url_loader_factory.cpp | 9 ++++-----
 src/core/web_contents_delegate_qt.cpp      | 8 ++++++++
 src/core/web_contents_delegate_qt.h        | 1 +
 4 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/src/core/api/qwebengineloadinginfo.h b/src/core/api/qwebengineloadinginfo.h
index e50718d7cae..48d14601ab6 100644
--- a/src/core/api/qwebengineloadinginfo.h
+++ b/src/core/api/qwebengineloadinginfo.h
@@ -12,9 +12,6 @@
 #include <QtCore/qurl.h>
 
 namespace QtWebEngineCore {
-namespace {
-class CustomURLLoader;
-}
 class WebContentsAdapter;
 class WebContentsDelegateQt;
 }
@@ -78,7 +75,6 @@ class Q_WEBENGINECORE_EXPORT QWebEngineLoadingInfo
     friend class QQuickWebEngineViewPrivate;
     friend class QtWebEngineCore::WebContentsAdapter;
     friend class QtWebEngineCore::WebContentsDelegateQt;
-    friend class QtWebEngineCore::CustomURLLoader;
 };
 
 QT_END_NAMESPACE
diff --git a/src/core/net/custom_url_loader_factory.cpp b/src/core/net/custom_url_loader_factory.cpp
index 954253b54de..b91a1289bda 100644
--- a/src/core/net/custom_url_loader_factory.cpp
+++ b/src/core/net/custom_url_loader_factory.cpp
@@ -28,6 +28,7 @@
 #include "qwebengineloadinginfo.h"
 #include "type_conversion.h"
 #include "web_contents_adapter_client.h"
+#include "web_contents_delegate_qt.h"
 #include "web_contents_view_qt.h"
 
 #include <QtCore/qbytearray.h>
@@ -358,10 +359,9 @@ class CustomURLLoader : public network::mojom::URLLoader
     void notifySuccess() override
     {
         if (m_webContents) {
-            WebContentsAdapterClient *client = WebContentsViewQt::from(static_cast<content::WebContentsImpl *>(m_webContents)->GetView())->client();
-            QWebEngineLoadingInfo info(toQt(m_request.url), QWebEngineLoadingInfo::LoadSucceededStatus);
-            client->loadFinished(std::move(info));
-            client->updateNavigationActions();
+            WebContentsDelegateQt *delegate =
+                    static_cast<WebContentsDelegateQt *>(m_webContents->GetDelegate());
+            delegate->emitLoadSucceeded(toQt(m_request.url));
         }
     }
     void notifyReadyRead() override
@@ -534,4 +534,3 @@ mojo::PendingRemote<network::mojom::URLLoaderFactory> CreateCustomURLLoaderFacto
 }
 
 } // namespace QtWebEngineCore
-
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index e16f5d769a2..70ee07cbb18 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -479,6 +479,14 @@ void WebContentsDelegateQt::DidStopLoading()
     m_loadingInfo.clear();
 }
 
+void WebContentsDelegateQt::emitLoadSucceeded(const QUrl &url)
+{
+    // Used by CustomURLLoader to emit LoadSucceeded bypassing the inner state of this delegate
+    m_viewClient->loadFinished(
+            QWebEngineLoadingInfo(url, QWebEngineLoadingInfo::LoadSucceededStatus));
+    m_viewClient->updateNavigationActions();
+}
+
 void WebContentsDelegateQt::didFailLoad(const QUrl &url, int errorCode, const QString &errorDescription)
 {
     m_viewClient->iconChanged(QUrl());
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index 88056c3ca36..df9b5e3e802 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -132,6 +132,7 @@ class WebContentsDelegateQt : public content::WebContentsDelegate
                                   content::RenderFrameHost *render_frame_host,
                                   bool is_full_page) override;
 
+    void emitLoadSucceeded(const QUrl &url);
     void didFailLoad(const QUrl &url, int errorCode, const QString &errorDescription);
     void overrideWebPreferences(content::WebContents *, blink::web_pref::WebPreferences*);
     void allowCertificateError(const QSharedPointer<CertificateErrorController> &);

From d442e295f4d74d40f243c191adbea7cf75b8bf45 Mon Sep 17 00:00:00 2001
From: Allan Sandfeld Jensen <allan.jensen@qt.io>
Date: Tue, 30 Jan 2024 14:39:23 +0100
Subject: [PATCH 009/356] Adaptations for Chromium 120

Change-Id: I487d2c6cf56fdda5fb95e6b2715e7dbc42527c2d
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit bbf7a2e7c387f9618e31addcbeb38fd859819cf5)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebengineurlscheme.cpp          |  2 +-
 src/core/autofill_client_qt.cpp               | 15 +++-----------
 src/core/autofill_client_qt.h                 |  6 ++----
 src/core/browser_accessibility_qt.cpp         |  2 +-
 src/core/clipboard_qt.cpp                     |  7 +++++--
 .../native_skia_output_device_vulkan.cpp      |  2 +-
 src/core/configure/BUILD.root.gn.in           | 10 ++++------
 ...sponse_interceptor_url_loader_throttle.cpp | 18 ++++++++---------
 .../proxying_restricted_cookie_manager_qt.cpp |  7 +++++--
 .../proxying_restricted_cookie_manager_qt.h   |  2 ++
 src/core/net/webui_controller_factory_qt.cpp  |  2 +-
 src/core/ozone/gl_share_context_qt.h          |  2 +-
 src/core/platform_notification_service_qt.cpp | 20 +++++++++++++++++++
 src/core/platform_notification_service_qt.h   |  2 ++
 src/core/pref_service_adapter.cpp             |  3 +--
 .../printing/print_view_manager_base_qt.cpp   |  1 -
 src/core/profile_adapter.cpp                  |  1 -
 .../renderer/content_renderer_client_qt.cpp   | 11 +++++-----
 .../extensions_renderer_client_qt.cpp         |  2 +-
 .../extensions/resource_request_policy_qt.cpp |  2 +-
 .../extensions/resource_request_policy_qt.h   |  2 +-
 src/core/type_conversion.h                    |  4 ++--
 src/core/web_contents_adapter.cpp             |  8 ++++++--
 src/core/web_contents_view_qt.cpp             |  6 ++++--
 src/core/web_contents_view_qt.h               |  8 ++++++--
 src/core/web_engine_context.cpp               |  3 ---
 tools/scripts/version_resolver.py             |  4 ++--
 27 files changed, 86 insertions(+), 66 deletions(-)

diff --git a/src/core/api/qwebengineurlscheme.cpp b/src/core/api/qwebengineurlscheme.cpp
index 3093c2b8edd..be56a304801 100644
--- a/src/core/api/qwebengineurlscheme.cpp
+++ b/src/core/api/qwebengineurlscheme.cpp
@@ -372,7 +372,7 @@ void QWebEngineUrlScheme::registerScheme(const QWebEngineUrlScheme &scheme)
 */
 QWebEngineUrlScheme QWebEngineUrlScheme::schemeByName(const QByteArray &name)
 {
-    base::StringPiece namePiece{ name.data(), static_cast<size_t>(name.size()) };
+    std::string_view namePiece{ name.data(), static_cast<size_t>(name.size()) };
     if (const url::CustomScheme *cs = url::CustomScheme::FindScheme(namePiece))
         return QWebEngineUrlScheme(new QWebEngineUrlSchemePrivate(*cs));
     return QWebEngineUrlScheme();
diff --git a/src/core/autofill_client_qt.cpp b/src/core/autofill_client_qt.cpp
index 3bdc62e199c..44a242d5c6b 100644
--- a/src/core/autofill_client_qt.cpp
+++ b/src/core/autofill_client_qt.cpp
@@ -70,12 +70,10 @@ void AutofillClientQt::ShowAutofillPopup(const autofill::AutofillClient::PopupOp
                                        autoSelectFirstSuggestion);
 }
 
-void AutofillClientQt::UpdateAutofillPopupDataListValues(const std::vector<std::u16string> &values,
-                                                         const std::vector<std::u16string> &labels)
+void AutofillClientQt::UpdateAutofillPopupDataListValues(
+        base::span<const autofill::SelectOption> datalist)
 {
-    Q_UNUSED(labels);
-
-    if (values.empty())
+    if (datalist.empty())
         HideAutofillPopup(autofill::PopupHidingReason::kNoSuggestions);
 }
 
@@ -130,13 +128,6 @@ scoped_refptr<network::SharedURLLoaderFactory> AutofillClientQt::GetURLLoaderFac
     return nullptr;
 }
 
-void AutofillClientQt::PropagateAutofillPredictionsDeprecated(autofill::AutofillDriver *,
-                                                              const std::vector<autofill::FormStructure *> &)
-{
-    // For testing purposes only.
-    NOTIMPLEMENTED();
-}
-
 WebContentsAdapterClient *AutofillClientQt::adapterClient()
 {
     return WebContentsViewQt::from(
diff --git a/src/core/autofill_client_qt.h b/src/core/autofill_client_qt.h
index cd38de462e6..b14a486e14f 100644
--- a/src/core/autofill_client_qt.h
+++ b/src/core/autofill_client_qt.h
@@ -46,8 +46,8 @@ class AutofillClientQt : public autofill::ContentAutofillClient,
 
     void ShowAutofillPopup(const autofill::AutofillClient::PopupOpenArgs &open_args,
                            base::WeakPtr<autofill::AutofillPopupDelegate> delegate) override;
-    void UpdateAutofillPopupDataListValues(const std::vector<std::u16string> &values,
-                                           const std::vector<std::u16string> &labels) override;
+    void UpdateAutofillPopupDataListValues(
+            base::span<const autofill::SelectOption> datalist) override;
     void PinPopupView() override;
     PopupOpenArgs GetReopenPopupArgs(
             autofill::AutofillSuggestionTriggerSource trigger_source) const override;
@@ -58,8 +58,6 @@ class AutofillClientQt : public autofill::ContentAutofillClient,
     void HideAutofillPopup(autofill::PopupHidingReason reason) override;
     bool IsAutocompleteEnabled() const override;
     bool IsPasswordManagerEnabled() override;
-    void PropagateAutofillPredictionsDeprecated(autofill::AutofillDriver *,
-                                                const std::vector<autofill::FormStructure *> &) override;
     bool IsOffTheRecord() override;
     scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override;
 
diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp
index de3347df36d..ff3d21fb74a 100644
--- a/src/core/browser_accessibility_qt.cpp
+++ b/src/core/browser_accessibility_qt.cpp
@@ -617,7 +617,7 @@ QAccessible::Role BrowserAccessibilityInterface::role() const
         return QAccessible::ComboBox;
     case ax::mojom::Role::kPortal:
         return QAccessible::Button;
-    case ax::mojom::Role::kPre:
+    case ax::mojom::Role::kPreDeprecated:
         return QAccessible::Section;
     case ax::mojom::Role::kProgressIndicator:
         return QAccessible::ProgressBar;
diff --git a/src/core/clipboard_qt.cpp b/src/core/clipboard_qt.cpp
index 3f49c6e3c26..774ba8954b9 100644
--- a/src/core/clipboard_qt.cpp
+++ b/src/core/clipboard_qt.cpp
@@ -234,7 +234,8 @@ void ClipboardQt::ReadAvailableTypes(ui::ClipboardBuffer type,
 
     if (mimeData->hasFormat(QString::fromLatin1(ui::kMimeTypeWebCustomData))) {
         const QByteArray customData = mimeData->data(QString::fromLatin1(ui::kMimeTypeWebCustomData));
-        ui::ReadCustomDataTypes(customData.constData(), customData.size(), types);
+        const base::span custom_data(customData.constData(), (unsigned long)customData.size());
+        ui::ReadCustomDataTypes(base::as_bytes(custom_data), types);
     }
 }
 
@@ -342,7 +343,9 @@ void ClipboardQt::ReadCustomData(ui::ClipboardBuffer clipboard_type, const std::
     if (!mimeData)
         return;
     const QByteArray customData = mimeData->data(QString::fromLatin1(ui::kMimeTypeWebCustomData));
-    ui::ReadCustomDataForType(customData.constData(), customData.size(), type, result);
+    const base::span custom_data(customData.constData(), (unsigned long)customData.size());
+    if (auto maybe_result = ui::ReadCustomDataForType(base::as_bytes(custom_data), type))
+        *result = *std::move(maybe_result);
 }
 
 void ClipboardQt::ReadBookmark(const ui::DataTransferEndpoint *data_dst, std::u16string *title, std::string *url) const
diff --git a/src/core/compositor/native_skia_output_device_vulkan.cpp b/src/core/compositor/native_skia_output_device_vulkan.cpp
index f51eba98521..50768a2ef4b 100644
--- a/src/core/compositor/native_skia_output_device_vulkan.cpp
+++ b/src/core/compositor/native_skia_output_device_vulkan.cpp
@@ -201,7 +201,7 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
     importedImageCreateInfo.pNext = &externalMemoryImageCreateInfo;
     importedImageCreateInfo.flags = 0;
     importedImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
-    importedImageCreateInfo.format = gpu::ToVkFormat(m_frontBuffer->sharedImageFormat());
+    importedImageCreateInfo.format = gpu::ToVkFormatSinglePlanar(m_frontBuffer->sharedImageFormat());
     importedImageCreateInfo.extent.width = static_cast<uint32_t>(size().width());
     importedImageCreateInfo.extent.height = static_cast<uint32_t>(size().height());
     importedImageCreateInfo.extent.depth = 1;
diff --git a/src/core/configure/BUILD.root.gn.in b/src/core/configure/BUILD.root.gn.in
index 986db502629..698fb16cba0 100644
--- a/src/core/configure/BUILD.root.gn.in
+++ b/src/core/configure/BUILD.root.gn.in
@@ -349,10 +349,10 @@ source_set("qtwebengine_sources") {
     "//chrome/browser/tab_contents/web_contents_collection.h",
     "//chrome/browser/ui/webui/device_log_ui.cc",
     "//chrome/browser/ui/webui/device_log_ui.h",
-    "//chrome/browser/ui/webui/devtools_ui.cc",
-    "//chrome/browser/ui/webui/devtools_ui.h",
-    "//chrome/browser/ui/webui/devtools_ui_data_source.cc",
-    "//chrome/browser/ui/webui/devtools_ui_data_source.h",
+    "//chrome/browser/ui/webui/devtools/devtools_ui.cc",
+    "//chrome/browser/ui/webui/devtools/devtools_ui.h",
+    "//chrome/browser/ui/webui/devtools/devtools_ui_data_source.cc",
+    "//chrome/browser/ui/webui/devtools/devtools_ui_data_source.h",
     "//chrome/browser/ui/webui/net_internals/net_internals_ui.cc",
     "//chrome/browser/ui/webui/net_internals/net_internals_ui.h",
     "//chrome/browser/ui/webui/user_actions/user_actions_ui.cc",
@@ -364,8 +364,6 @@ source_set("qtwebengine_sources") {
     "//chrome/common/chrome_switches.cc",
     "//chrome/common/chrome_switches.h",
     "//chrome/common/pref_names.h",
-    "//chrome/common/url_constants.cc",
-    "//chrome/common/url_constants.h",
     "//chrome/common/webui_url_constants.cc",
     "//chrome/common/webui_url_constants.h",
     "//components/embedder_support/user_agent_utils.cc",
diff --git a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
index 159fa28ca97..a99c68367e9 100644
--- a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
+++ b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
@@ -30,6 +30,9 @@
 #include <tuple>
 
 namespace {
+
+constexpr uint32_t kFullPageMimeHandlerDataPipeSize = 512U;
+
 void ClearAllButFrameAncestors(network::mojom::URLResponseHead *response_head)
 {
     response_head->headers->RemoveHeader("Content-Security-Policy");
@@ -123,9 +126,7 @@ void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL
 
     MimeTypesHandler::ReportUsedHandler(extension_id);
 
-    std::string view_id = base::Uuid::GenerateRandomV4().AsLowercaseString();
-    // The string passed down to the original client with the response body.
-    std::string payload = view_id;
+    const std::string stream_id = base::Uuid::GenerateRandomV4().AsLowercaseString();
 
     mojo::PendingRemote<network::mojom::URLLoader> dummy_new_loader;
     std::ignore = dummy_new_loader.InitWithNewPipeAndPassReceiver();
@@ -134,19 +135,18 @@ void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL
         new_client.BindNewPipeAndPassReceiver();
 
 
-    uint32_t data_pipe_size = 64U;
     // Provide the MimeHandlerView code a chance to override the payload. This is
     // the case where the resource is handled by frame-based MimeHandlerView.
-    *defer = extensions::MimeHandlerViewAttachHelper::OverrideBodyForInterceptedResponse(
-        m_frame_tree_node_id, response_url, response_head->mime_type, view_id,
-        &payload, &data_pipe_size,
+    const std::string payload = extensions::MimeHandlerViewAttachHelper::OverrideBodyForInterceptedResponse(
+        m_frame_tree_node_id, response_url, response_head->mime_type, stream_id,
         base::BindOnce(
             &PluginResponseInterceptorURLLoaderThrottle::ResumeLoad,
             weak_factory_.GetWeakPtr()));
+    *defer = true;
 
     mojo::ScopedDataPipeProducerHandle producer_handle;
     mojo::ScopedDataPipeConsumerHandle consumer_handle;
-    CHECK_EQ(MOJO_RESULT_OK, mojo::CreateDataPipe(data_pipe_size, producer_handle, consumer_handle));
+    CHECK_EQ(MOJO_RESULT_OK, mojo::CreateDataPipe(kFullPageMimeHandlerDataPipeSize, producer_handle, consumer_handle));
 
     uint32_t len = static_cast<uint32_t>(payload.size());
     CHECK_EQ(MOJO_RESULT_OK,
@@ -189,7 +189,7 @@ void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL
       FROM_HERE,
       base::BindOnce(
             &extensions::StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent,
-            extension_id, view_id, embedded, m_frame_tree_node_id,
+            extension_id, stream_id, embedded, m_frame_tree_node_id,
             std::move(transferrable_loader), response_url));
 }
 
diff --git a/src/core/net/proxying_restricted_cookie_manager_qt.cpp b/src/core/net/proxying_restricted_cookie_manager_qt.cpp
index d4d5cc4ab3c..29e6de968f5 100644
--- a/src/core/net/proxying_restricted_cookie_manager_qt.cpp
+++ b/src/core/net/proxying_restricted_cookie_manager_qt.cpp
@@ -67,13 +67,14 @@ void ProxyingRestrictedCookieManagerQt::GetAllForUrl(const GURL &url,
                                                      const net::SiteForCookies &site_for_cookies,
                                                      const url::Origin &top_frame_origin, bool has_storage_access,
                                                      network::mojom::CookieManagerGetOptionsPtr options,
+                                                     bool is_ad_tagged,
                                                      GetAllForUrlCallback callback)
 {
     DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
 
     if (allowCookies(url, site_for_cookies)) {
         underlying_restricted_cookie_manager_->GetAllForUrl(url, site_for_cookies, top_frame_origin, has_storage_access,
-                                                            std::move(options), std::move(callback));
+                                                            std::move(options), is_ad_tagged, std::move(callback));
     } else {
         std::move(callback).Run(std::vector<net::CookieWithAccessResult>());
     }
@@ -121,7 +122,7 @@ void ProxyingRestrictedCookieManagerQt::SetCookieFromString(const GURL &url,
         underlying_restricted_cookie_manager_->SetCookieFromString(url, site_for_cookies, top_frame_origin, has_storage_access,
                                                                    cookie, std::move(callback));
     } else {
-        std::move(callback).Run(false, false); // FIXME: is true, true in aw_proxying_restricted_cookie_manager.cc though..
+        std::move(callback).Run();
     }
 }
 
@@ -129,6 +130,7 @@ void ProxyingRestrictedCookieManagerQt::GetCookiesString(const GURL &url,
                                                          const net::SiteForCookies &site_for_cookies,
                                                          const url::Origin &top_frame_origin,
                                                          bool has_storage_access, bool get_version_shared_memory,
+                                                         bool is_ad_tagged,
                                                          GetCookiesStringCallback callback)
 {
     DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
@@ -136,6 +138,7 @@ void ProxyingRestrictedCookieManagerQt::GetCookiesString(const GURL &url,
     if (allowCookies(url, site_for_cookies)) {
         underlying_restricted_cookie_manager_->GetCookiesString(url, site_for_cookies, top_frame_origin,
                                                                 has_storage_access, get_version_shared_memory,
+                                                                is_ad_tagged,
                                                                 std::move(callback));
     } else {
         std::move(callback).Run(network::mojom::kInvalidCookieVersion, base::ReadOnlySharedMemoryRegion(), "");
diff --git a/src/core/net/proxying_restricted_cookie_manager_qt.h b/src/core/net/proxying_restricted_cookie_manager_qt.h
index faf0545c31b..ba30a448e9f 100644
--- a/src/core/net/proxying_restricted_cookie_manager_qt.h
+++ b/src/core/net/proxying_restricted_cookie_manager_qt.h
@@ -29,6 +29,7 @@ class ProxyingRestrictedCookieManagerQt : public network::mojom::RestrictedCooki
                       const url::Origin &top_frame_origin,
                       bool has_storage_access,
                       network::mojom::CookieManagerGetOptionsPtr options,
+                      bool is_ad_tagged,
                       GetAllForUrlCallback callback) override;
 
     void SetCanonicalCookie(const net::CanonicalCookie& cookie,
@@ -54,6 +55,7 @@ class ProxyingRestrictedCookieManagerQt : public network::mojom::RestrictedCooki
                           const net::SiteForCookies &site_for_cookies,
                           const url::Origin &top_frame_origin,
                           bool has_storage_access, bool get_version_shared_memory,
+                          bool is_ad_tagged,
                           GetCookiesStringCallback callback) override;
     void CookiesEnabledFor(const GURL &url,
                            const net::SiteForCookies &site_for_cookies,
diff --git a/src/core/net/webui_controller_factory_qt.cpp b/src/core/net/webui_controller_factory_qt.cpp
index ed35a3e36fe..d38576b8261 100644
--- a/src/core/net/webui_controller_factory_qt.cpp
+++ b/src/core/net/webui_controller_factory_qt.cpp
@@ -15,7 +15,7 @@
 #include "chrome/browser/accessibility/accessibility_ui.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/device_log_ui.h"
-#include "chrome/browser/ui/webui/devtools_ui.h"
+#include "chrome/browser/ui/webui/devtools/devtools_ui.h"
 #include "chrome/browser/ui/webui/net_internals/net_internals_ui.h"
 #include "chrome/browser/ui/webui/user_actions/user_actions_ui.h"
 #include "chrome/common/url_constants.h"
diff --git a/src/core/ozone/gl_share_context_qt.h b/src/core/ozone/gl_share_context_qt.h
index 89be0042118..1144d738464 100644
--- a/src/core/ozone/gl_share_context_qt.h
+++ b/src/core/ozone/gl_share_context_qt.h
@@ -21,7 +21,7 @@ class QtShareGLContext : public gl::GLContext
     void *GetHandle() override { return m_handle; }
     unsigned int CheckStickyGraphicsResetStatusImpl() override;
     // We don't care about the rest, this context shouldn't be used except for its handle.
-    bool Initialize(gl::GLSurface *, const gl::GLContextAttribs &) override
+    bool InitializeImpl(gl::GLSurface *, const gl::GLContextAttribs &) override
     {
         Q_UNREACHABLE();
         return false;
diff --git a/src/core/platform_notification_service_qt.cpp b/src/core/platform_notification_service_qt.cpp
index 182a5ad849f..2c0a39a67c1 100644
--- a/src/core/platform_notification_service_qt.cpp
+++ b/src/core/platform_notification_service_qt.cpp
@@ -8,6 +8,8 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_event_dispatcher.h"
 #include "ui/message_center/public/cpp/notification_delegate.h"
+#include "url/gurl.h"
+#include "url/origin.h"
 
 #include "profile_adapter.h"
 #include "profile_adapter_client.h"
@@ -153,6 +155,24 @@ void PlatformNotificationServiceQt::GetDisplayedNotifications(DisplayedNotificat
     std::move(callback).Run(std::move(movableStdStringSet), true /* supports_synchronization */);
 }
 
+void PlatformNotificationServiceQt::GetDisplayedNotificationsForOrigin(const GURL &url, DisplayedNotificationsCallback callback)
+{
+    Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+    ProfileQt *profile = static_cast<ProfileQt *>(browser_context);
+
+    const url::Origin origin = url::Origin::Create(url);
+    std::set<std::string> movableStdStringSet;
+    auto it = profile->profileAdapter()->persistentNotifications().constBegin();
+    const auto end = profile->profileAdapter()->persistentNotifications().constEnd();
+    while (it != end) {
+        if (it.value()->isShown() && origin.IsSameOriginWith(toGurl(it.value()->origin())))
+            movableStdStringSet.insert(it.key().toStdString());
+        ++it;
+    }
+
+    std::move(callback).Run(std::move(movableStdStringSet), true /* supports_synchronization */);
+}
+
 int64_t PlatformNotificationServiceQt::ReadNextPersistentNotificationId()
 {
     Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
diff --git a/src/core/platform_notification_service_qt.h b/src/core/platform_notification_service_qt.h
index bf8fcca04fa..1435f79e984 100644
--- a/src/core/platform_notification_service_qt.h
+++ b/src/core/platform_notification_service_qt.h
@@ -56,6 +56,8 @@ class PlatformNotificationServiceQt : public content::PlatformNotificationServic
     // Records a given notification to UKM.
     void RecordNotificationUkmEvent(const content::NotificationDatabaseData&) override { }
 
+    void GetDisplayedNotificationsForOrigin(const GURL&, DisplayedNotificationsCallback callback) override;
+
     content::BrowserContext *browser_context;
 };
 
diff --git a/src/core/pref_service_adapter.cpp b/src/core/pref_service_adapter.cpp
index 544a84de1f1..ae7cf102bc4 100644
--- a/src/core/pref_service_adapter.cpp
+++ b/src/core/pref_service_adapter.cpp
@@ -87,8 +87,7 @@ void PrefServiceAdapter::setup(const ProfileAdapter &profileAdapter)
     registry->RegisterIntegerPref(prefs::kNotificationNextPersistentId, 10000);
     registry->RegisterDictionaryPref(prefs::kPushMessagingAppIdentifierMap);
     registry->RegisterListPref(prefs::kAccountInfo);
-    registry->RegisterStringPref(prefs::kGoogleServicesLastUsername,
-                               std::string());
+    registry->RegisterStringPref(prefs::kGoogleServicesLastSyncingUsername, std::string());
     registry->RegisterStringPref(prefs::kGoogleServicesAccountId, std::string());
     registry->RegisterBooleanPref(prefs::kGoogleServicesConsentedToSync, false);
     registry->RegisterBooleanPref(prefs::kAutologinEnabled, true);
diff --git a/src/core/printing/print_view_manager_base_qt.cpp b/src/core/printing/print_view_manager_base_qt.cpp
index b2b8e34fc3e..a691bc2b64b 100644
--- a/src/core/printing/print_view_manager_base_qt.cpp
+++ b/src/core/printing/print_view_manager_base_qt.cpp
@@ -17,7 +17,6 @@
 #include "base/task/thread_pool.h"
 #include "base/timer/timer.h"
 #include "base/values.h"
-#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/printing/print_job.h"
 #include "chrome/browser/printing/print_job_manager.h"
 #include "chrome/browser/printing/printer_query.h"
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index c0906003acb..7d6f5cda0ba 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -6,7 +6,6 @@
 #include "base/files/file_util.h"
 #include "base/task/cancelable_task_tracker.h"
 #include "base/threading/thread_restrictions.h"
-#include "base/time/time_to_iso8601.h"
 #include "components/embedder_support/user_agent_utils.h"
 #include "components/favicon/core/favicon_service.h"
 #include "components/history/content/browser/history_database_helper.h"
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp
index cc127e55fc2..b82c0fb0355 100644
--- a/src/core/renderer/content_renderer_client_qt.cpp
+++ b/src/core/renderer/content_renderer_client_qt.cpp
@@ -196,13 +196,12 @@ void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame *render_fr
     ExtensionsRendererClientQt::GetInstance()->RenderFrameCreated(render_frame, render_frame_observer->registry());
 #endif
 
-    autofill::PasswordAutofillAgent *password_autofill_agent =
-            new autofill::PasswordAutofillAgent(render_frame, associated_interfaces);
-    autofill::PasswordGenerationAgent *password_generation_agent =
-            new autofill::PasswordGenerationAgent(render_frame, password_autofill_agent,
-                                                  associated_interfaces);
+    auto password_autofill_agent =
+            std::make_unique<autofill::PasswordAutofillAgent>(render_frame, associated_interfaces);
+    auto password_generation_agent =
+            std::make_unique<autofill::PasswordGenerationAgent>(render_frame, password_autofill_agent.get(), associated_interfaces);
 
-    new autofill::AutofillAgent(render_frame, password_autofill_agent, password_generation_agent,
+    new autofill::AutofillAgent(render_frame, std::move(password_autofill_agent), std::move(password_generation_agent),
                                 associated_interfaces);
 }
 
diff --git a/src/core/renderer/extensions/extensions_renderer_client_qt.cpp b/src/core/renderer/extensions/extensions_renderer_client_qt.cpp
index b36ed9e8b45..f201e645795 100644
--- a/src/core/renderer/extensions/extensions_renderer_client_qt.cpp
+++ b/src/core/renderer/extensions/extensions_renderer_client_qt.cpp
@@ -149,7 +149,7 @@ void ExtensionsRendererClientQt::WillSendRequest(blink::WebLocalFrame *frame,
     if (url.ProtocolIs(extensions::kExtensionScheme) &&
             !resource_request_policy_->CanRequestResource(url, frame,
                                                           transition_type,
-                                                          base::OptionalFromPtr(initiator_origin))) {
+                                                          initiator_origin)) {
         *new_url = GURL(chrome::kExtensionInvalidRequestURL);
     }
 }
diff --git a/src/core/renderer/extensions/resource_request_policy_qt.cpp b/src/core/renderer/extensions/resource_request_policy_qt.cpp
index a61e533107a..2e4eea771de 100644
--- a/src/core/renderer/extensions/resource_request_policy_qt.cpp
+++ b/src/core/renderer/extensions/resource_request_policy_qt.cpp
@@ -51,7 +51,7 @@ void ResourceRequestPolicyQt::OnExtensionUnloaded(const ExtensionId &extension_i
 bool ResourceRequestPolicyQt::CanRequestResource(const GURL &resource_url,
                                                  blink::WebLocalFrame *frame,
                                                  ui::PageTransition transition_type,
-                                                 const absl::optional<url::Origin>& initiator_origin)
+                                                 const url::Origin *initiator_origin)
 {
     CHECK(resource_url.SchemeIs(kExtensionScheme));
 
diff --git a/src/core/renderer/extensions/resource_request_policy_qt.h b/src/core/renderer/extensions/resource_request_policy_qt.h
index ec108519fa5..6807f509137 100644
--- a/src/core/renderer/extensions/resource_request_policy_qt.h
+++ b/src/core/renderer/extensions/resource_request_policy_qt.h
@@ -39,7 +39,7 @@ class ResourceRequestPolicyQt
     bool CanRequestResource(const GURL &resource_url,
                             blink::WebLocalFrame *frame,
                             ui::PageTransition transition_type,
-                            const absl::optional<url::Origin> &initiator_origin);
+                            const url::Origin *initiator_origin);
 
 private:
     Dispatcher *m_dispatcher;
diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h
index 0da8a6931b6..688ea014d34 100644
--- a/src/core/type_conversion.h
+++ b/src/core/type_conversion.h
@@ -209,11 +209,11 @@ QIcon toQIcon(const std::vector<SkBitmap> &bitmaps);
 
 inline QDateTime toQt(base::Time time)
 {
-    return QDateTime::fromMSecsSinceEpoch(time.ToJavaTime());
+    return QDateTime::fromMSecsSinceEpoch(time.InMillisecondsSinceUnixEpoch());
 }
 
 inline base::Time toTime(const QDateTime &dateTime) {
-    return base::Time::FromJavaTime(dateTime.toMSecsSinceEpoch());
+    return base::Time::FromMillisecondsSinceUnixEpoch(dateTime.toMSecsSinceEpoch());
 }
 
 inline QNetworkCookie toQt(const net::CanonicalCookie & cookie)
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 7d9e119e94a..e73eca7f37f 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -1736,8 +1736,12 @@ static void fillDropDataFromMimeData(content::DropData *dropData, const QMimeDat
     if (mimeData->hasText())
         dropData->text = toOptionalString16(mimeData->text());
     if (mimeData->hasFormat(QLatin1String(ui::kMimeTypeWebCustomData))) {
-        QByteArray customData = mimeData->data(QLatin1String(ui::kMimeTypeWebCustomData));
-        ui::ReadCustomDataIntoMap(customData.constData(), customData.length(), &dropData->custom_data);
+        const QByteArray customData = mimeData->data(QLatin1String(ui::kMimeTypeWebCustomData));
+        const base::span custom_data(customData.constData(), (long unsigned)customData.length());
+        if (auto maybe_data = ui::ReadCustomDataIntoMap(base::as_bytes(custom_data)))
+            dropData->custom_data = *std::move(maybe_data);
+        else
+            dropData->custom_data.clear();
     }
 }
 
diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp
index 023f9e99f29..50d964de7fc 100644
--- a/src/core/web_contents_view_qt.cpp
+++ b/src/core/web_contents_view_qt.cpp
@@ -227,6 +227,7 @@ static Qt::DropActions toQtDropActions(blink::DragOperationsMask ops)
 }
 
 void WebContentsViewQt::StartDragging(const content::DropData &drop_data,
+                                      const url::Origin& source_origin,
                                       blink::DragOperationsMask allowed_ops,
                                       const gfx::ImageSkia &image,
                                       const gfx::Vector2d &image_offset,
@@ -256,10 +257,11 @@ void WebContentsViewQt::StartDragging(const content::DropData &drop_data,
 #endif // QT_CONFIG(draganddrop)
 }
 
-void WebContentsViewQt::UpdateDragCursor(ui::mojom::DragOperation dragOperation)
+void WebContentsViewQt::UpdateDragOperation(ui::mojom::DragOperation dragOperation, bool isDrag)
 {
 #if QT_CONFIG(draganddrop)
-    m_client->webContentsAdapter()->updateDragAction(int(dragOperation));
+    if (isDrag)
+        m_client->webContentsAdapter()->updateDragAction(int(dragOperation));
 #endif // QT_CONFIG(draganddrop)
 }
 
diff --git a/src/core/web_contents_view_qt.h b/src/core/web_contents_view_qt.h
index 8754250e641..78041a1506d 100644
--- a/src/core/web_contents_view_qt.h
+++ b/src/core/web_contents_view_qt.h
@@ -80,13 +80,17 @@ class WebContentsViewQt
 #endif
 
     // content::RenderViewHostDelegateView overrides:
-    void StartDragging(const content::DropData& drop_data, blink::DragOperationsMask allowed_ops,
+    void StartDragging(const content::DropData& drop_data,
+                       const url::Origin& source_origin,
+                       blink::DragOperationsMask allowed_ops,
                        const gfx::ImageSkia& image, const gfx::Vector2d& image_offset,
                        const gfx::Rect& drag_obj_rect,
                        const blink::mojom::DragEventSourceInfo &event_info,
                        content::RenderWidgetHostImpl *source_rwh) override;
 
-    void UpdateDragCursor(ui::mojom::DragOperation dragOperation) override;
+    void UpdateDragOperation(ui::mojom::DragOperation dragOperation, bool document_is_handling_drag) override;
+
+    void TransferDragSecurityInfo(content::WebContentsView *) override {}
 
     void ShowContextMenu(content::RenderFrameHost &, const content::ContextMenuParams &params) override;
 
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index e38d8af8917..e860e96b44d 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -903,9 +903,6 @@ WebEngineContext::WebEngineContext()
     enableFeatures.push_back(features::kNetworkServiceInProcess.name);
     enableFeatures.push_back(features::kTracingServiceInProcess.name);
 
-    // When enabled, event.movement is calculated in blink instead of in browser.
-    disableFeatures.push_back(features::kConsolidatedMovementXY.name);
-
     // Avoid crashing when websites tries using this feature (since 83)
     disableFeatures.push_back(features::kInstalledApp.name);
 
diff --git a/tools/scripts/version_resolver.py b/tools/scripts/version_resolver.py
index a29ee34e8f4..707524ef35d 100644
--- a/tools/scripts/version_resolver.py
+++ b/tools/scripts/version_resolver.py
@@ -43,8 +43,8 @@ def get_recursedeps(self):
         return self.local_scope["recursedeps"]
 
 
-chromium_version = '118.0.5993.220'
-chromium_branch = '5993'
+chromium_version = '120.0.6099.272'
+chromium_branch = '6099'
 ninja_version = 'v1.8.2'
 
 json_url = 'http://omahaproxy.appspot.com/all.json'

From f22d613e27b993e2baba78e0461f0c708c362c47 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Fri, 1 Mar 2024 20:27:18 +0100
Subject: [PATCH 010/356] Adaptations for Chromium 122

Includes following patches:

* 340b36c Bind SpellCheckHost to a RenderFrameHost
* f154285 Fix chrome://ukm webui after 122 update
* 3e67d86 Adapt datalist test to new Chromium behavior after 122 adaptations
* 76b532e Fix test failures in tst_accessibility
* 8a9ecf5 Adapt IME test to new Chromium behavior after 122 adaptations
* d65cd90 Fix to resolve the DCHECK failure during download operation
* e956d1d Ensure DelegatedFrameHost's frame sink ID is registered

Done-With: Anu Aliyas, Kaloyan Chehlarski, Martin Negyokru, Peter Varga
Change-Id: Ic5e8c0457c1633af18a8e11785041ab423e9362e
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit d868597035a206e57384bc2974db65bf817803a5)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/CMakeLists.txt                       |  5 ++
 src/core/api/CMakeLists.txt                   |  6 +-
 src/core/api/qwebengineurlrequestinfo.cpp     |  1 +
 src/core/api/qwebengineurlrequestinfo.h       |  3 +-
 src/core/autofill_client_qt.cpp               |  6 --
 src/core/autofill_client_qt.h                 |  7 +-
 src/core/autofill_popup_controller.cpp        |  6 +-
 src/core/browser_message_filter_qt.cpp        |  2 +
 src/core/browser_message_filter_qt.h          |  4 +-
 src/core/clipboard_qt.cpp                     | 16 ++--
 src/core/clipboard_qt.h                       |  7 +-
 .../extensions/extensions_api_provider_qt.cpp |  2 +-
 .../extensions/extensions_api_provider_qt.h   |  2 +-
 .../compositor/display_skia_output_device.cpp |  2 +-
 .../native_skia_output_device_vulkan.cpp      | 12 +--
 src/core/configure/BUILD.root.gn.in           | 15 +++-
 src/core/content_browser_client_qt.cpp        | 77 +++++++++++--------
 src/core/content_browser_client_qt.h          | 33 ++++----
 src/core/desktop_screen_qt.cpp                |  7 +-
 src/core/download_manager_delegate_qt.cpp     | 57 +++++++-------
 src/core/download_manager_delegate_qt.h       |  4 +-
 .../extensions/extension_host_delegate_qt.cpp |  7 +-
 .../extensions/extension_host_delegate_qt.h   |  2 +-
 .../extensions_browser_client_qt.cpp          |  7 +-
 .../extensions/extensions_browser_client_qt.h |  4 +
 .../extensions/file_system_delegate_qt.cpp    | 31 ++------
 src/core/extensions/file_system_delegate_qt.h | 17 ++--
 src/core/favicon_service_factory_qt.cpp       |  2 +-
 src/core/favicon_service_factory_qt.h         |  2 +-
 src/core/file_picker_controller.cpp           |  4 +-
 ...file_system_access_permission_context_qt.h |  2 +
 src/core/media_capture_devices_dispatcher.cpp | 30 +++++++-
 ...sponse_interceptor_url_loader_throttle.cpp | 24 +++---
 src/core/net/proxy_config_service_qt.cpp      |  1 -
 .../net/proxying_url_loader_factory_qt.cpp    |  1 +
 src/core/net/ssl_host_state_delegate_qt.cpp   |  4 +-
 src/core/net/ssl_host_state_delegate_qt.h     |  6 +-
 .../net/system_network_context_manager.cpp    |  5 +-
 src/core/net/webui_controller_factory_qt.cpp  |  2 +-
 src/core/ozone/gl_share_context_qt.cpp        |  5 ++
 src/core/ozone/gl_share_context_qt.h          |  1 +
 src/core/ozone/gl_surface_qt.cpp              |  9 +--
 src/core/ozone/ozone_platform_qt.cpp          |  9 +--
 src/core/ozone/surface_factory_qt.cpp         | 16 ++--
 src/core/permission_manager_qt.cpp            | 14 ++--
 src/core/permission_manager_qt.h              | 13 ++--
 src/core/profile_adapter.cpp                  | 19 +++--
 src/core/profile_io_data_qt.cpp               | 33 +++-----
 src/core/profile_io_data_qt.h                 |  6 --
 src/core/profile_qt.cpp                       |  5 --
 src/core/profile_qt.h                         |  1 -
 src/core/render_widget_host_view_qt.cpp       |  7 +-
 src/core/render_widget_host_view_qt.h         |  3 +-
 .../renderer/content_renderer_client_qt.cpp   | 27 ++++---
 .../renderer/content_renderer_client_qt.h     |  2 +-
 .../renderer/content_settings_observer_qt.cpp |  7 +-
 .../renderer/content_settings_observer_qt.h   |  3 +
 .../extensions_renderer_client_qt.cpp         |  5 +-
 .../loadable_plugin_placeholder_qt.cpp        | 10 +--
 .../renderer/render_frame_observer_qt.cpp     |  2 +-
 src/core/renderer/render_frame_observer_qt.h  |  2 +-
 .../renderer/user_resource_controller.cpp     |  5 +-
 .../qwebengine_convert_dict/CMakeLists.txt    |  3 +
 src/core/web_contents_delegate_qt.cpp         |  4 +-
 src/core/web_contents_delegate_qt.h           |  4 +-
 src/core/web_engine_context.cpp               |  2 +-
 .../auto/quick/qmltests/data/tst_datalist.qml | 14 +++-
 .../accessibility/tst_accessibility.cpp       | 19 +++--
 .../qwebengineview/tst_qwebengineview.cpp     | 23 +++---
 69 files changed, 378 insertions(+), 320 deletions(-)

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 8ba77607b79..a359cc57f91 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -350,6 +350,8 @@ foreach(arch ${archs})
             use_static_angle=true
             use_perfetto_client_library=false
             trial_comparison_cert_verifier_supported=false
+            enable_extensions_legacy_ipc=true
+            enable_bound_session_credentials=false
         )
         extend_gn_list(gnArgArg
             ARGS use_v8_context_snapshot v8_use_external_startup_data
@@ -577,6 +579,7 @@ target_include_directories(WebEngineCore PRIVATE
     ${buildDir}/$<CONFIG>/${arch}/gen
     ${buildDir}/$<CONFIG>/${arch}/gen/third_party/perfetto
     ${buildDir}/$<CONFIG>/${arch}/gen/third_party/perfetto/build_config
+    ${buildDir}/$<CONFIG>/${arch}/gen/base/allocator/partition_allocator/src
 )
 
 set(stamps QtWebEngineCore.stamp)
@@ -632,7 +635,9 @@ if(QT_FEATURE_webengine_spellchecker AND NOT CMAKE_CROSSCOMPILING)
     target_include_directories(${dict_target_name} PRIVATE
         ../3rdparty/chromium
         ../3rdparty/chromium/third_party/boringssl/src/include
+        ../3rdparty/chromium/base/allocator/partition_allocator/src
         ${buildDir}/$<CONFIG>/${arch}/gen
+        ${buildDir}/$<CONFIG>/${arch}/gen/base/allocator/partition_allocator/src
     )
     add_gn_build_artifacts_to_target(
         CMAKE_TARGET ${dict_target_name}
diff --git a/src/core/api/CMakeLists.txt b/src/core/api/CMakeLists.txt
index e14d0cd5c18..2a06baec664 100644
--- a/src/core/api/CMakeLists.txt
+++ b/src/core/api/CMakeLists.txt
@@ -51,6 +51,7 @@ qt_internal_add_module(WebEngineCore
         ../../3rdparty/chromium/third_party/abseil-cpp
         ../../3rdparty/chromium/third_party/perfetto/include
         ../../3rdparty/chromium/third_party/boringssl/src/include
+        ../../3rdparty/chromium/base/allocator/partition_allocator/src
     LIBRARIES
         Qt::CorePrivate
         Qt::GuiPrivate
@@ -67,10 +68,13 @@ qt_internal_add_module(WebEngineCore
 
 set_target_properties(WebEngineCore PROPERTIES QTWEBENGINEPROCESS_NAME ${qtWebEngineProcessName})
 set_target_properties(WebEngineCore PROPERTIES CXX_STANDARD 20)
-
 # Chromium included headers are not clean
 qt_skip_warnings_are_errors(WebEngineCore)
 
+if(MSVC AND NOT CLANG)
+    target_compile_options(WebEngineCore PRIVATE "/Zc:preprocessor")
+endif()
+
 if(CLANG OR GCC)
     target_compile_options(WebEngineCore PRIVATE
         "-Wno-unused-parameter"
diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp
index 152cf4dd09e..b323b5ec3b3 100644
--- a/src/core/api/qwebengineurlrequestinfo.cpp
+++ b/src/core/api/qwebengineurlrequestinfo.cpp
@@ -161,6 +161,7 @@ QWebEngineUrlRequestInfo::QWebEngineUrlRequestInfo(QWebEngineUrlRequestInfoPriva
     \value ResourceTypeNavigationPreloadSubFrame  A sub-frame service worker navigation preload request. (Added in Qt 5.14)
     \value ResourceTypeWebSocket  A WebSocket request. (Added in Qt 6.4)
     \value ResourceTypeUnknown  Unknown request type.
+    \value ResourceTypeJson A JSON module. (Added in Qt 6.9)
 
     \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 33efcbedafe..b8a02d07a82 100644
--- a/src/core/api/qwebengineurlrequestinfo.h
+++ b/src/core/api/qwebengineurlrequestinfo.h
@@ -47,8 +47,9 @@ class Q_WEBENGINECORE_EXPORT QWebEngineUrlRequestInfo
         ResourceTypePluginResource, // A resource requested by a plugin
         ResourceTypeNavigationPreloadMainFrame = 19, // A main-frame service worker navigation preload request
         ResourceTypeNavigationPreloadSubFrame,  // A sub-frame service worker navigation preload request
+        ResourceTypeJson, // a JSON module (import ... with { type: "json" })
 #ifndef Q_QDOC
-        ResourceTypeLast = ResourceTypeNavigationPreloadSubFrame,
+        ResourceTypeLast = ResourceTypeJson,
 #endif
         ResourceTypeWebSocket = 254,
         ResourceTypeUnknown = 255
diff --git a/src/core/autofill_client_qt.cpp b/src/core/autofill_client_qt.cpp
index 44a242d5c6b..15162e9e926 100644
--- a/src/core/autofill_client_qt.cpp
+++ b/src/core/autofill_client_qt.cpp
@@ -97,12 +97,6 @@ std::vector<autofill::Suggestion> AutofillClientQt::GetPopupSuggestions() const
     return {};
 }
 
-void AutofillClientQt::UpdatePopup(const std::vector<autofill::Suggestion> &, autofill::PopupType, autofill::AutofillSuggestionTriggerSource)
-{
-    // Called by password_manager component only.
-    NOTIMPLEMENTED();
-}
-
 void AutofillClientQt::HideAutofillPopup(autofill::PopupHidingReason)
 {
     adapterClient()->hideAutofillPopup();
diff --git a/src/core/autofill_client_qt.h b/src/core/autofill_client_qt.h
index b14a486e14f..4f10882d24c 100644
--- a/src/core/autofill_client_qt.h
+++ b/src/core/autofill_client_qt.h
@@ -19,6 +19,7 @@
 #include <vector>
 
 #include "base/memory/weak_ptr.h"
+#include "base/containers/span.h"
 #include "components/autofill/content/browser/content_autofill_client.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
@@ -52,9 +53,9 @@ class AutofillClientQt : public autofill::ContentAutofillClient,
     PopupOpenArgs GetReopenPopupArgs(
             autofill::AutofillSuggestionTriggerSource trigger_source) const override;
     std::vector<autofill::Suggestion> GetPopupSuggestions() const override;
-    void UpdatePopup(const std::vector<autofill::Suggestion>& suggestions,
-                     autofill::PopupType popup_type,
-                     autofill::AutofillSuggestionTriggerSource trigger_source) override;
+    void UpdatePopup(const std::vector<autofill::Suggestion> &suggestions,
+                     autofill::FillingProduct main_filling_product,
+                     autofill::AutofillSuggestionTriggerSource trigger_source) override{};
     void HideAutofillPopup(autofill::PopupHidingReason reason) override;
     bool IsAutocompleteEnabled() const override;
     bool IsPasswordManagerEnabled() override;
diff --git a/src/core/autofill_popup_controller.cpp b/src/core/autofill_popup_controller.cpp
index a6baf5fc29f..a4ce0b7f885 100644
--- a/src/core/autofill_popup_controller.cpp
+++ b/src/core/autofill_popup_controller.cpp
@@ -9,6 +9,8 @@
 
 namespace QtWebEngineCore {
 
+using SuggestionPosition = autofill::AutofillPopupDelegate::SuggestionPosition;
+
 AutofillPopupController::AutofillPopupController(AutofillPopupControllerPrivate *dd)
 {
     Q_ASSERT(dd);
@@ -26,7 +28,7 @@ void AutofillPopupController::setCurrentIndex(const QModelIndex &index)
 
     if (m_currentIndex.isValid()) {
         const autofill::Suggestion &suggestion = d->suggestions[m_currentIndex.row()];
-        d->delegate->DidSelectSuggestion(suggestion, autofill::AutofillSuggestionTriggerSource::kFormControlElementClicked);
+        d->delegate->DidSelectSuggestion(suggestion);
     }
 
     Q_EMIT currentIndexChanged(index);
@@ -79,7 +81,7 @@ void AutofillPopupController::acceptSuggestion()
 
     const int index = m_currentIndex.row();
     const autofill::Suggestion &suggestion = d->suggestions[index];
-    d->delegate->DidAcceptSuggestion(suggestion, index, autofill::AutofillSuggestionTriggerSource::kFormControlElementClicked);
+    d->delegate->DidAcceptSuggestion(suggestion, SuggestionPosition{ .row = index });
 }
 
 void AutofillPopupController::notifyPopupShown()
diff --git a/src/core/browser_message_filter_qt.cpp b/src/core/browser_message_filter_qt.cpp
index e8fcb994ab1..8708fc8306d 100644
--- a/src/core/browser_message_filter_qt.cpp
+++ b/src/core/browser_message_filter_qt.cpp
@@ -19,6 +19,7 @@ BrowserMessageFilterQt::BrowserMessageFilterQt(int /*render_process_id*/, Profil
 {
 }
 
+#if BUILDFLAG(CONTENT_ENABLE_LEGACY_IPC)
 bool BrowserMessageFilterQt::OnMessageReceived(const IPC::Message& message)
 {
     IPC_BEGIN_MESSAGE_MAP(BrowserMessageFilterQt, message)
@@ -31,6 +32,7 @@ bool BrowserMessageFilterQt::OnMessageReceived(const IPC::Message& message)
     IPC_END_MESSAGE_MAP()
     return true;
 }
+#endif
 
 void BrowserMessageFilterQt::OnAllowStorageAccess(int /*render_frame_id*/,
                                                   const GURL &origin_url,
diff --git a/src/core/browser_message_filter_qt.h b/src/core/browser_message_filter_qt.h
index 0f5721c824f..c19d2f352e9 100644
--- a/src/core/browser_message_filter_qt.h
+++ b/src/core/browser_message_filter_qt.h
@@ -5,6 +5,7 @@
 #define BROWSER_MESSAGE_FILTER_QT_H
 
 #include "base/functional/callback.h"
+#include "content/common/buildflags.h"
 #include "content/public/browser/browser_message_filter.h"
 
 class GURL;
@@ -20,8 +21,9 @@ class BrowserMessageFilterQt : public content::BrowserMessageFilter
     BrowserMessageFilterQt(int render_process_id, Profile *profile);
 
 private:
+#if BUILDFLAG(CONTENT_ENABLE_LEGACY_IPC)
     bool OnMessageReceived(const IPC::Message& message) override;
-
+#endif
 
     void OnAllowStorageAccess(int render_frame_id,
                               const GURL &origin_url,
diff --git a/src/core/clipboard_qt.cpp b/src/core/clipboard_qt.cpp
index 774ba8954b9..1140164ae98 100644
--- a/src/core/clipboard_qt.cpp
+++ b/src/core/clipboard_qt.cpp
@@ -9,10 +9,12 @@
 #include "clipboard_change_observer.h"
 #include "type_conversion.h"
 
+#include "base/containers/map_util.h"
 #include "base/logging.h"
 #include "base/strings/utf_offset_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/types/variant_util.h"
+#include "base/types/optional_util.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/base/clipboard/custom_data_helper.h"
 #include "ui/base/clipboard/clipboard.h"
@@ -128,8 +130,10 @@ void ClipboardQt::WriteText(base::StringPiece text)
     getUncommittedData()->setText(toQString(text));
 }
 
-void ClipboardQt::WriteHTML(base::StringPiece markup, absl::optional<base::StringPiece> source_url)
+void ClipboardQt::WriteHTML(base::StringPiece markup, absl::optional<base::StringPiece> source_url,
+                            ui::ClipboardContentType /*content_type*/)
 {
+
     QString markup_string = toQString(markup);
 #if defined (Q_OS_MACOS)
     // We need to prepend the charset on macOS to prevent garbled Unicode characters
@@ -390,10 +394,9 @@ const ui::ClipboardSequenceNumberToken &ClipboardQt::GetSequenceNumber(ui::Clipb
             : clipboardChangeObserver()->getSelectionSequenceNumber();
 }
 
-const ui::DataTransferEndpoint *ClipboardQt::GetSource(ui::ClipboardBuffer buffer) const
+absl::optional<ui::DataTransferEndpoint> ClipboardQt::GetSource(ui::ClipboardBuffer buffer) const
 {
-    auto it = m_dataSrc.find(buffer);
-    return it == m_dataSrc.end() ? nullptr : it->second.get();
+    return base::OptionalFromPtr(base::FindPtrOrNull(m_dataSrc, buffer));
 }
 
 void ClipboardQt::ReadFilenames(ui::ClipboardBuffer buffer,
@@ -423,11 +426,6 @@ void ClipboardQt::WriteFilenames(std::vector<ui::FileInfo> filenames)
     getUncommittedData()->setUrls(urls);
 }
 
-void ClipboardQt::WriteUnsanitizedHTML(base::StringPiece markup, absl::optional<base::StringPiece> source_url)
-{
-    WriteHTML(std::move(markup), std::move(source_url));
-}
-
 #if defined(USE_OZONE)
 bool ClipboardQt::IsSelectionBufferAvailable() const
 {
diff --git a/src/core/clipboard_qt.h b/src/core/clipboard_qt.h
index 22f24cfe5ac..62dc2fbe6a3 100644
--- a/src/core/clipboard_qt.h
+++ b/src/core/clipboard_qt.h
@@ -36,7 +36,8 @@ class ClipboardQt : public ui::Clipboard
 
     std::vector<std::u16string> GetStandardFormats(ui::ClipboardBuffer buffer, const ui::DataTransferEndpoint *data_dst) const override;
 
-    const ui::DataTransferEndpoint *GetSource(ui::ClipboardBuffer buffer) const override;
+    absl::optional<ui::DataTransferEndpoint> GetSource(ui::ClipboardBuffer buffer) const override;
+
     void ReadFilenames(ui::ClipboardBuffer buffer,
                        const ui::DataTransferEndpoint *data_dst,
                        std::vector<ui::FileInfo> *result) const override;
@@ -48,7 +49,8 @@ class ClipboardQt : public ui::Clipboard
                                                  std::unique_ptr<ui::DataTransferEndpoint> data_src) override;
 
     void WriteText(base::StringPiece text) override;
-    void WriteHTML(base::StringPiece markup, absl::optional<base::StringPiece> source_url) override;
+    void WriteHTML(base::StringPiece markup, absl::optional<base::StringPiece> source_url,
+                   ui::ClipboardContentType content_type) override;
     void WriteRTF(base::StringPiece rtf) override;
     void WriteBookmark(base::StringPiece title, base::StringPiece url) override;
     void WriteWebSmartPaste() override;
@@ -56,7 +58,6 @@ class ClipboardQt : public ui::Clipboard
     void WriteData(const ui::ClipboardFormatType &format, base::span<const uint8_t> data) override;
     void WriteSvg(base::StringPiece markup) override;
     void WriteFilenames(std::vector<ui::FileInfo> filenames) override;
-    void WriteUnsanitizedHTML(base::StringPiece markup, absl::optional<base::StringPiece> source_url) override;
 
     base::flat_map<ui::ClipboardBuffer, std::unique_ptr<ui::DataTransferEndpoint>> m_dataSrc;
 };
diff --git a/src/core/common/extensions/extensions_api_provider_qt.cpp b/src/core/common/extensions/extensions_api_provider_qt.cpp
index 1c8e89747a5..5a0f6d89169 100644
--- a/src/core/common/extensions/extensions_api_provider_qt.cpp
+++ b/src/core/common/extensions/extensions_api_provider_qt.cpp
@@ -57,7 +57,7 @@ bool ExtensionsAPIProviderQt::IsAPISchemaGenerated(const std::string &name)
             api::QtWebEngineGeneratedSchemas::IsGenerated(name);
 }
 
-base::StringPiece ExtensionsAPIProviderQt::GetAPISchema(const std::string &name)
+std::string_view ExtensionsAPIProviderQt::GetAPISchema(const std::string &name)
 {
     if (!api::GeneratedSchemas::Get(name).empty())
         return api::GeneratedSchemas::Get(name);
diff --git a/src/core/common/extensions/extensions_api_provider_qt.h b/src/core/common/extensions/extensions_api_provider_qt.h
index 34e8bdd9f6b..b5e67aabf4c 100644
--- a/src/core/common/extensions/extensions_api_provider_qt.h
+++ b/src/core/common/extensions/extensions_api_provider_qt.h
@@ -18,7 +18,7 @@ class ExtensionsAPIProviderQt : public ExtensionsAPIProvider
     void AddPermissionFeatures(FeatureProvider* provider) override;
 
     bool IsAPISchemaGenerated(const std::string& name) override;
-    base::StringPiece GetAPISchema(const std::string& name) override;
+    std::string_view GetAPISchema(const std::string &name) override;
 
     // Adds feature definitions to the given |provider| of the specified type.
     void AddManifestFeatures(FeatureProvider* provider) override { }
diff --git a/src/core/compositor/display_skia_output_device.cpp b/src/core/compositor/display_skia_output_device.cpp
index 0ca466fe82a..ab891f81400 100644
--- a/src/core/compositor/display_skia_output_device.cpp
+++ b/src/core/compositor/display_skia_output_device.cpp
@@ -31,7 +31,7 @@ class DisplaySkiaOutputDevice::Buffer
 
         m_texture = m_parent->m_contextState->gr_context()->createBackendTexture(
                 m_shape.imageInfo.width(), m_shape.imageInfo.height(), colorType,
-                GrMipMapped::kNo, GrRenderable::kYes);
+                skgpu::Mipmapped::kNo, GrRenderable::kYes);
         DCHECK(m_texture.isValid());
 
         DCHECK(m_texture.backend() == GrBackendApi::kOpenGL);
diff --git a/src/core/compositor/native_skia_output_device_vulkan.cpp b/src/core/compositor/native_skia_output_device_vulkan.cpp
index 50768a2ef4b..b775276f665 100644
--- a/src/core/compositor/native_skia_output_device_vulkan.cpp
+++ b/src/core/compositor/native_skia_output_device_vulkan.cpp
@@ -4,6 +4,7 @@
 #include "native_skia_output_device_vulkan.h"
 
 #include "gpu/command_buffer/service/shared_image/shared_image_format_service_utils.h"
+#include "ui/base/ozone_buildflags.h"
 
 #include <QtGui/qvulkaninstance.h>
 #include <QtGui/qvulkanfunctions.h>
@@ -11,17 +12,17 @@
 #include <QtQuick/qsgtexture.h>
 
 #if defined(USE_OZONE)
-#include "ui/ozone/buildflags.h"
-#if BUILDFLAG(OZONE_PLATFORM_X11)
+#if BUILDFLAG(IS_OZONE_X11)
 // We need to define USE_VULKAN_XCB for proper vulkan function pointers.
 // Avoiding it may lead to call wrong vulkan functions.
 // This is originally defined in chromium/gpu/vulkan/BUILD.gn.
 #define USE_VULKAN_XCB
-#endif // BUILDFLAG(OZONE_PLATFORM_X11)
+#endif // BUILDFLAG(IS_OZONE_X11)
 #include "gpu/vulkan/vulkan_function_pointers.h"
-
 #include "components/viz/common/gpu/vulkan_context_provider.h"
 #include "gpu/vulkan/vulkan_device_queue.h"
+#include "third_party/skia/include/gpu/vk/GrVkTypes.h"
+#include "third_party/skia/include/gpu/ganesh/vk/GrVkBackendSurface.h"
 #endif // defined(USE_OZONE)
 
 namespace QtWebEngineCore {
@@ -84,7 +85,8 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
             return nullptr;
         }
 
-        backendTexture.getVkImageInfo(&vkImageInfo);
+        GrBackendTextures::GetVkImageInfo(backendTexture, &vkImageInfo);
+
         if (vkImageInfo.fAlloc.fMemory == VK_NULL_HANDLE) {
             qWarning("VULKAN: Unable to access Vulkan memory.");
             return nullptr;
diff --git a/src/core/configure/BUILD.root.gn.in b/src/core/configure/BUILD.root.gn.in
index 698fb16cba0..1fbbadf2671 100644
--- a/src/core/configure/BUILD.root.gn.in
+++ b/src/core/configure/BUILD.root.gn.in
@@ -92,6 +92,8 @@ config("cpp20_config") {
   # Chromium is built with C++20
   if (is_win) {
     cflags_cc = [ "/std:c++20" ]
+  } else if(is_gcc) {
+    cflags_cc = [ "-std=gnu++20" ]
   } else {
     cflags_cc = [ "-std=c++20" ]
   }
@@ -207,6 +209,8 @@ source_set("qtwebengine_spellcheck_sources") {
   sources = [
     "//chrome/browser/spellchecker/spell_check_host_chrome_impl.cc",
     "//chrome/browser/spellchecker/spell_check_host_chrome_impl.h",
+    "//chrome/browser/spellchecker/spell_check_initialization_host_impl.cc",
+    "//chrome/browser/spellchecker/spell_check_initialization_host_impl.h",
     "//chrome/browser/spellchecker/spellcheck_custom_dictionary.cc",
     "//chrome/browser/spellchecker/spellcheck_custom_dictionary.h",
     "//chrome/browser/spellchecker/spellcheck_factory.cc",
@@ -278,6 +282,7 @@ source_set("qtwebengine_sources") {
     "//components/performance_manager",
     "//components/permissions:permissions_common",
     "//components/plugins/renderer/",
+    "//components/compose:buildflags",
     "//content/browser/resources/quota:resources",
     "//extensions/buildflags:buildflags",
     "//pdf:buildflags",
@@ -347,8 +352,8 @@ source_set("qtwebengine_sources") {
     "//chrome/browser/tab_contents/form_interaction_tab_helper.h",
     "//chrome/browser/tab_contents/web_contents_collection.cc",
     "//chrome/browser/tab_contents/web_contents_collection.h",
-    "//chrome/browser/ui/webui/device_log_ui.cc",
-    "//chrome/browser/ui/webui/device_log_ui.h",
+    "//chrome/browser/ui/webui/device_log/device_log_ui.cc",
+    "//chrome/browser/ui/webui/device_log/device_log_ui.h",
     "//chrome/browser/ui/webui/devtools/devtools_ui.cc",
     "//chrome/browser/ui/webui/devtools/devtools_ui.h",
     "//chrome/browser/ui/webui/devtools/devtools_ui_data_source.cc",
@@ -364,6 +369,7 @@ source_set("qtwebengine_sources") {
     "//chrome/common/chrome_switches.cc",
     "//chrome/common/chrome_switches.h",
     "//chrome/common/pref_names.h",
+    "//chrome/common/url_constants.h",
     "//chrome/common/webui_url_constants.cc",
     "//chrome/common/webui_url_constants.h",
     "//components/embedder_support/user_agent_utils.cc",
@@ -556,6 +562,7 @@ group("qtwebengine_resources") {
       "//chrome/browser:resources",
       "//chrome/browser/resources:component_extension_resources",
       "//chrome/common:resources",
+      "//chrome/browser/resources/device_log:resources",
       "//components/resources:components_resources",
       ":qtwebengine_repack_resources",
       ":qtwebengine_repack_resources_100",
@@ -571,9 +578,11 @@ repack("qtwebengine_repack_resources") {
     "$root_gen_dir/chrome/accessibility_resources.pak",
     "$root_gen_dir/chrome/common_resources.pak",
     "$root_gen_dir/chrome/dev_ui_browser_resources.pak",
+    "$root_gen_dir/chrome/device_log_resources.pak",
     "$root_gen_dir/chrome/net_internals_resources.pak",
     "$root_gen_dir/components/components_resources.pak",
     "$root_gen_dir/components/dev_ui_components_resources.pak",
+    "$root_gen_dir/components/ukm_resources.pak",
     "$root_gen_dir/content/attribution_internals_resources.pak",
     "$root_gen_dir/content/browser/resources/media/media_internals_resources.pak",
     "$root_gen_dir/content/browser/tracing/tracing_resources.pak",
@@ -597,8 +606,10 @@ repack("qtwebengine_repack_resources") {
      "//chrome/browser/resources/accessibility:resources",
      "//chrome/browser/resources/net_internals:resources",
      "//chrome/common:resources_grit",
+     "//chrome/browser/resources/device_log:resources_grit",
      "//components/resources:components_resources_grit",
      "//components/resources:dev_ui_components_resources_grit",
+     "//components/ukm/debug:resources",
      "//content/browser/resources/attribution_reporting:resources",
      "//content/browser/resources/gpu:resources",
      "//content/browser/resources/histograms:resources_grit",
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index f57cf545572..6fec6a1e87b 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -95,6 +95,7 @@
 
 #if QT_CONFIG(webengine_spellchecker)
 #include "chrome/browser/spellchecker/spell_check_host_chrome_impl.h"
+#include "chrome/browser/spellchecker/spell_check_initialization_host_impl.h"
 #include "chrome/browser/spellchecker/spellcheck_factory.h"
 #include "chrome/browser/spellchecker/spellcheck_service.h"
 #include "components/spellcheck/browser/pref_names.h"
@@ -228,7 +229,7 @@ void ContentBrowserClientQt::RenderProcessWillLaunch(content::RenderProcessHost
 #endif
 
 #if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
-    WebRtcLoggingController::AttachToRenderProcessHost(host, WebEngineContext::current()->webRtcLogUploader());
+    WebRtcLoggingController::AttachToRenderProcessHost(host);
 #endif
 
     // Allow requesting custom schemes.
@@ -240,12 +241,13 @@ void ContentBrowserClientQt::RenderProcessWillLaunch(content::RenderProcessHost
     // FIXME: Add a settings variable to enable/disable the file scheme.
     policy->GrantRequestScheme(id, url::kFileScheme);
     profileAdapter->userResourceController()->renderProcessStartedWithHost(host);
+#if BUILDFLAG(CONTENT_ENABLE_LEGACY_IPC)
     host->AddFilter(new BrowserMessageFilterQt(id, profile));
 #if BUILDFLAG(ENABLE_EXTENSIONS)
     host->AddFilter(new extensions::ExtensionMessageFilter(id, profile));
     host->AddFilter(new extensions::MessagingAPIMessageFilter(id, profile));
 #endif //ENABLE_EXTENSIONS
-
+#endif // CONTENT_ENABLE_LEGACY_IPC
     bool is_incognito_process = profile->IsOffTheRecord();
     mojo::AssociatedRemote<qtwebengine::mojom::RendererConfiguration> renderer_configuration;
     host->GetChannel()->GetRemoteAssociatedInterface(&renderer_configuration);
@@ -390,8 +392,9 @@ void ContentBrowserClientQt::BindHostReceiverForRenderer(content::RenderProcessH
                                                          mojo::GenericPendingReceiver receiver)
 {
 #if QT_CONFIG(webengine_spellchecker)
-    if (auto host_receiver = receiver.As<spellcheck::mojom::SpellCheckHost>()) {
-        SpellCheckHostChromeImpl::Create(render_process_host->GetID(), std::move(host_receiver));
+    if (auto host_receiver = receiver.As<spellcheck::mojom::SpellCheckInitializationHost>()) {
+        SpellCheckInitializationHostImpl::Create(render_process_host->GetID(),
+                                                 std::move(host_receiver));
         return;
     }
 #endif
@@ -434,6 +437,15 @@ void ContentBrowserClientQt::RegisterBrowserInterfaceBindersForFrame(
         mojo::BinderMapWithContext<content::RenderFrameHost *> *map)
 {
     map->Add<network_hints::mojom::NetworkHintsHandler>(base::BindRepeating(&BindNetworkHintsHandler));
+#if QT_CONFIG(webengine_spellchecker)
+    map->Add<spellcheck::mojom::SpellCheckHost>(base::BindRepeating(
+            [](content::RenderFrameHost *frame_host,
+               mojo::PendingReceiver<spellcheck::mojom::SpellCheckHost> receiver) {
+                SpellCheckHostChromeImpl::Create(frame_host->GetProcess()->GetID(),
+                                                 std::move(receiver));
+            }));
+#endif
+
 #if BUILDFLAG(ENABLE_EXTENSIONS)
     map->Add<extensions::mime_handler::MimeHandlerService>(base::BindRepeating(&BindMimeHandlerService));
     map->Add<extensions::mime_handler::BeforeUnloadControl>(base::BindRepeating(&BindBeforeUnloadControl));
@@ -460,13 +472,9 @@ void ContentBrowserClientQt::ExposeInterfacesToRenderer(service_manager::BinderR
 {
     if (auto *manager = performance_manager::PerformanceManagerRegistry::GetInstance())
         manager->CreateProcessNodeAndExposeInterfacesToRendererProcess(registry, render_process_host);
-#if BUILDFLAG(ENABLE_EXTENSIONS)
-    associated_registry->AddInterface<extensions::mojom::EventRouter>(
-                base::BindRepeating(&extensions::EventRouter::BindForRenderer, render_process_host->GetID()));
-    associated_registry->AddInterface<guest_view::mojom::GuestViewHost>(
-                base::BindRepeating(&extensions::ExtensionsGuestView::CreateForComponents, render_process_host->GetID()));
-    associated_registry->AddInterface<extensions::mojom::GuestView>(
-                base::BindRepeating(&extensions::ExtensionsGuestView::CreateForExtensions, render_process_host->GetID()));
+#if BUILDFLAG(ENABLE_EXTENSIONS) && BUILDFLAG(ENABLE_EXTENSIONS_LEGACY_IPC)
+    associated_registry->AddInterface<extensions::mojom::EventRouter>(base::BindRepeating(
+            &extensions::EventRouter::BindForRenderer, render_process_host->GetID()));
 #else
     Q_UNUSED(associated_registry);
 #endif
@@ -502,12 +510,13 @@ void ContentBrowserClientQt::RegisterAssociatedInterfaceBindersForRenderFrameHos
                         extensions::ExtensionWebContentsObserverQt::BindLocalFrameHost(std::move(receiver), render_frame_host);
                     }, &rfh));
 #endif
-    associated_registry.AddInterface<autofill::mojom::AutofillDriver>(
-                base::BindRepeating(
-                    [](content::RenderFrameHost *render_frame_host,
-                       mojo::PendingAssociatedReceiver<autofill::mojom::AutofillDriver> receiver) {
-                        autofill::ContentAutofillDriverFactory::BindAutofillDriver(std::move(receiver), render_frame_host);
-                    }, &rfh));
+    associated_registry.AddInterface<autofill::mojom::AutofillDriver>(base::BindRepeating(
+            [](content::RenderFrameHost *render_frame_host,
+               mojo::PendingAssociatedReceiver<autofill::mojom::AutofillDriver> receiver) {
+                autofill::ContentAutofillDriverFactory::BindAutofillDriver(render_frame_host,
+                                                                           std::move(receiver));
+            },
+            &rfh));
 #if BUILDFLAG(ENABLE_PDF)
     associated_registry.AddInterface<pdf::mojom::PdfService>(
                 base::BindRepeating(
@@ -517,6 +526,12 @@ void ContentBrowserClientQt::RegisterAssociatedInterfaceBindersForRenderFrameHos
                     }, &rfh));
 #endif  // BUILDFLAG(ENABLE_PDF)
     ContentBrowserClient::RegisterAssociatedInterfaceBindersForRenderFrameHost(rfh, associated_registry);
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+    associated_registry.AddInterface<guest_view::mojom::GuestViewHost>(base::BindRepeating(
+            &extensions::ExtensionsGuestView::CreateForComponents, rfh.GetGlobalId()));
+    associated_registry.AddInterface<extensions::mojom::GuestView>(base::BindRepeating(
+            &extensions::ExtensionsGuestView::CreateForExtensions, rfh.GetGlobalId()));
+#endif
 }
 
 bool ContentBrowserClientQt::CanCreateWindow(
@@ -764,7 +779,8 @@ std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
 ContentBrowserClientQt::CreateURLLoaderThrottles(
         const network::ResourceRequest &request, content::BrowserContext *browser_context,
         const base::RepeatingCallback<content::WebContents *()> & /*wc_getter*/,
-        content::NavigationUIData * /*navigation_ui_data*/, int frame_tree_node_id)
+        content::NavigationUIData * /*navigation_ui_data*/, int frame_tree_node_id,
+        absl::optional<int64_t> navigation_id)
 {
     std::vector<std::unique_ptr<blink::URLLoaderThrottle>> result;
     result.push_back(std::make_unique<ProtocolHandlerThrottle>(
@@ -883,13 +899,10 @@ bool ContentBrowserClientQt::HasErrorPage(int httpStatusCode, content::WebConten
 }
 
 std::unique_ptr<content::LoginDelegate> ContentBrowserClientQt::CreateLoginDelegate(
-        const net::AuthChallengeInfo &authInfo,
-        content::WebContents *web_contents,
-        const content::GlobalRequestID & /*request_id*/,
-        bool /*is_main_frame*/,
-        const GURL &url,
-        scoped_refptr<net::HttpResponseHeaders> /*response_headers*/,
-        bool first_auth_attempt,
+        const net::AuthChallengeInfo &authInfo, content::WebContents *web_contents,
+        content::BrowserContext *browser_context, const content::GlobalRequestID & /*request_id*/,
+        bool /*is_main_frame*/, const GURL &url,
+        scoped_refptr<net::HttpResponseHeaders> /*response_headers*/, bool first_auth_attempt,
         LoginAuthRequiredCallback auth_required_callback)
 {
     auto loginDelegate = std::make_unique<LoginDelegateQt>(authInfo, web_contents, url, first_auth_attempt, std::move(auth_required_callback));
@@ -1029,9 +1042,8 @@ std::vector<base::FilePath> ContentBrowserClientQt::GetNetworkContextsParentDire
         toFilePath(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)) };
 }
 
-void ContentBrowserClientQt::RegisterNonNetworkNavigationURLLoaderFactories(int frame_tree_node_id,
-                                                                            ukm::SourceIdObj ukm_source_id,
-                                                                            NonNetworkURLLoaderFactoryMap *factories)
+void ContentBrowserClientQt::RegisterNonNetworkNavigationURLLoaderFactories(
+        int frame_tree_node_id, NonNetworkURLLoaderFactoryMap *factories)
 {
     content::WebContents *web_contents = content::WebContents::FromFrameTreeNodeId(frame_tree_node_id);
     Profile *profile = Profile::FromBrowserContext(web_contents->GetBrowserContext());
@@ -1041,10 +1053,9 @@ void ContentBrowserClientQt::RegisterNonNetworkNavigationURLLoaderFactories(int
         factories->emplace(scheme.toStdString(), CreateCustomURLLoaderFactory(profileAdapter, web_contents));
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
-    factories->emplace(
-        extensions::kExtensionScheme,
-        extensions::CreateExtensionNavigationURLLoaderFactory(profile, ukm_source_id,
-                                                              !!extensions::WebViewGuest::FromWebContents(web_contents)));
+    factories->emplace(extensions::kExtensionScheme,
+                       extensions::CreateExtensionNavigationURLLoaderFactory(
+                               profile, !!extensions::WebViewGuest::FromWebContents(web_contents)));
 #endif
 }
 
@@ -1309,7 +1320,7 @@ void ContentBrowserClientQt::CreateWebSocket(
     std::move(factory).Run(to_url, std::move(headers), std::move(handshake_client), mojo::NullRemote(), mojo::NullRemote());
 }
 
-void ContentBrowserClientQt::SiteInstanceGotProcess(content::SiteInstance *site_instance)
+void ContentBrowserClientQt::SiteInstanceGotProcessAndSite(content::SiteInstance *site_instance)
 {
 #if BUILDFLAG(ENABLE_EXTENSIONS)
     content::BrowserContext *context = site_instance->GetBrowserContext();
diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h
index 7d8e9802898..b40c2a343cb 100644
--- a/src/core/content_browser_client_qt.h
+++ b/src/core/content_browser_client_qt.h
@@ -150,15 +150,13 @@ class ContentBrowserClientQt : public content::ContentBrowserClient
     void GetAdditionalMappedFilesForChildProcess(const base::CommandLine& command_line, int child_process_id, content::PosixFileDescriptorInfo* mappings) override;
 #endif
 
-    std::unique_ptr<content::LoginDelegate> CreateLoginDelegate(
-            const net::AuthChallengeInfo &auth_info,
-            content::WebContents *web_contents,
-            const content::GlobalRequestID& request_id,
-            bool is_request_for_main_frame,
-            const GURL &url,
-            scoped_refptr<net::HttpResponseHeaders> response_headers,
-            bool first_auth_attempt,
-            LoginAuthRequiredCallback auth_required_callback) override;
+    std::unique_ptr<content::LoginDelegate>
+    CreateLoginDelegate(const net::AuthChallengeInfo &auth_info, content::WebContents *web_contents,
+                        content::BrowserContext *browser_context,
+                        const content::GlobalRequestID &request_id, bool is_request_for_main_frame,
+                        const GURL &url, scoped_refptr<net::HttpResponseHeaders> response_headers,
+                        bool first_auth_attempt,
+                        LoginAuthRequiredCallback auth_required_callback) override;
 
     bool HandleExternalProtocol(
             const GURL &url,
@@ -174,10 +172,12 @@ class ContentBrowserClientQt : public content::ContentBrowserClient
             content::RenderFrameHost *initiator_document,
             mojo::PendingRemote<network::mojom::URLLoaderFactory> *out_factory) override;
 
-    std::vector<std::unique_ptr<blink::URLLoaderThrottle>> CreateURLLoaderThrottles(
-            const network::ResourceRequest &request, content::BrowserContext *browser_context,
-            const base::RepeatingCallback<content::WebContents *()> &wc_getter,
-            content::NavigationUIData *navigation_ui_data, int frame_tree_node_id) override;
+    std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
+    CreateURLLoaderThrottles(const network::ResourceRequest &request,
+                             content::BrowserContext *browser_context,
+                             const base::RepeatingCallback<content::WebContents *()> &wc_getter,
+                             content::NavigationUIData *navigation_ui_data, int frame_tree_node_id,
+                             absl::optional<int64_t> navigation_id) override;
 
     std::vector<std::unique_ptr<content::NavigationThrottle>> CreateThrottlesForNavigation(
             content::NavigationHandle *navigation_handle) override;
@@ -214,9 +214,8 @@ class ContentBrowserClientQt : public content::ContentBrowserClient
                                        cert_verifier::mojom::CertVerifierCreationParams *cert_verifier_creation_params) override;
 
     std::vector<base::FilePath> GetNetworkContextsParentDirectory() override;
-    void RegisterNonNetworkNavigationURLLoaderFactories(int frame_tree_node_id,
-                                                        ukm::SourceIdObj ukm_source_id,
-                                                        NonNetworkURLLoaderFactoryMap *factories) override;
+    void RegisterNonNetworkNavigationURLLoaderFactories(
+            int frame_tree_node_id, NonNetworkURLLoaderFactoryMap *factories) override;
     void RegisterNonNetworkSubresourceURLLoaderFactories(int render_process_id, int render_frame_id,
                                                          const absl::optional<url::Origin>& request_initiator_origin,
                                                          NonNetworkURLLoaderFactoryMap *factories) override;
@@ -224,7 +223,7 @@ class ContentBrowserClientQt : public content::ContentBrowserClient
                                                                 NonNetworkURLLoaderFactoryMap* factories) override;
     void RegisterNonNetworkServiceWorkerUpdateURLLoaderFactories(content::BrowserContext* browser_context,
                                                                  NonNetworkURLLoaderFactoryMap* factories) override;
-    void SiteInstanceGotProcess(content::SiteInstance *site_instance) override;
+    void SiteInstanceGotProcessAndSite(content::SiteInstance *site_instance) override;
     base::flat_set<std::string> GetPluginMimeTypesWithExternalHandlers(content::BrowserContext *browser_context) override;
 
     std::unique_ptr<content::WebContentsViewDelegate> GetWebContentsViewDelegate(content::WebContents *web_contents) override;
diff --git a/src/core/desktop_screen_qt.cpp b/src/core/desktop_screen_qt.cpp
index fb68f7b092f..2b45e91d11d 100644
--- a/src/core/desktop_screen_qt.cpp
+++ b/src/core/desktop_screen_qt.cpp
@@ -2,7 +2,7 @@
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
 
 #include "desktop_screen_qt.h"
-
+#include "ui/base/ozone_buildflags.h"
 #include "ui/display/display.h"
 
 #include "type_conversion.h"
@@ -10,14 +10,11 @@
 #include <QGuiApplication>
 #include <QScreen>
 
-#if defined(USE_OZONE)
-#include "ui/ozone/buildflags.h"
-#if BUILDFLAG(OZONE_PLATFORM_X11)
+#if BUILDFLAG(IS_LINUX) && BUILDFLAG(IS_OZONE_X11)
 #define USE_XSCREENSAVER
 #include "ui/base/x/x11_screensaver.h"
 #include "ui/base/x/x11_util.h"
 #endif
-#endif
 
 #include <cmath>
 
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index c0fd0d3eeed..7ccd063ffda 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -47,16 +47,13 @@ download::DownloadItem *DownloadManagerDelegateQt::findDownloadById(quint32 down
     return dlm->GetDownload(downloadId);
 }
 
-void DownloadManagerDelegateQt::cancelDownload(content::DownloadTargetCallback callback)
+void DownloadManagerDelegateQt::cancelDownload(download::DownloadTargetCallback callback)
 {
-    std::move(callback).Run(base::FilePath(),
-                            download::DownloadItem::TARGET_DISPOSITION_PROMPT,
-                            download::DownloadDangerType::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
-                            download::DownloadItem::UNKNOWN,
-                            base::FilePath(),
-                            base::FilePath(),
-                            std::string(),
-                            download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED);
+    download::DownloadTargetInfo target_info;
+    target_info.target_disposition = download::DownloadItem::TARGET_DISPOSITION_PROMPT;
+    target_info.danger_type = download::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT;
+    target_info.interrupt_reason = download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED;
+    std::move(callback).Run(std::move(target_info));
 }
 
 bool DownloadManagerDelegateQt::cancelDownload(quint32 downloadId)
@@ -87,7 +84,7 @@ void DownloadManagerDelegateQt::removeDownload(quint32 downloadId)
 }
 
 bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *item,
-                                                        content::DownloadTargetCallback *callback)
+                                                        download::DownloadTargetCallback *callback)
 {
     m_currentId = item->GetId();
 
@@ -95,13 +92,15 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
     // will already return that the file exists. Forced file paths seem to be only used for
     // store downloads and other special downloads, so they might never end up here anyway.
     if (!item->GetForcedFilePath().empty()) {
-        std::move(*callback).Run(item->GetForcedFilePath(), download::DownloadItem::TARGET_DISPOSITION_PROMPT,
-                                 download::DownloadDangerType::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
-                                 download::DownloadItem::VALIDATED,
-                                 item->GetForcedFilePath(),
-                                 item->GetFileNameToReportUser(),
-                                 item->GetMimeType(),
-                                 download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE);
+        download::DownloadTargetInfo target_info;
+        target_info.target_disposition = download::DownloadItem::TARGET_DISPOSITION_PROMPT;
+        target_info.danger_type = download::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT;
+        target_info.insecure_download_status = download::DownloadItem::VALIDATED;
+        target_info.mime_type = item->GetMimeType();
+        target_info.display_name = item->GetFileNameToReportUser();
+        target_info.target_path = item->GetForcedFilePath();
+        target_info.intermediate_path = item->GetForcedFilePath();
+        std::move(*callback).Run(std::move(target_info));
         return true;
     }
 
@@ -211,14 +210,17 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
         }
 
         base::FilePath filePathForCallback(toFilePathString(suggestedFile.absoluteFilePath()));
-        std::move(*callback).Run(filePathForCallback,
-                                 download::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
-                                 download::DownloadDangerType::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
-                                 download::DownloadItem::VALIDATED,
-                                 filePathForCallback.AddExtension(toFilePathString("download")),
-                                 base::FilePath(),
-                                 item->GetMimeType(),
-                                 download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE);
+        download::DownloadTargetInfo target_info;
+        target_info.target_disposition = download::DownloadItem::TARGET_DISPOSITION_OVERWRITE;
+        target_info.danger_type = download::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT;
+        target_info.insecure_download_status = download::DownloadItem::VALIDATED;
+        target_info.mime_type = item->GetMimeType();
+        target_info.intermediate_path =
+                filePathForCallback.AddExtension(toFilePathString("download"));
+        target_info.display_name = base::FilePath();
+        target_info.target_path = filePathForCallback;
+        target_info.interrupt_reason = download::DOWNLOAD_INTERRUPT_REASON_NONE;
+        std::move(*callback).Run(std::move(target_info));
     } else
         cancelDownload(std::move(*callback));
 
@@ -306,7 +308,10 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content
     if (!info.accepted)
         return;
 
-    std::move(callback).Run(toFilePath(info.path), static_cast<content::SavePageType>(info.savePageFormat),
+    content::SavePackagePathPickedParams params;
+    params.file_path = toFilePath(info.path);
+    params.save_type = static_cast<content::SavePageType>(info.savePageFormat);
+    std::move(callback).Run(std::move(params),
                             base::BindOnce(&DownloadManagerDelegateQt::savePackageDownloadCreated,
                                            m_weakPtrFactory.GetWeakPtr()));
 }
diff --git a/src/core/download_manager_delegate_qt.h b/src/core/download_manager_delegate_qt.h
index cc6d49764f6..e7dfad29dcf 100644
--- a/src/core/download_manager_delegate_qt.h
+++ b/src/core/download_manager_delegate_qt.h
@@ -35,7 +35,7 @@ class DownloadManagerDelegateQt
     void GetNextId(content::DownloadIdCallback callback) override;
 
     bool DetermineDownloadTarget(download::DownloadItem *item,
-                                 content::DownloadTargetCallback *callback) override;
+                                 download::DownloadTargetCallback *callback) override;
 
     void GetSaveDir(content::BrowserContext* browser_context,
                     base::FilePath* website_save_dir,
@@ -56,7 +56,7 @@ class DownloadManagerDelegateQt
     void OnDownloadDestroyed(download::DownloadItem *download) override;
 
 private:
-    void cancelDownload(content::DownloadTargetCallback callback);
+    void cancelDownload(download::DownloadTargetCallback callback);
     download::DownloadItem *findDownloadById(quint32 downloadId);
     void savePackageDownloadCreated(download::DownloadItem *download);
     ProfileAdapter *m_profileAdapter;
diff --git a/src/core/extensions/extension_host_delegate_qt.cpp b/src/core/extensions/extension_host_delegate_qt.cpp
index aa408a544d9..16133a598f8 100644
--- a/src/core/extensions/extension_host_delegate_qt.cpp
+++ b/src/core/extensions/extension_host_delegate_qt.cpp
@@ -86,10 +86,9 @@ void ExtensionHostDelegateQt::ProcessMediaAccessRequest(content::WebContents *we
     });
 }
 
-bool ExtensionHostDelegateQt::CheckMediaAccessPermission(content::RenderFrameHost *render_frame_host,
-                                                         const GURL &security_origin,
-                                                         blink::mojom::MediaStreamType type,
-                                                         const Extension *extension)
+bool ExtensionHostDelegateQt::CheckMediaAccessPermission(
+        content::RenderFrameHost *render_frame_host, const url::Origin &security_origin,
+        blink::mojom::MediaStreamType type, const Extension *extension)
 {
     Q_UNUSED(render_frame_host);
     Q_UNUSED(security_origin);
diff --git a/src/core/extensions/extension_host_delegate_qt.h b/src/core/extensions/extension_host_delegate_qt.h
index 1c2688933ea..38b5d4a2fd1 100644
--- a/src/core/extensions/extension_host_delegate_qt.h
+++ b/src/core/extensions/extension_host_delegate_qt.h
@@ -27,7 +27,7 @@ class ExtensionHostDelegateQt : public ExtensionHostDelegate
                                    content::MediaResponseCallback callback,
                                    const Extension *extension) override;
     bool CheckMediaAccessPermission(content::RenderFrameHost *render_frame_host,
-                                    const GURL &security_origin,
+                                    const url::Origin &security_origin,
                                     blink::mojom::MediaStreamType type,
                                     const Extension *extension) override;
     content::PictureInPictureResult EnterPictureInPicture(content::WebContents *web_contents) override;
diff --git a/src/core/extensions/extensions_browser_client_qt.cpp b/src/core/extensions/extensions_browser_client_qt.cpp
index 19fc6c808b5..36151cee562 100644
--- a/src/core/extensions/extensions_browser_client_qt.cpp
+++ b/src/core/extensions/extensions_browser_client_qt.cpp
@@ -542,5 +542,10 @@ media_device_salt::MediaDeviceSaltService *ExtensionsBrowserClientQt::GetMediaDe
     // Not needed for QWE
     return nullptr;
 }
-
+mojo::PendingRemote<network::mojom::URLLoaderFactory>
+ExtensionsBrowserClientQt::GetControlledFrameEmbedderURLLoader(
+        int frame_tree_node_id, content::BrowserContext *browser_context)
+{
+    return mojo::PendingRemote<network::mojom::URLLoaderFactory>();
+}
 } // namespace extensions
diff --git a/src/core/extensions/extensions_browser_client_qt.h b/src/core/extensions/extensions_browser_client_qt.h
index bcc8f142b26..34a84631106 100644
--- a/src/core/extensions/extensions_browser_client_qt.h
+++ b/src/core/extensions/extensions_browser_client_qt.h
@@ -108,6 +108,10 @@ class ExtensionsBrowserClientQt : public ExtensionsBrowserClient
 
     media_device_salt::MediaDeviceSaltService *GetMediaDeviceSaltService(content::BrowserContext *context) override;
 
+    mojo::PendingRemote<network::mojom::URLLoaderFactory>
+    GetControlledFrameEmbedderURLLoader(int frame_tree_node_id,
+                                        content::BrowserContext *browser_context) override;
+
 private:
     // Support for extension APIs.
     std::unique_ptr<ExtensionsAPIClient> api_client_;
diff --git a/src/core/extensions/file_system_delegate_qt.cpp b/src/core/extensions/file_system_delegate_qt.cpp
index 7c1c5bbd843..6c5b3391913 100644
--- a/src/core/extensions/file_system_delegate_qt.cpp
+++ b/src/core/extensions/file_system_delegate_qt.cpp
@@ -41,36 +41,21 @@ FileEntryPickerQt::FileEntryPickerQt(
 
 FileEntryPickerQt::~FileEntryPickerQt() = default;
 
-void FileEntryPickerQt::FileSelected(const base::FilePath &path,
-        int index,
-        void *params)
+void FileEntryPickerQt::FileSelected(const ui::SelectedFileInfo &file, int index, void *params)
 {
-    MultiFilesSelected({path}, params);
+    MultiFilesSelected({ file }, params);
 }
 
-void FileEntryPickerQt::FileSelectedWithExtraInfo(const ui::SelectedFileInfo& file,
-        int index,
-        void *params)
-{
-    FileSelected(file.file_path, index, params);
-}
-
-void FileEntryPickerQt::MultiFilesSelected(const std::vector<base::FilePath>& files,
-                      void* params)
+void FileEntryPickerQt::MultiFilesSelected(const std::vector<ui::SelectedFileInfo> &files,
+                                           void *params)
 {
     Q_UNUSED(params);
-    std::move(m_filesSelectedCallback).Run(files);
-    delete this;
-}
-
-void FileEntryPickerQt::MultiFilesSelectedWithExtraInfo(
-        const std::vector<ui::SelectedFileInfo> &files,
-        void *params)
-{
     std::vector<base::FilePath> paths;
-    for (const auto& file : files)
+    for (const auto &file : files) {
         paths.push_back(file.file_path);
-    MultiFilesSelected(paths, params);
+    }
+    std::move(m_filesSelectedCallback).Run(paths);
+    delete this;
 }
 
 void FileEntryPickerQt::FileSelectionCanceled(void *params)
diff --git a/src/core/extensions/file_system_delegate_qt.h b/src/core/extensions/file_system_delegate_qt.h
index 1e9d87c38fa..01b56fa569d 100644
--- a/src/core/extensions/file_system_delegate_qt.h
+++ b/src/core/extensions/file_system_delegate_qt.h
@@ -19,6 +19,10 @@ namespace content {
 class BrowserContext;
 }  // namespace content
 
+namespace ui {
+struct SelectedFileInfo;
+}
+
 namespace extensions {
 
 class FileEntryPickerQt : public ui::SelectFileDialog::Listener {
@@ -38,17 +42,8 @@ class FileEntryPickerQt : public ui::SelectFileDialog::Listener {
     ~FileEntryPickerQt() override;
 
     // ui::SelectFileDialog::Listener implementation.
-    void FileSelected(const base::FilePath &path,
-        int index,
-        void *params) override;
-    void FileSelectedWithExtraInfo(const ui::SelectedFileInfo &file,
-        int index,
-        void *params) override;
-    void MultiFilesSelected(const std::vector<base::FilePath> &files,
-                          void *params) override;
-    void MultiFilesSelectedWithExtraInfo(
-        const std::vector<ui::SelectedFileInfo> &files,
-        void *params) override;
+    void FileSelected(const ui::SelectedFileInfo &file, int index, void *params) override;
+    void MultiFilesSelected(const std::vector<ui::SelectedFileInfo> &files, void *params) override;
     void FileSelectionCanceled(void *params) override;
 
     FileSystemDelegate::FilesSelectedCallback m_filesSelectedCallback;
diff --git a/src/core/favicon_service_factory_qt.cpp b/src/core/favicon_service_factory_qt.cpp
index dd2a1979acb..1ed33d559e2 100644
--- a/src/core/favicon_service_factory_qt.cpp
+++ b/src/core/favicon_service_factory_qt.cpp
@@ -46,7 +46,7 @@ std::unique_ptr<history::HistoryBackendClient> HistoryClientQt::CreateBackendCli
     return nullptr;
 }
 
-void HistoryClientQt::UpdateBookmarkLastUsedTime(const base::Uuid &, base::Time /*time*/)
+void HistoryClientQt::UpdateBookmarkLastUsedTime(int64_t /*bookmark_node_id*/, base::Time /*time*/)
 {
 }
 
diff --git a/src/core/favicon_service_factory_qt.h b/src/core/favicon_service_factory_qt.h
index 55d5f3b3306..0c3bfd7b56a 100644
--- a/src/core/favicon_service_factory_qt.h
+++ b/src/core/favicon_service_factory_qt.h
@@ -51,7 +51,7 @@ class HistoryClientQt : public history::HistoryClient
     history::CanAddURLCallback GetThreadSafeCanAddURLCallback() const override;
     void NotifyProfileError(sql::InitStatus init_status, const std::string &diagnostics) override;
     std::unique_ptr<history::HistoryBackendClient> CreateBackendClient() override;
-    void UpdateBookmarkLastUsedTime(const base::Uuid &, base::Time) override;
+    void UpdateBookmarkLastUsedTime(int64_t bookmark_node_id, base::Time time) override;
 };
 
 class HistoryServiceFactoryQt : public BrowserContextKeyedServiceFactory
diff --git a/src/core/file_picker_controller.cpp b/src/core/file_picker_controller.cpp
index 9b452135865..9f97892966a 100644
--- a/src/core/file_picker_controller.cpp
+++ b/src/core/file_picker_controller.cpp
@@ -9,6 +9,7 @@
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/public/browser/file_select_listener.h"
 #include "ui/shell_dialogs/select_file_dialog.h"
+#include "ui/shell_dialogs/selected_file_info.h"
 
 #include <QtCore/qcoreapplication.h>
 #include <QDir>
@@ -214,7 +215,8 @@ void FilePickerController::filesSelectedInChooser(const QStringList &filesList)
         if (files.empty())
             d_ptr->fileSystemAccessDialogListener->FileSelectionCanceled(nullptr);
         else
-            d_ptr->fileSystemAccessDialogListener->MultiFilesSelected(files, nullptr);
+            d_ptr->fileSystemAccessDialogListener->MultiFilesSelected(
+                    ui::FilePathListToSelectedFileInfoList(files), nullptr);
     }
 }
 
diff --git a/src/core/file_system_access/file_system_access_permission_context_qt.h b/src/core/file_system_access/file_system_access_permission_context_qt.h
index 06fbfae3f0e..b569c81c020 100644
--- a/src/core/file_system_access/file_system_access_permission_context_qt.h
+++ b/src/core/file_system_access/file_system_access_permission_context_qt.h
@@ -53,6 +53,8 @@ class FileSystemAccessPermissionContextQt : public content::FileSystemAccessPerm
     base::FilePath GetWellKnownDirectoryPath(blink::mojom::WellKnownDirectory directory, const url::Origin &origin) override;
     std::u16string GetPickerTitle(const blink::mojom::FilePickerOptionsPtr &) override;
     void NotifyEntryMoved(const url::Origin &, const base::FilePath &, const base::FilePath &) override;
+    void OnFileCreatedFromShowSaveFilePicker(const GURL &file_picker_binding_context,
+                                             const storage::FileSystemURL &url) override{};
 
     void NavigatedAwayFromOrigin(const url::Origin &origin);
     content::BrowserContext *profile() const { return m_profile; }
diff --git a/src/core/media_capture_devices_dispatcher.cpp b/src/core/media_capture_devices_dispatcher.cpp
index 6dc45c4429b..73885b6f203 100644
--- a/src/core/media_capture_devices_dispatcher.cpp
+++ b/src/core/media_capture_devices_dispatcher.cpp
@@ -13,11 +13,13 @@
 #include "web_engine_settings.h"
 
 #include "base/strings/strcat.h"
+#include "blink/public/common/page/page_zoom.h"
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/desktop_media_id.h"
 #include "content/public/browser/desktop_streams_registry.h"
+#include "content/public/browser/host_zoom_map.h"
 #include "content/public/browser/media_capture_devices.h"
 #include "content/public/browser/render_process_host.h"
 #include "media/audio/audio_device_description.h"
@@ -107,6 +109,27 @@ media::mojom::CaptureHandlePtr CreateCaptureHandle(content::WebContents *capture
     return result;
 }
 
+absl::optional<int> GetZoomLevel(content::WebContents *capturer,
+                                 const content::DesktopMediaID &captured_id)
+{
+    content::RenderFrameHost *const captured_rfh =
+            content::RenderFrameHost::FromID(captured_id.web_contents_id.render_process_id,
+                                             captured_id.web_contents_id.main_render_frame_id);
+    if (!captured_rfh || !captured_rfh->IsActive()) {
+        return absl::nullopt;
+    }
+
+    content::WebContents *const captured_wc =
+            content::WebContents::FromRenderFrameHost(captured_rfh);
+    if (!captured_wc) {
+        return absl::nullopt;
+    }
+
+    double zoom_level =
+            blink::PageZoomLevelToZoomFactor(content::HostZoomMap::GetZoomLevel(captured_wc));
+    return std::round(100 * zoom_level);
+}
+
 // Based on chrome/browser/media/webrtc/desktop_capture_devices_util.cc:
 media::mojom::DisplayMediaInformationPtr DesktopMediaIDToDisplayMediaInformation(content::WebContents *capturer,
                                                                                  const url::Origin &capturer_origin,
@@ -122,6 +145,7 @@ media::mojom::DisplayMediaInformationPtr DesktopMediaIDToDisplayMediaInformation
 #endif  // defined(USE_AURA)
 
     media::mojom::CaptureHandlePtr capture_handle;
+    int zoom_level = 100;
     switch (media_id.type) {
     case content::DesktopMediaID::TYPE_SCREEN:
         display_surface = media::mojom::DisplayCaptureSurfaceType::MONITOR;
@@ -137,12 +161,16 @@ media::mojom::DisplayMediaInformationPtr DesktopMediaIDToDisplayMediaInformation
         display_surface = media::mojom::DisplayCaptureSurfaceType::BROWSER;
         cursor = media::mojom::CursorCaptureType::MOTION;
         capture_handle = CreateCaptureHandle(capturer, capturer_origin, media_id);
+        if (base::FeatureList::IsEnabled(features::kCapturedSurfaceControlKillswitch)) {
+            zoom_level = GetZoomLevel(capturer, media_id).value_or(zoom_level);
+        }
         break;
     case content::DesktopMediaID::TYPE_NONE:
         break;
     }
 
-    return media::mojom::DisplayMediaInformation::New(display_surface, logical_surface, cursor, std::move(capture_handle));
+    return media::mojom::DisplayMediaInformation::New(display_surface, logical_surface, cursor,
+                                                      std::move(capture_handle), zoom_level);
 }
 
 
diff --git a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
index a99c68367e9..319d3a56633 100644
--- a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
+++ b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
@@ -124,8 +124,6 @@ void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL
     if (extension_id == extension_misc::kPdfExtensionId && response_head->headers)
         ClearAllButFrameAncestors(response_head);
 
-    MimeTypesHandler::ReportUsedHandler(extension_id);
-
     const std::string stream_id = base::Uuid::GenerateRandomV4().AsLowercaseString();
 
     mojo::PendingRemote<network::mojom::URLLoader> dummy_new_loader;
@@ -134,14 +132,15 @@ void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL
     mojo::PendingReceiver<network::mojom::URLLoaderClient> new_client_receiver =
         new_client.BindNewPipeAndPassReceiver();
 
-
+    const std::string internal_id = base::UnguessableToken::Create().ToString();
     // Provide the MimeHandlerView code a chance to override the payload. This is
     // the case where the resource is handled by frame-based MimeHandlerView.
-    const std::string payload = extensions::MimeHandlerViewAttachHelper::OverrideBodyForInterceptedResponse(
-        m_frame_tree_node_id, response_url, response_head->mime_type, stream_id,
-        base::BindOnce(
-            &PluginResponseInterceptorURLLoaderThrottle::ResumeLoad,
-            weak_factory_.GetWeakPtr()));
+    const std::string payload =
+            extensions::MimeHandlerViewAttachHelper::OverrideBodyForInterceptedResponse(
+                    m_frame_tree_node_id, response_url, response_head->mime_type, stream_id,
+                    internal_id,
+                    base::BindOnce(&PluginResponseInterceptorURLLoaderThrottle::ResumeLoad,
+                                   weak_factory_.GetWeakPtr()));
     *defer = true;
 
     mojo::ScopedDataPipeProducerHandle producer_handle;
@@ -186,11 +185,10 @@ void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL
     bool embedded = m_request_destination !=
             network::mojom::RequestDestination::kDocument;
     content::GetUIThreadTaskRunner({})->PostTask(
-      FROM_HERE,
-      base::BindOnce(
-            &extensions::StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent,
-            extension_id, stream_id, embedded, m_frame_tree_node_id,
-            std::move(transferrable_loader), response_url));
+            FROM_HERE,
+            base::BindOnce(&extensions::StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent,
+                           extension_id, stream_id, embedded, m_frame_tree_node_id,
+                           std::move(transferrable_loader), response_url, internal_id));
 }
 
 void PluginResponseInterceptorURLLoaderThrottle::ResumeLoad()
diff --git a/src/core/net/proxy_config_service_qt.cpp b/src/core/net/proxy_config_service_qt.cpp
index fcce08550a9..d74ec699df8 100644
--- a/src/core/net/proxy_config_service_qt.cpp
+++ b/src/core/net/proxy_config_service_qt.cpp
@@ -27,7 +27,6 @@ net::ProxyServer ProxyConfigServiceQt::fromQNetworkProxy(const QNetworkProxy &qt
         return net::ProxyServer::FromSchemeHostAndPort(net::ProxyServer::SCHEME_HTTP, host, port);
     case QNetworkProxy::NoProxy:
     case QNetworkProxy::DefaultProxy:
-        return net::ProxyServer(net::ProxyServer::SCHEME_DIRECT, net::HostPortPair());
     default:
         return net::ProxyServer(net::ProxyServer::SCHEME_INVALID, net::HostPortPair());
     }
diff --git a/src/core/net/proxying_url_loader_factory_qt.cpp b/src/core/net/proxying_url_loader_factory_qt.cpp
index 3a83ed7ea74..220f44023f6 100644
--- a/src/core/net/proxying_url_loader_factory_qt.cpp
+++ b/src/core/net/proxying_url_loader_factory_qt.cpp
@@ -65,6 +65,7 @@ ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeCspReport, blink::mojom
 ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypePluginResource, blink::mojom::ResourceType::kPluginResource)
 ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeNavigationPreloadMainFrame, blink::mojom::ResourceType::kNavigationPreloadMainFrame)
 ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeNavigationPreloadSubFrame, blink::mojom::ResourceType::kNavigationPreloadSubFrame)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeJson, blink::mojom::ResourceType::kJson)
 ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeLast, blink::mojom::ResourceType::kMaxValue)
 
 extern WebContentsAdapterClient::NavigationType pageTransitionToNavigationType(ui::PageTransition transition);
diff --git a/src/core/net/ssl_host_state_delegate_qt.cpp b/src/core/net/ssl_host_state_delegate_qt.cpp
index 41967f14efc..809a95c8dc4 100644
--- a/src/core/net/ssl_host_state_delegate_qt.cpp
+++ b/src/core/net/ssl_host_state_delegate_qt.cpp
@@ -127,9 +127,9 @@ void SSLHostStateDelegateQt::SetHttpsEnforcementForHost(const std::string &host,
     // Intentional no-op see aw_ssl_host_state_delegate
 }
 
-bool SSLHostStateDelegateQt::IsHttpsEnforcedForHost(const std::string &host, content::StoragePartition *storage_partition)
+bool SSLHostStateDelegateQt::IsHttpsEnforcedForUrl(const GURL &url,
+                                                   content::StoragePartition *storage_partition)
 {
-    // Intentional no-op
     return false;
 }
 
diff --git a/src/core/net/ssl_host_state_delegate_qt.h b/src/core/net/ssl_host_state_delegate_qt.h
index 0b3d7974c2c..f210f028a18 100644
--- a/src/core/net/ssl_host_state_delegate_qt.h
+++ b/src/core/net/ssl_host_state_delegate_qt.h
@@ -39,11 +39,13 @@ class SSLHostStateDelegateQt : public content::SSLHostStateDelegate
     bool DidHostRunInsecureContent(const std::string &host, int child_id, InsecureContentType content_type) override;
     void AllowHttpForHost(const std::string &host, content::StoragePartition *web_contents) override;
     bool IsHttpAllowedForHost(const std::string &host, content::StoragePartition *web_contents) override;
-    void SetHttpsEnforcementForHost(const std::string &host, bool enforce, content::StoragePartition *storage_partition) override;
-    bool IsHttpsEnforcedForHost(const std::string &host, content::StoragePartition *web_contents) override;
+    void SetHttpsEnforcementForHost(const std::string &host, bool enforce,
+                                    content::StoragePartition *storage_partition) override;
     void RevokeUserAllowExceptions(const std::string &host) override;
     bool HasAllowException(const std::string &host, content::StoragePartition *web_contents) override;
     bool HasAllowExceptionForAnyHost(content::StoragePartition *storage_partition) override;
+    bool IsHttpsEnforcedForUrl(const GURL &url,
+                               content::StoragePartition *storage_partition) override;
 
 private:
     std::map<std::string, CertPolicy> m_certPolicyforHost;
diff --git a/src/core/net/system_network_context_manager.cpp b/src/core/net/system_network_context_manager.cpp
index 439d1066c29..78098529da5 100644
--- a/src/core/net/system_network_context_manager.cpp
+++ b/src/core/net/system_network_context_manager.cpp
@@ -236,10 +236,7 @@ void SystemNetworkContextManager::OnNetworkServiceCreated(network::mojom::Networ
 
         log_list_mojo.push_back(std::move(log_info));
     }
-    network_service->UpdateCtLogList(
-            std::move(log_list_mojo),
-            certificate_transparency::GetLogListTimestamp(),
-            base::DoNothing());
+    network_service->UpdateCtLogList(std::move(log_list_mojo), base::DoNothing());
 
     // The system NetworkContext is created first
     network_service_network_context_.reset();
diff --git a/src/core/net/webui_controller_factory_qt.cpp b/src/core/net/webui_controller_factory_qt.cpp
index d38576b8261..2acd05cae7a 100644
--- a/src/core/net/webui_controller_factory_qt.cpp
+++ b/src/core/net/webui_controller_factory_qt.cpp
@@ -14,7 +14,7 @@
 #include "build/build_config.h"
 #include "chrome/browser/accessibility/accessibility_ui.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/webui/device_log_ui.h"
+#include "chrome/browser/ui/webui/device_log/device_log_ui.h"
 #include "chrome/browser/ui/webui/devtools/devtools_ui.h"
 #include "chrome/browser/ui/webui/net_internals/net_internals_ui.h"
 #include "chrome/browser/ui/webui/user_actions/user_actions_ui.h"
diff --git a/src/core/ozone/gl_share_context_qt.cpp b/src/core/ozone/gl_share_context_qt.cpp
index b1c5e201f10..f2078b59785 100644
--- a/src/core/ozone/gl_share_context_qt.cpp
+++ b/src/core/ozone/gl_share_context_qt.cpp
@@ -43,6 +43,11 @@ QtShareGLContext::QtShareGLContext(QOpenGLContext *context)
 #endif // QT_CONFIG(opengl)
 }
 
+QtShareGLContext::~QtShareGLContext()
+{
+    OnContextWillDestroy();
+}
+
 unsigned int QtShareGLContext::CheckStickyGraphicsResetStatusImpl()
 {
 #if QT_CONFIG(opengl)
diff --git a/src/core/ozone/gl_share_context_qt.h b/src/core/ozone/gl_share_context_qt.h
index 1144d738464..6b0546a72ea 100644
--- a/src/core/ozone/gl_share_context_qt.h
+++ b/src/core/ozone/gl_share_context_qt.h
@@ -18,6 +18,7 @@ class QtShareGLContext : public gl::GLContext
 
 public:
     QtShareGLContext(QOpenGLContext *qtContext);
+    ~QtShareGLContext() override;
     void *GetHandle() override { return m_handle; }
     unsigned int CheckStickyGraphicsResetStatusImpl() override;
     // We don't care about the rest, this context shouldn't be used except for its handle.
diff --git a/src/core/ozone/gl_surface_qt.cpp b/src/core/ozone/gl_surface_qt.cpp
index 0cbe75cbd3e..cebeb8b67f2 100644
--- a/src/core/ozone/gl_surface_qt.cpp
+++ b/src/core/ozone/gl_surface_qt.cpp
@@ -128,15 +128,14 @@ bool usingSoftwareDynamicGL()
 #endif // QT_CONFIG(opengl)
 }
 
-scoped_refptr<GLSurface>
-CreateOffscreenGLSurfaceWithFormat(GLDisplay *display, const gfx::Size& size, GLSurfaceFormat format)
+scoped_refptr<GLSurface> CreateOffscreenGLSurface(GLDisplay *display, const gfx::Size &size)
 {
     scoped_refptr<GLSurface> surface;
     switch (GetGLImplementation()) {
     case kGLImplementationDesktopGLCoreProfile:
     case kGLImplementationDesktopGL: {
         surface = new GLSurfaceWGLQt(size);
-        if (surface->Initialize(format))
+        if (surface->Initialize(GLSurfaceFormat()))
             return surface;
         break;
     }
@@ -144,8 +143,8 @@ CreateOffscreenGLSurfaceWithFormat(GLDisplay *display, const gfx::Size& size, GL
     case kGLImplementationEGLGLES2: {
         GLDisplayEGL *display_egl = display->GetAs<gl::GLDisplayEGL>();
         if (display_egl->IsEGLSurfacelessContextSupported() && size.width() == 0 && size.height() == 0)
-            return InitializeGLSurfaceWithFormat(new SurfacelessEGL(display_egl, size), format);
-        return InitializeGLSurfaceWithFormat(new PbufferGLSurfaceEGL(display_egl, size), format);
+            return InitializeGLSurface(new SurfacelessEGL(display_egl, size));
+        return InitializeGLSurface(new PbufferGLSurfaceEGL(display_egl, size));
     }
     default:
         break;
diff --git a/src/core/ozone/ozone_platform_qt.cpp b/src/core/ozone/ozone_platform_qt.cpp
index 623cf43cfb8..6384ea2dbda 100644
--- a/src/core/ozone/ozone_platform_qt.cpp
+++ b/src/core/ozone/ozone_platform_qt.cpp
@@ -38,7 +38,7 @@
 #include <filesystem>
 #endif // BUILDFLAG(USE_XKBCOMMON)
 
-#if BUILDFLAG(OZONE_PLATFORM_X11)
+#if BUILDFLAG(IS_OZONE_X11)
 #include "ui/gfx/linux/gpu_memory_buffer_support_x11.h"
 #include "ui/ozone/platform/x11/gl_egl_utility_x11.h"
 
@@ -113,9 +113,6 @@ const ui::OzonePlatform::PlatformProperties &OzonePlatformQt::GetPlatformPropert
     if (!initialized) {
         DCHECK(m_supportsNativePixmaps);
         properties->fetch_buffer_formats_for_gmb_on_gpu = m_supportsNativePixmaps.value();
-#if BUILDFLAG(USE_VAAPI)
-        properties->supports_vaapi = m_supportsNativePixmaps.value();
-#endif
         initialized = true;
     }
 
@@ -238,7 +235,7 @@ void OzonePlatformQt::InitializeGPU(const ui::OzonePlatform::InitParams &params)
 {
     surface_factory_ozone_.reset(new QtWebEngineCore::SurfaceFactoryQt());
 
-#if BUILDFLAG(OZONE_PLATFORM_X11)
+#if BUILDFLAG(IS_OZONE_X11)
     if (params.enable_native_gpu_memory_buffers) {
         base::ThreadPool::PostTask(FROM_HERE,
                                    base::BindOnce([]()
@@ -263,7 +260,7 @@ bool OzonePlatformQt::IsNativePixmapConfigSupported(gfx::BufferFormat format, gf
 PlatformGLEGLUtility *OzonePlatformQt::GetPlatformGLEGLUtility()
 {
     if (!gl_egl_utility_) {
-#if BUILDFLAG(OZONE_PLATFORM_X11)
+#if BUILDFLAG(IS_OZONE_X11)
         if (GetQtXDisplay())
             gl_egl_utility_ = std::make_unique<GLEGLUtilityX11>();
         else
diff --git a/src/core/ozone/surface_factory_qt.cpp b/src/core/ozone/surface_factory_qt.cpp
index 2d311a02a26..1bfa49c6006 100644
--- a/src/core/ozone/surface_factory_qt.cpp
+++ b/src/core/ozone/surface_factory_qt.cpp
@@ -9,16 +9,16 @@
 #include "ozone/gl_ozone_egl_qt.h"
 
 #include "media/gpu/buildflags.h"
+#include "ui/base/ozone_buildflags.h"
 #include "ui/gfx/linux/drm_util_linux.h"
 #include "ui/gfx/linux/gbm_buffer.h"
 #include "ui/gfx/linux/native_pixmap_dmabuf.h"
 #include "ui/gl/egl_util.h"
-#include "ui/ozone/buildflags.h"
 
 #include <QDebug>
 #include <QtGui/qtgui-config.h>
 
-#if BUILDFLAG(OZONE_PLATFORM_X11)
+#if BUILDFLAG(IS_OZONE_X11)
 #include "ozone/gl_ozone_glx_qt.h"
 
 #include "ui/gfx/linux/gpu_memory_buffer_support_x11.h"
@@ -32,7 +32,7 @@ namespace QtWebEngineCore {
 
 SurfaceFactoryQt::SurfaceFactoryQt()
 {
-#if BUILDFLAG(OZONE_PLATFORM_X11)
+#if BUILDFLAG(IS_OZONE_X11)
     if (GLContextHelper::getGlxPlatformInterface()) {
         m_impl = { gl::GLImplementationParts(gl::kGLImplementationDesktopGL),
                    gl::GLImplementationParts(gl::kGLImplementationDisabled) };
@@ -73,7 +73,7 @@ SurfaceFactoryQt::CreateVulkanImplementation(bool /*allow_protected_memory*/,
 
 bool SurfaceFactoryQt::CanCreateNativePixmapForFormat(gfx::BufferFormat format)
 {
-#if BUILDFLAG(OZONE_PLATFORM_X11)
+#if BUILDFLAG(IS_OZONE_X11)
     if (GLContextHelper::getGlxPlatformInterface())
         return ui::GpuMemoryBufferSupportX11::GetInstance()->CanCreateNativePixmapForFormat(format);
 #endif
@@ -101,7 +101,7 @@ scoped_refptr<gfx::NativePixmap> SurfaceFactoryQt::CreateNativePixmap(
 
     gfx::NativePixmapHandle handle;
 
-#if BUILDFLAG(OZONE_PLATFORM_X11)
+#if BUILDFLAG(IS_OZONE_X11)
     if (GLContextHelper::getGlxPlatformInterface()) {
         auto gbmBuffer =
                 ui::GpuMemoryBufferSupportX11::GetInstance()->CreateBuffer(format, size, usage);
@@ -165,7 +165,7 @@ SurfaceFactoryQt::CreateNativePixmapFromHandle(
 #if QT_CONFIG(opengl)
     gfx::NativePixmapHandle bufferHandle;
 
-#if BUILDFLAG(OZONE_PLATFORM_X11)
+#if BUILDFLAG(IS_OZONE_X11)
     if (GLContextHelper::getGlxPlatformInterface()) {
         auto gbmBuffer = ui::GpuMemoryBufferSupportX11::GetInstance()->CreateBufferFromHandle(
                 size, format, std::move(handle));
@@ -250,10 +250,10 @@ SurfaceFactoryQt::CreateNativePixmapFromHandle(
 bool SurfaceFactoryQt::SupportsNativePixmaps()
 {
 #if QT_CONFIG(opengl)
-#if BUILDFLAG(OZONE_PLATFORM_X11)
+#if BUILDFLAG(IS_OZONE_X11)
     if (GLContextHelper::getGlxPlatformInterface())
         return ui::GpuMemoryBufferSupportX11::GetInstance()->has_gbm_device();
-#endif // BUILDFLAG(OZONE_PLATFORM_X11)
+#endif // BUILDFLAG(IS_OZONE_X11)
 
     if (GLContextHelper::getEglPlatformInterface())
         return EGLHelper::instance()->isDmaBufSupported();
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index 63189c1d7a0..2c1c0d3d670 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -494,12 +494,11 @@ void PermissionManagerQt::ResetPermission(
     updater.Get().Remove(requesting_origin.spec());
 }
 
-content::PermissionControllerDelegate::SubscriptionId PermissionManagerQt::SubscribePermissionStatusChange(
-    blink::PermissionType permission,
-    content::RenderProcessHost * /*render_process_host*/,
-    content::RenderFrameHost * /* render_frame_host */,
-    const GURL& requesting_origin,
-    base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
+content::PermissionControllerDelegate::SubscriptionId
+PermissionManagerQt::SubscribeToPermissionStatusChange(
+        blink::PermissionType permission, content::RenderProcessHost * /*render_process_host*/,
+        content::RenderFrameHost * /* render_frame_host */, const GURL &requesting_origin,
+        base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
 {
     auto subscriber_id = subscription_id_generator_.GenerateNextId();
     m_subscribers.insert( { subscriber_id,
@@ -507,7 +506,8 @@ content::PermissionControllerDelegate::SubscriptionId PermissionManagerQt::Subsc
     return subscriber_id;
 }
 
-void PermissionManagerQt::UnsubscribePermissionStatusChange(content::PermissionControllerDelegate::SubscriptionId subscription_id)
+void PermissionManagerQt::UnsubscribeFromPermissionStatusChange(
+        content::PermissionControllerDelegate::SubscriptionId subscription_id)
 {
     if (!m_subscribers.erase(subscription_id))
         LOG(WARNING) << "PermissionManagerQt::UnsubscribePermissionStatusChange called on unknown subscription id" << subscription_id;
diff --git a/src/core/permission_manager_qt.h b/src/core/permission_manager_qt.h
index ebab613d616..6a4df2efa80 100644
--- a/src/core/permission_manager_qt.h
+++ b/src/core/permission_manager_qt.h
@@ -57,14 +57,13 @@ class PermissionManagerQt : public content::PermissionControllerDelegate
             const content::PermissionRequestDescription &request_description,
             base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus> &)> callback) override;
 
-    content::PermissionControllerDelegate::SubscriptionId SubscribePermissionStatusChange(
-        blink::PermissionType permission,
-        content::RenderProcessHost* render_process_host,
-        content::RenderFrameHost* render_frame_host,
-        const GURL& requesting_origin,
-        const base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) override;
+    content::PermissionControllerDelegate::SubscriptionId SubscribeToPermissionStatusChange(
+            blink::PermissionType permission, content::RenderProcessHost *render_process_host,
+            content::RenderFrameHost *render_frame_host, const GURL &requesting_origin,
+            const base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) override;
 
-    void UnsubscribePermissionStatusChange(content::PermissionControllerDelegate::SubscriptionId subscription_id) override;
+    void UnsubscribeFromPermissionStatusChange(
+            content::PermissionControllerDelegate::SubscriptionId subscription_id) override;
 
 private:
     struct Request {
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index 7d6f5cda0ba..1f006295322 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -333,9 +333,9 @@ void ProfileAdapter::setHttpUserAgent(const QString &userAgent)
         }
 
     m_profile->ForEachLoadedStoragePartition(
-                base::BindRepeating([](const std::string &user_agent, content::StoragePartition *storage_partition) {
-                    storage_partition->GetNetworkContext()->SetUserAgent(user_agent);
-                }, stdUserAgent));
+            [stdUserAgent](content::StoragePartition *storage_partition) {
+                storage_partition->GetNetworkContext()->SetUserAgent(stdUserAgent);
+            });
 }
 
 ProfileAdapter::HttpCacheType ProfileAdapter::httpCacheType() const
@@ -490,10 +490,9 @@ const QList<QByteArray> ProfileAdapter::customUrlSchemes() const
 
 void ProfileAdapter::updateCustomUrlSchemeHandlers()
 {
-    m_profile->ForEachLoadedStoragePartition(
-        base::BindRepeating([](content::StoragePartition *storage_partition) {
-            storage_partition->ResetURLLoaderFactories();
-        }));
+    m_profile->ForEachLoadedStoragePartition([](content::StoragePartition *storage_partition) {
+        storage_partition->ResetURLLoaderFactories();
+    });
 }
 
 void ProfileAdapter::removeUrlSchemeHandler(QWebEngineUrlSchemeHandler *handler)
@@ -624,9 +623,9 @@ void ProfileAdapter::setHttpAcceptLanguage(const QString &httpAcceptLanguage)
     }
 
     m_profile->ForEachLoadedStoragePartition(
-        base::BindRepeating([](std::string accept_language, content::StoragePartition *storage_partition) {
-            storage_partition->GetNetworkContext()->SetAcceptLanguage(accept_language);
-        }, http_accept_language));
+            [http_accept_language](content::StoragePartition *storage_partition) {
+                storage_partition->GetNetworkContext()->SetAcceptLanguage(http_accept_language);
+            });
 }
 
 QVariant ProfileAdapter::clientHint(ClientHint clientHint) const
diff --git a/src/core/profile_io_data_qt.cpp b/src/core/profile_io_data_qt.cpp
index 859aff8d4fa..31a85a534c1 100644
--- a/src/core/profile_io_data_qt.cpp
+++ b/src/core/profile_io_data_qt.cpp
@@ -37,8 +37,6 @@ ProfileIODataQt::~ProfileIODataQt()
 {
     if (content::BrowserThread::IsThreadInitialized(content::BrowserThread::IO))
         DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
-    m_resourceContext.reset();
 }
 
 QPointer<ProfileAdapter> ProfileIODataQt::profileAdapter()
@@ -69,11 +67,6 @@ void ProfileIODataQt::shutdownOnUIThread()
     }
 }
 
-content::ResourceContext *ProfileIODataQt::resourceContext()
-{
-    return m_resourceContext.get();
-}
-
 #if BUILDFLAG(ENABLE_EXTENSIONS)
 extensions::ExtensionSystemQt* ProfileIODataQt::GetExtensionSystem()
 {
@@ -91,7 +84,6 @@ void ProfileIODataQt::initializeOnUIThread()
 {
     m_profileAdapter = m_profile->profileAdapter();
     DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-    m_resourceContext.reset(new content::ResourceContext());
     m_cookieDelegate = new CookieMonsterDelegateQt();
     m_cookieDelegate->setClient(m_profile->profileAdapter()->cookieStore());
     m_proxyConfigMonitor.reset(new ProxyConfigMonitor(m_profile->GetPrefs()));
@@ -152,15 +144,12 @@ void ProfileIODataQt::resetNetworkContext()
     Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
     Q_ASSERT(m_clearHttpCacheState != Removing);
     setFullConfiguration();
-    m_profile->ForEachLoadedStoragePartition(
-            base::BindRepeating([](ProfileIODataQt *profileData,
-                                   content::StoragePartition *storage) {
-                storage->SetNetworkContextCreatedObserver(profileData);
-
-                auto storage_impl = static_cast<content::StoragePartitionImpl *>(storage);
-                storage_impl->ResetURLLoaderFactories();
-                storage_impl->ResetNetworkContext();
-            }, this));
+    m_profile->ForEachLoadedStoragePartition([this](content::StoragePartition *storage) {
+        storage->SetNetworkContextCreatedObserver(this);
+        auto storage_impl = static_cast<content::StoragePartitionImpl *>(storage);
+        storage_impl->ResetURLLoaderFactories();
+        storage_impl->ResetNetworkContext();
+    });
 }
 
 void ProfileIODataQt::OnNetworkContextCreated(content::StoragePartition *storage)
@@ -174,12 +163,10 @@ void ProfileIODataQt::OnNetworkContextCreated(content::StoragePartition *storage
 
     bool pendingReset = false;
     m_profile->ForEachLoadedStoragePartition(
-            base::BindRepeating([](bool *pendingReset,
-                                   ProfileIODataQt *profileData,
-                                   content::StoragePartition *storage) {
-                if (storage->GetNetworkContextCreatedObserver() == profileData)
-                    *pendingReset = true;
-            }, &pendingReset, this));
+            [&pendingReset, this](content::StoragePartition *storage) {
+                if (storage->GetNetworkContextCreatedObserver() == this)
+                    pendingReset = true;
+            });
 
     if (pendingReset)
         return;
diff --git a/src/core/profile_io_data_qt.h b/src/core/profile_io_data_qt.h
index 0d032e4dcfc..a871307d70f 100644
--- a/src/core/profile_io_data_qt.h
+++ b/src/core/profile_io_data_qt.h
@@ -20,10 +20,6 @@ namespace mojom {
 class CertVerifierCreationParams;
 }}
 
-namespace content {
-class ResourceContext;
-}
-
 namespace extensions {
 class ExtensionSystemQt;
 }
@@ -66,7 +62,6 @@ class ProfileIODataQt : public content::StoragePartition::NetworkContextCreatedO
     virtual ~ProfileIODataQt();
 
     QPointer<ProfileAdapter> profileAdapter();
-    content::ResourceContext *resourceContext();
 #if BUILDFLAG(ENABLE_EXTENSIONS)
     extensions::ExtensionSystemQt* GetExtensionSystem();
 #endif // BUILDFLAG(ENABLE_EXTENSIONS)
@@ -104,7 +99,6 @@ class ProfileIODataQt : public content::StoragePartition::NetworkContextCreatedO
     void removeBrowsingDataRemoverObserver();
 
     ProfileQt *m_profile;
-    std::unique_ptr<content::ResourceContext> m_resourceContext;
     scoped_refptr<CookieMonsterDelegateQt> m_cookieDelegate;
     QPointer<ProfileAdapter> m_profileAdapter; // never dereferenced in IO thread and it is passed by qpointer
     ProfileAdapter::PersistentCookiesPolicy m_persistentCookiesPolicy;
diff --git a/src/core/profile_qt.cpp b/src/core/profile_qt.cpp
index d8a6c191cb2..c54e8485b49 100644
--- a/src/core/profile_qt.cpp
+++ b/src/core/profile_qt.cpp
@@ -116,11 +116,6 @@ bool ProfileQt::IsOffTheRecord()
     return m_profileAdapter->isOffTheRecord();
 }
 
-content::ResourceContext *ProfileQt::GetResourceContext()
-{
-    return m_profileIOData->resourceContext();
-}
-
 content::DownloadManagerDelegate *ProfileQt::GetDownloadManagerDelegate()
 {
     return m_profileAdapter->downloadManagerDelegate();
diff --git a/src/core/profile_qt.h b/src/core/profile_qt.h
index 4865632559e..a267efbc91b 100644
--- a/src/core/profile_qt.h
+++ b/src/core/profile_qt.h
@@ -40,7 +40,6 @@ class ProfileQt : public Profile
     base::FilePath GetPath() override;
     bool IsOffTheRecord() override;
 
-    content::ResourceContext *GetResourceContext() override;
     content::DownloadManagerDelegate *GetDownloadManagerDelegate() override;
     content::BrowserPluginGuestManager *GetGuestManager() override;
     storage::SpecialStoragePolicy *GetSpecialStoragePolicy() override;
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 81817442ae1..98d0471c1d2 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -21,7 +21,6 @@
 #include "content/browser/renderer_host/frame_tree.h"
 #include "content/browser/renderer_host/frame_tree_node.h"
 #include "content/browser/renderer_host/cursor_manager.h"
-#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
 #include "content/browser/renderer_host/render_frame_host_impl.h"
 #include "content/browser/renderer_host/render_view_host_delegate.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
@@ -29,6 +28,7 @@
 #include "content/browser/renderer_host/ui_events_helper.h"
 #include "content/common/content_switches_internal.h"
 #include "content/common/cursors/webcursor.h"
+#include "content/common/input/synthetic_gesture_target.h"
 #include "content/public/browser/web_contents.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/base/cursor/cursor.h"
@@ -160,6 +160,8 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget
                                        &m_delegatedFrameHostClient,
                                        true /* should_register_frame_sink_id */));
 
+    m_delegatedFrameHost->SetIsFrameSinkIdOwner(true);
+
     content::ImageTransportFactory *imageTransportFactory = content::ImageTransportFactory::GetInstance();
     ui::ContextFactory *contextFactory = imageTransportFactory->GetContextFactory();
     m_uiCompositor.reset(new FlingingCompositor(
@@ -916,8 +918,7 @@ void RenderWidgetHostViewQt::WheelEventAck(const blink::WebMouseWheelEvent &even
 }
 
 void RenderWidgetHostViewQt::GestureEventAck(const blink::WebGestureEvent &event,
-                                             blink::mojom::InputEventResultState ack_result,
-                                             blink::mojom::ScrollResultDataPtr scroll_result_data)
+                                             blink::mojom::InputEventResultState ack_result)
 {
     // Forward unhandled scroll events back as wheel events
     if (event.GetType() != blink::WebInputEvent::Type::kGestureScrollUpdate)
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index 43cff430bc8..49c1125fc26 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -95,8 +95,7 @@ class RenderWidgetHostViewQt
     void WheelEventAck(const blink::WebMouseWheelEvent &event,
                        blink::mojom::InputEventResultState ack_result) override;
     void GestureEventAck(const blink::WebGestureEvent &event,
-                         blink::mojom::InputEventResultState ack_result,
-                         blink::mojom::ScrollResultDataPtr scroll_result_data) override;
+                         blink::mojom::InputEventResultState ack_result) override;
     content::MouseWheelPhaseHandler *GetMouseWheelPhaseHandler() override;
     viz::ScopedSurfaceIdAllocator DidUpdateVisualProperties(const cc::RenderFrameMetadata &metadata) override;
     void OnDidUpdateVisualPropertiesComplete(const cc::RenderFrameMetadata &metadata);
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp
index b82c0fb0355..0622fc27e13 100644
--- a/src/core/renderer/content_renderer_client_qt.cpp
+++ b/src/core/renderer/content_renderer_client_qt.cpp
@@ -11,7 +11,6 @@
 #include "web_engine_library_info.h"
 
 #include "base/task/sequenced_task_runner.h"
-#include "components/autofill/content/renderer/autofill_agent.h"
 #include "components/autofill/content/renderer/password_autofill_agent.h"
 #include "components/autofill/content/renderer/password_generation_agent.h"
 #include "components/cdm/renderer/external_clear_key_key_system_info.h"
@@ -37,6 +36,7 @@
 #include "third_party/blink/public/platform/web_url_error.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/base/webui/jstemplate_builder.h"
+#include "ui/base/webui/web_ui_util.h"
 
 #if QT_CONFIG(webengine_spellchecker)
 #include "components/spellcheck/renderer/spellcheck.h"
@@ -178,7 +178,7 @@ void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame *render_fr
     new QtWebEngineCore::ContentSettingsObserverQt(render_frame);
 
 #if QT_CONFIG(webengine_spellchecker)
-    new SpellCheckProvider(render_frame, m_spellCheck.data(), this);
+    new SpellCheckProvider(render_frame, m_spellCheck.data());
 #endif
 #if QT_CONFIG(webengine_printing_and_pdf)
     new printing::PrintRenderFrameHelper(render_frame, base::WrapUnique(new PrintWebViewHelperDelegateQt()));
@@ -188,9 +188,8 @@ void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame *render_fr
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
     associated_interfaces->AddInterface<extensions::mojom::MimeHandlerViewContainerManager>(
-                base::BindRepeating(
-                    &extensions::MimeHandlerViewContainerManager::BindReceiver,
-                    render_frame->GetRoutingID()));
+            base::BindRepeating(&extensions::MimeHandlerViewContainerManager::BindReceiver,
+                                base::Unretained(render_frame)));
 
     auto registry = std::make_unique<service_manager::BinderRegistry>();
     ExtensionsRendererClientQt::GetInstance()->RenderFrameCreated(render_frame, render_frame_observer->registry());
@@ -201,8 +200,12 @@ void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame *render_fr
     auto password_generation_agent =
             std::make_unique<autofill::PasswordGenerationAgent>(render_frame, password_autofill_agent.get(), associated_interfaces);
 
-    new autofill::AutofillAgent(render_frame, std::move(password_autofill_agent), std::move(password_generation_agent),
-                                associated_interfaces);
+    new autofill::AutofillAgent(
+            render_frame,
+            { autofill::AutofillAgent::UsesKeyboardAccessoryForSuggestions(false),
+              autofill::AutofillAgent::ExtractAllDatalists(false) },
+            std::move(password_autofill_agent), std::move(password_generation_agent),
+            associated_interfaces);
 }
 
 void ContentRendererClientQt::WebViewCreated(blink::WebView *web_view,
@@ -302,13 +305,13 @@ void ContentRendererClientQt::GetNavigationErrorStringsInternal(content::RenderF
         if (template_html.empty())
             NOTREACHED() << "unable to load template. ID: " << resourceId;
         else // "t" is the id of the templates root node.
-            *errorHtml = webui::GetTemplatesHtml(template_html, errorPageState.strings, "t");
+            *errorHtml = webui::GetLocalizedHtml(template_html, errorPageState.strings);
     }
 }
 
-uint64_t ContentRendererClientQt::VisitedLinkHash(const char *canonicalUrl, size_t length)
+uint64_t ContentRendererClientQt::VisitedLinkHash(std::string_view canonicalUrl)
 {
-    return m_visitedLinkReader->ComputeURLFingerprint(canonicalUrl, length);
+    return m_visitedLinkReader->ComputeURLFingerprint(canonicalUrl);
 }
 
 bool ContentRendererClientQt::IsLinkVisited(uint64_t linkHash)
@@ -354,8 +357,8 @@ void AppendParams(const std::vector<content::WebPluginMimeType::Param> &addition
         values[existing_size + i] = blink::WebString::FromUTF16(additional_params[i].value);
     }
 
-    existing_names->Swap(names);
-    existing_values->Swap(values);
+    existing_names->swap(names);
+    existing_values->swap(values);
 }
 #endif  // BUILDFLAG(ENABLE_PLUGINS)
 
diff --git a/src/core/renderer/content_renderer_client_qt.h b/src/core/renderer/content_renderer_client_qt.h
index b2231f00acd..8151c9710fe 100644
--- a/src/core/renderer/content_renderer_client_qt.h
+++ b/src/core/renderer/content_renderer_client_qt.h
@@ -66,7 +66,7 @@ class ContentRendererClientQt
                                             int http_status,
                                             content::mojom::AlternativeErrorPageOverrideInfoPtr alternative_error_page_info,
                                             std::string *error_html)  override;
-    uint64_t VisitedLinkHash(const char *canonical_url, size_t length) override;
+    uint64_t VisitedLinkHash(std::string_view canonical_url) override;
     bool IsLinkVisited(uint64_t linkHash) override;
     std::unique_ptr<blink::WebPrescientNetworking> CreatePrescientNetworking(content::RenderFrame *render_frame) override;
     void GetSupportedKeySystems(media::GetSupportedKeySystemsCB cb) override;
diff --git a/src/core/renderer/content_settings_observer_qt.cpp b/src/core/renderer/content_settings_observer_qt.cpp
index 3e3c159f516..c78f53d8a84 100644
--- a/src/core/renderer/content_settings_observer_qt.cpp
+++ b/src/core/renderer/content_settings_observer_qt.cpp
@@ -39,6 +39,7 @@ ContentSettingsObserverQt::ContentSettingsObserverQt(content::RenderFrame *rende
 
 ContentSettingsObserverQt::~ContentSettingsObserverQt() {}
 
+#if BUILDFLAG(CONTENT_ENABLE_LEGACY_IPC)
 bool ContentSettingsObserverQt::OnMessageReceived(const IPC::Message &message)
 {
     bool handled = true;
@@ -49,6 +50,7 @@ bool ContentSettingsObserverQt::OnMessageReceived(const IPC::Message &message)
 
     return handled;
 }
+#endif
 
 void ContentSettingsObserverQt::DidCommitProvisionalLoad(ui::PageTransition /*transition*/)
 {
@@ -83,11 +85,12 @@ void ContentSettingsObserverQt::AllowStorageAccess(StorageType storage_type,
 
     // Verify there are no duplicate insertions.
     DCHECK(inserted);
-
+#if BUILDFLAG(CONTENT_ENABLE_LEGACY_IPC)
     Send(new QtWebEngineHostMsg_RequestStorageAccessAsync(routing_id(), m_currentRequestId,
                                                           url::Origin(frame->GetSecurityOrigin()).GetURL(),
                                                           url::Origin(frame->Top()->GetSecurityOrigin()).GetURL(),
                                                           int(storage_type)));
+#endif
 }
 
 bool ContentSettingsObserverQt::AllowStorageAccessSync(StorageType storage_type)
@@ -105,9 +108,11 @@ bool ContentSettingsObserverQt::AllowStorageAccessSync(StorageType storage_type)
     }
 
     bool result = false;
+#if BUILDFLAG(CONTENT_ENABLE_LEGACY_IPC)
     Send(new QtWebEngineHostMsg_AllowStorageAccess(routing_id(), url::Origin(frame->GetSecurityOrigin()).GetURL(),
                                                    url::Origin(frame->Top()->GetSecurityOrigin()).GetURL(),
                                                    int(storage_type), &result));
+#endif
     if (sameOrigin)
         m_cachedStoragePermissions[key] = result;
     return result;
diff --git a/src/core/renderer/content_settings_observer_qt.h b/src/core/renderer/content_settings_observer_qt.h
index 415d0b6b739..f843c61ee38 100644
--- a/src/core/renderer/content_settings_observer_qt.h
+++ b/src/core/renderer/content_settings_observer_qt.h
@@ -9,6 +9,7 @@
 #define CONTENT_SETTINGS_OBSERVER_QT_H
 
 #include "base/containers/flat_map.h"
+#include "content/common/buildflags.h"
 #include "content/public/renderer/render_frame_observer.h"
 #include "content/public/renderer/render_frame_observer_tracker.h"
 #include "third_party/blink/public/platform/web_content_settings_client.h"
@@ -33,7 +34,9 @@ class ContentSettingsObserverQt
 
 private:
     // RenderFrameObserver implementation:
+#if BUILDFLAG(CONTENT_ENABLE_LEGACY_IPC)
     bool OnMessageReceived(const IPC::Message &message) override;
+#endif
     void DidCommitProvisionalLoad(ui::PageTransition transition) override;
     void OnDestruct() override;
 
diff --git a/src/core/renderer/extensions/extensions_renderer_client_qt.cpp b/src/core/renderer/extensions/extensions_renderer_client_qt.cpp
index f201e645795..9db6bbe3627 100644
--- a/src/core/renderer/extensions/extensions_renderer_client_qt.cpp
+++ b/src/core/renderer/extensions/extensions_renderer_client_qt.cpp
@@ -31,6 +31,7 @@
 #include "extensions/renderer/extensions_render_frame_observer.h"
 #include "extensions/renderer/renderer_extension_registry.h"
 #include "extensions/renderer/script_context.h"
+#include "extensions/renderer/extensions_renderer_api_provider.h"
 #include "third_party/blink/public/platform/web_url.h"
 #include "third_party/blink/public/web/web_plugin_params.h"
 
@@ -108,7 +109,9 @@ void ExtensionsRendererClientQt::RenderThreadStarted()
 {
     content::RenderThread *thread = content::RenderThread::Get();
     if (!extension_dispatcher_)
-        extension_dispatcher_.reset(new extensions::Dispatcher(std::make_unique<ExtensionsDispatcherDelegateQt>()));
+        extension_dispatcher_.reset(new extensions::Dispatcher(
+                std::make_unique<ExtensionsDispatcherDelegateQt>(),
+                std::vector<std::unique_ptr<extensions::ExtensionsRendererAPIProvider>>()));
     extension_dispatcher_->OnRenderThreadStarted(thread);
     permissions_policy_delegate_.reset(new RendererPermissionsPolicyDelegateQt(extension_dispatcher_.get()));
     resource_request_policy_.reset(new extensions::ResourceRequestPolicyQt(extension_dispatcher_.get()));
diff --git a/src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp b/src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp
index 06fd4f71f96..4d25be12a27 100644
--- a/src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp
+++ b/src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp
@@ -22,11 +22,11 @@ namespace QtWebEngineCore {
 // static
 gin::WrapperInfo LoadablePluginPlaceholderQt::kWrapperInfo = {gin::kEmbedderNativeGin};
 
-LoadablePluginPlaceholderQt::LoadablePluginPlaceholderQt(content::RenderFrame* render_frame,
-                                                         const blink::WebPluginParams& params,
-                                                         const std::string& html_data,
-                                                         const std::u16string& title)
-    : plugins::LoadablePluginPlaceholder(render_frame, params, html_data)
+LoadablePluginPlaceholderQt::LoadablePluginPlaceholderQt(content::RenderFrame *render_frame,
+                                                         const blink::WebPluginParams &params,
+                                                         const std::string &html_data,
+                                                         const std::u16string &title)
+    : plugins::LoadablePluginPlaceholder(render_frame, params)
 {}
 
 LoadablePluginPlaceholderQt::~LoadablePluginPlaceholderQt()
diff --git a/src/core/renderer/render_frame_observer_qt.cpp b/src/core/renderer/render_frame_observer_qt.cpp
index e6489eefbb2..03fb0d9e881 100644
--- a/src/core/renderer/render_frame_observer_qt.cpp
+++ b/src/core/renderer/render_frame_observer_qt.cpp
@@ -51,7 +51,7 @@ bool RenderFrameObserverQt::OnAssociatedInterfaceRequestForFrame(const std::stri
     return m_associated_interfaces.TryBindInterface(interface_name, handle);
 }
 
-void RenderFrameObserverQt::WillDetach()
+void RenderFrameObserverQt::WillDetach(blink::DetachReason reason)
 {
     m_isFrameDetached = true;
 }
diff --git a/src/core/renderer/render_frame_observer_qt.h b/src/core/renderer/render_frame_observer_qt.h
index 8cab3bd9a6c..c3a1dd8ba1f 100644
--- a/src/core/renderer/render_frame_observer_qt.h
+++ b/src/core/renderer/render_frame_observer_qt.h
@@ -34,7 +34,7 @@ class RenderFrameObserverQt
         const std::string &interface_name,
         mojo::ScopedInterfaceEndpointHandle *handle) override;
     void OnDestruct() override;
-    void WillDetach() override;
+    void WillDetach(blink::DetachReason detach_reason) override;
 
     bool isFrameDetached() const;
 
diff --git a/src/core/renderer/user_resource_controller.cpp b/src/core/renderer/user_resource_controller.cpp
index eff304981c5..82579ea7d79 100644
--- a/src/core/renderer/user_resource_controller.cpp
+++ b/src/core/renderer/user_resource_controller.cpp
@@ -110,7 +110,7 @@ class UserResourceController::RenderFrameObserverHelper
     void DidCommitProvisionalLoad(ui::PageTransition transition) override;
     void DidDispatchDOMContentLoadedEvent() override;
     void DidFinishLoad() override;
-    void WillDetach() override;
+    void WillDetach(blink::DetachReason detach_reason) override;
     void OnDestruct() override;
     void AddScript(const QtWebEngineCore::UserScriptData &data) override;
     void RemoveScript(const QtWebEngineCore::UserScriptData &data) override;
@@ -231,7 +231,8 @@ void UserResourceController::RenderFrameObserverHelper::DidFinishLoad()
                                QtWebEngineCore::UserScriptData::AfterLoad));
 }
 
-void UserResourceController::RenderFrameObserverHelper::WillDetach()
+void UserResourceController::RenderFrameObserverHelper::WillDetach(
+        blink::DetachReason detach_reason)
 {
     m_runner.reset();
 }
diff --git a/src/core/tools/qwebengine_convert_dict/CMakeLists.txt b/src/core/tools/qwebengine_convert_dict/CMakeLists.txt
index 5e8a1de143e..fcc11bdcb8c 100644
--- a/src/core/tools/qwebengine_convert_dict/CMakeLists.txt
+++ b/src/core/tools/qwebengine_convert_dict/CMakeLists.txt
@@ -11,6 +11,9 @@ if(QT_FEATURE_webengine_spellchecker AND NOT CMAKE_CROSSCOMPILING)
         INCLUDE_DIRECTORIES
             ../../../3rdparty/chromium/third_party/abseil-cpp
     )
+    if(MSVC AND NOT CLANG)
+        target_compile_options(${dict_target_name} PRIVATE "/Zc:preprocessor")
+    endif()
     if(COMMAND qt_internal_return_unless_building_tools)
         qt_internal_return_unless_building_tools()
     endif()
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 70ee07cbb18..c2cd6981ab3 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -794,7 +794,9 @@ void WebContentsDelegateQt::BeforeUnloadFired(content::WebContents *tab, bool pr
         m_viewClient->windowCloseRejected();
 }
 
-bool WebContentsDelegateQt::CheckMediaAccessPermission(content::RenderFrameHost *, const GURL& security_origin, blink::mojom::MediaStreamType type)
+bool WebContentsDelegateQt::CheckMediaAccessPermission(content::RenderFrameHost *,
+                                                       const url::Origin &security_origin,
+                                                       blink::mojom::MediaStreamType type)
 {
     switch (type) {
     case blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE:
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index df9b5e3e802..899d46cd0c6 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -106,7 +106,9 @@ class WebContentsDelegateQt : public content::WebContentsDelegate
     void UpdateTargetURL(content::WebContents* source, const GURL& url) override;
     void RequestToLockMouse(content::WebContents *web_contents, bool user_gesture, bool last_unlocked_by_target) override;
     void BeforeUnloadFired(content::WebContents* tab, bool proceed, bool* proceed_to_fire_unload) override;
-    bool CheckMediaAccessPermission(content::RenderFrameHost* render_frame_host, const GURL& security_origin, blink::mojom::MediaStreamType type) override;
+    bool CheckMediaAccessPermission(content::RenderFrameHost *render_frame_host,
+                                    const url::Origin &security_origin,
+                                    blink::mojom::MediaStreamType type) override;
     void RegisterProtocolHandler(content::RenderFrameHost* frame_host, const std::string& protocol, const GURL& url, bool user_gesture) override;
     void UnregisterProtocolHandler(content::RenderFrameHost* frame_host, const std::string& protocol, const GURL& url, bool user_gesture) override;
     bool TakeFocus(content::WebContents *source, bool reverse) override;
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index e860e96b44d..50821fa984e 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -837,7 +837,7 @@ static void initializeFeatureList(base::CommandLine *commandLine, std::vector<st
 
     commandLine->AppendSwitchASCII(switches::kEnableFeatures, enableFeaturesString);
     commandLine->AppendSwitchASCII(switches::kDisableFeatures, disableFeaturesString);
-    base::FeatureList::InitializeInstance(enableFeaturesString, disableFeaturesString);
+    base::FeatureList::InitInstance(enableFeaturesString, disableFeaturesString);
 }
 
 WebEngineContext::WebEngineContext()
diff --git a/tests/auto/quick/qmltests/data/tst_datalist.qml b/tests/auto/quick/qmltests/data/tst_datalist.qml
index f739639b2b3..1e5a7ad6b86 100644
--- a/tests/auto/quick/qmltests/data/tst_datalist.qml
+++ b/tests/auto/quick/qmltests/data/tst_datalist.qml
@@ -105,10 +105,13 @@ TestWebEngineView {
             keyClick(Qt.Key_Escape);
             tryVerify(function() { return listView() == null; });
 
-            // Key Down should open the popup and select the first suggestion.
+            // The first Key Down opens the popup.
             keyClick(Qt.Key_Down);
             tryVerify(function() { return listView() != null; });
-            compare(listView().currentIndex, 0);
+
+            // The second Key Down selects the first suggestion.
+            keyClick(Qt.Key_Down);
+            tryCompare(listView(), "currentIndex", 0);
             verify(listView().currentItem);
         }
 
@@ -120,10 +123,13 @@ TestWebEngineView {
             // Make sure there is no open popup yet.
             verify(!listView());
 
-            // Key Down should open the popup and select the first suggestion.
+            // The first Key Down opens the popup.
             keyClick(Qt.Key_Down);
             tryVerify(function() { return listView() != null; });
-            compare(listView().currentIndex, 0);
+
+            // The second Key Down selects the first suggestion.
+            keyClick(Qt.Key_Down);
+            tryCompare(listView(), "currentIndex", 0);
 
             // Test keyboard navigation in list.
             keyClick(Qt.Key_Up);
diff --git a/tests/auto/widgets/accessibility/tst_accessibility.cpp b/tests/auto/widgets/accessibility/tst_accessibility.cpp
index 1579b61e2fe..0a65e7a9566 100644
--- a/tests/auto/widgets/accessibility/tst_accessibility.cpp
+++ b/tests/auto/widgets/accessibility/tst_accessibility.cpp
@@ -94,13 +94,13 @@ void tst_Accessibility::noPage()
 void tst_Accessibility::hierarchy()
 {
     QWebEngineView webView;
+    QSignalSpy spyFinished(&webView, &QWebEngineView::loadFinished);
     webView.setHtml("<html><body>" \
         "Hello world" \
         "<input type='text' value='some text'></input>" \
         "</body></html>");
     webView.show();
-    QSignalSpy spyFinished(&webView, &QWebEngineView::loadFinished);
-    QVERIFY(spyFinished.wait());
+    QTRY_VERIFY(spyFinished.size());
 
     QAccessibleInterface *view = QAccessible::queryAccessibleInterface(&webView);
     QVERIFY(view);
@@ -581,28 +581,27 @@ void tst_Accessibility::crossTreeParent()
     webView.show();
     QVERIFY(spyFinished.wait());
     QAccessibleInterface *view = QAccessible::queryAccessibleInterface(&webView);
-    QAccessibleInterface *document = view->child(0);
-    QCOMPARE(document->role(), QAccessible::WebDocument);
-    QTRY_COMPARE(document->childCount(), 1);
-    QAccessibleInterface *p = document->child(0);
+    QCOMPARE(view->child(0)->role(), QAccessible::WebDocument);
+    QTRY_COMPARE(view->child(0)->childCount(), 1);
+    QAccessibleInterface *p = view->child(0)->child(0);
     QVERIFY(p);
-    QCOMPARE(p->parent(), document);
+    QCOMPARE(p->parent(), view->child(0));
     p = p->child(0);
     QVERIFY(p);
     QCOMPARE(p->role(), QAccessible::WebDocument);
-    QCOMPARE(p->parent()->parent(), document);
+    QCOMPARE(p->parent()->parent(), view->child(0));
     QTRY_COMPARE(p->childCount(), 1);
     p = p->child(0);
     QVERIFY(p);
     QAccessibleInterface *subdocument = p;
     QCOMPARE(p->role(), QAccessible::WebDocument);
-    QCOMPARE(p->parent()->parent()->parent(), document);
+    QCOMPARE(p->parent()->parent()->parent(), view->child(0));
     p = p->child(0);
     QVERIFY(p);
     QVERIFY(p->object());
     QCOMPARE(p->role(), QAccessible::Paragraph);
     QCOMPARE(p->parent(), subdocument);
-    QCOMPARE(p->parent()->parent()->parent()->parent(), document);
+    QCOMPARE(p->parent()->parent()->parent()->parent(), view->child(0));
     QCOMPARE(p->parent()->parent()->parent()->parent()->parent(), view);
     QCOMPARE(p->object()->objectName(), QStringLiteral("my_id"));
 }
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index f4ed06e147d..03acd69feb6 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -2947,8 +2947,8 @@ void tst_QWebEngineView::imeJSInputEvents()
 
     QTRY_COMPARE(logLines().size(), 4);
     QCOMPARE(logLines()[0], QStringLiteral("[object CompositionEvent] compositionstart "));
-    QCOMPARE(logLines()[1], QStringLiteral("[object InputEvent] beforeinput preedit"));
-    QCOMPARE(logLines()[2], QStringLiteral("[object CompositionEvent] compositionupdate preedit"));
+    QCOMPARE(logLines()[1], QStringLiteral("[object CompositionEvent] compositionupdate preedit"));
+    QCOMPARE(logLines()[2], QStringLiteral("[object InputEvent] beforeinput preedit"));
     QCOMPARE(logLines()[3], QStringLiteral("[object InputEvent] input preedit"));
 
     {
@@ -2960,8 +2960,8 @@ void tst_QWebEngineView::imeJSInputEvents()
     }
 
     QTRY_COMPARE(logLines().size(), 9);
-    QCOMPARE(logLines()[4], QStringLiteral("[object InputEvent] beforeinput commit"));
-    QCOMPARE(logLines()[5], QStringLiteral("[object CompositionEvent] compositionupdate commit"));
+    QCOMPARE(logLines()[4], QStringLiteral("[object CompositionEvent] compositionupdate commit"));
+    QCOMPARE(logLines()[5], QStringLiteral("[object InputEvent] beforeinput commit"));
     QCOMPARE(logLines()[6], QStringLiteral("[object TextEvent] textInput commit"));
     QCOMPARE(logLines()[7], QStringLiteral("[object InputEvent] input commit"));
     QCOMPARE(logLines()[8], QStringLiteral("[object CompositionEvent] compositionend commit"));
@@ -2979,8 +2979,8 @@ void tst_QWebEngineView::imeJSInputEvents()
 
     QTRY_COMPARE(logLines().size(), 4);
     QCOMPARE(logLines()[0], QStringLiteral("[object CompositionEvent] compositionstart "));
-    QCOMPARE(logLines()[1], QStringLiteral("[object InputEvent] beforeinput preedit"));
-    QCOMPARE(logLines()[2], QStringLiteral("[object CompositionEvent] compositionupdate preedit"));
+    QCOMPARE(logLines()[1], QStringLiteral("[object CompositionEvent] compositionupdate preedit"));
+    QCOMPARE(logLines()[2], QStringLiteral("[object InputEvent] beforeinput preedit"));
     QCOMPARE(logLines()[3], QStringLiteral("[object InputEvent] input preedit"));
 
     {
@@ -2991,8 +2991,8 @@ void tst_QWebEngineView::imeJSInputEvents()
     }
 
     QTRY_COMPARE(logLines().size(), 9);
-    QCOMPARE(logLines()[4], QStringLiteral("[object InputEvent] beforeinput "));
-    QCOMPARE(logLines()[5], QStringLiteral("[object CompositionEvent] compositionupdate "));
+    QCOMPARE(logLines()[4], QStringLiteral("[object CompositionEvent] compositionupdate "));
+    QCOMPARE(logLines()[5], QStringLiteral("[object InputEvent] beforeinput "));
     QCOMPARE(logLines()[6], QStringLiteral("[object TextEvent] textInput "));
     QCOMPARE(logLines()[7], QStringLiteral("[object InputEvent] input null"));
     QCOMPARE(logLines()[8], QStringLiteral("[object CompositionEvent] compositionend "));
@@ -3894,10 +3894,13 @@ void tst_QWebEngineView::datalist()
     QTest::keyClick(view.windowHandle(), Qt::Key_Escape);
     QTRY_VERIFY(!listView());
 
-    // Key Down should open the popup and select the first suggestion.
+    // The first Key Down opens the popup.
     QTest::keyClick(view.windowHandle(), Qt::Key_Down);
     QTRY_VERIFY(listView());
-    QCOMPARE(listView()->currentIndex().row(), 0);
+
+    // The second Key Down selects the first suggestion.
+    QTest::keyClick(view.windowHandle(), Qt::Key_Down);
+    QTRY_COMPARE(listView()->currentIndex().row(), 0);
 
     // Test keyboard navigation in list.
     QTest::keyClick(view.windowHandle(), Qt::Key_Up);

From 999dca5dc80ad3fe63d2f1052d18a27a018718bb Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Tue, 4 Jun 2024 09:46:44 +0200
Subject: [PATCH 011/356] Update Chromium for 122-based

Blacklist dynamicFrame faliling test.

Task-number: QTBUG-126049
Change-Id: I1bc03ce1987ed033d10322f1984c03e272e334b8
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit e23488c5d24eb383d61d53a84803a2925536b8fd)
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
---
 src/3rdparty                                | 2 +-
 tests/auto/widgets/qwebenginepage/BLACKLIST | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/3rdparty b/src/3rdparty
index f3033f5aa9b..6434c2d5827 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit f3033f5aa9be1e98096c55972166d0be6cb64920
+Subproject commit 6434c2d5827960f6a9ae839da3981b84965ac77e
diff --git a/tests/auto/widgets/qwebenginepage/BLACKLIST b/tests/auto/widgets/qwebenginepage/BLACKLIST
index 52def48d170..01d1ffe3d9b 100644
--- a/tests/auto/widgets/qwebenginepage/BLACKLIST
+++ b/tests/auto/widgets/qwebenginepage/BLACKLIST
@@ -13,3 +13,7 @@ macos
 
 [backgroundColor]
 macos
+
+[dynamicFrame]
+ubuntu-22.04
+

From f5f23448c17a34e497a6da818f26e72ef1b4c385 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Mon, 6 May 2024 12:52:38 +0200
Subject: [PATCH 012/356] Update snapshot filters and version for 122-based
 snapshot

Change-Id: I4cafb01aa2bc4f6e3dad21550a01256f31daadca
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit f3170e5b5207a320493194b7ad165478c6ebd547)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 tools/scripts/take_snapshot.py    | 5 +++++
 tools/scripts/version_resolver.py | 4 ++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/tools/scripts/take_snapshot.py b/tools/scripts/take_snapshot.py
index e312dd64c7a..2e2d3991716 100755
--- a/tools/scripts/take_snapshot.py
+++ b/tools/scripts/take_snapshot.py
@@ -188,6 +188,10 @@ def isInChromiumBlacklist(file_path):
               and not file_path.startswith('third_party/node/node_modules/js-tokens/')
               and not file_path.startswith('third_party/node/node_modules/jsesc/')
               and not file_path.startswith('third_party/node/node_modules/jsonschema/')
+              and not file_path.startswith('third_party/node/node_modules/@lit/reactive-element/')
+              and not file_path.startswith('third_party/node/node_modules/lit-element/')
+              and not file_path.startswith('third_party/node/node_modules/lit-html/')
+              and not file_path.startswith('third_party/node/node_modules/lit/')
               and not file_path.startswith('third_party/node/node_modules/lodash.camelcase/')
               and not file_path.startswith('third_party/node/node_modules/lodash.sortby/')
               and not file_path.startswith('third_party/node/node_modules/minimatch/')
@@ -271,6 +275,7 @@ def isInChromiumBlacklist(file_path):
             or '/fuzzer/' in file_path
             or '/fuzzers/' in file_path
             or '/fuzzing/' in file_path
+            and not file_path.endswith('internals_fuzzing.idl')
         ))
         or ('/test' in file_path
          and ('/testdata/' in file_path
diff --git a/tools/scripts/version_resolver.py b/tools/scripts/version_resolver.py
index 707524ef35d..9021d1e202e 100644
--- a/tools/scripts/version_resolver.py
+++ b/tools/scripts/version_resolver.py
@@ -43,8 +43,8 @@ def get_recursedeps(self):
         return self.local_scope["recursedeps"]
 
 
-chromium_version = '120.0.6099.272'
-chromium_branch = '6099'
+chromium_version = '122.0.6261.72'
+chromium_branch = '6261'
 ninja_version = 'v1.8.2'
 
 json_url = 'http://omahaproxy.appspot.com/all.json'

From 1ec6b541830c62eb390862b42f0e8cab5ad3410e Mon Sep 17 00:00:00 2001
From: Szabolcs David <davidsz@inf.u-szeged.hu>
Date: Fri, 17 May 2024 12:14:41 +0200
Subject: [PATCH 013/356] Revive push messaging

It crashes due to missing preferences. This patch isolates push message
related prefs and uses their 3rdparty registration functions where it's
possible - hoping to reduce their maintenance time in the future.

Correct a missing character in the docs.

Pick-to: 6.7
Change-Id: Ia713bdb16edef8bc535624ba61a47c9f5d7c4155
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit b5954b3d3d46e8825ce99a9a958c561a34d369f9)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/pref_service_adapter.cpp             | 29 ++++++++++---------
 .../doc/snippets/push-notifications/commands  |  2 +-
 2 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/src/core/pref_service_adapter.cpp b/src/core/pref_service_adapter.cpp
index ae7cf102bc4..d561cab4fbc 100644
--- a/src/core/pref_service_adapter.cpp
+++ b/src/core/pref_service_adapter.cpp
@@ -19,9 +19,12 @@
 #include "components/prefs/pref_service_factory.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/signin/internal/identity_manager/account_tracker_service.h"
-#include "components/signin/public/base/signin_pref_names.h"
+#include "components/signin/internal/identity_manager/gaia_cookie_manager_service.h"
+#include "components/signin/internal/identity_manager/primary_account_manager.h"
+#include "components/signin/internal/identity_manager/profile_oauth2_token_service.h"
 #include "components/user_prefs/user_prefs.h"
 #include "components/proxy_config/pref_proxy_config_tracker_impl.h"
+#include "chrome/browser/gcm/gcm_product_util.h"
 #include "chrome/common/pref_names.h"
 #include "extensions/buildflags/buildflags.h"
 #include "content/public/browser/browser_context.h"
@@ -84,16 +87,20 @@ void PrefServiceAdapter::setup(const ProfileAdapter &profileAdapter)
 #endif // QT_CONFIG(webengine_spellchecker)
     registry->RegisterBooleanPref(prefs::kShowInternalAccessibilityTree, false);
     registry->RegisterBooleanPref(prefs::kAccessibilityImageLabelsEnabled, false);
+
+    // chrome/browser/notifications
     registry->RegisterIntegerPref(prefs::kNotificationNextPersistentId, 10000);
+    // chrome/browser/push_messaging
     registry->RegisterDictionaryPref(prefs::kPushMessagingAppIdentifierMap);
-    registry->RegisterListPref(prefs::kAccountInfo);
-    registry->RegisterStringPref(prefs::kGoogleServicesLastSyncingUsername, std::string());
-    registry->RegisterStringPref(prefs::kGoogleServicesAccountId, std::string());
-    registry->RegisterBooleanPref(prefs::kGoogleServicesConsentedToSync, false);
-    registry->RegisterBooleanPref(prefs::kAutologinEnabled, true);
-    registry->RegisterListPref(prefs::kReverseAutologinRejectedEmailList);
-    registry->RegisterBooleanPref(prefs::kSigninAllowed, true);
-    registry->RegisterBooleanPref(prefs::kSignedInWithCredentialProvider, false);
+    // chrome/browser/gcm
+    gcm::RegisterPrefs(registry.get());
+
+    // signin
+    PrimaryAccountManager::RegisterProfilePrefs(registry.get());
+    ProfileOAuth2TokenService::RegisterProfilePrefs(registry.get());
+    GaiaCookieManagerService::RegisterPrefs(registry.get());
+    AccountTrackerService::RegisterPrefs(registry.get());
+
 #if defined(Q_OS_WIN)
     OSCrypt::RegisterLocalPrefs(registry.get());
 #endif
@@ -133,10 +140,6 @@ void PrefServiceAdapter::setup(const ProfileAdapter &profileAdapter)
     registry->RegisterDictionaryPref(prefs::kDevToolsSyncedPreferencesSyncDisabled);
     registry->RegisterDictionaryPref(prefs::kDevToolsSyncedPreferencesSyncEnabled);
 
-    registry->RegisterStringPref(prefs::kGoogleServicesSigninScopedDeviceId, std::string());
-    registry->RegisterStringPref(prefs::kGaiaCookieLastListAccountsData, std::string());
-    registry->RegisterStringPref(prefs::kGCMProductCategoryForSubtypes, std::string());
-
     {
         base::ScopedAllowBlocking allowBlock;
         m_prefService = factory.Create(registry);
diff --git a/src/webenginewidgets/doc/snippets/push-notifications/commands b/src/webenginewidgets/doc/snippets/push-notifications/commands
index aee9761c10f..077538e2e55 100644
--- a/src/webenginewidgets/doc/snippets/push-notifications/commands
+++ b/src/webenginewidgets/doc/snippets/push-notifications/commands
@@ -11,7 +11,7 @@ npm install web-push express
 //! [1]
 
 //! [2]
-./node_odules/.bin/web-push generate-vapid-keys
+./node_modules/.bin/web-push generate-vapid-keys
 //! [2]
 
 //! [3]

From 5583321d089d299f10452027e2e243507bf64a5e Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Tue, 11 Jun 2024 16:32:45 +0200
Subject: [PATCH 014/356] Update Chromium
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Submodule src/3rdparty 6434c2d5..b953fab5:
* Fix crash when cleaning up indexed database, debug MSVC
* Fix MSVC debug mode assertion in Viz
* ANGLE: Silence private data warnings when using Direct3D11 backing
* Disable DCHECK failure instrumentation in PendingTask destructor

Change-Id: Ibce1d5dde11c3a6f2ff3a35a187d289c134ab919
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
(cherry picked from commit 413eef173b24d6070b7bdf5131caa50ef839cd8d)
---
 src/3rdparty | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/3rdparty b/src/3rdparty
index 6434c2d5827..b953fab5b59 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit 6434c2d5827960f6a9ae839da3981b84965ac77e
+Subproject commit b953fab5b599be589a978c79735c62c35dad28b5

From 8912f84dc19f90c88f55b64f2840e2f86a087151 Mon Sep 17 00:00:00 2001
From: Anu Aliyas <anu.aliyas@qt.io>
Date: Wed, 22 May 2024 16:55:24 +0200
Subject: [PATCH 015/356] Report an error if system icu is enabled outside
 Linux and Android

The default value for the GN argument icu_use_data_file is true. If it
is true, it will try to load the external ICU data, and if the external
data file is not present, it will result in a runtime error. system icu
option only valid for linux and android. Added code to report configure
failure when using QT_FEATURE_webengine_system_icu=ON for unsupported
platforms

Fixes: QTBUG-125452
Pick-to: 6.7 6.6
Change-Id: I4db6edbd6e45fa216df27843084e21f993492f0e
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 7e6f28e544c3887245809b019392b26da6bb693e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 configure.cmake | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure.cmake b/configure.cmake
index 2d826e6ddc8..dedd11cff8b 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -315,7 +315,7 @@ qt_feature("webengine-system-re2" PRIVATE
 qt_feature("webengine-system-icu" PRIVATE
     LABEL "icu"
     AUTODETECT FALSE
-    CONDITION ICU_FOUND
+    CONDITION UNIX AND NOT APPLE AND ICU_FOUND
 )
 qt_feature("webengine-system-libwebp" PRIVATE
     LABEL "libwebp, libwebpmux and libwebpdemux"

From be07b12340af3ebd61d8b87755f5e9731276f1db Mon Sep 17 00:00:00 2001
From: Anu Aliyas <anu.aliyas@qt.io>
Date: Wed, 15 May 2024 11:46:36 +0200
Subject: [PATCH 016/356] Remove trial_comparison_cert_verifier_supported from
 GN argument list

The specified argument was removed as part of chromium change
https://chromium-review.googlesource.com/c/chromium/src/+/4834506 and
it is no longer need for 122 based chromium.

Change-Id: Ia20d7486f1e106b781d301ba83ce83248b7a1206
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 95e69c58cfa6264568c00112f3ae5c1f00a66b24)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/CMakeLists.txt | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index a359cc57f91..d43188813db 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -349,7 +349,6 @@ foreach(arch ${archs})
             devtools_skip_typecheck=false
             use_static_angle=true
             use_perfetto_client_library=false
-            trial_comparison_cert_verifier_supported=false
             enable_extensions_legacy_ipc=true
             enable_bound_session_credentials=false
         )

From 3439cacdbf76cbd52fd5328aef126ba51914f5a7 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Sat, 15 Jun 2024 21:38:15 +0000
Subject: [PATCH 017/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I94e76e11ff50c0d62c289dab505e302a25cbdb74
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 37198aaddc8..6703bb2ca2b 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: b241e3f8bc951dfbac152bbf58532170ed910756
+    ref: d021fd7cb13491ad30e52fd6ebbdb655860bf045
     required: true
   ../qtpositioning:
-    ref: edda8a2bba1e447ba08f977f8156d45f19cb0b72
+    ref: 49731b3ba22a38ab3a433fdb83f087896fb8d315
     required: false
   ../qttools:
-    ref: f7d623d562d55b75eef0a43e1045a5da8d7609fc
+    ref: 407ff594b7b4be74731f3e3a5b265b8f073d517a
     required: false
   ../qtwebchannel:
-    ref: 779185f6fa8e33bc183332c7e89b908904dea591
+    ref: e432e4c05cc94d1e35b74b832c71109340b75a3d
     required: false

From c6f0efbda04a53342030817d141122461baaea00 Mon Sep 17 00:00:00 2001
From: Szabolcs David <davidsz@inf.u-szeged.hu>
Date: Thu, 11 Apr 2024 14:41:53 +0200
Subject: [PATCH 018/356] Add V8 version to chrome://qt

Insert the required V8_VERSION_STRING among the template replacements.

Task-number: QTBUG-123500
Change-Id: I8310427300d20c5885ddbc2a5e39d8ec6bf31a26
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 97a8fd263c01d2091cbcc7a5aaa685ec708ebb84)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/net/version_ui_qt.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/core/net/version_ui_qt.cpp b/src/core/net/version_ui_qt.cpp
index 61a89596a2d..a49dea62aaa 100644
--- a/src/core/net/version_ui_qt.cpp
+++ b/src/core/net/version_ui_qt.cpp
@@ -9,12 +9,14 @@
 #include "chrome/browser/profiles/profile.h"
 #include "qtwebengine/grit/qt_webengine_resources.h"
 #include "services/network/public/cpp/content_security_policy/content_security_policy.h"
+#include "v8/include/v8-version-string.h"
 
 namespace {
 const char kQtWebEngineVersion[] = "qtwebengine_version";
 const char kQtWebEngineChromiumVersion[] = "qtwebengine_chromium_version";
 const char kQtWebEngineChromiumSecurityPatchVersion[] =
         "qtwebengine_chromium_security_patch_version";
+const char kQtWebEngineChromiumV8Version[] = "qtwebengine_chromium_v8_version";
 const char kCommandLine[] = "command_line";
 const char kQtVersionCSS[] = "qt_version.css";
 const char kQtLogo[] = "images/qt.png";
@@ -23,7 +25,6 @@ const char kQtWebEngineLogo[] = "images/qtwebengine.png";
 
 VersionUIQt::VersionUIQt(content::WebUI *web_ui) : content::WebUIController(web_ui)
 {
-
     Profile *profile = Profile::FromWebUI(web_ui);
     content::WebUIDataSource *html_source =
             content::WebUIDataSource::CreateAndAdd(profile, chrome::kChromeUIVersionQtHost);
@@ -39,6 +40,7 @@ VersionUIQt::VersionUIQt(content::WebUI *web_ui) : content::WebUIController(web_
     html_source->AddString(kQtWebEngineChromiumVersion, qWebEngineChromiumVersion());
     html_source->AddString(kQtWebEngineChromiumSecurityPatchVersion,
                            qWebEngineChromiumSecurityPatchVersion());
+    html_source->AddString(kQtWebEngineChromiumV8Version, V8_VERSION_STRING);
 #if BUILDFLAG(IS_WIN)
     html_source->AddString(
             kCommandLine,

From 70a07884c0868ad9972d5de61d41b0e1a2663426 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Wed, 12 Jun 2024 15:18:07 +0200
Subject: [PATCH 019/356] Fix build with no extensions

Match cmake file and fix linker issue:
"undefined symbol: PDFDocumentHelperClientQt"

Change-Id: Ie9ac1f8e0137b482a666349a4254419dab773d10
Reviewed-by: Szabolcs David <davidsz@inf.u-szeged.hu>
(cherry picked from commit a8e4c357253d655fe00f8d5dd78cc1ab89261a1d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/content_browser_client_qt.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index 6fec6a1e87b..c32bb3411b4 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -148,12 +148,11 @@
 #include "components/pdf/browser/pdf_navigation_throttle.h"
 #include "components/pdf/browser/pdf_url_loader_request_interceptor.h"
 #include "components/pdf/browser/pdf_document_helper.h"
-
-#include "printing/pdf_document_helper_client_qt.h"
 #endif
 
 #if BUILDFLAG(ENABLE_PDF) && BUILDFLAG(ENABLE_EXTENSIONS)
 #include "extensions/pdf_iframe_navigation_throttle_qt.h"
+#include "printing/pdf_document_helper_client_qt.h"
 #endif
 
 #include <QGuiApplication>
@@ -517,7 +516,7 @@ void ContentBrowserClientQt::RegisterAssociatedInterfaceBindersForRenderFrameHos
                                                                            std::move(receiver));
             },
             &rfh));
-#if BUILDFLAG(ENABLE_PDF)
+#if BUILDFLAG(ENABLE_PDF) && BUILDFLAG(ENABLE_EXTENSIONS)
     associated_registry.AddInterface<pdf::mojom::PdfService>(
                 base::BindRepeating(
                     [](content::RenderFrameHost *render_frame_host,

From 234b0a434d0d8ff0c0a3d62eb44b4969154af9b2 Mon Sep 17 00:00:00 2001
From: Szabolcs David <davidsz@inf.u-szeged.hu>
Date: Tue, 11 Jun 2024 14:57:32 +0200
Subject: [PATCH 020/356] Clarify the OTR nature of default
 QQuickWebEngineProfiles

Since the default profile is OTR now, this behavior needs more mention
in the documentation.

Task-number: QTBUG-126085
Change-Id: I26b5f05cc8c76982bc97deaecd0df835c8ad82fb
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
(cherry picked from commit 6716aacd51e09fdf5e9eb01663a0115adce33567)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 .../api/qquickwebengineprofile.cpp            | 19 +++++++++++++++++--
 .../tst_qquickwebengineview.cpp               |  3 ++-
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/src/webenginequick/api/qquickwebengineprofile.cpp b/src/webenginequick/api/qquickwebengineprofile.cpp
index d3373d0b9b7..0246eb64549 100644
--- a/src/webenginequick/api/qquickwebengineprofile.cpp
+++ b/src/webenginequick/api/qquickwebengineprofile.cpp
@@ -365,7 +365,7 @@ QQuickWebEngineScriptCollection *QQuickWebEngineProfilePrivate::getUserScripts()
     whether a profile is off-the-record.
 
     Each web engine view has an associated profile. Views that do not have a specific profile set
-    share a common default one.
+    share a common one, which is off-the-record by default.
 */
 
 /*!
@@ -404,7 +404,12 @@ QQuickWebEngineScriptCollection *QQuickWebEngineProfilePrivate::getUserScripts()
 */
 
 /*!
-    Constructs a new profile with the parent \a parent.
+    Constructs a new off-the-record profile with the parent \a parent.
+
+    An off-the-record profile leaves no record on the local machine, and has no
+    persistent data or cache. Thus, the HTTP cache can only be in memory and the
+    cookies can only be non-persistent. Trying to change these settings will
+    have no effect.
 */
 QQuickWebEngineProfile::QQuickWebEngineProfile(QObject *parent)
     : QObject(parent),
@@ -478,6 +483,11 @@ void QQuickWebEngineProfile::setStorageName(const QString &name)
     Whether the web engine profile is \e off-the-record.
     An off-the-record profile forces cookies, the HTTP cache, and other normally persistent data
     to be stored only in memory. Profile is off-the-record by default.
+
+    Changing a profile from \e off-the-record to disk-based behavior also requires setting a
+    proper storageName.
+
+    \sa storageName()
 */
 
 
@@ -487,6 +497,11 @@ void QQuickWebEngineProfile::setStorageName(const QString &name)
     Whether the web engine profile is \e off-the-record.
     An off-the-record profile forces cookies, the HTTP cache, and other normally persistent data
     to be stored only in memory. Profile is off-the-record by default.
+
+    Changing a profile from \e off-the-record to disk-based behavior also requires setting a
+    proper storageName.
+
+    \sa setStorageName()
 */
 
 bool QQuickWebEngineProfile::isOffTheRecord() const
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index dbfa1cb3350..cc514f87379 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -99,7 +99,8 @@ private Q_SLOTS:
 tst_QQuickWebEngineView::tst_QQuickWebEngineView()
 {
     QtWebEngineQuick::initialize();
-    QQuickWebEngineProfile::defaultProfile()->setOffTheRecord(true);
+
+    QVERIFY(QQuickWebEngineProfile::defaultProfile()->isOffTheRecord());
 
     m_testSourceDirPath = QDir(QT_TESTCASE_SOURCEDIR).canonicalPath();
     if (!m_testSourceDirPath.endsWith(QLatin1Char('/')))

From 33b9eece53f4d185b8a4360fb7a8a47fb606aded Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Fri, 14 Jun 2024 07:53:50 +0200
Subject: [PATCH 021/356] Update Chromium
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Submodule src/3rdparty b953fab5..e2c58970:
* Merge "Merge remote-tracking branch 'origin/upstream-master' into HEAD" into 122-based
* Merge remote-tracking branch 'origin/upstream-master' into HEAD
* FIXUP: Fix QtWebEngine build on Windows
* [Backport] IWYU: missing include for std::memcpy usage in bdict_reader.cc
* Remove use of dawn_version_file
* FIXUP: Fix enable_extensions=false builds
* Fix missing <string> include
* FIXUP: [Backport] CVE-2024-3914: Use after free in V8
* BASELINE: Update Chromium to 122.0.6261.171
* [Backport] Don't define CRYPTO_addc_* and CRYPTO_subc_* in C++
* FIXUP: Add rsp target writer
* [Backport] CVE-2024-4671: Use after free in Visuals
* [Backport] CVE-2024-4558: Use after free in ANGLE
* [Backport] CVE-2024-4368: Use after free in Dawn
* [Backport] CVE-2024-4331: Use after free in Picture In Picture
* [Backport] CVE-2024-3845: Inappropriate implementation in Network (2/2)
* [Backport] CVE-2024-3845: Inappropriate implementation in Network (1/2)
* [Backport] Security bug 327698060
* [Backport] CVE-2024-3914: Use after free in V8 (2/2)
* [Backport] CVE-2024-3914: Use after free in V8 (1/2)
* [Backport] Security bug 323898565
* [Backport] CVE-2024-4058: Type Confusion in ANGLE
* [Backport] Security bug 40940917
* [Backport] CVE-2024-3837: Use after free in QUIC
* [Backport] CVE-2024-3839: Out of bounds read in Fonts
* [Backport] Security bug 326521449
* [Backport] CVE-2024-3515: Use after free in Dawn
* [Backport] CVE-2024-3516: Heap buffer overflow in ANGLE
* [Backport] CVE-2024-3157: Out of bounds write in Compositing
* [Backport] Security bug 326349405
* [Backport] CVE-2024-3159: Out of bounds memory access in V8
* [Backport] CVE-2024-3156: Inappropriate implementation in V8.
* [Backport] Security bug 327183408
* [Backport] Security bug 329674887 (2/2)
* [Backport] Security bug 329674887 (1/2)
* [Backport] CVE-2024-2887: Type Confusion in WebAssembly
* [Backport] CVE-2024-2885: Use after free in Dawn
* [Backport] Security bug 41495984
* [Backport] Security bug 40066823
* [Backport] CVE-2024-2627: Use after free in Canvas
* [Backport] CVE-2024-2626: Out of bounds read in Swiftshader (2/2)
* [Backport] CVE-2024-2626: Out of bounds read in Swiftshader (1/2)
* [Backport] CVE-2024-2625: Object lifecycle issue in V8

Change-Id: Iea06fef7a54ee4377309251950847ec2ba5fb01c
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
(cherry picked from commit d2d13b886431ad0760ad2fcda363f16c1d26e93c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 CHROMIUM_VERSION                | 4 ++--
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index 8bdc0df63b6..39028d6d975 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
-Based on Chromium version:                                      118.0.5993.220
-Patched with security patches up to Chromium version:           122.0.6261.128
+Based on Chromium version:                                      122.0.6261.171
+Patched with security patches up to Chromium version:           124.0.6367.202
diff --git a/src/3rdparty b/src/3rdparty
index b953fab5b59..e2c589700c3 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit b953fab5b599be589a978c79735c62c35dad28b5
+Subproject commit e2c589700c312d35a503a15c30ea6432d77cbca2
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 50821fa984e..f969b0e8b9e 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1218,7 +1218,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "122.0.6261.128"; // FIXME: Remember to update
+    return "124.0.6367.202"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From e0a8072f164c20e19e761224bb13707e3cc147a3 Mon Sep 17 00:00:00 2001
From: Allan Sandfeld Jensen <allan.jensen@qt.io>
Date: Mon, 10 Jun 2024 12:50:15 +0200
Subject: [PATCH 022/356] Make ImageAnimationPolicy a scoped enum

Change-Id: I2c03c6d56d18f37e60b287c337c67718178fbb2b
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
(cherry picked from commit edcdccfa232f995f5fc738fc2655f21a30d24f46)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 .../quicknanobrowser/BrowserWindow.qml        | 14 +++++++-------
 .../simplebrowser/webview.cpp                 | 12 ++++++------
 src/core/api/qwebenginesettings.cpp           |  2 +-
 src/core/api/qwebenginesettings.h             | 10 +++++-----
 src/core/doc/src/qwebenginesettings_lgpl.qdoc | 14 +++++++-------
 src/core/web_engine_settings.cpp              | 16 +++++++++-------
 .../api/qquickwebenginesettings.cpp           | 19 ++++++++++---------
 .../api/qquickwebenginesettings_p.h           |  8 ++++----
 tests/auto/quick/publicapi/tst_publicapi.cpp  |  6 +++---
 9 files changed, 52 insertions(+), 49 deletions(-)

diff --git a/examples/webenginequick/quicknanobrowser/BrowserWindow.qml b/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
index 2c5b3d86e75..d040667d32f 100644
--- a/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
+++ b/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
@@ -44,7 +44,7 @@ ApplicationWindow {
         property alias webRTCPublicInterfacesOnly : webRTCPublicInterfacesOnly.checked
         property alias devToolsEnabled: devToolsEnabled.checked
         property alias pdfViewerEnabled: pdfViewerEnabled.checked
-        property int imageAnimationPolicy: WebEngineSettings.AllowImageAnimation
+        property int imageAnimationPolicy: WebEngineSettings.ImageAnimationPolicy.Allow
     }
 
     Action {
@@ -377,9 +377,9 @@ ApplicationWindow {
                             text: "Disable All Image Animation"
                             checkable: true
                             autoExclusive: true
-                            checked: WebEngine.settings.imageAnimationPolicy === WebEngineSettings.DisallowImageAnimation
+                            checked: WebEngine.settings.imageAnimationPolicy === WebEngineSettings.ImageAnimationPolicy.Disallow
                             onTriggered: {
-                                appSettings.imageAnimationPolicy = WebEngineSettings.DisallowImageAnimation
+                                appSettings.imageAnimationPolicy = WebEngineSettings.ImageAnimationPolicy.Disallow
                             }
                         }
 
@@ -388,9 +388,9 @@ ApplicationWindow {
                             text: "Allow All Animated Images"
                             checkable: true
                             autoExclusive: true
-                            checked: WebEngine.settings.imageAnimationPolicy === WebEngineSettings.AllowImageAnimation
+                            checked: WebEngine.settings.imageAnimationPolicy === WebEngineSettings.ImageAnimationPolicy.Allow
                             onTriggered : {
-                                appSettings.imageAnimationPolicy = WebEngineSettings.AllowImageAnimation
+                                appSettings.imageAnimationPolicy = WebEngineSettings.ImageAnimationPolicy.Allow
                             }
                         }
 
@@ -399,9 +399,9 @@ ApplicationWindow {
                             text: "Animate Image Once"
                             checkable: true
                             autoExclusive: true
-                            checked: WebEngine.settings.imageAnimationPolicy === WebEngineSettings.AnimateImageOnce
+                            checked: WebEngine.settings.imageAnimationPolicy === WebEngineSettings.ImageAnimationPolicy.AnimateOnce
                             onTriggered : {
-                                appSettings.imageAnimationPolicy = WebEngineSettings.AnimateImageOnce
+                                appSettings.imageAnimationPolicy = WebEngineSettings.ImageAnimationPolicy.AnimateOnce
                             }
                         }
                     }
diff --git a/examples/webenginewidgets/simplebrowser/webview.cpp b/examples/webenginewidgets/simplebrowser/webview.cpp
index 3dcfc0c47c5..40a1508b4ef 100644
--- a/examples/webenginewidgets/simplebrowser/webview.cpp
+++ b/examples/webenginewidgets/simplebrowser/webview.cpp
@@ -227,29 +227,29 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
     disableImageAnimation->setCheckable(true);
     m_imageAnimationGroup->addAction(disableImageAnimation);
     connect(disableImageAnimation, &QAction::triggered, [this]() {
-        handleImageAnimationPolicyChange(QWebEngineSettings::DisallowImageAnimation);
+        handleImageAnimationPolicyChange(QWebEngineSettings::ImageAnimationPolicy::Disallow);
     });
     QAction *allowImageAnimationOnce =
             editImageAnimation->addAction(tr("Allow animated images, but only once"));
     allowImageAnimationOnce->setCheckable(true);
     m_imageAnimationGroup->addAction(allowImageAnimationOnce);
     connect(allowImageAnimationOnce, &QAction::triggered,
-            [this]() { handleImageAnimationPolicyChange(QWebEngineSettings::AnimateImageOnce); });
+            [this]() { handleImageAnimationPolicyChange(QWebEngineSettings::ImageAnimationPolicy::AnimateOnce); });
     QAction *allowImageAnimation = editImageAnimation->addAction(tr("Allow all animated images"));
     allowImageAnimation->setCheckable(true);
     m_imageAnimationGroup->addAction(allowImageAnimation);
     connect(allowImageAnimation, &QAction::triggered, [this]() {
-        handleImageAnimationPolicyChange(QWebEngineSettings::AllowImageAnimation);
+        handleImageAnimationPolicyChange(QWebEngineSettings::ImageAnimationPolicy::Allow);
     });
 
     switch (page()->settings()->imageAnimationPolicy()) {
-    case QWebEngineSettings::AllowImageAnimation:
+    case QWebEngineSettings::ImageAnimationPolicy::Allow:
         allowImageAnimation->setChecked(true);
         break;
-    case QWebEngineSettings::AnimateImageOnce:
+    case QWebEngineSettings::ImageAnimationPolicy::AnimateOnce:
         allowImageAnimationOnce->setChecked(true);
         break;
-    case QWebEngineSettings::DisallowImageAnimation:
+    case QWebEngineSettings::ImageAnimationPolicy::Disallow:
         disableImageAnimation->setChecked(true);
         break;
     default:
diff --git a/src/core/api/qwebenginesettings.cpp b/src/core/api/qwebenginesettings.cpp
index f19d8efe57f..a7ae80cd126 100644
--- a/src/core/api/qwebenginesettings.cpp
+++ b/src/core/api/qwebenginesettings.cpp
@@ -115,7 +115,7 @@ QWebEngineSettings::ImageAnimationPolicy QWebEngineSettings::imageAnimationPolic
 
 void QWebEngineSettings::resetImageAnimationPolicy()
 {
-    d_ptr->setImageAnimationPolicy(QWebEngineSettings::InheritedImageAnimationPolicy);
+    d_ptr->setImageAnimationPolicy(QWebEngineSettings::ImageAnimationPolicy::Inherited);
 }
 
 QT_END_NAMESPACE
diff --git a/src/core/api/qwebenginesettings.h b/src/core/api/qwebenginesettings.h
index 7f89f1ea631..f6b5dfe4d11 100644
--- a/src/core/api/qwebenginesettings.h
+++ b/src/core/api/qwebenginesettings.h
@@ -78,11 +78,11 @@ class Q_WEBENGINECORE_EXPORT QWebEngineSettings
         AllowAllUnknownUrlSchemes
     };
 
-    enum ImageAnimationPolicy {
-        InheritedImageAnimationPolicy = 0,
-        AllowImageAnimation,
-        AnimateImageOnce,
-        DisallowImageAnimation
+    enum class ImageAnimationPolicy : uint8_t {
+        Inherited = 0,
+        Allow,
+        AnimateOnce,
+        Disallow,
     };
 
 public:
diff --git a/src/core/doc/src/qwebenginesettings_lgpl.qdoc b/src/core/doc/src/qwebenginesettings_lgpl.qdoc
index cd7ff8e8c0d..dbe9c1d349f 100644
--- a/src/core/doc/src/qwebenginesettings_lgpl.qdoc
+++ b/src/core/doc/src/qwebenginesettings_lgpl.qdoc
@@ -208,13 +208,13 @@
     This enum describes how an image animation should be handled when the image frames
     are rendered for animation.
 
-    \value AllowImageAnimation
+    \value Allow
            Allows image animation when the image frames are rendered.
-    \value AnimateImageOnce
+    \value AnimateOnce
            Animate the image once when the image frames are rendered.
-    \value DisallowImageAnimation
+    \value Disallow
            Disallows image animation when the image frames are rendered.
-    \omitvalue InheritedImageAnimationPolicy
+    \omitvalue Inherited
 
     \sa imageAnimationPolicy setImageAnimationPolicy resetImageAnimationPolicy
 */
@@ -312,7 +312,7 @@
     \fn QWebEngineSettings::ImageAnimationPolicy QWebEngineSettings::imageAnimationPolicy() const
     \since Qt 6.8
     Returns the currently selected policy for handling image animation when the image frames are rendered.
-    Default is \l{QWebEngineSettings::AllowImageAnimation}.
+    Default is \l{QWebEngineSettings::ImageAnimationPolicy::Allow}.
     \sa setImageAnimationPolicy resetImageAnimationPolicy
 */
 
@@ -320,13 +320,13 @@
     \fn void QWebEngineSettings::setImageAnimationPolicy(QWebEngineSettings::ImageAnimationPolicy policy)
     \since Qt 6.8
     Sets the policy for handling image animation when the image frames are rendered to \a policy.
-    Default is \l{QWebEngineSettings::AllowImageAnimation}.
+    Default is \l{QWebEngineSettings::ImageAnimationPolicy::Allow}.
     \sa imageAnimationPolicy resetImageAnimationPolicy
 */
 
 /*!
     \fn void QWebEngineSettings::resetImageAnimationPolicy()
-    \since Qt 6.7
+    \since Qt 6.8
     Removes the policy for handling image animation.
     \sa imageAnimationPolicy setImageAnimationPolicy
 */
diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp
index e302998f085..452ba639330 100644
--- a/src/core/web_engine_settings.cpp
+++ b/src/core/web_engine_settings.cpp
@@ -60,12 +60,14 @@ blink::mojom::ImageAnimationPolicy
 toBlinkImageAnimationPolicy(QWebEngineSettings::ImageAnimationPolicy policy)
 {
     switch (policy) {
-    case QWebEngineSettings::AllowImageAnimation:
+    case QWebEngineSettings::ImageAnimationPolicy::Allow:
         return blink::mojom::ImageAnimationPolicy::kImageAnimationPolicyAllowed;
-    case QWebEngineSettings::AnimateImageOnce:
+    case QWebEngineSettings::ImageAnimationPolicy::AnimateOnce:
         return blink::mojom::ImageAnimationPolicy::kImageAnimationPolicyAnimateOnce;
-    case QWebEngineSettings::DisallowImageAnimation:
+    case QWebEngineSettings::ImageAnimationPolicy::Disallow:
         return blink::mojom::ImageAnimationPolicy::kImageAnimationPolicyNoAnimation;
+    case QWebEngineSettings::ImageAnimationPolicy::Inherited:
+        break;
     }
     return blink::mojom::ImageAnimationPolicy::kImageAnimationPolicyAllowed;
 }
@@ -74,7 +76,7 @@ WebEngineSettings::WebEngineSettings(WebEngineSettings *_parentSettings)
     : m_adapter(nullptr)
     , parentSettings(_parentSettings)
     , m_unknownUrlSchemePolicy(QWebEngineSettings::InheritedUnknownUrlSchemePolicy)
-    , m_imageAnimationPolicy(QWebEngineSettings::InheritedImageAnimationPolicy)
+    , m_imageAnimationPolicy(QWebEngineSettings::ImageAnimationPolicy::Inherited)
 {
     if (parentSettings)
         parentSettings->childSettings.insert(this);
@@ -217,13 +219,13 @@ void WebEngineSettings::setImageAnimationPolicy(QWebEngineSettings::ImageAnimati
 
 QWebEngineSettings::ImageAnimationPolicy WebEngineSettings::imageAnimationPolicy() const
 {
-    if (m_imageAnimationPolicy != QWebEngineSettings::InheritedImageAnimationPolicy)
+    if (m_imageAnimationPolicy != QWebEngineSettings::ImageAnimationPolicy::Inherited)
         return m_imageAnimationPolicy;
 
     if (parentSettings)
         return parentSettings->imageAnimationPolicy();
 
-    return QWebEngineSettings::AllowImageAnimation;
+    return QWebEngineSettings::ImageAnimationPolicy::Allow;
 }
 
 QWebEngineSettings::UnknownUrlSchemePolicy WebEngineSettings::unknownUrlSchemePolicy() const
@@ -333,7 +335,7 @@ void WebEngineSettings::initDefaults()
 
     m_defaultEncoding = QStringLiteral("ISO-8859-1");
     m_unknownUrlSchemePolicy = QWebEngineSettings::InheritedUnknownUrlSchemePolicy;
-    m_imageAnimationPolicy = QWebEngineSettings::InheritedImageAnimationPolicy;
+    m_imageAnimationPolicy = QWebEngineSettings::ImageAnimationPolicy::Inherited;
 }
 
 void WebEngineSettings::scheduleApply()
diff --git a/src/webenginequick/api/qquickwebenginesettings.cpp b/src/webenginequick/api/qquickwebenginesettings.cpp
index 5dc093a4472..4a66605d6da 100644
--- a/src/webenginequick/api/qquickwebenginesettings.cpp
+++ b/src/webenginequick/api/qquickwebenginesettings.cpp
@@ -496,11 +496,12 @@ QString QQuickWebEngineSettings::defaultTextEncoding() const
     return d_ptr->defaultTextEncoding();
 }
 
-ASSERT_ENUMS_MATCH(QQuickWebEngineSettings::AllowImageAnimation,
-                   QWebEngineSettings::AllowImageAnimation)
-ASSERT_ENUMS_MATCH(QQuickWebEngineSettings::AnimateImageOnce, QWebEngineSettings::AnimateImageOnce)
-ASSERT_ENUMS_MATCH(QQuickWebEngineSettings::DisallowImageAnimation,
-                   QWebEngineSettings::DisallowImageAnimation)
+ASSERT_ENUMS_MATCH(QQuickWebEngineSettings::ImageAnimationPolicy::Allow,
+                   QWebEngineSettings::ImageAnimationPolicy::Allow)
+ASSERT_ENUMS_MATCH(QQuickWebEngineSettings::ImageAnimationPolicy::AnimateOnce,
+                   QWebEngineSettings::ImageAnimationPolicy::AnimateOnce)
+ASSERT_ENUMS_MATCH(QQuickWebEngineSettings::ImageAnimationPolicy::Disallow,
+                   QWebEngineSettings::ImageAnimationPolicy::Disallow)
 /*!
     \qmlproperty enumeration WebEngineSettings::imageAnimationPolicy
     \since QtWebEngine 6.8
@@ -508,14 +509,14 @@ ASSERT_ENUMS_MATCH(QQuickWebEngineSettings::DisallowImageAnimation,
     Specifies how an image animation should be handled when the image frames
     are rendered for animation.
 
-    \value WebEngineSettings.AllowImageAnimation
+    \value WebEngineSettings.ImageAnimationPolicy.Allow
            Allows all image animations when the image frames are rendered.
-    \value WebEngineSettings.AnimateImageOnce
+    \value WebEngineSettings.ImageAnimationPolicy.AnimateOnce
            Animate the image once when the image frames are rendered.
-    \value WebEngineSettings.DisallowImageAnimation
+    \value WebEngineSettings.ImageAnimationPolicy.Disallow
            Disallows all image animations when the image frames are rendered.
 
-    Default value is \c {WebEngineSettings.AllowImageAnimation}.
+    Default value is \c {WebEngineSettings.ImageAnimationPolicy.Allow}.
 */
 QQuickWebEngineSettings::ImageAnimationPolicy QQuickWebEngineSettings::imageAnimationPolicy() const
 {
diff --git a/src/webenginequick/api/qquickwebenginesettings_p.h b/src/webenginequick/api/qquickwebenginesettings_p.h
index ed3c778845f..3320c45d884 100644
--- a/src/webenginequick/api/qquickwebenginesettings_p.h
+++ b/src/webenginequick/api/qquickwebenginesettings_p.h
@@ -74,10 +74,10 @@ class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineSettings : public QObject {
 
     Q_ENUM(UnknownUrlSchemePolicy)
 
-    enum ImageAnimationPolicy {
-        AllowImageAnimation = 1,
-        AnimateImageOnce,
-        DisallowImageAnimation
+    enum class ImageAnimationPolicy : uint8_t {
+        Allow = 1,
+        AnimateOnce,
+        Disallow,
     };
 
     Q_ENUM(ImageAnimationPolicy)
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index e6605dc4103..0046de78453 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -923,9 +923,9 @@ static const QStringList expectedAPI = QStringList()
     << "QWebEngineWebAuthPinRequest.error --> QWebEngineWebAuthUxRequest::PinEntryError"
     << "QWebEngineWebAuthPinRequest.minPinLength --> int"
     << "QWebEngineWebAuthPinRequest.remainingAttempts --> int"
-    << "QQuickWebEngineSettings.AllowImageAnimation --> ImageAnimationPolicy"
-    << "QQuickWebEngineSettings.AnimateImageOnce --> ImageAnimationPolicy"
-    << "QQuickWebEngineSettings.DisallowImageAnimation --> ImageAnimationPolicy"
+    << "QQuickWebEngineSettings.ImageAnimationPolicy.Allow --> ImageAnimationPolicy"
+    << "QQuickWebEngineSettings.ImageAnimationPolicy.AnimateOnce --> ImageAnimationPolicy"
+    << "QQuickWebEngineSettings.ImageAnimationPolicy.Disallow --> ImageAnimationPolicy"
     << "QQuickWebEngineSettings.imageAnimationPolicy --> QQuickWebEngineSettings::ImageAnimationPolicy"
     << "QQuickWebEngineSettings.imageAnimationPolicyChanged() --> void"
     << "QWebEngineFrame.htmlName --> QString"

From 34d5d5c59f10f454a1dd0d72d41cf52d9b4f7416 Mon Sep 17 00:00:00 2001
From: Martin Negyokru <negyokru@inf.u-szeged.hu>
Date: Mon, 10 Jun 2024 15:12:31 +0200
Subject: [PATCH 023/356] Fix warnings after 122 update

Fix [-Wswitch] warnings.
Test the newly added accessibility role.

Change-Id: Ieea34a759dd630a0b60eac2cd74d1420916a5b85
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit b400e36004b8af8ece0d65495e05302120ddd2cb)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/browser_accessibility_qt.cpp                  | 1 +
 src/core/permission_manager_qt.cpp                     | 3 +++
 src/core/type_conversion.cpp                           | 1 +
 tests/auto/widgets/accessibility/tst_accessibility.cpp | 1 +
 4 files changed, 6 insertions(+)

diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp
index ff3d21fb74a..60e5390e3d0 100644
--- a/src/core/browser_accessibility_qt.cpp
+++ b/src/core/browser_accessibility_qt.cpp
@@ -408,6 +408,7 @@ QAccessible::Role BrowserAccessibilityInterface::role() const
     case ax::mojom::Role::kDirectory:
         return QAccessible::List;
     case ax::mojom::Role::kDisclosureTriangle:
+    case ax::mojom::Role::kDisclosureTriangleGrouped:
         return QAccessible::Button;
     case ax::mojom::Role::kGenericContainer:
         return QAccessible::Section;
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index 2c1c0d3d670..95f79bb118d 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -69,6 +69,9 @@ static QWebEnginePermission::Feature toQt(blink::PermissionType type)
     case blink::PermissionType::VR:
     case blink::PermissionType::STORAGE_ACCESS_GRANT:
     case blink::PermissionType::TOP_LEVEL_STORAGE_ACCESS:
+    case blink::PermissionType::CAPTURED_SURFACE_CONTROL:
+    case blink::PermissionType::SMART_CARD:
+    case blink::PermissionType::WEB_PRINTING:
     case blink::PermissionType::NUM:
         LOG(INFO) << "Unexpected unsupported Blink permission type: " << static_cast<int>(type);
         break;
diff --git a/src/core/type_conversion.cpp b/src/core/type_conversion.cpp
index 2d4fb323dc4..0a3c2489c45 100644
--- a/src/core/type_conversion.cpp
+++ b/src/core/type_conversion.cpp
@@ -32,6 +32,7 @@ QImage toQImage(const SkBitmap &bitmap)
     case kR16G16_float_SkColorType:
     case kR16G16_unorm_SkColorType:
     case kR8_unorm_SkColorType:
+    case kRGBA_10x6_SkColorType:
         qWarning("Unknown or unsupported skia image format");
         break;
     case kAlpha_8_SkColorType:
diff --git a/tests/auto/widgets/accessibility/tst_accessibility.cpp b/tests/auto/widgets/accessibility/tst_accessibility.cpp
index 0a65e7a9566..200f9a5fb3e 100644
--- a/tests/auto/widgets/accessibility/tst_accessibility.cpp
+++ b/tests/auto/widgets/accessibility/tst_accessibility.cpp
@@ -378,6 +378,7 @@ void tst_Accessibility::roles_data()
     QTest::newRow("ax::mojom::Role::kDialog") << QString("<div role='dialog'></div>") << 0 << QAccessible::Dialog;
     //QTest::newRow("ax::mojom::Role::kDirectory") << QString("<ul role='directory'></ul>") << 0 << QAccessible::List; // FIXME: Aria role 'directory' should work
     QTest::newRow("ax::mojom::Role::kDisclosureTriangle") << QString("<details><summary>a</summary></details>") << 1 << QAccessible::Button;
+    QTest::newRow("ax::mojom::Role::kDisclosureTriangleGroup") << QString("<details name='groupName'><summary>a</summary></details>") << 1 << QAccessible::Button;
     QTest::newRow("ax::mojom::Role::kGenericContainer") << QString("<div>a</div>") << 0 << QAccessible::Section;
     QTest::newRow("ax::mojom::Role::kDocCover") << QString("<div role='doc-cover'></div>") << 0 << QAccessible::Graphic;
     QTest::newRow("ax::mojom::Role::kDocBackLink") << QString("<div role='doc-backlink'></div>") << 0 << QAccessible::Link;

From 72fcd240a5de9a10c3d7fc12896ea23b9f5addb9 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Tue, 18 Jun 2024 14:37:05 +0200
Subject: [PATCH 024/356] Remove ninja project from sync scripts
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Change-Id: Id861858b413b880ed7f69bb0485b672d2d218d5a
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
(cherry picked from commit 1e8d0c5cad19ec6a5e31ce36e71edb80df971932)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 tools/scripts/init-repository.py  | 14 --------------
 tools/scripts/take_snapshot.py    | 16 ----------------
 tools/scripts/version_resolver.py |  4 ----
 3 files changed, 34 deletions(-)

diff --git a/tools/scripts/init-repository.py b/tools/scripts/init-repository.py
index e6ec0c44053..0b973ebd6eb 100755
--- a/tools/scripts/init-repository.py
+++ b/tools/scripts/init-repository.py
@@ -16,7 +16,6 @@
 import version_resolver as resolver
 
 chromium_src = os.environ.get('CHROMIUM_SRC_DIR')
-ninja_src = os.path.join(qtwebengine_root, 'src/3rdparty_upstream/ninja')
 gn_src = os.path.join(qtwebengine_root, 'src/3rdparty_upstream/gn')
 use_external_chromium = False
 
@@ -39,7 +38,6 @@
         chromium_src = os.path.join(qtwebengine_root, 'src/3rdparty_upstream/chromium')
     if args.snapshot or not chromium_src:
         chromium_src = os.path.join(qtwebengine_root, 'src/3rdparty/chromium')
-        ninja_src = os.path.join(qtwebengine_root, 'src/3rdparty/ninja')
         gn_src = os.path.join(qtwebengine_root, 'src/3rdparty/gn')
         args.snapshot = True
     print('CHROMIUM_SRC_DIR not set, using Chromium in' + chromium_src)
@@ -63,27 +61,16 @@ def updateLastChange():
 
 def initUpstreamSubmodules():
     gn_url = 'https://gn.googlesource.com/gn'
-    ninja_url = 'https://github.com/martine/ninja.git'
     chromium_url = 'https://chromium.googlesource.com/chromium/src.git'
-    ninja_shasum = 'refs/tags/' + resolver.currentNinjaVersion()
     chromium_ref = 'refs/tags/' + resolver.currentVersion()
     os.chdir(qtwebengine_root)
 
     current_submodules = subprocess.check_output(['git', 'submodule']).decode()
     if not 'src/3rdparty_upstream/gn' in current_submodules:
         subprocess.call(['git', 'submodule', 'add', gn_url, 'src/3rdparty_upstream/gn'])
-    if not 'src/3rdparty_upstream/ninja' in current_submodules:
-        subprocess.call(['git', 'submodule', 'add', ninja_url, 'src/3rdparty_upstream/ninja'])
     if not use_external_chromium and not 'src/3rdparty_upstream/chromium' in current_submodules:
         subprocess.call(['git', 'submodule', 'add', chromium_url, 'src/3rdparty_upstream/chromium'])
 
-    ninjaSubmodule = GitSubmodule.Submodule()
-    ninjaSubmodule.path = 'src/3rdparty_upstream/ninja'
-    ninjaSubmodule.ref = ninja_shasum
-    ninjaSubmodule.url = ninja_url
-    ninjaSubmodule.os = 'all'
-    ninjaSubmodule.initialize()
-
     gnSubmodule = GitSubmodule.Submodule()
     gnSubmodule.path = 'src/3rdparty_upstream/gn'
     gnSubmodule.ref = 'master'
@@ -103,7 +90,6 @@ def initUpstreamSubmodules():
 
     # Unstage repositories so we do not accidentally commit them.
     subprocess.call(['git', 'reset', '-q', 'HEAD', 'src/3rdparty_upstream/gn'])
-    subprocess.call(['git', 'reset', '-q', 'HEAD', 'src/3rdparty_upstream/ninja'])
     subprocess.call(['git', 'reset', '-q', 'HEAD', 'src/3rdparty_upstream/chromium'])
 
 def initSnapshot():
diff --git a/tools/scripts/take_snapshot.py b/tools/scripts/take_snapshot.py
index 2e2d3991716..70ce7e5bf49 100755
--- a/tools/scripts/take_snapshot.py
+++ b/tools/scripts/take_snapshot.py
@@ -382,21 +382,6 @@ def exportGn():
             copyFile(f, os.path.join(third_party_gn, f))
     print("")
 
-def exportNinja():
-    third_party_upstream_ninja = os.path.join(third_party_upstream, 'ninja')
-    third_party_ninja = os.path.join(third_party, 'ninja')
-    os.makedirs(third_party_ninja);
-    print('exporting contents of:' + third_party_upstream_ninja)
-    os.chdir(third_party_upstream_ninja)
-    files = listFilesInCurrentRepository()
-    print('copying files to ' + third_party_ninja)
-    for i in range(len(files)):
-        printProgress(i+1, len(files))
-        f = files[i].decode()
-        if not isInGitBlacklist(f):
-            copyFile(f, os.path.join(third_party_ninja, f))
-    print("")
-
 def exportChromium():
     third_party_upstream_chromium = os.path.join(third_party_upstream, 'chromium')
     third_party_chromium = os.path.join(third_party, 'chromium')
@@ -461,7 +446,6 @@ def exportChromium():
 clearDirectory(third_party)
 
 exportGn()
-exportNinja()
 exportChromium()
 
 print('done.')
diff --git a/tools/scripts/version_resolver.py b/tools/scripts/version_resolver.py
index 9021d1e202e..c8923c0f9bc 100644
--- a/tools/scripts/version_resolver.py
+++ b/tools/scripts/version_resolver.py
@@ -45,7 +45,6 @@ def get_recursedeps(self):
 
 chromium_version = '122.0.6261.72'
 chromium_branch = '6261'
-ninja_version = 'v1.8.2'
 
 json_url = 'http://omahaproxy.appspot.com/all.json'
 
@@ -72,9 +71,6 @@ def get_recursedeps(self):
 def currentVersion():
     return chromium_version
 
-def currentNinjaVersion():
-    return ninja_version
-
 def readReleaseChannels():
     response = urllib2.urlopen(json_url)
     raw_json = response.read().strip()

From 08cf629f6349b8462fabc0f90d3014140159caa0 Mon Sep 17 00:00:00 2001
From: Martin Negyokru <negyokru@inf.u-szeged.hu>
Date: Wed, 8 May 2024 09:41:56 +0200
Subject: [PATCH 025/356] Handle single file selection in fileChooser

There are some components (eg. devtools) that implement their own
SelectFileDialog::Listener. They expect 'FileSelected' calls for single
file selections.

Fixes an issue with devtools_file_helper after 122 update.

Change-Id: Iffb5515b9b040dde2e3634b1daddd9e5056d13ca
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 24805532be9d5d8962c90f0dd9ad0d666cb03c7a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/file_picker_controller.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/core/file_picker_controller.cpp b/src/core/file_picker_controller.cpp
index 9f97892966a..fb124df7bb8 100644
--- a/src/core/file_picker_controller.cpp
+++ b/src/core/file_picker_controller.cpp
@@ -214,6 +214,9 @@ void FilePickerController::filesSelectedInChooser(const QStringList &filesList)
 
         if (files.empty())
             d_ptr->fileSystemAccessDialogListener->FileSelectionCanceled(nullptr);
+        else if (files.size() == 1)
+            d_ptr->fileSystemAccessDialogListener->FileSelected(
+                    ui::SelectedFileInfo(files[0]), 0, nullptr);
         else
             d_ptr->fileSystemAccessDialogListener->MultiFilesSelected(
                     ui::FilePathListToSelectedFileInfoList(files), nullptr);

From 67367b7b231d2d22358cb87d1e744e391d6f05d3 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Tue, 18 Jun 2024 15:29:17 +0200
Subject: [PATCH 026/356] Update resovler version to 122.0.6261.171
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Change-Id: I7428e3782b700846c8565a91f8ed0b1f3d0d5362
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
(cherry picked from commit 390054d7f7176846ff69758a1991a5162ab1d653)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 tools/scripts/version_resolver.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/scripts/version_resolver.py b/tools/scripts/version_resolver.py
index c8923c0f9bc..ad71f06e281 100644
--- a/tools/scripts/version_resolver.py
+++ b/tools/scripts/version_resolver.py
@@ -43,7 +43,7 @@ def get_recursedeps(self):
         return self.local_scope["recursedeps"]
 
 
-chromium_version = '122.0.6261.72'
+chromium_version = '122.0.6261.171'
 chromium_branch = '6261'
 
 json_url = 'http://omahaproxy.appspot.com/all.json'

From 42643386f4d733366b17b5b8d103af49d44d77be Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 13 Jun 2024 08:35:57 +0200
Subject: [PATCH 027/356] Remove unused WebRtcLogUploader

It is not referenced by the WebRtcLoggingController after the 122-based
adaptations. See, https://crrev.com/c/5021200

Change-Id: Ifd03c5af09575abb37832ad663f61dc0aacfbf3e
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 260b930ac3480dae8204a292dabd7bb98edffbef)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/web_engine_context.cpp | 22 ----------------------
 src/core/web_engine_context.h   |  7 -------
 2 files changed, 29 deletions(-)

diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index f969b0e8b9e..74453d1992e 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -20,9 +20,6 @@
 #include "base/task/thread_pool/thread_pool_instance.h"
 #include "base/threading/thread_restrictions.h"
 #include "cc/base/switches.h"
-#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
-#include "chrome/browser/media/webrtc/webrtc_log_uploader.h"
-#endif
 #include "chrome/common/chrome_switches.h"
 #include "content/common/process_visibility_tracker.h"
 #include "content/gpu/gpu_child_thread.h"
@@ -658,11 +655,6 @@ void WebEngineContext::destroy()
     if (m_devtoolsServer)
         m_devtoolsServer->stop();
 
-#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
-    if (m_webrtcLogUploader)
-        m_webrtcLogUploader->Shutdown();
-#endif
-
     // Normally the GPU thread is shut down when the GpuProcessHost is destroyed
     // on IO thread (triggered by ~BrowserMainRunner). But by that time the UI
     // task runner is not working anymore so we need to do this earlier.
@@ -710,10 +702,6 @@ void WebEngineContext::destroy()
 
     // Drop the false reference.
     m_handle->Release();
-
-#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
-    m_webrtcLogUploader.reset();
-#endif
 }
 
 WebEngineContext::~WebEngineContext()
@@ -1109,16 +1097,6 @@ printing::PrintJobManager* WebEngineContext::getPrintJobManager()
 }
 #endif
 
-#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
-WebRtcLogUploader *WebEngineContext::webRtcLogUploader()
-{
-    if (!m_webrtcLogUploader)
-        m_webrtcLogUploader = std::make_unique<WebRtcLogUploader>();
-    return m_webrtcLogUploader.get();
-}
-#endif
-
-
 base::CommandLine *WebEngineContext::initCommandLine(bool &useEmbeddedSwitches,
                                                      bool &enableGLSoftwareRendering)
 {
diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h
index faed5866180..7a36fd00187 100644
--- a/src/core/web_engine_context.h
+++ b/src/core/web_engine_context.h
@@ -48,7 +48,6 @@ struct SandboxInterfaceInfo;
 #endif
 
 QT_FORWARD_DECLARE_CLASS(QObject)
-class WebRtcLogUploader;
 
 namespace QtWebEngineCore {
 
@@ -74,9 +73,6 @@ class WebEngineContext : public base::RefCounted<WebEngineContext> {
     QObject *globalQObject();
 #if QT_CONFIG(webengine_printing_and_pdf)
     printing::PrintJobManager* getPrintJobManager();
-#endif
-#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
-    WebRtcLogUploader *webRtcLogUploader();
 #endif
     void destroyProfileAdapter();
     void addProfileAdapter(ProfileAdapter *profileAdapter);
@@ -110,9 +106,6 @@ class WebEngineContext : public base::RefCounted<WebEngineContext> {
 
 #if QT_CONFIG(webengine_printing_and_pdf)
     std::unique_ptr<printing::PrintJobManager> m_printJobManager;
-#endif
-#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
-    std::unique_ptr<WebRtcLogUploader> m_webrtcLogUploader;
 #endif
     static scoped_refptr<QtWebEngineCore::WebEngineContext> m_handle;
     static bool m_destroyed;

From 8242ec532e2575579d5ac5797cb8dd422f37d5c9 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 13 Jun 2024 09:35:57 +0200
Subject: [PATCH 028/356] Remove some leftover forward declarations and
 includes after Chromium update

Change-Id: I0ad59891ccede8e6690fab1f132f43b434f61600
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 200b6245651545fa2f4ff510687689b6d8bf0ee0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/autofill_client_qt.h          |  1 -
 src/core/content_browser_client_qt.cpp | 13 +++++--------
 src/core/content_browser_client_qt.h   |  7 -------
 src/core/profile_qt.cpp                |  1 -
 src/core/profile_qt.h                  |  4 ----
 5 files changed, 5 insertions(+), 21 deletions(-)

diff --git a/src/core/autofill_client_qt.h b/src/core/autofill_client_qt.h
index 4f10882d24c..59b728cc7e6 100644
--- a/src/core/autofill_client_qt.h
+++ b/src/core/autofill_client_qt.h
@@ -22,7 +22,6 @@
 #include "base/containers/span.h"
 #include "components/autofill/content/browser/content_autofill_client.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_user_data.h"
 
 #include <QScopedPointer>
 
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index c32bb3411b4..341c4629588 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -16,7 +16,6 @@
 #include "components/performance_manager/embedder/performance_manager_registry.h"
 #include "components/performance_manager/public/performance_manager.h"
 #include "content/browser/web_contents/web_contents_impl.h"
-#include "content/public/browser/browser_main_runner.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/child_process_security_policy.h"
 #include "content/public/browser/client_certificate_delegate.h"
@@ -25,15 +24,12 @@
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
-#include "content/public/browser/render_view_host.h"
 #include "content/public/browser/shared_cors_origin_access_list.h"
 #include "content/public/browser/url_loader_request_interceptor.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_user_data.h"
 #include "content/public/browser/web_contents_view_delegate.h"
 #include "content/public/browser/web_ui_url_loader_factory.h"
 #include "content/public/common/content_switches.h"
-#include "content/public/common/main_function_params.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/common/user_agent.h"
 #include "extensions/buildflags/buildflags.h"
@@ -57,7 +53,6 @@
 
 #include "profile_adapter.h"
 #include "browser_main_parts_qt.h"
-#include "browser_message_filter_qt.h"
 #include "certificate_error_controller.h"
 #include "client_cert_select_controller.h"
 #include "custom_handlers/protocol_handler_registry_factory.h"
@@ -70,7 +65,6 @@
 #include "net/proxying_restricted_cookie_manager_qt.h"
 #include "net/proxying_url_loader_factory_qt.h"
 #include "net/system_network_context_manager.h"
-#include "platform_notification_service_qt.h"
 #include "profile_qt.h"
 #include "profile_io_data_qt.h"
 #include "renderer_host/user_resource_controller_host.h"
@@ -80,7 +74,6 @@
 #include "web_contents_adapter.h"
 #include "web_contents_delegate_qt.h"
 #include "web_contents_view_qt.h"
-#include "web_engine_context.h"
 #include "web_engine_library_info.h"
 #include "web_engine_settings.h"
 #include "authenticator_request_client_delegate_qt.h"
@@ -88,6 +81,10 @@
 #include "api/qwebenginecookiestore_p.h"
 #include "api/qwebengineurlrequestinfo_p.h"
 
+#if BUILDFLAG(CONTENT_ENABLE_LEGACY_IPC)
+#include "browser_message_filter_qt.h"
+#endif
+
 #if QT_CONFIG(webengine_geolocation)
 #include "base/memory/ptr_util.h"
 #include "location_provider_qt.h"
@@ -190,7 +187,7 @@ bool IsHandledProtocol(base::StringPiece scheme)
         return true;
     return false;
 }
-}
+} // namespace url
 
 namespace QtWebEngineCore {
 
diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h
index b40c2a343cb..333b08ea22d 100644
--- a/src/core/content_browser_client_qt.h
+++ b/src/core/content_browser_client_qt.h
@@ -10,17 +10,10 @@
 namespace content {
 class BrowserContext;
 class BrowserMainParts;
-
-#if QT_CONFIG(webengine_pepper_plugins)
-class BrowserPpapiHost;
-#endif
-
 class DevToolsManagerDelegate;
 class RenderFrameHost;
 class RenderProcessHost;
-class ResourceContext;
 class WebContents;
-struct MainFunctionParams;
 struct Referrer;
 } // namespace content
 
diff --git a/src/core/profile_qt.cpp b/src/core/profile_qt.cpp
index c54e8485b49..ffb1297a5cf 100644
--- a/src/core/profile_qt.cpp
+++ b/src/core/profile_qt.cpp
@@ -15,7 +15,6 @@
 #include "qtwebenginecoreglobal_p.h"
 #include "type_conversion.h"
 #include "web_engine_library_info.h"
-#include "web_engine_context.h"
 
 #include "base/base_paths.h"
 #include "base/files/file_util.h"
diff --git a/src/core/profile_qt.h b/src/core/profile_qt.h
index a267efbc91b..5394182e4e1 100644
--- a/src/core/profile_qt.h
+++ b/src/core/profile_qt.h
@@ -11,10 +11,6 @@
 
 class PrefService;
 
-namespace content {
-class ResourceContext;
-}
-
 namespace extensions {
 class ExtensionSystemQt;
 }

From 324b3d9d29936dfbefea574ec825c1852bcd1898 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Thu, 13 Jun 2024 16:48:19 +0200
Subject: [PATCH 029/356] Stabilize
 tst_QWebEngineProfile::permissionPersistence

For some reason, the server used to load pages sometimes refuses to
stop(). This change adds a TRY_VERIFY to ensure it stops correctly.

Change-Id: I05c57e22ca5debbc7f02e48cbed40a30ce3ae43f
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 6ec047b73d030ff5dca171c02fd6027632825c82)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index 6245a6c7a23..3cd400fdc64 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -1099,7 +1099,7 @@ void tst_QWebEngineProfile::permissionPersistence()
         storageDir.remove("permissions.json");
     }
 
-    QVERIFY(server.stop());
+    QTRY_VERIFY(server.stop());
 }
 
 void tst_QWebEngineProfile::getPermission_data()

From 4b7f183dc5adc73388e776d90422c19628cd0eee Mon Sep 17 00:00:00 2001
From: Martin Negyokru <negyokru@inf.u-szeged.hu>
Date: Tue, 11 Jun 2024 10:31:48 +0200
Subject: [PATCH 030/356] Fix QWEPermission related warnings

Fix compiler warnings that are related to QWebEnginePermission.

Change-Id: Icac1352e4934f73a205b85896b6f83171b759dd3
Reviewed-by: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit f4090baa2d1d7f6c4c963ac8034d7a24836f0e6c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 examples/webenginewidgets/push-notifications/main.cpp | 2 +-
 src/core/api/qwebenginepage.cpp                       | 8 ++++++--
 src/core/api/qwebenginepermission.cpp                 | 2 ++
 src/core/permission_manager_qt.cpp                    | 3 ++-
 src/core/web_contents_adapter.cpp                     | 2 ++
 5 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/examples/webenginewidgets/push-notifications/main.cpp b/examples/webenginewidgets/push-notifications/main.cpp
index 950ebfc9f14..2a52ea39e0e 100644
--- a/examples/webenginewidgets/push-notifications/main.cpp
+++ b/examples/webenginewidgets/push-notifications/main.cpp
@@ -22,7 +22,7 @@ int main(int argc, char *argv[])
 
     QObject::connect(view.page(), &QWebEnginePage::permissionRequested,
                      [&](QWebEnginePermission permission) {
-                         if (permission.feature() != QWebEnginePage::Notifications)
+                         if (permission.feature() != QWebEnginePermission::Notifications)
                              return;
 
                          permission.grant();
diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp
index f0260fd0d31..d7e56c0a1dd 100644
--- a/src/core/api/qwebenginepage.cpp
+++ b/src/core/api/qwebenginepage.cpp
@@ -1857,8 +1857,8 @@ QT_WARNING_DISABLE_DEPRECATED
 void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEnginePage::Feature feature, QWebEnginePage::PermissionPolicy policy)
 {
     Q_D(QWebEnginePage);
-    QWebEnginePermission::Feature f;
-    QWebEnginePermission::State s;
+    QWebEnginePermission::Feature f = QWebEnginePermission::Feature::Unsupported;
+    QWebEnginePermission::State s = QWebEnginePermission::State::Invalid;
 
     switch (feature) {
     case QWebEnginePage::Notifications:
@@ -1891,6 +1891,8 @@ void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEngine
     case QWebEnginePage::LocalFontsAccess:
         f = QWebEnginePermission::LocalFontsAccess;
         break;
+    default:
+        Q_UNREACHABLE();
     }
 
     switch (policy) {
@@ -1903,6 +1905,8 @@ void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEngine
     case QWebEnginePage::PermissionGrantedByUser:
         s = QWebEnginePermission::Granted;
         break;
+    default:
+        Q_UNREACHABLE();
     }
 
     d->adapter->setFeaturePermission(securityOrigin, f, s);
diff --git a/src/core/api/qwebenginepermission.cpp b/src/core/api/qwebenginepermission.cpp
index d898b8c7e59..61e76ee4a0d 100644
--- a/src/core/api/qwebenginepermission.cpp
+++ b/src/core/api/qwebenginepermission.cpp
@@ -300,6 +300,8 @@ bool QWebEnginePermission::isTransient(QWebEnginePermission::Feature feature)
     case QWebEnginePermission::Unsupported:
         return false;
     }
+
+    Q_UNREACHABLE_RETURN(false);
 }
 
 QT_END_NAMESPACE
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index 95f79bb118d..1f826e7124d 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -98,6 +98,7 @@ static blink::PermissionType toBlink(QWebEnginePermission::Feature feature)
     case QWebEnginePermission::LocalFontsAccess:
         return blink::PermissionType::LOCAL_FONTS;
     case QWebEnginePermission::MediaAudioVideoCapture:
+    case QWebEnginePermission::MouseLock:
     case QWebEnginePermission::Unsupported:
         LOG(INFO) << "Unexpected unsupported WebEngine permission type: " << static_cast<int>(feature);
         return blink::PermissionType::NUM;
@@ -173,8 +174,8 @@ static blink::mojom::PermissionStatus getStatusFromSettings(blink::PermissionTyp
 
 PermissionManagerQt::PermissionManagerQt(ProfileAdapter *profileAdapter)
     : m_requestIdCount(0)
-    , m_persistence(true)
     , m_profileAdapter(profileAdapter)
+    , m_persistence(true)
 {
     PrefServiceFactory factory;
     factory.set_async(false);
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index e73eca7f37f..ed169b161e5 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -1423,6 +1423,7 @@ void WebContentsAdapter::setFeaturePermission(const QUrl &origin, QWebEnginePerm
     CHECK_INITIALIZED();
     if (feature == QWebEnginePermission::MouseLock) {
         switch (state) {
+        case QWebEnginePermission::Invalid:
         case QWebEnginePermission::Ask:
             // Do nothing
             break;
@@ -1445,6 +1446,7 @@ void WebContentsAdapter::setFeaturePermission(const QUrl &origin, QWebEnginePerm
         WebContentsAdapterClient::MediaDesktopAudioCapture);
 
     switch (state) {
+    case QWebEnginePermission::Invalid:
     case QWebEnginePermission::Ask:
         // Do nothing
         return;

From c6fa99b96028817d657a793e9f0cc8220b778078 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kai=20K=C3=B6hne?= <kai.koehne@qt.io>
Date: Mon, 24 Jun 2024 13:55:25 +0200
Subject: [PATCH 031/356] Replace urn:dje license identifier with SPDX
 compatible one

We aim for using only valid SPDX expressions in LicenseId fields.
But SPDX does not contain a generic 'Public Domain' license, which
is why we were going for urn.dje licenses originally. Anyhow,
best practice is to use custom LicenseRef- licenses in this case.

Task-number: QTBUG-126403
Pick-to: 6.7
Change-Id: I1d050ae42603168c6a4c9d44eeb7fdd6767af060
Reviewed-by: Lucie Gerard <lucie.gerard@qt.io>
(cherry picked from commit 8e22839aa06bed928e37bf9172ee7b31fc2b7ee1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 LICENSES/LicenseRef-Tango-Icons-Public-Domain.txt              | 1 +
 .../quicknanobrowser/icons/3rdparty/qt_attribution.json        | 3 +--
 .../permissionbrowser/resources/3rdparty/qt_attribution.json   | 3 +--
 .../simplebrowser/data/3rdparty/qt_attribution.json            | 3 +--
 4 files changed, 4 insertions(+), 6 deletions(-)
 create mode 100644 LICENSES/LicenseRef-Tango-Icons-Public-Domain.txt

diff --git a/LICENSES/LicenseRef-Tango-Icons-Public-Domain.txt b/LICENSES/LicenseRef-Tango-Icons-Public-Domain.txt
new file mode 100644
index 00000000000..220881da67d
--- /dev/null
+++ b/LICENSES/LicenseRef-Tango-Icons-Public-Domain.txt
@@ -0,0 +1 @@
+The icons in this repository are herefore released into the Public Domain.
diff --git a/examples/webenginequick/quicknanobrowser/icons/3rdparty/qt_attribution.json b/examples/webenginequick/quicknanobrowser/icons/3rdparty/qt_attribution.json
index d8d85d6f153..48dbde66037 100644
--- a/examples/webenginequick/quicknanobrowser/icons/3rdparty/qt_attribution.json
+++ b/examples/webenginequick/quicknanobrowser/icons/3rdparty/qt_attribution.json
@@ -9,9 +9,8 @@
     "Homepage": "http://tango.freedesktop.org/Tango_Icon_Library",
     "Version": "0.8.90",
     "DownloadLocation": "http://tango.freedesktop.org/releases/tango-icon-theme-0.8.90.tar.gz",
-    "LicenseId": "urn:dje:license:public-domain",
+    "LicenseId": "LicenseRef-Tango-Icons-Public-Domain",
     "License": "Public Domain",
-    "LicenseFile": "COPYING",
     "Copyright": ["Ulisse Perusin <uli.peru@gmail.com>",
     "Steven Garrity <sgarrity@silverorange.com>",
     "Lapo Calamandrei <calamandrei@gmail.com>",
diff --git a/examples/webenginewidgets/permissionbrowser/resources/3rdparty/qt_attribution.json b/examples/webenginewidgets/permissionbrowser/resources/3rdparty/qt_attribution.json
index e11663d5e41..63fe372c21c 100644
--- a/examples/webenginewidgets/permissionbrowser/resources/3rdparty/qt_attribution.json
+++ b/examples/webenginewidgets/permissionbrowser/resources/3rdparty/qt_attribution.json
@@ -9,9 +9,8 @@
     "Homepage": "http://tango.freedesktop.org/Tango_Icon_Library",
     "Version": "0.8.90",
     "DownloadLocation": "http://tango.freedesktop.org/releases/tango-icon-theme-0.8.90.tar.gz",
-    "LicenseId": "urn:dje:license:public-domain",
+    "LicenseId": "LicenseRef-Tango-Icons-Public-Domain",
     "License": "Public Domain",
-    "LicenseFile": "COPYING",
     "Copyright": ["Ulisse Perusin <uli.peru@gmail.com>",
     "Steven Garrity <sgarrity@silverorange.com>",
     "Lapo Calamandrei <calamandrei@gmail.com>",
diff --git a/examples/webenginewidgets/simplebrowser/data/3rdparty/qt_attribution.json b/examples/webenginewidgets/simplebrowser/data/3rdparty/qt_attribution.json
index fbc96416ee1..301e933eb8e 100644
--- a/examples/webenginewidgets/simplebrowser/data/3rdparty/qt_attribution.json
+++ b/examples/webenginewidgets/simplebrowser/data/3rdparty/qt_attribution.json
@@ -9,9 +9,8 @@
     "Homepage": "http://tango.freedesktop.org/Tango_Icon_Library",
     "Version": "0.8.90",
     "DownloadLocation": "http://tango.freedesktop.org/releases/tango-icon-theme-0.8.90.tar.gz",
-    "LicenseId": "urn:dje:license:public-domain",
+    "LicenseId": "LicenseRef-Tango-Icons-Public-Domain",
     "License": "Public Domain",
-    "LicenseFile": "COPYING",
     "Copyright": ["Ulisse Perusin <uli.peru@gmail.com>",
     "Steven Garrity <sgarrity@silverorange.com>",
     "Lapo Calamandrei <calamandrei@gmail.com>",

From d08874c52183c470cbd62dfeb26c9d18c0795de2 Mon Sep 17 00:00:00 2001
From: Szabolcs David <davidsz@inf.u-szeged.hu>
Date: Wed, 19 Jun 2024 16:01:49 +0200
Subject: [PATCH 032/356] Fix deprecation of QWebEngineUrlRequestJob::NoError
 after API review

Change-Id: I6919c441053f4378d1785bfa97067ef58c0240e1
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 63224bc040533663963a2a81fedb0ef203383698)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebengineurlrequestjob.cpp | 2 +-
 src/core/api/qwebengineurlrequestjob.h   | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/core/api/qwebengineurlrequestjob.cpp b/src/core/api/qwebengineurlrequestjob.cpp
index 5ad22f3441d..b969b2369e1 100644
--- a/src/core/api/qwebengineurlrequestjob.cpp
+++ b/src/core/api/qwebengineurlrequestjob.cpp
@@ -32,7 +32,7 @@ QT_BEGIN_NAMESPACE
     This enum type holds the type of the error that occurred:
 
     \value  NoError
-            The request was successful. (Deprecated since Qt 6.7)
+            The request was successful. (Deprecated since Qt 6.8)
     \value  UrlNotFound
             The requested URL was not found.
     \value  UrlInvalid
diff --git a/src/core/api/qwebengineurlrequestjob.h b/src/core/api/qwebengineurlrequestjob.h
index 858c03e6eb3..8448efdefd3 100644
--- a/src/core/api/qwebengineurlrequestjob.h
+++ b/src/core/api/qwebengineurlrequestjob.h
@@ -26,11 +26,11 @@ class Q_WEBENGINECORE_EXPORT QWebEngineUrlRequestJob : public QObject
     ~QWebEngineUrlRequestJob();
 
     enum Error {
-#if QT_DEPRECATED_SINCE(6, 7)
+#if QT_DEPRECATED_SINCE(6, 8)
         NoError Q_DECL_ENUMERATOR_DEPRECATED_X(
             "This attribute has no effect.") = 0,
 #endif
-        UrlNotFound,
+        UrlNotFound = 1,
         UrlInvalid,
         RequestAborted,
         RequestDenied,

From 661a06bf3eed90d000eeb2116cc37681b4a7736e Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 20 Jun 2024 14:42:44 +0200
Subject: [PATCH 033/356] Remove leftover EGL context initialization methods

Their usage was removed by
caf5f383a Fix building on Windows and macOS with chromium EGL

Change-Id: I1e707a6976a1acd28081964cea6571dde6ea7979
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 21ab3a899a9dcd6100d677c169b725d632e41028)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/ozone/gl_context_qt.cpp | 17 -----------------
 src/core/ozone/gl_context_qt.h   |  3 ---
 2 files changed, 20 deletions(-)

diff --git a/src/core/ozone/gl_context_qt.cpp b/src/core/ozone/gl_context_qt.cpp
index 2e358c0fbb0..634e2aa0f64 100644
--- a/src/core/ozone/gl_context_qt.cpp
+++ b/src/core/ozone/gl_context_qt.cpp
@@ -75,23 +75,6 @@ void GLContextHelper::destroy()
     contextHelper = nullptr;
 }
 
-bool GLContextHelper::initializeContextOnBrowserThread(gl::GLContext* context, gl::GLSurface* surface, gl::GLContextAttribs attribs)
-{
-    return context->Initialize(surface, attribs);
-}
-
-bool GLContextHelper::initializeContext(gl::GLContext* context, gl::GLSurface* surface, gl::GLContextAttribs attribs)
-{
-    bool ret = false;
-    Qt::ConnectionType connType = (QThread::currentThread() == qApp->thread()) ? Qt::DirectConnection : Qt::BlockingQueuedConnection;
-    QMetaObject::invokeMethod(contextHelper, "initializeContextOnBrowserThread", connType,
-            Q_RETURN_ARG(bool, ret),
-            Q_ARG(gl::GLContext*, context),
-            Q_ARG(gl::GLSurface*, surface),
-            Q_ARG(gl::GLContextAttribs, attribs));
-    return ret;
-}
-
 void* GLContextHelper::getEGLConfig()
 {
     QByteArray resource = QByteArrayLiteral("eglconfig");
diff --git a/src/core/ozone/gl_context_qt.h b/src/core/ozone/gl_context_qt.h
index 41c6a5f0c9b..1607284331b 100644
--- a/src/core/ozone/gl_context_qt.h
+++ b/src/core/ozone/gl_context_qt.h
@@ -28,7 +28,6 @@ class GLContextHelper : public QObject {
 public:
     static void initialize();
     static void destroy();
-    static bool initializeContext(gl::GLContext* context, gl::GLSurface* surface, gl::GLContextAttribs attribs);
 
     static void* getEGLConfig();
     static void* getGlXConfig();
@@ -42,8 +41,6 @@ class GLContextHelper : public QObject {
     static void *getEglPlatformInterface();
 
 private:
-    Q_INVOKABLE bool initializeContextOnBrowserThread(gl::GLContext* context, gl::GLSurface* surface, gl::GLContextAttribs attribs);
-
     static GLContextHelper* contextHelper;
     bool m_robustness = false;
 };

From d46f4a69a62ffc440ebd6d52ae9eabe440827910 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 20 Jun 2024 14:08:58 +0200
Subject: [PATCH 034/356] Initialize extension settings for EGL

This fixes vaapi for EGL backend. b_EGL_MESA_image_dma_buf_export
setting has to be initialized because vaapi uses the
EGL_MESA_image_dma_buf_export extension.

Also override the extension settings with our own capability check
results.

If EGL_EXT_create_context_robustness extension is not overridden it may
cause EGL_BAD_MATCH error when creating EGL context.

Change-Id: I29d4b2203f14131ffd1781f8b24c1e4e5752ffe7
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit e01cdda43c2c93dda47da5f2a447f41417d5d36e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/ozone/gl_surface_egl_qt.cpp | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/src/core/ozone/gl_surface_egl_qt.cpp b/src/core/ozone/gl_surface_egl_qt.cpp
index a0c120ac61c..cc588453d16 100644
--- a/src/core/ozone/gl_surface_egl_qt.cpp
+++ b/src/core/ozone/gl_surface_egl_qt.cpp
@@ -14,7 +14,7 @@
 #include "ui/gl/gl_display_manager.h"
 #include "ui/gl/init/gl_factory.h"
 
-#if !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_WIN)
+#if defined(USE_OZONE)
 
 using ui::GetLastEGLErrorString;
 
@@ -47,6 +47,21 @@ gl::GLDisplay *GLSurfaceEGLQt::InitializeOneOff(gl::GpuPreference preference)
         return nullptr;
     }
 
+    egl_display->ext->InitializeExtensionSettings(egl_display->GetDisplay());
+    if (egl_display->ext->b_EGL_EXT_create_context_robustness) {
+        egl_display->ext->b_EGL_EXT_create_context_robustness =
+                GLContextHelper::isCreateContextRobustnessSupported();
+    }
+
+    if (egl_display->ext->b_EGL_EXT_image_dma_buf_import
+        || egl_display->ext->b_EGL_EXT_image_dma_buf_import_modifiers
+        || egl_display->ext->b_EGL_MESA_image_dma_buf_export) {
+        const bool dmaBufSupported = EGLHelper::instance()->isDmaBufSupported();
+        egl_display->ext->b_EGL_EXT_image_dma_buf_import = dmaBufSupported;
+        egl_display->ext->b_EGL_EXT_image_dma_buf_import_modifiers = dmaBufSupported;
+        egl_display->ext->b_EGL_MESA_image_dma_buf_export = dmaBufSupported;
+    }
+
     g_config = GLContextHelper::getEGLConfig();
     if (!g_config) {
         LOG(ERROR) << "GLContextHelper::getEGLConfig() failed.";
@@ -195,4 +210,4 @@ void* GLSurfacelessQtEGL::GetShareHandle()
 }
 
 } // namespace gl
-#endif // !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_WIN)
+#endif // defined(USE_OZONE)

From 7338266ed2fc40941deef18f3c5c04d27699f695 Mon Sep 17 00:00:00 2001
From: Alexei Cazacov <alexei.cazacov@qt.io>
Date: Fri, 7 Jun 2024 08:40:25 +0300
Subject: [PATCH 035/356] Docs: fix the QML docs for the PdfSelection::text
 property

The QML docs described the "string" property, but the actual property
name is "text".

Add a selectAll() shortcut to the withdoc.qml manual test while
we're at it, for easier checking of behavior.

Fixes: QTBUG-126138
Pick-to: 6.7 6.5 6.2
Change-Id: Ieab6188661d4e9b1c1f4dc4faaf355b94bdc3f4c
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
(cherry picked from commit 1caa4fd26b25d97507e916780e34e70720ceb0b2)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/pdfquick/qquickpdfselection.cpp | 7 ++++---
 tests/manual/quick/pdf/withdoc.qml  | 4 ++++
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/pdfquick/qquickpdfselection.cpp b/src/pdfquick/qquickpdfselection.cpp
index 4776cb8b4ed..5a9aa0025e6 100644
--- a/src/pdfquick/qquickpdfselection.cpp
+++ b/src/pdfquick/qquickpdfselection.cpp
@@ -470,9 +470,10 @@ void QQuickPdfSelection::setHold(bool hold)
 }
 
 /*!
-    \qmlproperty string PdfSelection::string
+    \qmlproperty string PdfSelection::text
 
-    The string found.
+    The text that was found in the rectangular area between \l from and \l to,
+    or all text on the \l page if selectAll() was called.
 */
 QString QQuickPdfSelection::text() const
 {
@@ -483,7 +484,7 @@ QString QQuickPdfSelection::text() const
 /*!
     \qmlmethod void PdfSelection::copyToClipboard()
 
-    Copies plain text from the \l string property to the system clipboard.
+    Copies plain text from the \l text property to the system clipboard.
 */
 void QQuickPdfSelection::copyToClipboard() const
 {
diff --git a/tests/manual/quick/pdf/withdoc.qml b/tests/manual/quick/pdf/withdoc.qml
index 0a2a8663087..c388e041edd 100644
--- a/tests/manual/quick/pdf/withdoc.qml
+++ b/tests/manual/quick/pdf/withdoc.qml
@@ -125,6 +125,10 @@ Window {
                             image.sourceSize.height = image.implicitHeight / image.zoomFactor
                         }
                     }
+                    Shortcut {
+                        sequence: StandardKey.SelectAll
+                        onActivated: selection.selectAll()
+                    }
                     Shortcut {
                         sequence: "Ctrl+0"
                         onActivated: image.sourceSize = undefined

From f8e0ab645e76be0bc50888c67a501e47a8a46be0 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Thu, 27 Jun 2024 06:11:25 +0000
Subject: [PATCH 036/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I0f123e24e09b74071580b22e5587e95f34994aad
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 6703bb2ca2b..a4a9f46a3b7 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: d021fd7cb13491ad30e52fd6ebbdb655860bf045
+    ref: 8206b9b4b159c9a0244ff4f92d4c3bb8fad13c1c
     required: true
   ../qtpositioning:
-    ref: 49731b3ba22a38ab3a433fdb83f087896fb8d315
+    ref: 5a12dc643d425e96d19f6a543f7c6c51a01aa857
     required: false
   ../qttools:
-    ref: 407ff594b7b4be74731f3e3a5b265b8f073d517a
+    ref: df2a2fc4c6b32ad6203a6c90222dd9051c2f1ba5
     required: false
   ../qtwebchannel:
-    ref: e432e4c05cc94d1e35b74b832c71109340b75a3d
+    ref: 4579fb731a4954633e4398477896bbf6968c34bc
     required: false

From a955c950752680bc7c015d2101a67c4ccaeca42a Mon Sep 17 00:00:00 2001
From: Szabolcs David <davidsz@inf.u-szeged.hu>
Date: Tue, 25 Jun 2024 16:09:07 +0200
Subject: [PATCH 037/356] Additions to QWebEngineClientHints (post API review)

- Make this class accessible from QML
- Mark properties as FINAL
- Change fullVersionList to QVariantMap to support it in QML
- Access ProfileAdapter through QPointer instead of raw pointer to make
it safer

Change-Id: Ib242059378aaf6fd2c5f176ba26ed6f94e2afd76
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit d745868c586fb6469e8bd5ee6134ce3b4a83c40a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 .../quicknanobrowser/ApplicationRoot.qml      |  6 ++
 src/core/api/qwebengineclienthints.cpp        | 63 ++++++++++++++++---
 src/core/api/qwebengineclienthints.h          | 47 ++++++++------
 .../api/qquickwebengineprofile.h              |  1 +
 tests/auto/quick/publicapi/tst_publicapi.cpp  | 14 +++++
 .../qwebenginepage/tst_qwebenginepage.cpp     | 11 ++--
 6 files changed, 108 insertions(+), 34 deletions(-)

diff --git a/examples/webenginequick/quicknanobrowser/ApplicationRoot.qml b/examples/webenginequick/quicknanobrowser/ApplicationRoot.qml
index 55c41440976..5a27d46df95 100644
--- a/examples/webenginequick/quicknanobrowser/ApplicationRoot.qml
+++ b/examples/webenginequick/quicknanobrowser/ApplicationRoot.qml
@@ -10,6 +10,12 @@ QtObject {
     property QtObject defaultProfile: WebEngineProfile {
         storageName: "Profile"
         offTheRecord: false
+
+        Component.onCompleted: {
+            let fullVersionList = defaultProfile.clientHints.fullVersionList;
+            fullVersionList["QuickNanoBrowser"] = "1.0";
+            defaultProfile.clientHints.fullVersionList = fullVersionList;
+        }
     }
 
     property QtObject otrProfile: WebEngineProfile {
diff --git a/src/core/api/qwebengineclienthints.cpp b/src/core/api/qwebengineclienthints.cpp
index 907d4ae76d8..ced25b4c91c 100644
--- a/src/core/api/qwebengineclienthints.cpp
+++ b/src/core/api/qwebengineclienthints.cpp
@@ -6,6 +6,7 @@
 #include "profile_adapter.h"
 
 #include <QJsonObject>
+#include <QVariantMap>
 
 QT_BEGIN_NAMESPACE
 
@@ -35,11 +36,15 @@ QT_BEGIN_NAMESPACE
     \sa QWebEngineProfile::clientHints(), QQuickWebEngineProfile::clientHints()
 */
 
+/*! \internal
+ */
 QWebEngineClientHints::QWebEngineClientHints(QtWebEngineCore::ProfileAdapter *profileAdapter)
     : m_profileAdapter(profileAdapter)
 {
 }
 
+/*! \internal
+ */
 QWebEngineClientHints::~QWebEngineClientHints()
 {
 }
@@ -50,6 +55,8 @@ QWebEngineClientHints::~QWebEngineClientHints()
 */
 QString QWebEngineClientHints::arch() const
 {
+    if (!m_profileAdapter)
+        return QString();
     return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAArchitecture).toString();
 }
 
@@ -61,6 +68,8 @@ QString QWebEngineClientHints::arch() const
 */
 QString QWebEngineClientHints::platform() const
 {
+    if (!m_profileAdapter)
+        return QString();
     return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAPlatform).toString();
 }
 
@@ -70,6 +79,8 @@ QString QWebEngineClientHints::platform() const
 */
 QString QWebEngineClientHints::model() const
 {
+    if (!m_profileAdapter)
+        return QString();
     return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAModel).toString();
 }
 
@@ -81,6 +92,8 @@ QString QWebEngineClientHints::model() const
 */
 bool QWebEngineClientHints::isMobile() const
 {
+    if (!m_profileAdapter)
+        return false;
     return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAMobile).toBool();
 }
 
@@ -90,6 +103,8 @@ bool QWebEngineClientHints::isMobile() const
 */
 QString QWebEngineClientHints::fullVersion() const
 {
+    if (!m_profileAdapter)
+        return QString();
     return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAFullVersion).toString();
 }
 
@@ -99,6 +114,8 @@ QString QWebEngineClientHints::fullVersion() const
 */
 QString QWebEngineClientHints::platformVersion() const
 {
+    if (!m_profileAdapter)
+        return QString();
     return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAPlatformVersion).toString();
 }
 
@@ -108,6 +125,8 @@ QString QWebEngineClientHints::platformVersion() const
 */
 QString QWebEngineClientHints::bitness() const
 {
+    if (!m_profileAdapter)
+        return QString();
     return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UABitness).toString();
 }
 
@@ -115,15 +134,17 @@ QString QWebEngineClientHints::bitness() const
     \property QWebEngineClientHints::fullVersionList
     The value of the \c{Sec-CH-UA-Full-Version-List} HTTP header and \c{fullVersionList} member of NavigatorUAData in JavaScript.
 
-    It holds brand name and version number pairs in a QHash. The provided values will be automatically extended by the currently used version
+    It holds brand name and version number pairs in a QVariantMap. The provided values will be automatically extended by the currently used version
     of Chromium and a semi-random brand.
 */
-QHash<QString,QString> QWebEngineClientHints::fullVersionList() const
+QVariantMap QWebEngineClientHints::fullVersionList() const
 {
-    QHash<QString, QString> ret;
+    QVariantMap ret;
+    if (!m_profileAdapter)
+        return ret;
     QJsonObject fullVersionList = m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAFullVersionList).toJsonObject();
     for (const QString &key : fullVersionList.keys())
-        ret.insert(key, fullVersionList.value(key).toString());
+        ret.insert(key, fullVersionList.value(key).toVariant());
     return ret;
 }
 
@@ -133,54 +154,74 @@ QHash<QString,QString> QWebEngineClientHints::fullVersionList() const
 */
 bool QWebEngineClientHints::isWow64() const
 {
+    if (!m_profileAdapter)
+        return false;
     return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAWOW64).toBool();
 }
 
 void QWebEngineClientHints::setArch(const QString &arch)
 {
+    if (!m_profileAdapter)
+        return;
     m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAArchitecture, QVariant(arch));
 }
 
 void QWebEngineClientHints::setPlatform(const QString &platform)
 {
+    if (!m_profileAdapter)
+        return;
     m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAPlatform, QVariant(platform));
 }
 
 void QWebEngineClientHints::setModel(const QString &model)
 {
+    if (!m_profileAdapter)
+        return;
     m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAModel, QVariant(model));
 }
 
-void QWebEngineClientHints::setIsMobile(const bool mobile)
+void QWebEngineClientHints::setIsMobile(bool mobile)
 {
+    if (!m_profileAdapter)
+        return;
     m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAMobile, QVariant(mobile));
 }
 
 void QWebEngineClientHints::setFullVersion(const QString &fullVerson)
 {
+    if (!m_profileAdapter)
+        return;
     m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAFullVersion, QVariant(fullVerson));
 }
 
 void QWebEngineClientHints::setPlatformVersion(const QString &platformVersion)
 {
+    if (!m_profileAdapter)
+        return;
     m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAPlatformVersion, QVariant(platformVersion));
 }
 
 void QWebEngineClientHints::setBitness(const QString &bitness)
 {
+    if (!m_profileAdapter)
+        return;
     m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UABitness, QVariant(bitness));
 }
 
-void QWebEngineClientHints::setFullVersionList(const QHash<QString,QString> &fullVersionList)
+void QWebEngineClientHints::setFullVersionList(const QVariantMap &fullVersionList)
 {
+    if (!m_profileAdapter)
+        return;
     QJsonObject jsonObject;
     for (auto i = fullVersionList.cbegin(), end = fullVersionList.cend(); i != end; ++i)
-        jsonObject.insert(i.key(), QJsonValue(i.value()));
+        jsonObject.insert(i.key(), QJsonValue(i.value().toString()));
     m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAFullVersionList, QVariant(jsonObject));
 }
 
-void QWebEngineClientHints::setIsWow64(const bool wow64)
+void QWebEngineClientHints::setIsWow64(bool wow64)
 {
+    if (!m_profileAdapter)
+        return;
     m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAWOW64, QVariant(wow64));
 }
 
@@ -192,11 +233,15 @@ void QWebEngineClientHints::setIsWow64(const bool wow64)
 */
 bool QWebEngineClientHints::isAllClientHintsEnabled()
 {
+    if (!m_profileAdapter)
+        return true;
     return m_profileAdapter->clientHintsEnabled();
 }
 
 void QWebEngineClientHints::setAllClientHintsEnabled(bool enabled)
 {
+    if (!m_profileAdapter)
+        return;
     m_profileAdapter->setClientHintsEnabled(enabled);
 }
 
@@ -205,6 +250,8 @@ void QWebEngineClientHints::setAllClientHintsEnabled(bool enabled)
 */
 void QWebEngineClientHints::resetAll()
 {
+    if (!m_profileAdapter)
+        return;
     m_profileAdapter->resetClientHints();
 }
 
diff --git a/src/core/api/qwebengineclienthints.h b/src/core/api/qwebengineclienthints.h
index 8956b5cb629..efaebb99e94 100644
--- a/src/core/api/qwebengineclienthints.h
+++ b/src/core/api/qwebengineclienthints.h
@@ -7,7 +7,9 @@
 #include <QtWebEngineCore/qtwebenginecoreglobal.h>
 
 #include <QtCore/qobject.h>
-#include <QtCore/qhash.h>
+#include <QtCore/qpointer.h>
+#include <QtCore/qvariantmap.h>
+#include <QtQml/qqmlregistration.h>
 
 namespace QtWebEngineCore {
 class ProfileAdapter;
@@ -15,22 +17,26 @@ class ProfileAdapter;
 
 QT_BEGIN_NAMESPACE
 
-class Q_WEBENGINECORE_EXPORT QWebEngineClientHints
+class Q_WEBENGINECORE_EXPORT QWebEngineClientHints : public QObject
 {
-    Q_GADGET
-    Q_PROPERTY(QString arch READ arch WRITE setArch)
-    Q_PROPERTY(QString platform READ platform WRITE setPlatform)
-    Q_PROPERTY(QString model READ model WRITE setModel)
-    Q_PROPERTY(bool mobile READ isMobile WRITE setIsMobile)
-    Q_PROPERTY(QString fullVersion READ fullVersion WRITE setFullVersion)
-    Q_PROPERTY(QString platformVersion READ platformVersion WRITE setPlatformVersion)
-    Q_PROPERTY(QString bitness READ bitness WRITE setBitness)
-    Q_PROPERTY(QHash<QString,QString> fullVersionList READ fullVersionList WRITE setFullVersionList)
-    Q_PROPERTY(bool wow64 READ isWow64 WRITE setIsWow64)
-
-    Q_PROPERTY(bool isAllClientHintsEnabled READ isAllClientHintsEnabled WRITE setAllClientHintsEnabled)
+    Q_OBJECT
+    Q_PROPERTY(QString arch READ arch WRITE setArch FINAL)
+    Q_PROPERTY(QString platform READ platform WRITE setPlatform FINAL)
+    Q_PROPERTY(QString model READ model WRITE setModel FINAL)
+    Q_PROPERTY(bool mobile READ isMobile WRITE setIsMobile FINAL)
+    Q_PROPERTY(QString fullVersion READ fullVersion WRITE setFullVersion FINAL)
+    Q_PROPERTY(QString platformVersion READ platformVersion WRITE setPlatformVersion FINAL)
+    Q_PROPERTY(QString bitness READ bitness WRITE setBitness FINAL)
+    Q_PROPERTY(QVariantMap fullVersionList READ fullVersionList WRITE setFullVersionList FINAL)
+    Q_PROPERTY(bool wow64 READ isWow64 WRITE setIsWow64 FINAL)
+
+    Q_PROPERTY(bool isAllClientHintsEnabled READ isAllClientHintsEnabled WRITE setAllClientHintsEnabled FINAL)
 
 public:
+    QML_NAMED_ELEMENT(WebEngineClientHints)
+    QML_UNCREATABLE("")
+    QML_ADDED_IN_VERSION(6, 8)
+
     ~QWebEngineClientHints();
 
     QString arch() const;
@@ -40,31 +46,32 @@ class Q_WEBENGINECORE_EXPORT QWebEngineClientHints
     QString fullVersion() const;
     QString platformVersion() const;
     QString bitness() const;
-    QHash<QString,QString> fullVersionList() const;
+    QVariantMap fullVersionList() const;
     bool isWow64() const;
 
     void setArch(const QString &);
     void setPlatform(const QString &);
     void setModel(const QString &);
-    void setIsMobile(const bool);
+    void setIsMobile(bool);
     void setFullVersion(const QString &);
     void setPlatformVersion(const QString &);
     void setBitness(const QString &);
-    void setFullVersionList(const QHash<QString,QString> &);
-    void setIsWow64(const bool);
+    void setFullVersionList(const QVariantMap &);
+    void setIsWow64(bool);
 
     bool isAllClientHintsEnabled();
     void setAllClientHintsEnabled(bool enabled);
 
-    void resetAll();
+    Q_INVOKABLE void resetAll();
 
 private:
     explicit QWebEngineClientHints(QtWebEngineCore::ProfileAdapter *profileAdapter);
+
     Q_DISABLE_COPY(QWebEngineClientHints)
     friend class QWebEngineProfilePrivate;
     friend class QQuickWebEngineProfilePrivate;
 
-    QtWebEngineCore::ProfileAdapter *m_profileAdapter;
+    QPointer<QtWebEngineCore::ProfileAdapter> m_profileAdapter;
 };
 
 QT_END_NAMESPACE
diff --git a/src/webenginequick/api/qquickwebengineprofile.h b/src/webenginequick/api/qquickwebengineprofile.h
index 186a11d7bc4..f5b7ce8e7e0 100644
--- a/src/webenginequick/api/qquickwebengineprofile.h
+++ b/src/webenginequick/api/qquickwebengineprofile.h
@@ -41,6 +41,7 @@ class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineProfile : public QObject {
     Q_PROPERTY(QQuickWebEngineScriptCollection *userScripts READ userScripts)
     Q_PROPERTY(QString downloadPath READ downloadPath WRITE setDownloadPath NOTIFY downloadPathChanged FINAL REVISION(1,5))
     Q_PROPERTY(bool isPushServiceEnabled READ isPushServiceEnabled WRITE setPushServiceEnabled NOTIFY pushServiceEnabledChanged FINAL REVISION(6,5))
+    Q_PROPERTY(QWebEngineClientHints *clientHints READ clientHints FINAL REVISION(6,8))
     QML_NAMED_ELEMENT(WebEngineProfile)
     QML_ADDED_IN_VERSION(1, 1)
     QML_EXTRA_VERSION(2, 0)
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index 0046de78453..45501cd6099 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -20,6 +20,7 @@
 #include <QtWebEngineCore/QWebEngineNotification>
 #include <QtWebEngineCore/QWebEngineQuotaRequest>
 #include <QtWebEngineCore/QWebEngineRegisterProtocolHandlerRequest>
+#include <QtWebEngineCore/QWebEngineClientHints>
 #include <QtWebEngineCore/QWebEngineContextMenuRequest>
 #include <QtWebEngineCore/QWebEngineDownloadRequest>
 #include <QtWebEngineCore/QWebEngineScript>
@@ -80,6 +81,7 @@ static const QList<const QMetaObject *> typesToCheck = QList<const QMetaObject *
     << &QWebEngineWebAuthUxRequest::staticMetaObject
     << &QWebEngineWebAuthPinRequest::staticMetaObject
     << &QWebEngineFrame::staticMetaObject
+    << &QWebEngineClientHints::staticMetaObject
     ;
 
 static QList<QMetaEnum> knownEnumNames = QList<QMetaEnum>()
@@ -144,6 +146,17 @@ static const QStringList expectedAPI = QStringList()
     << "QWebEngineCertificateError.overridable --> bool"
     << "QWebEngineCertificateError.rejectCertificate() --> void"
     << "QWebEngineCertificateError.url --> QUrl"
+    << "QWebEngineClientHints.arch --> QString"
+    << "QWebEngineClientHints.platform --> QString"
+    << "QWebEngineClientHints.model --> QString"
+    << "QWebEngineClientHints.mobile --> bool"
+    << "QWebEngineClientHints.fullVersion --> QString"
+    << "QWebEngineClientHints.platformVersion --> QString"
+    << "QWebEngineClientHints.bitness --> QString"
+    << "QWebEngineClientHints.fullVersionList --> QVariantMap"
+    << "QWebEngineClientHints.wow64 --> bool"
+    << "QWebEngineClientHints.isAllClientHintsEnabled --> bool"
+    << "QWebEngineClientHints.resetAll() --> void"
     << "QQuickWebEngineClientCertificateOption.issuer --> QString"
     << "QQuickWebEngineClientCertificateOption.subject --> QString"
     << "QQuickWebEngineClientCertificateOption.effectiveDate --> QDateTime"
@@ -395,6 +408,7 @@ static const QStringList expectedAPI = QStringList()
     << "QQuickWebEngineProfile.cachePathChanged() --> void"
     << "QQuickWebEngineProfile.clearHttpCache() --> void"
     << "QQuickWebEngineProfile.clearHttpCacheCompleted() --> void"
+    << "QQuickWebEngineProfile.clientHints --> QWebEngineClientHints*"
     << "QQuickWebEngineProfile.downloadFinished(QQuickWebEngineDownloadRequest*) --> void"
     << "QQuickWebEngineProfile.downloadRequested(QQuickWebEngineDownloadRequest*) --> void"
     << "QQuickWebEngineProfile.downloadPath --> QString"
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index e7f2ce1cd7a..5af1e9ff9ff 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -5434,11 +5434,11 @@ void tst_QWebEnginePage::clientHints_data()
     QTest::addColumn<QString>("platformVersion");
     QTest::addColumn<QString>("bitness");
     QTest::addColumn<bool>("isWOW64");
-    QTest::addColumn<QHash<QString, QString>>("fullVersionList");
+    QTest::addColumn<QVariantMap>("fullVersionList");
 
-    QTest::newRow("Modify values") << true << "Abc" << "AmigaOS" << "Ultra" << true << "1.99" << "3" << "x64" << true << QHash<QString, QString>({{"APITest", "1.0.0"}, {"App", "5.0"}});
-    QTest::newRow("Empty values") << true << "" << "" << "" << false << "" << "" << "" << false << QHash<QString, QString>();
-    QTest::newRow("Disable headers") << false << "" << "" << "" << false << "" << "" << "" << false << QHash<QString, QString>();
+    QTest::newRow("Modify values") << true << "Abc" << "AmigaOS" << "Ultra" << true << "1.99" << "3" << "x64" << true << QVariantMap({{"APITest", "1.0.0"}, {"App", "5.0"}});
+    QTest::newRow("Empty values") << true << "" << "" << "" << false << "" << "" << "" << false << QVariantMap();
+    QTest::newRow("Disable headers") << false << "" << "" << "" << false << "" << "" << "" << false << QVariantMap();
 }
 
 void tst_QWebEnginePage::clientHints()
@@ -5452,8 +5452,7 @@ void tst_QWebEnginePage::clientHints()
     QFETCH(QString, platformVersion);
     QFETCH(QString, bitness);
     QFETCH(bool, isWOW64);
-    typedef QHash<QString, QString> brandVersionPairs;
-    QFETCH(brandVersionPairs, fullVersionList);
+    QFETCH(QVariantMap, fullVersionList);
 
     QWebEnginePage page;
     QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));

From 2d053c4fd0a58500090434c4c6ffa818035d6ec0 Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Fri, 21 Jun 2024 15:45:28 +0200
Subject: [PATCH 038/356] Use QAnyStringView instead of QString cr

Change-Id: I54f1cd3784ef2fb3e9547281592db9217f819966
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit c258d265a5d56f7c4684487a27322d8aeebe95fa)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebenginepage.cpp | 4 ++--
 src/core/api/qwebenginepage.h   | 3 ++-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp
index d7e56c0a1dd..a5c06f29ce8 100644
--- a/src/core/api/qwebenginepage.cpp
+++ b/src/core/api/qwebenginepage.cpp
@@ -2574,10 +2574,10 @@ QWebEngineFrame QWebEnginePage::mainFrame()
     Returns the frame with the given \a name. If there are multiple frames with the same
     name, which one is returned is arbitrary. If no frame was found, returns \c std::nullopt.
 */
-std::optional<QWebEngineFrame> QWebEnginePage::findFrameByName(const QString &name)
+std::optional<QWebEngineFrame> QWebEnginePage::findFrameByName(QAnyStringView name)
 {
     Q_D(QWebEnginePage);
-    if (auto maybeId = d->adapter->findFrameIdByName(name)) {
+    if (auto maybeId = d->adapter->findFrameIdByName(name.toString())) {
         return QWebEngineFrame(d, *maybeId);
     }
     return {};
diff --git a/src/core/api/qwebenginepage.h b/src/core/api/qwebenginepage.h
index cca7c55e7a8..61c9bd990c1 100644
--- a/src/core/api/qwebenginepage.h
+++ b/src/core/api/qwebenginepage.h
@@ -11,6 +11,7 @@
 #include <QtWebEngineCore/qwebengineframe.h>
 #include <QtWebEngineCore/qwebenginepermission.h>
 
+#include <QtCore/qanystringview.h>
 #include <QtCore/qobject.h>
 #include <QtCore/qurl.h>
 #include <QtGui/qpagelayout.h>
@@ -324,7 +325,7 @@ QT_WARNING_POP
     void setVisible(bool visible);
 
     QWebEngineFrame mainFrame();
-    std::optional<QWebEngineFrame> findFrameByName(const QString &name);
+    std::optional<QWebEngineFrame> findFrameByName(QAnyStringView name);
 
     void acceptAsNewWindow(QWebEngineNewWindowRequest &request);
 

From bcfb37c93850ae4bfc189d6d48835f4467e90159 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucie=20G=C3=A9rard?= <lucie.gerard@qt.io>
Date: Thu, 28 Mar 2024 15:35:21 +0100
Subject: [PATCH 039/356] Correct license for test files
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

According to QUIP-18 [1], all test files should be
LicenseRef-Qt-Commercial OR GPL-3.0-only

[1]: https://contribute.qt-project.org/quips/18

Pick-to: 6.7
Task-number: QTBUG-121787
Change-Id: I7ba480e5d9b9095ad6686c8b1c857f35caf17d04
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Kai Köhne <kai.koehne@qt.io>
(cherry picked from commit a2d4c8a183e763b097e16f52172092cdb627b731)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 tests/auto/core/certificateerror/tst_certificateerror.cpp       | 2 +-
 tests/auto/core/devtools/tst_devtools.cpp                       | 2 +-
 .../auto/core/getdomainandregistry/tst_getdomainandregistry.cpp | 2 +-
 tests/auto/core/origins/tst_origins.cpp                         | 2 +-
 tests/auto/core/qtversion/tst_qtversion.cpp                     | 2 +-
 .../tst_qwebengineclientcertificatestore.cpp                    | 2 +-
 .../core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp    | 2 +-
 .../qwebengineglobalsettings/tst_qwebengineglobalsettings.cpp   | 2 +-
 .../core/qwebengineloadinginfo/tst_qwebengineloadinginfo.cpp    | 2 +-
 .../tst_qwebengineurlrequestinterceptor.cpp                     | 2 +-
 .../qwebengineurlrequestjob/tst_qwebengineurlrequestjob.cpp     | 2 +-
 tests/auto/core/webenginedriver/browser/main.cpp                | 2 +-
 tests/auto/core/webenginedriver/tst_webenginedriver.cpp         | 2 +-
 tests/auto/httpserver/httpreqrep.cpp                            | 2 +-
 tests/auto/httpserver/httpreqrep.h                              | 2 +-
 tests/auto/httpserver/httpserver.cpp                            | 2 +-
 tests/auto/httpserver/httpserver.h                              | 2 +-
 tests/auto/httpserver/httpsserver.h                             | 2 +-
 tests/auto/httpserver/proxy_server.cpp                          | 2 +-
 tests/auto/httpserver/proxy_server.h                            | 2 +-
 tests/auto/pdf/qpdfbookmarkmodel/tst_qpdfbookmarkmodel.cpp      | 2 +-
 tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp                | 2 +-
 tests/auto/pdf/qpdfpagenavigator/tst_qpdfpagenavigator.cpp      | 2 +-
 tests/auto/pdf/qpdfpagerenderer/tst_qpdfpagerenderer.cpp        | 2 +-
 tests/auto/pdf/qpdfsearchmodel/tst_qpdfsearchmodel.cpp          | 2 +-
 tests/auto/pdfquick/multipageview/tst_multipageview.cpp         | 2 +-
 tests/auto/pdfquick/pdfpageimage/tst_pdfpageimage.cpp           | 2 +-
 tests/auto/pdfquick/shared/util.cpp                             | 2 +-
 tests/auto/pdfquick/shared/util.h                               | 2 +-
 tests/auto/quick/dialogs/WebView.qml                            | 2 +-
 tests/auto/quick/dialogs/testhandler.cpp                        | 2 +-
 tests/auto/quick/dialogs/testhandler.h                          | 2 +-
 tests/auto/quick/dialogs/tst_dialogs.cpp                        | 2 +-
 tests/auto/quick/inspectorserver/tst_inspectorserver.cpp        | 2 +-
 tests/auto/quick/publicapi/tst_publicapi.cpp                    | 2 +-
 tests/auto/quick/qmltests/data/TestWebEngineView.qml            | 2 +-
 tests/auto/quick/qmltests/data/titleupdate.js                   | 2 +-
 tests/auto/quick/qmltests/data/tst_action.qml                   | 2 +-
 tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml       | 2 +-
 tests/auto/quick/qmltests/data/tst_audioMuted.qml               | 2 +-
 tests/auto/quick/qmltests/data/tst_basicProfiles.qml            | 2 +-
 tests/auto/quick/qmltests/data/tst_certificateError.qml         | 2 +-
 tests/auto/quick/qmltests/data/tst_contextMenu.qml              | 2 +-
 tests/auto/quick/qmltests/data/tst_datalist.qml                 | 2 +-
 tests/auto/quick/qmltests/data/tst_desktopBehaviorLoadHtml.qml  | 2 +-
 tests/auto/quick/qmltests/data/tst_download.qml                 | 2 +-
 tests/auto/quick/qmltests/data/tst_dragHandlerUnderView.qml     | 2 +-
 tests/auto/quick/qmltests/data/tst_favicon.qml                  | 2 +-
 tests/auto/quick/qmltests/data/tst_faviconDatabase.qml          | 2 +-
 tests/auto/quick/qmltests/data/tst_filePicker.qml               | 2 +-
 tests/auto/quick/qmltests/data/tst_filesystem.qml               | 2 +-
 tests/auto/quick/qmltests/data/tst_findText.qml                 | 2 +-
 tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml        | 2 +-
 tests/auto/quick/qmltests/data/tst_geopermission.qml            | 2 +-
 tests/auto/quick/qmltests/data/tst_getUserMedia.qml             | 2 +-
 tests/auto/quick/qmltests/data/tst_inputMethod.qml              | 2 +-
 tests/auto/quick/qmltests/data/tst_inputTextDirection.qml       | 2 +-
 tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml        | 2 +-
 tests/auto/quick/qmltests/data/tst_keyboardEvents.qml           | 2 +-
 tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml  | 2 +-
 tests/auto/quick/qmltests/data/tst_linkHovered.qml              | 2 +-
 tests/auto/quick/qmltests/data/tst_loadFail.qml                 | 2 +-
 tests/auto/quick/qmltests/data/tst_loadHtml.qml                 | 2 +-
 tests/auto/quick/qmltests/data/tst_loadProgress.qml             | 2 +-
 tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml       | 2 +-
 tests/auto/quick/qmltests/data/tst_loadUrl.qml                  | 2 +-
 tests/auto/quick/qmltests/data/tst_mouseClick.qml               | 2 +-
 tests/auto/quick/qmltests/data/tst_mouseMove.qml                | 2 +-
 tests/auto/quick/qmltests/data/tst_navigationHistory.qml        | 2 +-
 tests/auto/quick/qmltests/data/tst_navigationRequested.qml      | 2 +-
 tests/auto/quick/qmltests/data/tst_newViewRequest.qml           | 2 +-
 tests/auto/quick/qmltests/data/tst_notification.qml             | 2 +-
 tests/auto/quick/qmltests/data/tst_properties.qml               | 2 +-
 tests/auto/quick/qmltests/data/tst_runJavaScript.qml            | 2 +-
 tests/auto/quick/qmltests/data/tst_scrollPosition.qml           | 2 +-
 tests/auto/quick/qmltests/data/tst_settings.qml                 | 2 +-
 tests/auto/quick/qmltests/data/tst_titleChanged.qml             | 2 +-
 .../quick/qmltests/data/tst_unhandledKeyEventPropagation.qml    | 2 +-
 tests/auto/quick/qmltests/data/tst_userScriptCollection.qml     | 2 +-
 tests/auto/quick/qmltests/data/tst_userScripts.qml              | 2 +-
 tests/auto/quick/qmltests/data/tst_viewSource.qml               | 2 +-
 tests/auto/quick/qmltests/data/tst_webchannel.qml               | 2 +-
 .../QtWebEngine/ControlsDelegates/AlertDialog.qml               | 2 +-
 .../QtWebEngine/ControlsDelegates/ConfirmDialog.qml             | 2 +-
 .../QtWebEngine/ControlsDelegates/DirectoryPicker.qml           | 2 +-
 .../mock-delegates/QtWebEngine/ControlsDelegates/FilePicker.qml | 2 +-
 .../mock-delegates/QtWebEngine/ControlsDelegates/Menu.qml       | 2 +-
 .../mock-delegates/QtWebEngine/ControlsDelegates/MenuItem.qml   | 2 +-
 .../QtWebEngine/ControlsDelegates/PromptDialog.qml              | 2 +-
 .../qmltests/mock-delegates/TestParams/FilePickerParams.qml     | 2 +-
 .../quick/qmltests/mock-delegates/TestParams/JSDialogParams.qml | 2 +-
 .../quick/qmltests/mock-delegates/TestParams/MenuParams.qml     | 2 +-
 tests/auto/quick/qmltests/tst_qmltests.cpp                      | 2 +-
 .../tst_qquickwebenginedefaultsurfaceformat.cpp                 | 2 +-
 .../auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp  | 2 +-
 .../tst_qquickwebengineviewgraphics.cpp                         | 2 +-
 tests/auto/quick/qtbug-70248/tst_qtbug-70248.cpp                | 2 +-
 tests/auto/quick/uidelegates/tst_uidelegates.cpp                | 2 +-
 tests/auto/util/qt_webengine_quicktest.h                        | 2 +-
 tests/auto/util/quickutil.h                                     | 2 +-
 tests/auto/util/testwindow.h                                    | 2 +-
 tests/auto/util/util.h                                          | 2 +-
 tests/auto/util/widgetutil.h                                    | 2 +-
 .../widgets/defaultsurfaceformat/tst_defaultsurfaceformat.cpp   | 2 +-
 tests/auto/widgets/favicon/tst_favicon.cpp                      | 2 +-
 tests/auto/widgets/loadsignals/tst_loadsignals.cpp              | 2 +-
 tests/auto/widgets/offscreen/tst_offscreen.cpp                  | 2 +-
 tests/auto/widgets/printing/tst_printing.cpp                    | 2 +-
 tests/auto/widgets/proxy/tst_proxy.cpp                          | 2 +-
 tests/auto/widgets/proxypac/proxyserver.cpp                     | 2 +-
 tests/auto/widgets/proxypac/proxyserver.h                       | 2 +-
 tests/auto/widgets/proxypac/tst_proxypac.cpp                    | 2 +-
 tests/auto/widgets/qtbug_110287/tst_qtbug_110287.cpp            | 2 +-
 .../qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp | 2 +-
 tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp  | 2 +-
 tests/auto/widgets/schemes/tst_schemes.cpp                      | 2 +-
 tests/auto/widgets/shutdown/tst_shutdown.cpp                    | 2 +-
 tests/auto/widgets/spellchecking/tst_spellchecking.cpp          | 2 +-
 tests/auto/widgets/touchinput/tst_touchinput.cpp                | 2 +-
 tests/manual/quick/geopermission/main.cpp                       | 2 +-
 tests/manual/quick/geopermission/tst_geopermission.qml          | 2 +-
 tests/manual/quick/pdf/bookmarks-list.qml                       | 2 +-
 tests/manual/quick/pdf/bookmarks.qml                            | 2 +-
 tests/manual/quick/pdf/gridview.qml                             | 2 +-
 tests/manual/quick/pdf/listview.qml                             | 2 +-
 tests/manual/quick/pdf/multipleDocuments.qml                    | 2 +-
 tests/manual/quick/pdf/pdfPageView.qml                          | 2 +-
 tests/manual/quick/pdf/pessimizedListView.qml                   | 2 +-
 tests/manual/quick/pdf/simplest.qml                             | 2 +-
 tests/manual/quick/pdf/underscoredLinks.qml                     | 2 +-
 tests/manual/quick/pdf/withdoc.qml                              | 2 +-
 tests/manual/quick/touchbrowser/AddressBar.qml                  | 2 +-
 tests/manual/quick/touchbrowser/MockTouchPoint.qml              | 2 +-
 tests/manual/quick/touchbrowser/main.cpp                        | 2 +-
 tests/manual/quick/touchbrowser/main.qml                        | 2 +-
 tests/manual/touchmocking/touchmockingapplication.cpp           | 2 +-
 tests/manual/touchmocking/touchmockingapplication.h             | 2 +-
 tests/manual/touchmocking/utils.h                               | 2 +-
 tests/manual/widgets/geolocation/main.cpp                       | 2 +-
 tests/manual/widgets/inputmethods/colorpicker.cpp               | 2 +-
 tests/manual/widgets/inputmethods/colorpicker.h                 | 2 +-
 tests/manual/widgets/inputmethods/controlview.cpp               | 2 +-
 tests/manual/widgets/inputmethods/controlview.h                 | 2 +-
 tests/manual/widgets/inputmethods/main.cpp                      | 2 +-
 tests/manual/widgets/inputmethods/referenceview.cpp             | 2 +-
 tests/manual/widgets/inputmethods/referenceview.h               | 2 +-
 tests/manual/widgets/inputmethods/testview.cpp                  | 2 +-
 tests/manual/widgets/inputmethods/testview.h                    | 2 +-
 tests/manual/widgets/inputmethods/webview.cpp                   | 2 +-
 tests/manual/widgets/inputmethods/webview.h                     | 2 +-
 tests/manual/widgets/touchbrowser/main.cpp                      | 2 +-
 tests/manual/widgets/webgl/main.cpp                             | 2 +-
 tests/manual/widgets/webrtc/main.cpp                            | 2 +-
 153 files changed, 153 insertions(+), 153 deletions(-)

diff --git a/tests/auto/core/certificateerror/tst_certificateerror.cpp b/tests/auto/core/certificateerror/tst_certificateerror.cpp
index 61201e250bf..252e1544d64 100644
--- a/tests/auto/core/certificateerror/tst_certificateerror.cpp
+++ b/tests/auto/core/certificateerror/tst_certificateerror.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 #include <httpsserver.h>
 #include <util.h>
 
diff --git a/tests/auto/core/devtools/tst_devtools.cpp b/tests/auto/core/devtools/tst_devtools.cpp
index 57a2b83a357..7284f0d51e5 100644
--- a/tests/auto/core/devtools/tst_devtools.cpp
+++ b/tests/auto/core/devtools/tst_devtools.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QtTest/QtTest>
 
diff --git a/tests/auto/core/getdomainandregistry/tst_getdomainandregistry.cpp b/tests/auto/core/getdomainandregistry/tst_getdomainandregistry.cpp
index e9e0bf105d0..f5b8910e8d2 100644
--- a/tests/auto/core/getdomainandregistry/tst_getdomainandregistry.cpp
+++ b/tests/auto/core/getdomainandregistry/tst_getdomainandregistry.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QtTest/QtTest>
 #include <QtWebEngineCore/qtwebenginecoreglobal.h>
diff --git a/tests/auto/core/origins/tst_origins.cpp b/tests/auto/core/origins/tst_origins.cpp
index 81385701f74..06af1123e2a 100644
--- a/tests/auto/core/origins/tst_origins.cpp
+++ b/tests/auto/core/origins/tst_origins.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <util.h>
 #include "httpserver.h"
diff --git a/tests/auto/core/qtversion/tst_qtversion.cpp b/tests/auto/core/qtversion/tst_qtversion.cpp
index 44c2d4e5c90..66df04412c4 100644
--- a/tests/auto/core/qtversion/tst_qtversion.cpp
+++ b/tests/auto/core/qtversion/tst_qtversion.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2023 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QtTest/QtTest>
 #include <QtWebEngineCore/qwebenginepage.h>
diff --git a/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp b/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp
index 7d82a56405f..d203ab130b3 100644
--- a/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp
+++ b/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <httpsserver.h>
 #include <util.h>
diff --git a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
index 3fff2cd459c..a75002ae51c 100644
--- a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
+++ b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <util.h>
 #include <QtTest/QtTest>
diff --git a/tests/auto/core/qwebengineglobalsettings/tst_qwebengineglobalsettings.cpp b/tests/auto/core/qwebengineglobalsettings/tst_qwebengineglobalsettings.cpp
index 5b6b64778d2..3e46a823e2a 100644
--- a/tests/auto/core/qwebengineglobalsettings/tst_qwebengineglobalsettings.cpp
+++ b/tests/auto/core/qwebengineglobalsettings/tst_qwebengineglobalsettings.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2023 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QtTest>
 #include <widgetutil.h>
diff --git a/tests/auto/core/qwebengineloadinginfo/tst_qwebengineloadinginfo.cpp b/tests/auto/core/qwebengineloadinginfo/tst_qwebengineloadinginfo.cpp
index ccae7436bdd..010932ea093 100644
--- a/tests/auto/core/qwebengineloadinginfo/tst_qwebengineloadinginfo.cpp
+++ b/tests/auto/core/qwebengineloadinginfo/tst_qwebengineloadinginfo.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2023 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QtTest/QtTest>
 #include <QtWebEngineCore/qwebengineprofile.h>
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
index 7cea14c0cc9..c84de3599f8 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
 
diff --git a/tests/auto/core/qwebengineurlrequestjob/tst_qwebengineurlrequestjob.cpp b/tests/auto/core/qwebengineurlrequestjob/tst_qwebengineurlrequestjob.cpp
index d92aad5c4bd..acddfb0e021 100644
--- a/tests/auto/core/qwebengineurlrequestjob/tst_qwebengineurlrequestjob.cpp
+++ b/tests/auto/core/qwebengineurlrequestjob/tst_qwebengineurlrequestjob.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2023 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QtTest/QtTest>
 #include <util.h>
diff --git a/tests/auto/core/webenginedriver/browser/main.cpp b/tests/auto/core/webenginedriver/browser/main.cpp
index 4b8f3513fe2..b43b06f2e59 100644
--- a/tests/auto/core/webenginedriver/browser/main.cpp
+++ b/tests/auto/core/webenginedriver/browser/main.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2023 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QtWebEngineCore/qwebenginepage.h>
 #include <QtWebEngineWidgets/qwebengineview.h>
diff --git a/tests/auto/core/webenginedriver/tst_webenginedriver.cpp b/tests/auto/core/webenginedriver/tst_webenginedriver.cpp
index cd3098b25cb..66e14e68307 100644
--- a/tests/auto/core/webenginedriver/tst_webenginedriver.cpp
+++ b/tests/auto/core/webenginedriver/tst_webenginedriver.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2023 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QtTest/QtTest>
 
diff --git a/tests/auto/httpserver/httpreqrep.cpp b/tests/auto/httpserver/httpreqrep.cpp
index 8b338ce4eb5..65a1df36559 100644
--- a/tests/auto/httpserver/httpreqrep.cpp
+++ b/tests/auto/httpserver/httpreqrep.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 #include "httpreqrep.h"
 
 HttpReqRep::HttpReqRep(QTcpSocket *socket, QObject *parent)
diff --git a/tests/auto/httpserver/httpreqrep.h b/tests/auto/httpserver/httpreqrep.h
index 774c08eb126..2b90b774b16 100644
--- a/tests/auto/httpserver/httpreqrep.h
+++ b/tests/auto/httpserver/httpreqrep.h
@@ -1,5 +1,5 @@
 // Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 #ifndef HTTPREQREP_H
 #define HTTPREQREP_H
 
diff --git a/tests/auto/httpserver/httpserver.cpp b/tests/auto/httpserver/httpserver.cpp
index e08af77e773..8a1d8e6f685 100644
--- a/tests/auto/httpserver/httpserver.cpp
+++ b/tests/auto/httpserver/httpserver.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 #include "httpserver.h"
 
 #include <QFile>
diff --git a/tests/auto/httpserver/httpserver.h b/tests/auto/httpserver/httpserver.h
index 201eef4c6f5..a1c2e3791f0 100644
--- a/tests/auto/httpserver/httpserver.h
+++ b/tests/auto/httpserver/httpserver.h
@@ -1,5 +1,5 @@
 // Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 #ifndef HTTPSERVER_H
 #define HTTPSERVER_H
 
diff --git a/tests/auto/httpserver/httpsserver.h b/tests/auto/httpserver/httpsserver.h
index d029851aa8d..237314965db 100644
--- a/tests/auto/httpserver/httpsserver.h
+++ b/tests/auto/httpserver/httpsserver.h
@@ -1,5 +1,5 @@
 // Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 #ifndef HTTPSSERVER_H
 #define HTTPSSERVER_H
 
diff --git a/tests/auto/httpserver/proxy_server.cpp b/tests/auto/httpserver/proxy_server.cpp
index 3384153118d..e47214ee43f 100644
--- a/tests/auto/httpserver/proxy_server.cpp
+++ b/tests/auto/httpserver/proxy_server.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include "proxy_server.h"
 #include <QDataStream>
diff --git a/tests/auto/httpserver/proxy_server.h b/tests/auto/httpserver/proxy_server.h
index 6be0c4e1ab1..8f7cd4cc6c2 100644
--- a/tests/auto/httpserver/proxy_server.h
+++ b/tests/auto/httpserver/proxy_server.h
@@ -1,5 +1,5 @@
 // Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #ifndef PROXY_SERVER_H
 #define PROXY_SERVER_H
diff --git a/tests/auto/pdf/qpdfbookmarkmodel/tst_qpdfbookmarkmodel.cpp b/tests/auto/pdf/qpdfbookmarkmodel/tst_qpdfbookmarkmodel.cpp
index a1804e17954..7c9216534ae 100644
--- a/tests/auto/pdf/qpdfbookmarkmodel/tst_qpdfbookmarkmodel.cpp
+++ b/tests/auto/pdf/qpdfbookmarkmodel/tst_qpdfbookmarkmodel.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 
 #include <QtTest/QtTest>
diff --git a/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp b/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp
index d222bff0cd2..45d1d5a7b01 100644
--- a/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp
+++ b/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 
 #include <QtTest/QtTest>
diff --git a/tests/auto/pdf/qpdfpagenavigator/tst_qpdfpagenavigator.cpp b/tests/auto/pdf/qpdfpagenavigator/tst_qpdfpagenavigator.cpp
index 327a9f36a57..4044757660e 100644
--- a/tests/auto/pdf/qpdfpagenavigator/tst_qpdfpagenavigator.cpp
+++ b/tests/auto/pdf/qpdfpagenavigator/tst_qpdfpagenavigator.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 
 #include <QtTest/QtTest>
diff --git a/tests/auto/pdf/qpdfpagerenderer/tst_qpdfpagerenderer.cpp b/tests/auto/pdf/qpdfpagerenderer/tst_qpdfpagerenderer.cpp
index 39d32df0b72..ca14338cc14 100644
--- a/tests/auto/pdf/qpdfpagerenderer/tst_qpdfpagerenderer.cpp
+++ b/tests/auto/pdf/qpdfpagerenderer/tst_qpdfpagerenderer.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QPdfDocument>
 #include <QPdfPageRenderer>
diff --git a/tests/auto/pdf/qpdfsearchmodel/tst_qpdfsearchmodel.cpp b/tests/auto/pdf/qpdfsearchmodel/tst_qpdfsearchmodel.cpp
index cf71b148e04..f5e946d1945 100644
--- a/tests/auto/pdf/qpdfsearchmodel/tst_qpdfsearchmodel.cpp
+++ b/tests/auto/pdf/qpdfsearchmodel/tst_qpdfsearchmodel.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2020 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 
 #include <QtTest/QtTest>
diff --git a/tests/auto/pdfquick/multipageview/tst_multipageview.cpp b/tests/auto/pdfquick/multipageview/tst_multipageview.cpp
index c5e0b30dbba..71c09077c36 100644
--- a/tests/auto/pdfquick/multipageview/tst_multipageview.cpp
+++ b/tests/auto/pdfquick/multipageview/tst_multipageview.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QSignalSpy>
 #include <QTest>
diff --git a/tests/auto/pdfquick/pdfpageimage/tst_pdfpageimage.cpp b/tests/auto/pdfquick/pdfpageimage/tst_pdfpageimage.cpp
index d2c9c8709f6..3f98025fa71 100644
--- a/tests/auto/pdfquick/pdfpageimage/tst_pdfpageimage.cpp
+++ b/tests/auto/pdfquick/pdfpageimage/tst_pdfpageimage.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2024 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QRegularExpression>
 #include <QSignalSpy>
diff --git a/tests/auto/pdfquick/shared/util.cpp b/tests/auto/pdfquick/shared/util.cpp
index c540ebfa66e..1bf9b45b764 100644
--- a/tests/auto/pdfquick/shared/util.cpp
+++ b/tests/auto/pdfquick/shared/util.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include "util.h"
 #include <QtQuick/QQuickItem>
diff --git a/tests/auto/pdfquick/shared/util.h b/tests/auto/pdfquick/shared/util.h
index 9ceb711afe8..2788e6104a6 100644
--- a/tests/auto/pdfquick/shared/util.h
+++ b/tests/auto/pdfquick/shared/util.h
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #ifndef QUICK_VISUAL_TEST_UTIL_H
 #define QUICK_VISUAL_TEST_UTIL_H
diff --git a/tests/auto/quick/dialogs/WebView.qml b/tests/auto/quick/dialogs/WebView.qml
index 45fafb42d1c..6db0e5777b6 100644
--- a/tests/auto/quick/dialogs/WebView.qml
+++ b/tests/auto/quick/dialogs/WebView.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtWebEngine
diff --git a/tests/auto/quick/dialogs/testhandler.cpp b/tests/auto/quick/dialogs/testhandler.cpp
index f4585263075..0596626f1fa 100644
--- a/tests/auto/quick/dialogs/testhandler.cpp
+++ b/tests/auto/quick/dialogs/testhandler.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include "testhandler.h"
 
diff --git a/tests/auto/quick/dialogs/testhandler.h b/tests/auto/quick/dialogs/testhandler.h
index c72e8184119..fef41d075f3 100644
--- a/tests/auto/quick/dialogs/testhandler.h
+++ b/tests/auto/quick/dialogs/testhandler.h
@@ -1,5 +1,5 @@
 // Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #ifndef TESTHANDLER_H
 #define TESTHANDLER_H
diff --git a/tests/auto/quick/dialogs/tst_dialogs.cpp b/tests/auto/quick/dialogs/tst_dialogs.cpp
index 2b861efa62a..6f54019c7ff 100644
--- a/tests/auto/quick/dialogs/tst_dialogs.cpp
+++ b/tests/auto/quick/dialogs/tst_dialogs.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include "testhandler.h"
 #include <quickutil.h>
diff --git a/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp b/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp
index a9638bee471..32683ad1df5 100644
--- a/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp
+++ b/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QNetworkAccessManager>
 #include <QNetworkReply>
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index 45501cd6099..f27515c51c3 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QMetaEnum>
 #include <QMetaMethod>
diff --git a/tests/auto/quick/qmltests/data/TestWebEngineView.qml b/tests/auto/quick/qmltests/data/TestWebEngineView.qml
index 415985471d8..aefeb9af56d 100644
--- a/tests/auto/quick/qmltests/data/TestWebEngineView.qml
+++ b/tests/auto/quick/qmltests/data/TestWebEngineView.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/titleupdate.js b/tests/auto/quick/qmltests/data/titleupdate.js
index 720e836761f..94bfd90dfd9 100644
--- a/tests/auto/quick/qmltests/data/titleupdate.js
+++ b/tests/auto/quick/qmltests/data/titleupdate.js
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 function updateTitle()
 {
diff --git a/tests/auto/quick/qmltests/data/tst_action.qml b/tests/auto/quick/qmltests/data/tst_action.qml
index 9e49c2dbfe1..52891197dbb 100644
--- a/tests/auto/quick/qmltests/data/tst_action.qml
+++ b/tests/auto/quick/qmltests/data/tst_action.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml b/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml
index 77968f6b637..d9ca1e8e66f 100644
--- a/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml
+++ b/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_audioMuted.qml b/tests/auto/quick/qmltests/data/tst_audioMuted.qml
index 85f813f0c28..11527f8480c 100644
--- a/tests/auto/quick/qmltests/data/tst_audioMuted.qml
+++ b/tests/auto/quick/qmltests/data/tst_audioMuted.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2020 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_basicProfiles.qml b/tests/auto/quick/qmltests/data/tst_basicProfiles.qml
index 97a25cdd87e..11d631344b9 100644
--- a/tests/auto/quick/qmltests/data/tst_basicProfiles.qml
+++ b/tests/auto/quick/qmltests/data/tst_basicProfiles.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_certificateError.qml b/tests/auto/quick/qmltests/data/tst_certificateError.qml
index 220ef9ac832..6c8e680e046 100644
--- a/tests/auto/quick/qmltests/data/tst_certificateError.qml
+++ b/tests/auto/quick/qmltests/data/tst_certificateError.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2020 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_contextMenu.qml b/tests/auto/quick/qmltests/data/tst_contextMenu.qml
index 58e27b8ba6d..9a34d3f339f 100644
--- a/tests/auto/quick/qmltests/data/tst_contextMenu.qml
+++ b/tests/auto/quick/qmltests/data/tst_contextMenu.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_datalist.qml b/tests/auto/quick/qmltests/data/tst_datalist.qml
index 1e5a7ad6b86..9e4d766ef42 100644
--- a/tests/auto/quick/qmltests/data/tst_datalist.qml
+++ b/tests/auto/quick/qmltests/data/tst_datalist.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtQuick.Controls
diff --git a/tests/auto/quick/qmltests/data/tst_desktopBehaviorLoadHtml.qml b/tests/auto/quick/qmltests/data/tst_desktopBehaviorLoadHtml.qml
index 6cb2841ec8c..5e2dd19c255 100644
--- a/tests/auto/quick/qmltests/data/tst_desktopBehaviorLoadHtml.qml
+++ b/tests/auto/quick/qmltests/data/tst_desktopBehaviorLoadHtml.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_download.qml b/tests/auto/quick/qmltests/data/tst_download.qml
index 61a363c3972..a0cb8970b48 100644
--- a/tests/auto/quick/qmltests/data/tst_download.qml
+++ b/tests/auto/quick/qmltests/data/tst_download.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_dragHandlerUnderView.qml b/tests/auto/quick/qmltests/data/tst_dragHandlerUnderView.qml
index c22bd44c285..35332b4e42a 100644
--- a/tests/auto/quick/qmltests/data/tst_dragHandlerUnderView.qml
+++ b/tests/auto/quick/qmltests/data/tst_dragHandlerUnderView.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2023 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_favicon.qml b/tests/auto/quick/qmltests/data/tst_favicon.qml
index 15f116e5db3..fcc24dfb7de 100644
--- a/tests/auto/quick/qmltests/data/tst_favicon.qml
+++ b/tests/auto/quick/qmltests/data/tst_favicon.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_faviconDatabase.qml b/tests/auto/quick/qmltests/data/tst_faviconDatabase.qml
index 28439061920..c1679000107 100644
--- a/tests/auto/quick/qmltests/data/tst_faviconDatabase.qml
+++ b/tests/auto/quick/qmltests/data/tst_faviconDatabase.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_filePicker.qml b/tests/auto/quick/qmltests/data/tst_filePicker.qml
index a7b59b2e9bb..8c769a04291 100644
--- a/tests/auto/quick/qmltests/data/tst_filePicker.qml
+++ b/tests/auto/quick/qmltests/data/tst_filePicker.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_filesystem.qml b/tests/auto/quick/qmltests/data/tst_filesystem.qml
index fa0da4457b9..5ed05b419dd 100644
--- a/tests/auto/quick/qmltests/data/tst_filesystem.qml
+++ b/tests/auto/quick/qmltests/data/tst_filesystem.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2023 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_findText.qml b/tests/auto/quick/qmltests/data/tst_findText.qml
index 597cff73e97..bd2bfbb480b 100644
--- a/tests/auto/quick/qmltests/data/tst_findText.qml
+++ b/tests/auto/quick/qmltests/data/tst_findText.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml b/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml
index f070e4bc5ed..b440e572099 100644
--- a/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml
+++ b/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_geopermission.qml b/tests/auto/quick/qmltests/data/tst_geopermission.qml
index e425a82c742..1eb68749738 100644
--- a/tests/auto/quick/qmltests/data/tst_geopermission.qml
+++ b/tests/auto/quick/qmltests/data/tst_geopermission.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_getUserMedia.qml b/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
index 9a876778b37..fbc863a45f6 100644
--- a/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
+++ b/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_inputMethod.qml b/tests/auto/quick/qmltests/data/tst_inputMethod.qml
index cf79e8a4d89..d8ed8e55e90 100644
--- a/tests/auto/quick/qmltests/data/tst_inputMethod.qml
+++ b/tests/auto/quick/qmltests/data/tst_inputMethod.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_inputTextDirection.qml b/tests/auto/quick/qmltests/data/tst_inputTextDirection.qml
index 2141db4c80a..52675983a6b 100644
--- a/tests/auto/quick/qmltests/data/tst_inputTextDirection.qml
+++ b/tests/auto/quick/qmltests/data/tst_inputTextDirection.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2023 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml b/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml
index 6e91b2e7742..49ba5ae471c 100644
--- a/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml
+++ b/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml b/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml
index 0f69a7e81a7..6a67b698316 100644
--- a/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml
+++ b/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml b/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml
index d0bc75619b4..33be0329a2e 100644
--- a/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml
+++ b/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_linkHovered.qml b/tests/auto/quick/qmltests/data/tst_linkHovered.qml
index a11bd2450bd..593beb7356a 100644
--- a/tests/auto/quick/qmltests/data/tst_linkHovered.qml
+++ b/tests/auto/quick/qmltests/data/tst_linkHovered.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_loadFail.qml b/tests/auto/quick/qmltests/data/tst_loadFail.qml
index 8e9224bbf92..b6d3419f7c6 100644
--- a/tests/auto/quick/qmltests/data/tst_loadFail.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadFail.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_loadHtml.qml b/tests/auto/quick/qmltests/data/tst_loadHtml.qml
index 8f94cd4a27d..db2035842e9 100644
--- a/tests/auto/quick/qmltests/data/tst_loadHtml.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadHtml.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_loadProgress.qml b/tests/auto/quick/qmltests/data/tst_loadProgress.qml
index 2c06a02070f..30995d276ad 100644
--- a/tests/auto/quick/qmltests/data/tst_loadProgress.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadProgress.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml b/tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml
index c0eb5932b91..d6e6e108aaa 100644
--- a/tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_loadUrl.qml b/tests/auto/quick/qmltests/data/tst_loadUrl.qml
index 25a62c8787c..757343703c5 100644
--- a/tests/auto/quick/qmltests/data/tst_loadUrl.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadUrl.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_mouseClick.qml b/tests/auto/quick/qmltests/data/tst_mouseClick.qml
index c0c6a696798..cc06416c171 100644
--- a/tests/auto/quick/qmltests/data/tst_mouseClick.qml
+++ b/tests/auto/quick/qmltests/data/tst_mouseClick.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_mouseMove.qml b/tests/auto/quick/qmltests/data/tst_mouseMove.qml
index 5ded24c57c5..6ee58fcb030 100644
--- a/tests/auto/quick/qmltests/data/tst_mouseMove.qml
+++ b/tests/auto/quick/qmltests/data/tst_mouseMove.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_navigationHistory.qml b/tests/auto/quick/qmltests/data/tst_navigationHistory.qml
index 2ea76c3872a..54d2ffd4bcc 100644
--- a/tests/auto/quick/qmltests/data/tst_navigationHistory.qml
+++ b/tests/auto/quick/qmltests/data/tst_navigationHistory.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_navigationRequested.qml b/tests/auto/quick/qmltests/data/tst_navigationRequested.qml
index 31c0cf44e31..785cfa27abd 100644
--- a/tests/auto/quick/qmltests/data/tst_navigationRequested.qml
+++ b/tests/auto/quick/qmltests/data/tst_navigationRequested.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
index 68350d10737..67142677144 100644
--- a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
+++ b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_notification.qml b/tests/auto/quick/qmltests/data/tst_notification.qml
index 5defbff4b6f..4f064af3d3c 100644
--- a/tests/auto/quick/qmltests/data/tst_notification.qml
+++ b/tests/auto/quick/qmltests/data/tst_notification.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_properties.qml b/tests/auto/quick/qmltests/data/tst_properties.qml
index 13d40ed116d..e3d6ed6254f 100644
--- a/tests/auto/quick/qmltests/data/tst_properties.qml
+++ b/tests/auto/quick/qmltests/data/tst_properties.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_runJavaScript.qml b/tests/auto/quick/qmltests/data/tst_runJavaScript.qml
index f16cd9c419f..542a3aac697 100644
--- a/tests/auto/quick/qmltests/data/tst_runJavaScript.qml
+++ b/tests/auto/quick/qmltests/data/tst_runJavaScript.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_scrollPosition.qml b/tests/auto/quick/qmltests/data/tst_scrollPosition.qml
index cc7d15e4c77..e90f879139d 100644
--- a/tests/auto/quick/qmltests/data/tst_scrollPosition.qml
+++ b/tests/auto/quick/qmltests/data/tst_scrollPosition.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_settings.qml b/tests/auto/quick/qmltests/data/tst_settings.qml
index f47674aa7fa..4cd0bf6a7a2 100644
--- a/tests/auto/quick/qmltests/data/tst_settings.qml
+++ b/tests/auto/quick/qmltests/data/tst_settings.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_titleChanged.qml b/tests/auto/quick/qmltests/data/tst_titleChanged.qml
index 66a7c115f79..16dafa5932d 100644
--- a/tests/auto/quick/qmltests/data/tst_titleChanged.qml
+++ b/tests/auto/quick/qmltests/data/tst_titleChanged.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml b/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml
index 76363fa7113..75d0d38d9ac 100644
--- a/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml
+++ b/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_userScriptCollection.qml b/tests/auto/quick/qmltests/data/tst_userScriptCollection.qml
index 94c9937715e..fbf4f083332 100644
--- a/tests/auto/quick/qmltests/data/tst_userScriptCollection.qml
+++ b/tests/auto/quick/qmltests/data/tst_userScriptCollection.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_userScripts.qml b/tests/auto/quick/qmltests/data/tst_userScripts.qml
index 30704f47b4f..a64de389d8e 100644
--- a/tests/auto/quick/qmltests/data/tst_userScripts.qml
+++ b/tests/auto/quick/qmltests/data/tst_userScripts.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_viewSource.qml b/tests/auto/quick/qmltests/data/tst_viewSource.qml
index d4449f7de55..a79de3e3a2d 100644
--- a/tests/auto/quick/qmltests/data/tst_viewSource.qml
+++ b/tests/auto/quick/qmltests/data/tst_viewSource.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_webchannel.qml b/tests/auto/quick/qmltests/data/tst_webchannel.qml
index 780b559341b..0000a212557 100644
--- a/tests/auto/quick/qmltests/data/tst_webchannel.qml
+++ b/tests/auto/quick/qmltests/data/tst_webchannel.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/AlertDialog.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/AlertDialog.qml
index 7d7efda0c0c..424c3fdb26a 100644
--- a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/AlertDialog.qml
+++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/AlertDialog.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 // Both dialogs are basically expected to behave in the same way from an API point of view
 ConfirmDialog { }
diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/ConfirmDialog.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/ConfirmDialog.qml
index 6125d0b9862..db7c2d05aa0 100644
--- a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/ConfirmDialog.qml
+++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/ConfirmDialog.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQml
 import QtTest
diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/DirectoryPicker.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/DirectoryPicker.qml
index 71da28843fc..da423e44128 100644
--- a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/DirectoryPicker.qml
+++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/DirectoryPicker.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import "../../TestParams"
diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/FilePicker.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/FilePicker.qml
index 247088bcba6..6dac9973e17 100644
--- a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/FilePicker.qml
+++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/FilePicker.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import "../../TestParams"
diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/Menu.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/Menu.qml
index cd7ed48211c..35e3b274f94 100644
--- a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/Menu.qml
+++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/Menu.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQml
 import "../../TestParams"
diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/MenuItem.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/MenuItem.qml
index 67dab1bba40..8d3a2df5153 100644
--- a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/MenuItem.qml
+++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/MenuItem.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQml
 
diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/PromptDialog.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/PromptDialog.qml
index 81a63d91843..62e48906751 100644
--- a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/PromptDialog.qml
+++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/PromptDialog.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQml
 import QtTest
diff --git a/tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml b/tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml
index 67d67dc4039..342933365d6 100644
--- a/tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml
+++ b/tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 pragma Singleton
 import QtQuick
diff --git a/tests/auto/quick/qmltests/mock-delegates/TestParams/JSDialogParams.qml b/tests/auto/quick/qmltests/mock-delegates/TestParams/JSDialogParams.qml
index 1033b509efc..4f983119721 100644
--- a/tests/auto/quick/qmltests/mock-delegates/TestParams/JSDialogParams.qml
+++ b/tests/auto/quick/qmltests/mock-delegates/TestParams/JSDialogParams.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 pragma Singleton
 import QtQml
 
diff --git a/tests/auto/quick/qmltests/mock-delegates/TestParams/MenuParams.qml b/tests/auto/quick/qmltests/mock-delegates/TestParams/MenuParams.qml
index d8a01764c90..8b6bcb28587 100644
--- a/tests/auto/quick/qmltests/mock-delegates/TestParams/MenuParams.qml
+++ b/tests/auto/quick/qmltests/mock-delegates/TestParams/MenuParams.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 pragma Singleton
 import QtQml
diff --git a/tests/auto/quick/qmltests/tst_qmltests.cpp b/tests/auto/quick/qmltests/tst_qmltests.cpp
index 9e928157e9f..01a657e8b44 100644
--- a/tests/auto/quick/qmltests/tst_qmltests.cpp
+++ b/tests/auto/quick/qmltests/tst_qmltests.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <httpserver.h>
 
diff --git a/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp
index b4c95d67126..64c1cfaa4ec 100644
--- a/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp
+++ b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include "testwindow.h"
 #include "quickutil.h"
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index cc514f87379..abe5e1f3da5 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
 
diff --git a/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp b/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
index 3644ac48187..b7cc8e7deb7 100644
--- a/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
+++ b/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <quickutil.h>
 #include <QtTest/QtTest>
diff --git a/tests/auto/quick/qtbug-70248/tst_qtbug-70248.cpp b/tests/auto/quick/qtbug-70248/tst_qtbug-70248.cpp
index cf5c187c35c..1cf62e80086 100644
--- a/tests/auto/quick/qtbug-70248/tst_qtbug-70248.cpp
+++ b/tests/auto/quick/qtbug-70248/tst_qtbug-70248.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include "qtwebenginequickglobal.h"
 #include <QQuickWebEngineProfile>
diff --git a/tests/auto/quick/uidelegates/tst_uidelegates.cpp b/tests/auto/quick/uidelegates/tst_uidelegates.cpp
index fb8734f83a7..1c3024d949f 100644
--- a/tests/auto/quick/uidelegates/tst_uidelegates.cpp
+++ b/tests/auto/quick/uidelegates/tst_uidelegates.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include "testwindow.h"
 #include "quickutil.h"
diff --git a/tests/auto/util/qt_webengine_quicktest.h b/tests/auto/util/qt_webengine_quicktest.h
index bd98693de1f..4d68f90f0e8 100644
--- a/tests/auto/util/qt_webengine_quicktest.h
+++ b/tests/auto/util/qt_webengine_quicktest.h
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #ifndef QT_WEBENGINE_QUICKTEST_H
 #define QT_WEBENGINE_QUICKTEST_H
diff --git a/tests/auto/util/quickutil.h b/tests/auto/util/quickutil.h
index 687cb94dc85..c3542478f18 100644
--- a/tests/auto/util/quickutil.h
+++ b/tests/auto/util/quickutil.h
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #ifndef UTIL_H
 #define UTIL_H
diff --git a/tests/auto/util/testwindow.h b/tests/auto/util/testwindow.h
index f9ffd381afd..dfce32b43fd 100644
--- a/tests/auto/util/testwindow.h
+++ b/tests/auto/util/testwindow.h
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #ifndef TESTWINDOW_H
 #define TESTWINDOW_H
diff --git a/tests/auto/util/util.h b/tests/auto/util/util.h
index 5533eed80a8..eab5fa91359 100644
--- a/tests/auto/util/util.h
+++ b/tests/auto/util/util.h
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 // Functions and macros that really need to be in QTestLib
 
diff --git a/tests/auto/util/widgetutil.h b/tests/auto/util/widgetutil.h
index 67d09ee4f43..b673a811f88 100644
--- a/tests/auto/util/widgetutil.h
+++ b/tests/auto/util/widgetutil.h
@@ -1,5 +1,5 @@
 // Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 // Functions and macros that really need to be in QTestLib
 
diff --git a/tests/auto/widgets/defaultsurfaceformat/tst_defaultsurfaceformat.cpp b/tests/auto/widgets/defaultsurfaceformat/tst_defaultsurfaceformat.cpp
index c53f6f5b324..3fdba71c2f0 100644
--- a/tests/auto/widgets/defaultsurfaceformat/tst_defaultsurfaceformat.cpp
+++ b/tests/auto/widgets/defaultsurfaceformat/tst_defaultsurfaceformat.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <qtest.h>
 #include <util.h>
diff --git a/tests/auto/widgets/favicon/tst_favicon.cpp b/tests/auto/widgets/favicon/tst_favicon.cpp
index c70aa1182a4..e4b5619a6fd 100644
--- a/tests/auto/widgets/favicon/tst_favicon.cpp
+++ b/tests/auto/widgets/favicon/tst_favicon.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QtTest/QtTest>
 #include <util.h>
diff --git a/tests/auto/widgets/loadsignals/tst_loadsignals.cpp b/tests/auto/widgets/loadsignals/tst_loadsignals.cpp
index 6140b3766bd..b465f985823 100644
--- a/tests/auto/widgets/loadsignals/tst_loadsignals.cpp
+++ b/tests/auto/widgets/loadsignals/tst_loadsignals.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QtTest/QtTest>
 
diff --git a/tests/auto/widgets/offscreen/tst_offscreen.cpp b/tests/auto/widgets/offscreen/tst_offscreen.cpp
index 553dc653bc9..258178dd746 100644
--- a/tests/auto/widgets/offscreen/tst_offscreen.cpp
+++ b/tests/auto/widgets/offscreen/tst_offscreen.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QTest>
 #include <QSignalSpy>
diff --git a/tests/auto/widgets/printing/tst_printing.cpp b/tests/auto/widgets/printing/tst_printing.cpp
index 605fb57b5c7..c9f6e8cfa92 100644
--- a/tests/auto/widgets/printing/tst_printing.cpp
+++ b/tests/auto/widgets/printing/tst_printing.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
 #include <QtWebEngineCore/qtwebenginecore-config.h>
diff --git a/tests/auto/widgets/proxy/tst_proxy.cpp b/tests/auto/widgets/proxy/tst_proxy.cpp
index 3dc72618c9b..c16b8cf5aac 100644
--- a/tests/auto/widgets/proxy/tst_proxy.cpp
+++ b/tests/auto/widgets/proxy/tst_proxy.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2019 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include "proxy_server.h"
 #include <QTest>
diff --git a/tests/auto/widgets/proxypac/proxyserver.cpp b/tests/auto/widgets/proxypac/proxyserver.cpp
index f7a85974784..a7bbd6934f0 100644
--- a/tests/auto/widgets/proxypac/proxyserver.cpp
+++ b/tests/auto/widgets/proxypac/proxyserver.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include "proxyserver.h"
 #include <QDataStream>
diff --git a/tests/auto/widgets/proxypac/proxyserver.h b/tests/auto/widgets/proxypac/proxyserver.h
index c95856da954..4d622175ec1 100644
--- a/tests/auto/widgets/proxypac/proxyserver.h
+++ b/tests/auto/widgets/proxypac/proxyserver.h
@@ -1,5 +1,5 @@
 // Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #ifndef PROXY_SERVER_H
 #define PROXY_SERVER_H
diff --git a/tests/auto/widgets/proxypac/tst_proxypac.cpp b/tests/auto/widgets/proxypac/tst_proxypac.cpp
index 43ccbf028a3..19654d1a963 100644
--- a/tests/auto/widgets/proxypac/tst_proxypac.cpp
+++ b/tests/auto/widgets/proxypac/tst_proxypac.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include "proxy_server.h"
 #include <QTest>
diff --git a/tests/auto/widgets/qtbug_110287/tst_qtbug_110287.cpp b/tests/auto/widgets/qtbug_110287/tst_qtbug_110287.cpp
index 9453ae9b845..904d0849361 100644
--- a/tests/auto/widgets/qtbug_110287/tst_qtbug_110287.cpp
+++ b/tests/auto/widgets/qtbug_110287/tst_qtbug_110287.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QNetworkAccessManager>
 #include <QNetworkRequest>
diff --git a/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp b/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
index c81a27b3aaf..a47bdbcc4d3 100644
--- a/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
+++ b/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <util.h>
 
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index 3cd400fdc64..5303d99fc6c 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <util.h>
 #include <QtCore/qbuffer.h>
diff --git a/tests/auto/widgets/schemes/tst_schemes.cpp b/tests/auto/widgets/schemes/tst_schemes.cpp
index 188c112e415..19bab06dafe 100644
--- a/tests/auto/widgets/schemes/tst_schemes.cpp
+++ b/tests/auto/widgets/schemes/tst_schemes.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QtTest/QtTest>
 
diff --git a/tests/auto/widgets/shutdown/tst_shutdown.cpp b/tests/auto/widgets/shutdown/tst_shutdown.cpp
index c2b31bb808f..88cbc6aa734 100644
--- a/tests/auto/widgets/shutdown/tst_shutdown.cpp
+++ b/tests/auto/widgets/shutdown/tst_shutdown.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 
 #include <QtTest/QtTest>
diff --git a/tests/auto/widgets/spellchecking/tst_spellchecking.cpp b/tests/auto/widgets/spellchecking/tst_spellchecking.cpp
index c643a56bacb..f5525c9f151 100644
--- a/tests/auto/widgets/spellchecking/tst_spellchecking.cpp
+++ b/tests/auto/widgets/spellchecking/tst_spellchecking.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <util.h>
 #include <QtTest/QtTest>
diff --git a/tests/auto/widgets/touchinput/tst_touchinput.cpp b/tests/auto/widgets/touchinput/tst_touchinput.cpp
index 42178558ccc..abc56a8e6cc 100644
--- a/tests/auto/widgets/touchinput/tst_touchinput.cpp
+++ b/tests/auto/widgets/touchinput/tst_touchinput.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2020 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <util.h>
 
diff --git a/tests/manual/quick/geopermission/main.cpp b/tests/manual/quick/geopermission/main.cpp
index e0ff6f3e7f3..b0e9a7eda9d 100644
--- a/tests/manual/quick/geopermission/main.cpp
+++ b/tests/manual/quick/geopermission/main.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2023 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QtWebEngineQuick/qtwebenginequickglobal.h>
 
diff --git a/tests/manual/quick/geopermission/tst_geopermission.qml b/tests/manual/quick/geopermission/tst_geopermission.qml
index ace48d464d4..6d6f4de8bc8 100644
--- a/tests/manual/quick/geopermission/tst_geopermission.qml
+++ b/tests/manual/quick/geopermission/tst_geopermission.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2023 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtTest
diff --git a/tests/manual/quick/pdf/bookmarks-list.qml b/tests/manual/quick/pdf/bookmarks-list.qml
index 2be0d68484b..e0af43054e0 100644
--- a/tests/manual/quick/pdf/bookmarks-list.qml
+++ b/tests/manual/quick/pdf/bookmarks-list.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 import QtQuick
 import QtQuick.Controls
 import QtQuick.Dialogs
diff --git a/tests/manual/quick/pdf/bookmarks.qml b/tests/manual/quick/pdf/bookmarks.qml
index e12629b31ca..86ae4e34761 100644
--- a/tests/manual/quick/pdf/bookmarks.qml
+++ b/tests/manual/quick/pdf/bookmarks.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 import QtQuick
 import QtQuick.Controls
 import QtQuick.Dialogs
diff --git a/tests/manual/quick/pdf/gridview.qml b/tests/manual/quick/pdf/gridview.qml
index 773e72388db..69b85470d42 100644
--- a/tests/manual/quick/pdf/gridview.qml
+++ b/tests/manual/quick/pdf/gridview.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 import QtQuick
 import QtQuick.Pdf
 
diff --git a/tests/manual/quick/pdf/listview.qml b/tests/manual/quick/pdf/listview.qml
index d01be9e86e3..1c997fdce7e 100644
--- a/tests/manual/quick/pdf/listview.qml
+++ b/tests/manual/quick/pdf/listview.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 import QtQuick
 import QtQuick.Pdf
 
diff --git a/tests/manual/quick/pdf/multipleDocuments.qml b/tests/manual/quick/pdf/multipleDocuments.qml
index 055808ab60d..7826c9a8f84 100644
--- a/tests/manual/quick/pdf/multipleDocuments.qml
+++ b/tests/manual/quick/pdf/multipleDocuments.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 import QtQuick
 import QtQuick.Controls
 import QtQuick.Dialogs
diff --git a/tests/manual/quick/pdf/pdfPageView.qml b/tests/manual/quick/pdf/pdfPageView.qml
index 22c0d5ac238..edf3aa05bf9 100644
--- a/tests/manual/quick/pdf/pdfPageView.qml
+++ b/tests/manual/quick/pdf/pdfPageView.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 import QtQuick
 import QtQuick.Controls
 import QtQuick.Dialogs
diff --git a/tests/manual/quick/pdf/pessimizedListView.qml b/tests/manual/quick/pdf/pessimizedListView.qml
index 1b514668e62..6e1083fd3b2 100644
--- a/tests/manual/quick/pdf/pessimizedListView.qml
+++ b/tests/manual/quick/pdf/pessimizedListView.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 import QtQuick
 import QtQuick.Controls
 import QtQuick.Dialogs
diff --git a/tests/manual/quick/pdf/simplest.qml b/tests/manual/quick/pdf/simplest.qml
index 3f39bb21341..0736f38aee6 100644
--- a/tests/manual/quick/pdf/simplest.qml
+++ b/tests/manual/quick/pdf/simplest.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 import QtQuick
 
 Image {
diff --git a/tests/manual/quick/pdf/underscoredLinks.qml b/tests/manual/quick/pdf/underscoredLinks.qml
index 514008ca26b..f23d9a5a1fc 100644
--- a/tests/manual/quick/pdf/underscoredLinks.qml
+++ b/tests/manual/quick/pdf/underscoredLinks.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 import QtQuick
 import QtQuick.Controls
 import QtQuick.Dialogs
diff --git a/tests/manual/quick/pdf/withdoc.qml b/tests/manual/quick/pdf/withdoc.qml
index c388e041edd..bcd1a9b5843 100644
--- a/tests/manual/quick/pdf/withdoc.qml
+++ b/tests/manual/quick/pdf/withdoc.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 import QtQuick
 import QtQuick.Controls
 import QtQuick.Dialogs
diff --git a/tests/manual/quick/touchbrowser/AddressBar.qml b/tests/manual/quick/touchbrowser/AddressBar.qml
index 42188c94eac..36a83d87289 100644
--- a/tests/manual/quick/touchbrowser/AddressBar.qml
+++ b/tests/manual/quick/touchbrowser/AddressBar.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtQuick.Controls
diff --git a/tests/manual/quick/touchbrowser/MockTouchPoint.qml b/tests/manual/quick/touchbrowser/MockTouchPoint.qml
index 895e12e70a6..8583d934fc3 100644
--- a/tests/manual/quick/touchbrowser/MockTouchPoint.qml
+++ b/tests/manual/quick/touchbrowser/MockTouchPoint.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 import QtQuick
 
 Item {
diff --git a/tests/manual/quick/touchbrowser/main.cpp b/tests/manual/quick/touchbrowser/main.cpp
index 1f4d7d86900..7db3f40a169 100644
--- a/tests/manual/quick/touchbrowser/main.cpp
+++ b/tests/manual/quick/touchbrowser/main.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include "touchmockingapplication.h"
 #include "utils.h"
diff --git a/tests/manual/quick/touchbrowser/main.qml b/tests/manual/quick/touchbrowser/main.qml
index 83ede7d75b9..ed60b36e53e 100644
--- a/tests/manual/quick/touchbrowser/main.qml
+++ b/tests/manual/quick/touchbrowser/main.qml
@@ -1,5 +1,5 @@
 // Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 import QtQuick
 import QtQuick.Layouts
diff --git a/tests/manual/touchmocking/touchmockingapplication.cpp b/tests/manual/touchmocking/touchmockingapplication.cpp
index feedae5cd69..d1536466296 100644
--- a/tests/manual/touchmocking/touchmockingapplication.cpp
+++ b/tests/manual/touchmocking/touchmockingapplication.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include "touchmockingapplication.h"
 
diff --git a/tests/manual/touchmocking/touchmockingapplication.h b/tests/manual/touchmocking/touchmockingapplication.h
index 4f6e744fc65..e42159451af 100644
--- a/tests/manual/touchmocking/touchmockingapplication.h
+++ b/tests/manual/touchmocking/touchmockingapplication.h
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #ifndef TOUCHMOCKINGAPPLICATION_H
 #define TOUCHMOCKINGAPPLICATION_H
diff --git a/tests/manual/touchmocking/utils.h b/tests/manual/touchmocking/utils.h
index 12d493d3f03..2e6fb1b0571 100644
--- a/tests/manual/touchmocking/utils.h
+++ b/tests/manual/touchmocking/utils.h
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #ifndef UTILS_H
 #define UTILS_H
diff --git a/tests/manual/widgets/geolocation/main.cpp b/tests/manual/widgets/geolocation/main.cpp
index 1f4cefe54e4..9e471650b01 100644
--- a/tests/manual/widgets/geolocation/main.cpp
+++ b/tests/manual/widgets/geolocation/main.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2023 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QApplication>
 #include <QFormLayout>
diff --git a/tests/manual/widgets/inputmethods/colorpicker.cpp b/tests/manual/widgets/inputmethods/colorpicker.cpp
index cc0840bcd6c..6ea8e808607 100644
--- a/tests/manual/widgets/inputmethods/colorpicker.cpp
+++ b/tests/manual/widgets/inputmethods/colorpicker.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include "colorpicker.h"
 
diff --git a/tests/manual/widgets/inputmethods/colorpicker.h b/tests/manual/widgets/inputmethods/colorpicker.h
index 0b6b3257a5c..719aa93eb20 100644
--- a/tests/manual/widgets/inputmethods/colorpicker.h
+++ b/tests/manual/widgets/inputmethods/colorpicker.h
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #ifndef COLORPICKER_H
 #define COLORPICKER_H
diff --git a/tests/manual/widgets/inputmethods/controlview.cpp b/tests/manual/widgets/inputmethods/controlview.cpp
index 86bf8cca967..85d7cfa0fe5 100644
--- a/tests/manual/widgets/inputmethods/controlview.cpp
+++ b/tests/manual/widgets/inputmethods/controlview.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include "controlview.h"
 
diff --git a/tests/manual/widgets/inputmethods/controlview.h b/tests/manual/widgets/inputmethods/controlview.h
index caa08593ffd..c686adbec57 100644
--- a/tests/manual/widgets/inputmethods/controlview.h
+++ b/tests/manual/widgets/inputmethods/controlview.h
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #ifndef CONTROLVIEW_H
 #define CONTROLVIEW_H
diff --git a/tests/manual/widgets/inputmethods/main.cpp b/tests/manual/widgets/inputmethods/main.cpp
index 2378e95aea7..4bba9f78208 100644
--- a/tests/manual/widgets/inputmethods/main.cpp
+++ b/tests/manual/widgets/inputmethods/main.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QApplication>
 #include <QFormLayout>
diff --git a/tests/manual/widgets/inputmethods/referenceview.cpp b/tests/manual/widgets/inputmethods/referenceview.cpp
index 27e784fbcd2..24957eaa954 100644
--- a/tests/manual/widgets/inputmethods/referenceview.cpp
+++ b/tests/manual/widgets/inputmethods/referenceview.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include "referenceview.h"
 
diff --git a/tests/manual/widgets/inputmethods/referenceview.h b/tests/manual/widgets/inputmethods/referenceview.h
index d943a93d01c..62c43faeb5e 100644
--- a/tests/manual/widgets/inputmethods/referenceview.h
+++ b/tests/manual/widgets/inputmethods/referenceview.h
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #ifndef REFERENCEVIEW_H
 #define REFERENCEVIEW_H
diff --git a/tests/manual/widgets/inputmethods/testview.cpp b/tests/manual/widgets/inputmethods/testview.cpp
index d57b22cc59c..e0e84d72b2a 100644
--- a/tests/manual/widgets/inputmethods/testview.cpp
+++ b/tests/manual/widgets/inputmethods/testview.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include "testview.h"
 
diff --git a/tests/manual/widgets/inputmethods/testview.h b/tests/manual/widgets/inputmethods/testview.h
index b99e60d75f3..5ba894bf3d9 100644
--- a/tests/manual/widgets/inputmethods/testview.h
+++ b/tests/manual/widgets/inputmethods/testview.h
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #ifndef TESTVIEW_H
 #define TESTVIEW_H
diff --git a/tests/manual/widgets/inputmethods/webview.cpp b/tests/manual/widgets/inputmethods/webview.cpp
index 915d73a7f8f..febd05049cf 100644
--- a/tests/manual/widgets/inputmethods/webview.cpp
+++ b/tests/manual/widgets/inputmethods/webview.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include "webview.h"
 #include <QWebEngineSettings>
diff --git a/tests/manual/widgets/inputmethods/webview.h b/tests/manual/widgets/inputmethods/webview.h
index a46dcb2f625..ec5a295d1ed 100644
--- a/tests/manual/widgets/inputmethods/webview.h
+++ b/tests/manual/widgets/inputmethods/webview.h
@@ -1,5 +1,5 @@
 // Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 #ifndef WEBVIEW_H
 #define WEBVIEW_H
 
diff --git a/tests/manual/widgets/touchbrowser/main.cpp b/tests/manual/widgets/touchbrowser/main.cpp
index 18baf79e89f..0aa3e791797 100644
--- a/tests/manual/widgets/touchbrowser/main.cpp
+++ b/tests/manual/widgets/touchbrowser/main.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include "touchmockingapplication.h"
 #include "utils.h"
diff --git a/tests/manual/widgets/webgl/main.cpp b/tests/manual/widgets/webgl/main.cpp
index 7037c34dba1..e9b4c285afc 100644
--- a/tests/manual/widgets/webgl/main.cpp
+++ b/tests/manual/widgets/webgl/main.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QtCore/QDebug>
 #include <QtCore/QLoggingCategory>
diff --git a/tests/manual/widgets/webrtc/main.cpp b/tests/manual/widgets/webrtc/main.cpp
index b5718159c8b..c1742445a4c 100644
--- a/tests/manual/widgets/webrtc/main.cpp
+++ b/tests/manual/widgets/webrtc/main.cpp
@@ -1,5 +1,5 @@
 // Copyright (C) 2023 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <QApplication>
 #include <QByteArray>

From 1eb8f906a5bb0cb3ed12ff8d65d595ac46b1fced Mon Sep 17 00:00:00 2001
From: Martin Negyokru <negyokru@inf.u-szeged.hu>
Date: Fri, 21 Jun 2024 08:59:48 +0200
Subject: [PATCH 040/356] Ensure deferred deletion of WebEngineQuickWidget

In some cases the event loop exits before
WebEngineQuickWidget::deletLater is called.
In this scenario the object will not be deleted.

Fixes: QTBUG-126401
Pick-to: 6.7 6.6
Change-Id: I9de8640c6f8d3b0f04665bce664f8b91523ddb69
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit a9357c72535b5e99f75b03af560badbb90dfa6f1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/webenginewidgets/api/qwebengineview.cpp       |  5 +++++
 .../widgets/qwebengineview/tst_qwebengineview.cpp | 15 +++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index ebb818cbd71..9dab3a45b22 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -141,6 +141,11 @@ class WebEngineQuickWidget : public QQuickWidget, public WidgetDelegate
     void Destroy() override
     {
         deleteLater();
+
+        // The event loop may be exited at this point.
+        // Ensure deferred deletion in this scenario.
+        if (QThread::currentThread()->loopLevel() == 0)
+            QCoreApplication::sendPostedEvents(this, QEvent::DeferredDelete);
     }
 
     bool ActiveFocusOnPress() override
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 03acd69feb6..3b481402e7e 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -189,6 +189,7 @@ private Q_SLOTS:
     void datalist();
     void longKeyEventText();
     void pageWithPaintListeners();
+    void deferredDelete();
 };
 
 // This will be called before the first test function is executed.
@@ -4006,5 +4007,19 @@ void tst_QWebEngineView::longKeyEventText()
     QTRY_VERIFY(consoleMessageSpy.size());
 }
 
+void tst_QWebEngineView::deferredDelete()
+{
+    {
+        QWebEngineView view;
+        QSignalSpy loadFinishedSpy(view.page(), &QWebEnginePage::loadFinished);
+        view.load(QUrl("chrome://qt"));
+        view.show();
+        QTRY_VERIFY(loadFinishedSpy.size());
+        QCOMPARE(QApplication::allWidgets().size(), 2); // QWebEngineView and WebEngineQuickWidget
+    }
+
+    QCOMPARE(QApplication::allWidgets().size(), 0);
+}
+
 QTEST_MAIN(tst_QWebEngineView)
 #include "tst_qwebengineview.moc"

From 0b9a2c616ec824557f6bfb4c432750fd4dcd4af7 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Fri, 28 Jun 2024 19:04:04 +0000
Subject: [PATCH 041/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I53e55c11a577d389d6b8e2e91b44ca857027e258
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index a4a9f46a3b7..a2e94f244e2 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 8206b9b4b159c9a0244ff4f92d4c3bb8fad13c1c
+    ref: f67b8f68a951fdd5fd21ce95cf0be0668397d3f8
     required: true
   ../qtpositioning:
-    ref: 5a12dc643d425e96d19f6a543f7c6c51a01aa857
+    ref: a94950c0e9df7cd8bdeeff38e8826b6ee522eee8
     required: false
   ../qttools:
-    ref: df2a2fc4c6b32ad6203a6c90222dd9051c2f1ba5
+    ref: 71e84ea044451757f6590df211c18372661717c0
     required: false
   ../qtwebchannel:
-    ref: 4579fb731a4954633e4398477896bbf6968c34bc
+    ref: 57aa7f5ae976f7bb4efebce011fcd0f8153bb158
     required: false

From eb4412f900262a564529adc6b20e1c4b443b2cda Mon Sep 17 00:00:00 2001
From: Paul Wicking <paul.wicking@qt.io>
Date: Fri, 28 Jun 2024 12:23:24 +0200
Subject: [PATCH 042/356] Doc: Increase warninglimit for doc builds to 2
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Technically the Qt WebEngine documentation builds without warnings, but
testing in CI two warnings are observed:

  warning: Already generated qtwebengine-3rdparty-inspector-protocol.html
           for this project
  warning: Already generated qtwebengine-3rdparty-lit.html
           for this project

These pages come from a qtattributionsscanner-generated source file,
codeattributions.qdoc.

The warnings do not affect the generated output. Increase the
documentation warning limit temporarily to let integrations pass.

Task-number: QTBUG-126546
Change-Id: I450c4ef4a03abdbf5ccbeab865468b302c92ee90
Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
(cherry picked from commit 33f30724f0e3e50abf559a14340ded85d35480ca)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/doc/qtwebengine.qdocconf | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/doc/qtwebengine.qdocconf b/src/core/doc/qtwebengine.qdocconf
index 6b78f13f8ce..89136314743 100644
--- a/src/core/doc/qtwebengine.qdocconf
+++ b/src/core/doc/qtwebengine.qdocconf
@@ -93,4 +93,4 @@ navigation.qmltypespage = "Qt WebEngine QML Types"
 macro.QWE    = "Qt \\WebEngine"
 
 # Enforce zero documentation warnings
-warninglimit = 0
+warninglimit = 2

From 537cbfb72459f0017a16eb7234f95bf9d82f72b7 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Wed, 26 Jun 2024 11:08:59 +0200
Subject: [PATCH 043/356] Fix QString and QChar deprecation warnings in
 web_engine_context.cpp

Change-Id: Iba85d76a11a61ea36b05ee2069959f68dd5d9fc1
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 86ac0c32fe9a6bc25054840a08c4343d22e1d817)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/web_engine_context.cpp | 113 ++++++++++++++++++--------------
 1 file changed, 64 insertions(+), 49 deletions(-)

diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 74453d1992e..bf6a06ae5af 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -178,27 +178,27 @@ class GPUInfo
         if (it != vendorIdMap.end())
             return it->second;
 
-        qWarning() << "Unknown Vendor ID:" << QString("0x%1").arg(vendorId, 0, 16);
+        qWarning() << "Unknown Vendor ID:" << QStringLiteral("0x%1").arg(vendorId, 0, 16);
         return Unknown;
     }
 
-    static Vendor deviceNameToVendor(QString deviceName)
+    static Vendor deviceNameToVendor(const QString &deviceName)
     {
         // TODO: Test and add more vendors to the list.
-        if (deviceName.contains(QLatin1String("AMD"), Qt::CaseInsensitive))
+        if (deviceName.contains(QLatin1StringView("AMD"), Qt::CaseInsensitive))
             return AMD;
-        if (deviceName.contains(QLatin1String("Intel"), Qt::CaseInsensitive))
+        if (deviceName.contains(QLatin1StringView("Intel"), Qt::CaseInsensitive))
             return Intel;
-        if (deviceName.contains(QLatin1String("Nvidia"), Qt::CaseInsensitive))
+        if (deviceName.contains(QLatin1StringView("Nvidia"), Qt::CaseInsensitive))
             return Nvidia;
 
 #if defined(USE_OZONE)
-        if (deviceName.contains(QLatin1String("Mesa llvmpipe")))
+        if (deviceName.contains(QLatin1StringView("Mesa llvmpipe")))
             return Mesa;
 #endif
 
 #if defined(Q_OS_MACOS)
-        if (deviceName.contains(QLatin1String("Apple")))
+        if (deviceName.contains(QLatin1StringView("Apple")))
             return Apple;
 #endif
 
@@ -259,8 +259,8 @@ class GPUInfo
                 const QRhiD3D11NativeHandles *handles =
                         static_cast<const QRhiD3D11NativeHandles *>(d3d11Rhi->nativeHandles());
                 Q_ASSERT(handles);
-                m_adapterLuid =
-                        QString("%1,%2").arg(handles->adapterLuidHigh).arg(handles->adapterLuidLow);
+                m_adapterLuid = QString::number(handles->adapterLuidHigh) % QLatin1Char(',')
+                        % QString::number(handles->adapterLuidLow);
             }
         }
 #elif defined(Q_OS_MACOS)
@@ -269,7 +269,7 @@ class GPUInfo
             QScopedPointer<QRhi> metalRhi(
                     QRhi::create(QRhi::Metal, &params, QRhi::Flags(), nullptr));
             if (metalRhi)
-                m_vendor = deviceNameToVendor(metalRhi->driverInfo().deviceName);
+                m_vendor = deviceNameToVendor(QLatin1StringView(metalRhi->driverInfo().deviceName));
         }
 #endif
 
@@ -280,7 +280,7 @@ class GPUInfo
             QScopedPointer<QRhi> glRhi(
                     QRhi::create(QRhi::OpenGLES2, &params, QRhi::Flags(), nullptr));
             if (glRhi)
-                m_vendor = deviceNameToVendor(glRhi->driverInfo().deviceName);
+                m_vendor = deviceNameToVendor(QLatin1StringView(glRhi->driverInfo().deviceName));
         }
 #endif
 
@@ -327,7 +327,7 @@ static bool usingSupportedSGBackend()
     QString device = QQuickWindow::sceneGraphBackend();
 
     for (int index = 0; index < args.count(); ++index) {
-        if (args.at(index).startsWith(QLatin1String("--device="))) {
+        if (args.at(index).startsWith(QLatin1StringView("--device="))) {
             device = args.at(index).mid(9);
             break;
         }
@@ -338,7 +338,7 @@ static bool usingSupportedSGBackend()
     if (device.isEmpty())
         device = qEnvironmentVariable("QMLSCENE_DEVICE");
 
-    return device.isEmpty() || device == QLatin1String("rhi");
+    return device.isEmpty() || device == QLatin1StringView("rhi");
 }
 
 #if QT_CONFIG(opengl)
@@ -358,7 +358,7 @@ bool usingSoftwareDynamicGL()
     wchar_t path[MAX_PATH];
     DWORD size = GetModuleFileName(handle, path, MAX_PATH);
     QFileInfo openGLModule(QString::fromWCharArray(path, size));
-    return openGLModule.fileName().contains(QLatin1String("opengl32sw"),Qt::CaseInsensitive);
+    return openGLModule.fileName().contains(QLatin1StringView("opengl32sw"), Qt::CaseInsensitive);
 #else
     return false;
 #endif
@@ -471,27 +471,41 @@ static void logContext(const std::string &glType, base::CommandLine *cmd)
 {
     if (Q_UNLIKELY(webEngineContextLog().isDebugEnabled())) {
         QStringList log;
-        log << "\n";
-
-        log << "Chromium GL Backend:" << glType.c_str() << "\n";
-        log << "Chromium ANGLE Backend:" << getAngleType(glType, cmd).c_str() << "\n";
-        log << "Chromium Vulkan Backend:" << getVulkanType(cmd).c_str() << "\n";
-        log << "\n";
-
-        log << "QSG RHI Backend:" << QSGRhiSupport::instance()->rhiBackendName() << "\n";
-        log << "QSG RHI Backend Supported:" << (usingSupportedSGBackend() ? "yes" : "no") << "\n";
-        log << "GPU Vendor:" << GPUInfo::vendorToString(GPUInfo::instance()->vendor()).c_str();
-        log << "\n";
+        log << QLatin1StringView("\n");
+
+        log << QLatin1StringView("Chromium GL Backend: " + glType) << QLatin1StringView("\n");
+        log << QLatin1StringView("Chromium ANGLE Backend: " + getAngleType(glType, cmd))
+            << QLatin1StringView("\n");
+        log << QLatin1StringView("Chromium Vulkan Backend: " + getVulkanType(cmd))
+            << QLatin1StringView("\n");
+        log << QLatin1StringView("\n");
+
+        log << QLatin1StringView("QSG RHI Backend:") << QSGRhiSupport::instance()->rhiBackendName()
+            << QLatin1StringView("\n");
+        log << QLatin1StringView("QSG RHI Backend Supported:")
+            << QLatin1StringView(usingSupportedSGBackend() ? "yes" : "no")
+            << QLatin1StringView("\n");
+        log << QLatin1StringView("GPU Vendor: "
+                                 + GPUInfo::vendorToString(GPUInfo::instance()->vendor()))
+            << QLatin1StringView("\n");
+        log << QLatin1StringView("\n");
 
 #if QT_CONFIG(opengl)
 #if defined(USE_OZONE)
-        log << "Using GLX:" << (GLContextHelper::getGlxPlatformInterface() ? "yes" : "no") << "\n";
-        log << "Using EGL:" << (GLContextHelper::getEglPlatformInterface() ? "yes" : "no") << "\n";
+        log << QLatin1StringView("Using GLX:")
+            << QLatin1StringView(GLContextHelper::getGlxPlatformInterface() ? "yes" : "no")
+            << QLatin1StringView("\n");
+        log << QLatin1StringView("Using EGL:")
+            << QLatin1StringView(GLContextHelper::getEglPlatformInterface() ? "yes" : "no")
+            << QLatin1StringView("\n");
 #endif
-        log << "Using Shared GL:" << (qt_gl_global_share_context() ? "yes" : "no") << "\n";
+        log << QLatin1StringView("Using Shared GL:")
+            << QLatin1StringView(qt_gl_global_share_context() ? "yes" : "no")
+            << QLatin1StringView("\n");
         if (qt_gl_global_share_context()) {
-            log << "Using Software Dynamic GL:" << (usingSoftwareDynamicGL() ? "yes" : "no")
-                << "\n";
+            log << QLatin1StringView("Using Software Dynamic GL:")
+                << QLatin1StringView(usingSoftwareDynamicGL() ? "yes" : "no")
+                << QLatin1StringView("\n");
 
             const QSurfaceFormat sharedFormat = qt_gl_global_share_context()
                     ? qt_gl_global_share_context()->format()
@@ -501,23 +515,23 @@ static void logContext(const std::string &glType, base::CommandLine *cmd)
                             sharedFormat.profile());
             const auto type = QMetaEnum::fromType<QSurfaceFormat::RenderableType>().valueToKey(
                     sharedFormat.renderableType());
-            log << "Surface Type:" << type << "\n";
-            log << "Surface Profile:" << profile << "\n";
-            log << "Surface Version:"
-                << QString("%1.%2")
+            log << QLatin1StringView("Surface Type:") << QLatin1StringView(type)
+                << QLatin1StringView("\n");
+            log << QLatin1StringView("Surface Profile:") << QLatin1StringView(profile)
+                << QLatin1StringView("\n");
+            log << QStringLiteral("Surface Version: %1.%2\n")
                             .arg(sharedFormat.majorVersion())
-                            .arg(sharedFormat.minorVersion())
-                << "\n";
+                            .arg(sharedFormat.minorVersion());
         }
-        log << "\n";
+        log << QLatin1StringView("\n");
 #endif // QT_CONFIG(opengl)
 
-        log << "Init Parameters:\n";
+        log << QLatin1StringView("Init Parameters:\n");
         const base::CommandLine::SwitchMap switchMap = cmd->GetSwitches();
         for (const auto &pair : switchMap)
-            log << " * " << toQt(pair.first) << toQt(pair.second) << "\n";
+            log << QStringLiteral(" *  %1 %2\n").arg(toQt(pair.first)).arg(toQt(pair.second));
 
-        qCDebug(webEngineContextLog) << qPrintable(log.join(" "));
+        qCDebug(webEngineContextLog) << qPrintable(log.join(QLatin1Char(' ')));
     }
 }
 
@@ -527,13 +541,14 @@ static void setupProxyPac(base::CommandLine *commandLine)
 {
     if (commandLine->HasSwitch(switches::kProxyPacUrl)) {
         QUrl pac_url(toQt(commandLine->GetSwitchValueASCII(switches::kProxyPacUrl)));
-        if (pac_url.isValid() && (pac_url.isLocalFile() ||
-                                  !pac_url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive))) {
+        if (pac_url.isValid()
+            && (pac_url.isLocalFile()
+                || !pac_url.scheme().compare(QLatin1StringView("qrc"), Qt::CaseInsensitive))) {
             QFile file;
             if (pac_url.isLocalFile())
                 file.setFileName(pac_url.toLocalFile());
             else
-                file.setFileName(pac_url.path().prepend(QChar(':')));
+                file.setFileName(pac_url.path().prepend(QLatin1Char(':')));
             if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text)) {
                 QByteArray ba = file.readAll();
                 commandLine->RemoveSwitch(switches::kProxyPacUrl);
@@ -562,16 +577,16 @@ static QStringList parseEnvCommandLine(const QString &cmdLine)
     for (const QChar c : cmdLine) {
         switch (state) {
         case Parse:
-            if (c == '"') {
+            if (c == QLatin1Char('"')) {
                 state = Quoted;
-            } else if (c != ' ' ) {
+            } else if (c != QLatin1Char(' ')) {
                 arg += c;
                 state = Unquoted;
             }
             // skips spaces
             break;
         case Quoted:
-            if (c == '"') {
+            if (c == QLatin1Char('"')) {
                 DCHECK(!arg.isEmpty());
                 state = Unquoted;
             } else {
@@ -580,10 +595,10 @@ static QStringList parseEnvCommandLine(const QString &cmdLine)
             }
             break;
         case Unquoted:
-            if (c == '"') {
+            if (c == QLatin1Char('"')) {
                 // skips quotes
                 state = Quoted;
-            } else if (c == ' ') {
+            } else if (c == QLatin1Char(' ')) {
                 arguments.append(arg);
                 arg.clear();
                 state = Parse;
@@ -1110,7 +1125,7 @@ base::CommandLine *WebEngineContext::initCommandLine(bool &useEmbeddedSwitches,
     }
 
     base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess();
-    int index = appArgs.indexOf(QRegularExpression(QLatin1String("--webEngineArgs"),
+    int index = appArgs.indexOf(QRegularExpression(QLatin1StringView("--webEngineArgs"),
                                                    QRegularExpression::CaseInsensitiveOption));
     if (qEnvironmentVariableIsSet(kChromiumFlagsEnv)) {
         appArgs = appArgs.mid(0, 1); // Take application name and drop the rest

From d8d0aeb17e892b049d8b876c9dc911f7e48afe0e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kai=20K=C3=B6hne?= <kai.koehne@qt.io>
Date: Tue, 25 Jun 2024 08:36:57 +0200
Subject: [PATCH 044/356] Replace urn:dje license identifier II

Amends 8e22839aa0

Task-number: QTBUG-126403
Pick-to: 6.7
Change-Id: I1560e5af29d2e94657a83e98bb649729b4a67cd2
Reviewed-by: Lucie Gerard <lucie.gerard@qt.io>
(cherry picked from commit 994986fb96044551b5c43523a3589e989c2b2294)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 .../cookiebrowser/3rdparty/qt_attribution.json                 | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/examples/webenginewidgets/cookiebrowser/3rdparty/qt_attribution.json b/examples/webenginewidgets/cookiebrowser/3rdparty/qt_attribution.json
index 35d9cf0d7ad..64ba15e00ef 100644
--- a/examples/webenginewidgets/cookiebrowser/3rdparty/qt_attribution.json
+++ b/examples/webenginewidgets/cookiebrowser/3rdparty/qt_attribution.json
@@ -9,9 +9,8 @@
     "Homepage": "http://tango.freedesktop.org/Tango_Icon_Library",
     "Version": "0.8.90",
     "DownloadLocation": "http://tango.freedesktop.org/releases/tango-icon-theme-0.8.90.tar.gz",
-    "LicenseId": "urn:dje:license:public-domain",
+    "LicenseId": "LicenseRef-Tango-Icons-Public-Domain",
     "License": "Public Domain",
-    "LicenseFile": "COPYING",
     "Copyright": ["Ulisse Perusin <uli.peru@gmail.com>",
     "Steven Garrity <sgarrity@silverorange.com>",
     "Lapo Calamandrei <calamandrei@gmail.com>",

From 55942cfb6b2306234c8278a70413ec827180ad08 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucie=20G=C3=A9rard?= <lucie.gerard@qt.io>
Date: Fri, 5 Apr 2024 11:52:48 +0200
Subject: [PATCH 045/356] Correct license for documentation file
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

According to QUIP-18 [1], all documentation files should be
LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

[1]: https://contribute.qt-project.org/quips/18

Pick-to: 6.7
Task-number: QTBUG-121787
Change-Id: Ibf7b2738d62e5f2075183d2f0376774583595a55
Reviewed-by: Kai Köhne <kai.koehne@qt.io>
(cherry picked from commit 86e97f65b6afc495ddf46f4b39eac47646e83b0a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/pdf/qpdfdocumentrenderoptions.qdoc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pdf/qpdfdocumentrenderoptions.qdoc b/src/pdf/qpdfdocumentrenderoptions.qdoc
index ad8e7bfdb88..253f3e37adb 100644
--- a/src/pdf/qpdfdocumentrenderoptions.qdoc
+++ b/src/pdf/qpdfdocumentrenderoptions.qdoc
@@ -1,5 +1,5 @@
 // Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
 
 #include "qpdfdocumentrenderoptions.h"
 

From 49e95e4bda8a0c6e5e3d91b8cbfdb53dc4cbed90 Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Thu, 27 Jun 2024 10:18:09 +0200
Subject: [PATCH 046/356] QWebEngineFrame: export symbols individually

Per API review comment, we should export members individually when the
class is not polymorphic.

Change-Id: I1d338606b9d1105aa817fb47ceac4683882bd360
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit f6dc5265fbf6d46319adada99d3881bad266ba4d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebengineframe.h | 50 ++++++++++++++++++----------------
 1 file changed, 27 insertions(+), 23 deletions(-)

diff --git a/src/core/api/qwebengineframe.h b/src/core/api/qwebengineframe.h
index b6953cdd21f..85b02407a4d 100644
--- a/src/core/api/qwebengineframe.h
+++ b/src/core/api/qwebengineframe.h
@@ -19,9 +19,9 @@ class WebContentsAdapterClient;
 
 QT_BEGIN_NAMESPACE
 
-class Q_WEBENGINECORE_EXPORT QWebEngineFrame
+class QWebEngineFrame
 {
-    Q_GADGET
+    Q_GADGET_EXPORT(Q_WEBENGINECORE_EXPORT)
 
     Q_PROPERTY(bool isValid READ isValid FINAL)
     Q_PROPERTY(QString name READ name FINAL)
@@ -34,26 +34,29 @@ class Q_WEBENGINECORE_EXPORT QWebEngineFrame
     QML_VALUE_TYPE(webEngineFrame)
     QML_ADDED_IN_VERSION(6, 8)
 
-    bool isValid() const;
-    QString name() const;
-    QString htmlName() const;
-    QList<QWebEngineFrame> children() const;
-    QUrl url() const;
-    QSizeF size() const;
-    bool isMainFrame() const;
-
-    void runJavaScript(const QString &script,
-                       const std::function<void(const QVariant &)> &callback);
-    void runJavaScript(const QString &script, quint32 worldId,
-                       const std::function<void(const QVariant &)> &callback);
-    Q_INVOKABLE void runJavaScript(const QString &script, quint32 worldId = 0);
-    Q_INVOKABLE void runJavaScript(const QString &script, const QJSValue &callback);
-    Q_INVOKABLE void runJavaScript(const QString &script, quint32 worldId,
-                                   const QJSValue &callback);
-
-    Q_INVOKABLE void printToPdf(const QString &filePath);
-    void printToPdf(const std::function<void(const QByteArray &)> &callback);
-    Q_INVOKABLE void printToPdf(const QJSValue &callback);
+    Q_WEBENGINECORE_EXPORT bool isValid() const;
+    Q_WEBENGINECORE_EXPORT QString name() const;
+    Q_WEBENGINECORE_EXPORT QString htmlName() const;
+    Q_WEBENGINECORE_EXPORT QList<QWebEngineFrame> children() const;
+    Q_WEBENGINECORE_EXPORT QUrl url() const;
+    Q_WEBENGINECORE_EXPORT QSizeF size() const;
+    Q_WEBENGINECORE_EXPORT bool isMainFrame() const;
+
+    Q_WEBENGINECORE_EXPORT void
+    runJavaScript(const QString &script, const std::function<void(const QVariant &)> &callback);
+    Q_WEBENGINECORE_EXPORT void
+    runJavaScript(const QString &script, quint32 worldId,
+                  const std::function<void(const QVariant &)> &callback);
+    Q_WEBENGINECORE_EXPORT Q_INVOKABLE void runJavaScript(const QString &script,
+                                                          quint32 worldId = 0);
+    Q_WEBENGINECORE_EXPORT Q_INVOKABLE void runJavaScript(const QString &script,
+                                                          const QJSValue &callback);
+    Q_WEBENGINECORE_EXPORT Q_INVOKABLE void runJavaScript(const QString &script, quint32 worldId,
+                                                          const QJSValue &callback);
+
+    Q_WEBENGINECORE_EXPORT Q_INVOKABLE void printToPdf(const QString &filePath);
+    Q_WEBENGINECORE_EXPORT void printToPdf(const std::function<void(const QByteArray &)> &callback);
+    Q_WEBENGINECORE_EXPORT Q_INVOKABLE void printToPdf(const QJSValue &callback);
 
     friend inline bool comparesEqual(const QWebEngineFrame &lhs,
                                      const QWebEngineFrame &rhs) noexcept
@@ -69,7 +72,8 @@ class Q_WEBENGINECORE_EXPORT QWebEngineFrame
     friend class QQuickWebEngineView;
     friend class QQuickWebEngineViewPrivate;
 
-    QWebEngineFrame(QtWebEngineCore::WebContentsAdapterClient *page, quint64 id);
+    Q_WEBENGINECORE_EXPORT QWebEngineFrame(QtWebEngineCore::WebContentsAdapterClient *page,
+                                           quint64 id);
 
     QtWebEngineCore::WebContentsAdapterClient *m_adapterClient;
     quint64 m_id;

From 75d1aa2dd1adb19e8a16de8ff84eae0529cbbb68 Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Wed, 17 Apr 2024 13:03:22 +0200
Subject: [PATCH 047/356] Implement MotionEvent::GetSourceDeviceId

Without this many errors are printed during tst_touchpoint

Change-Id: I9742fe50b1e915d52e1ff7a9b1e48511ca8bdcc6
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 841aa01aaf83c63ffd83bafe7509c17b6d36d467)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/render_widget_host_view_qt_delegate_client.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/core/render_widget_host_view_qt_delegate_client.cpp b/src/core/render_widget_host_view_qt_delegate_client.cpp
index 3e8cad6693a..02ad9b039e0 100644
--- a/src/core/render_widget_host_view_qt_delegate_client.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_client.cpp
@@ -88,6 +88,11 @@ class MotionEventQt : public ui::MotionEvent
     Action GetAction() const override { return action; }
     int GetActionIndex() const override { return index; }
     size_t GetPointerCount() const override { return touchPoints.size(); }
+    int32_t GetSourceDeviceId(size_t pointer_index) const override
+    {
+        return static_cast<int32_t>(
+                touchPoints[pointer_index].second.device()->uniqueId().numericId());
+    }
     int GetPointerId(size_t pointer_index) const override
     {
         return touchPoints[pointer_index].first;

From 05136d3d63f49b32dbe7ed2caa23519024478375 Mon Sep 17 00:00:00 2001
From: David Edmundson <davidedmundson@kde.org>
Date: Wed, 19 Jun 2024 10:37:45 +0100
Subject: [PATCH 048/356] Use device pixel ratio of the window rather than the
 screen
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Window device pixel ratio can differ from the screen depending on the
platform. The window is the more authorative source with new events in
Qt to support that.

In Chromium the rendering is still based off a screen factor, but each
view will have a completely independent set of screen variables, so we
can adjust the screen to match our current view.

Chromium itself also alters the screen scale factor on a per window
basis for their own native Wayland backend or if recording a window.

Fixes: QTBUG-113574
Change-Id: I12231c826525a9d7b5e30eed10324f65fbf8c16f
Reviewed-by: Moss Heim <moss.heim@qt.io>
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 21a9add47def34322b799683e1e1daff88dc4a06)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/render_widget_host_view_qt.cpp               | 5 +++++
 src/core/render_widget_host_view_qt_delegate_item.cpp | 2 ++
 2 files changed, 7 insertions(+)

diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 98d0471c1d2..4405de46c56 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -876,6 +876,11 @@ bool RenderWidgetHostViewQt::updateScreenInfo()
         return false;
 
     display::ScreenInfos newScreenInfos = screenInfosFromQtForUpdate(window->screen());
+
+    // We always want to use the scale from our current window
+    // This screen information is stored on a per-view basis
+    auto &screen = newScreenInfos.mutable_current();
+    screen.device_scale_factor = window->devicePixelRatio();
     if (screen_infos_ == newScreenInfos)
         return false;
 
diff --git a/src/core/render_widget_host_view_qt_delegate_item.cpp b/src/core/render_widget_host_view_qt_delegate_item.cpp
index 23e5bc93594..a9f872220ad 100644
--- a/src/core/render_widget_host_view_qt_delegate_item.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_item.cpp
@@ -345,6 +345,8 @@ void RenderWidgetHostViewQtDelegateItem::itemChange(ItemChange change, const Ite
             if (!m_isPopup)
                 onHide();
         }
+    } else if (change == QQuickItem::ItemDevicePixelRatioHasChanged) {
+        m_client->visualPropertiesChanged();
     }
 }
 

From f27fa91cf0fd102de148edec9ac54ea2b0fb69cf Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Wed, 3 Jul 2024 01:14:49 +0000
Subject: [PATCH 049/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Ia42e2f8e5b8701475184c6a109762a3b19f5ae9d
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index a2e94f244e2..d9a5ed195c7 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: f67b8f68a951fdd5fd21ce95cf0be0668397d3f8
+    ref: df193621ede18ee1166281435750fc1980b3bc1f
     required: true
   ../qtpositioning:
-    ref: a94950c0e9df7cd8bdeeff38e8826b6ee522eee8
+    ref: 31a8040367a3d79f1970799d283acb1be8e4f23b
     required: false
   ../qttools:
-    ref: 71e84ea044451757f6590df211c18372661717c0
+    ref: a5a69456bf87773b671aca85373085a948408ff9
     required: false
   ../qtwebchannel:
-    ref: 57aa7f5ae976f7bb4efebce011fcd0f8153bb158
+    ref: abad90db61a76dc0e1faaa2034837a8612bcdd83
     required: false

From 9603e7f5aee70ebfa2ef96e35b809e43b79f070b Mon Sep 17 00:00:00 2001
From: Anu Aliyas <anu.aliyas@qt.io>
Date: Wed, 8 May 2024 14:20:37 +0200
Subject: [PATCH 050/356] Add missing dependencies to webengine devtools source
 set

Missing dependencies are added to resolve the dependencies issues
encountered when compiling with Ninja 1.12.0

Fixes: QTBUG-125035
Pick-to: 6.7
Change-Id: Ia089f407852efdeb837c6fc348e9d1fbb43a0da7
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 35f49e787dd5894c0f890855b1ac2f0d7c24421d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/configure/BUILD.root.gn.in | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/core/configure/BUILD.root.gn.in b/src/core/configure/BUILD.root.gn.in
index 1fbbadf2671..0e913f1d44b 100644
--- a/src/core/configure/BUILD.root.gn.in
+++ b/src/core/configure/BUILD.root.gn.in
@@ -237,6 +237,7 @@ source_set("qtwebengine_spellcheck_sources") {
 source_set("devtools_sources") {
   configs += [ ":cpp20_config" ]
   deps = [
+    "//chrome/app:generated_resources",
     "//components/zoom",
     "//third_party/blink/public/mojom:mojom_platform",
     ]

From 129e37d823cc6a89ca0de04a12f72b4e2fad47f0 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Thu, 20 Jun 2024 16:35:13 +0200
Subject: [PATCH 051/356] QWebEnginePermission: Post-API review
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This commit contains fixes for the issues found during the API review
of the new permissions API. In particular:
- All new enums are now scoped
- Replaced isTransient with its opposite, isPersistent
- Renamed Feature to PermissionType
- Made origin() return a non-const QUrl
- Renamed PersistentPermissionsPolicy members to be more concise
- Fixed a couple of bugs in the implementation
- Updated documentation

Change-Id: Idf84e1c9ba3ae803ef4686e1caa7f3e6c198c87d
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 85ff9e35fdec602f71c66e9c93eefd2c6d911512)
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
---
 .../quicknanobrowser/BrowserWindow.qml        |  31 +--
 examples/webenginewidgets/maps/mainwindow.cpp |   2 +-
 .../webenginewidgets/notifications/main.cpp   |   2 +-
 .../doc/src/permissionbrowser.qdoc            |  32 ++--
 .../permissionbrowser/mainwindow.cpp          |  38 ++--
 .../permissionbrowser/permissiondialog.ui     |   4 +-
 .../push-notifications/main.cpp               |   2 +-
 .../simplebrowser/webview.cpp                 |  28 +--
 src/core/api/qwebenginepage.cpp               | 100 +++++-----
 src/core/api/qwebenginepage.h                 |  49 ++---
 src/core/api/qwebenginepage_p.h               |   4 +-
 src/core/api/qwebenginepermission.cpp         | 171 +++++++++--------
 src/core/api/qwebenginepermission.h           |  34 +++-
 src/core/api/qwebenginepermission_p.h         |   4 +-
 src/core/api/qwebengineprofile.cpp            |  68 +++----
 src/core/api/qwebengineprofile.h              |  16 +-
 src/core/doc/src/qtwebengine-features.qdoc    |   6 +-
 src/core/permission_manager_qt.cpp            | 178 +++++++++---------
 src/core/permission_manager_qt.h              |  12 +-
 src/core/profile_adapter.cpp                  |  27 +--
 src/core/profile_adapter.h                    |  15 +-
 src/core/web_contents_adapter.cpp             |  51 ++---
 src/core/web_contents_adapter.h               |   4 +-
 src/core/web_contents_adapter_client.h        |   4 +-
 src/core/web_contents_delegate_qt.cpp         |  10 +-
 src/core/web_contents_delegate_qt.h           |   2 +-
 .../api/qquickwebengineprofile.cpp            |  97 +++++-----
 .../api/qquickwebengineprofile.h              |  16 +-
 .../api/qquickwebenginesettings.cpp           |   4 +-
 .../api/qquickwebengineview.cpp               |  91 ++++-----
 .../api/qquickwebengineview_p.h               |  32 +---
 .../api/qquickwebengineview_p_p.h             |   4 +-
 .../doc/src/webengine_permission.qdoc         |  87 +++++----
 .../doc/src/webengineview_lgpl.qdoc           |   6 +-
 tests/auto/quick/publicapi/tst_publicapi.cpp  |  50 ++---
 .../quick/qmltests/data/tst_geopermission.qml |  10 +-
 .../quick/qmltests/data/tst_getUserMedia.qml  |  14 +-
 .../quick/qmltests/data/tst_notification.qml  |   9 +-
 .../qwebenginepage/tst_qwebenginepage.cpp     | 143 +++++++-------
 .../tst_qwebengineprofile.cpp                 |  95 +++++-----
 .../quick/geopermission/tst_geopermission.qml |   2 +-
 41 files changed, 781 insertions(+), 773 deletions(-)

diff --git a/examples/webenginequick/quicknanobrowser/BrowserWindow.qml b/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
index d040667d32f..02f5564aca2 100644
--- a/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
+++ b/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
@@ -748,53 +748,54 @@ ApplicationWindow {
         contentItem: Item {
             Label {
                 id: mainTextForPermissionDialog
-                text: permissionDialog.questionForFeature()
             }
         }
 
         onAccepted: permission.grant()
         onRejected: permission.deny()
         onVisibleChanged: {
-            if (visible)
+            if (visible) {
+                mainTextForPermissionDialog.text = questionForPermissionType();
                 width = contentWidth + 20;
+            }
         }
 
-        function questionForFeature() {
+        function questionForPermissionType() {
             var question = "Allow " + permission.origin + " to "
 
-            switch (permission.feature) {
-            case WebEnginePermission.Geolocation:
+            switch (permission.permissionType) {
+            case WebEnginePermission.PermissionType.Geolocation:
                 question += "access your location information?";
                 break;
-            case WebEnginePermission.MediaAudioCapture:
+            case WebEnginePermission.PermissionType.MediaAudioCapture:
                 question += "access your microphone?";
                 break;
-            case WebEnginePermission.MediaVideoCapture:
+            case WebEnginePermission.PermissionType.MediaVideoCapture:
                 question += "access your webcam?";
                 break;
-            case WebEnginePermission.MediaAudioVideoCapture:
+            case WebEnginePermission.PermissionType.MediaAudioVideoCapture:
                 question += "access your microphone and webcam?";
                 break;
-            case WebEnginePermission.MouseLock:
+            case WebEnginePermission.PermissionType.MouseLock:
                 question += "lock your mouse cursor?";
                 break;
-            case WebEnginePermission.DesktopVideoCapture:
+            case WebEnginePermission.PermissionType.DesktopVideoCapture:
                 question += "capture video of your desktop?";
                 break;
-            case WebEnginePermission.DesktopAudioVideoCapture:
+            case WebEnginePermission.PermissionType.DesktopAudioVideoCapture:
                 question += "capture audio and video of your desktop?";
                 break;
-            case WebEnginePermission.Notifications:
+            case WebEnginePermission.PermissionType.Notifications:
                 question += "show notification on your desktop?";
                 break;
-            case WebEnginePermission.ClipboardReadWrite:
+            case WebEnginePermission.PermissionType.ClipboardReadWrite:
                 question += "read from and write to your clipboard?";
                 break;
-            case WebEnginePermission.LocalFontsAccess:
+            case WebEnginePermission.PermissionType.LocalFontsAccess:
                 question += "access the fonts stored on your machine?";
                 break;
             default:
-                question += "access unknown or unsupported feature [" + permission.feature + "] ?";
+                question += "access unknown or unsupported permission type [" + permission.permissionType + "] ?";
                 break;
             }
 
diff --git a/examples/webenginewidgets/maps/mainwindow.cpp b/examples/webenginewidgets/maps/mainwindow.cpp
index ca98ca2630f..07b8d8ab3da 100644
--- a/examples/webenginewidgets/maps/mainwindow.cpp
+++ b/examples/webenginewidgets/maps/mainwindow.cpp
@@ -15,7 +15,7 @@ MainWindow::MainWindow(QWidget *parent)
 
     connect(page, &QWebEnginePage::permissionRequested,
             [this, page](QWebEnginePermission permission) {
-        if (permission.feature() != QWebEnginePermission::Geolocation)
+        if (permission.permissionType() != QWebEnginePermission::PermissionType::Geolocation)
             return;
 
         QMessageBox msgBox(this);
diff --git a/examples/webenginewidgets/notifications/main.cpp b/examples/webenginewidgets/notifications/main.cpp
index df9ebff73c8..e01dd03bc5f 100644
--- a/examples/webenginewidgets/notifications/main.cpp
+++ b/examples/webenginewidgets/notifications/main.cpp
@@ -35,7 +35,7 @@ int main(int argc, char *argv[])
 
     QObject::connect(view.page(), &QWebEnginePage::permissionRequested,
                      [&] (QWebEnginePermission permission) {
-                         if (permission.feature() != QWebEnginePermission::Notifications)
+                         if (permission.permissionType() != QWebEnginePermission::PermissionType::Notifications)
                              return;
                          permission.grant();
                      });
diff --git a/examples/webenginewidgets/permissionbrowser/doc/src/permissionbrowser.qdoc b/examples/webenginewidgets/permissionbrowser/doc/src/permissionbrowser.qdoc
index a266ec62a2a..3715d63cd94 100644
--- a/examples/webenginewidgets/permissionbrowser/doc/src/permissionbrowser.qdoc
+++ b/examples/webenginewidgets/permissionbrowser/doc/src/permissionbrowser.qdoc
@@ -65,7 +65,7 @@
     gets populated with a \c PermissionWidget whenever that happens.
 
     The \c PermissionWidget displays the permission's origin, the requested
-    \l QWebEnginePermission::Feature, as well as the current status of that permission.
+    \l QWebEnginePermission::PermissionType, as well as the current status of that permission.
     It also has buttons for granting and denying the permission. Since the permission status
     is (by default) remembered, the delete button allows the user to remove the permission
     from the underlying storage.
@@ -133,23 +133,23 @@
     \skipto void MainWindow::handlePermissionModified
     \printuntil /^\}/
 
-    Notably, we only do this in cases where we know the permission is remembered.
-    This is not true for transient \c Features,
-    which require a permission prompt be shown to the user every time they're needed.
+    Notably, we only do this in cases where we know the permission is remembered;
+    some \c PermissionTypes are non-persistent, which means they require
+    a permission prompt be shown to the user every time they're used.
     We also exclude permissions with a \l QWebEnginePermission::Ask state, which
     indicates that the permission was \l {QWebEnginePermission::reset}{reset}(),
     and we don't add anything to the list of existing permissions when
     \l QWebEngineProfile::persistentPermissionsPolicy is set to
-    \c NoPersistentPermissions.
+    \c AskEveryTime.
 
-    \note Check the \l QWebEnginePermission::Feature documentation to see which
-    \c Features are transient.
+    \note Check the \l QWebEnginePermission::PermissionType documentation to see which
+    \c PermissionTypes are persistent.
 
     \section1 Displaying and modifying existing permissions
 
     By default, permissions are stored to disk and retrieved again on application
     startup. To get a list of all existing website permissions, we call
-    \l QWebEngineProfile::listPermissions():
+    \l QWebEngineProfile::listAllPermissions():
 
     \quotefromfile webenginewidgets/permissionbrowser/mainwindow.cpp
     \skipto void MainWindow::loadStoredPermissions()
@@ -161,7 +161,7 @@
 
     \section1 Pre-granting permissions
 
-    Certain permissions may be granted in advance, provided the origin and Feature type
+    Certain permissions may be granted in advance, provided the origin and permission type
     are known. Clicking on the "New" button in the top right will create a pop-up
     dialog that allows you to do just that. The dialog is implemented by the
     \c PermissionDialog class:
@@ -171,8 +171,8 @@
     \printuntil /^\}/
 
     We populate the \l QComboBox using the QMetaEnum type associated with
-    \l QWebEnginePermission::Feature. We make sure to filter out transient
-    features, since pre-granting these is not supported.
+    \l QWebEnginePermission::PermissionType. We make sure to filter out non-persistent
+    permission types, since pre-granting these is not supported.
 
     We display the dialog and add show the resulting \c PermissionWidget
     in the UI inside the \c MainWindow::handleNewClicked slot. The new
@@ -191,22 +191,22 @@
     of each option.
 
     \list
-        \li \l QWebEngineProfile::PersistentPermissionsOnDisk is the default, and it ensures
+        \li \l QWebEngineProfile::StoreOnDisk is the default, and it ensures
         that any permissions that have been granted in the current application run will be
         loaded back up at next startup. A permission onlycneeds to be granted once, and
         subsequent uses of the API that triggered the request will automatically be granted,
         until the application calls QWebEnginePermission::reset().
-        li \l QWebEngineProfile::PersistentPermissionsInMemory Has the same behavior as above,
+        li \l QWebEngineProfile::StoreInMemory Has the same behavior as above,
         except that permissions will be destroyed at application exit, and not committed
         to disk.
-        li \l QWebEngineProfile::NoPersistentPermissions makes sure permissions are never
-        remembered, and all act as if they're transient. Thus, every time a web API needs
+        li \l QWebEngineProfile::AskEveryTime makes sure permissions are never
+        remembered, and all act as if they're non-persistent. Thus, every time a web API needs
         a permission, a new prompt will be shown to the user. This option is intended for
         backwards compatibility and applications which implement their own permission storage.
     \endlist
 
     To ensure the user will be shown previously existing permissions, we need to call
-    \l QWebEngineProfile::listPermissions():
+    \l QWebEngineProfile::listAllPermissions():
 
     \quotefromfile webenginewidgets/permissionbrowser/mainwindow.cpp
     \skipto void MainWindow::loadStoredPermissions()
diff --git a/examples/webenginewidgets/permissionbrowser/mainwindow.cpp b/examples/webenginewidgets/permissionbrowser/mainwindow.cpp
index 2fe3c3b1706..8fd811e8383 100644
--- a/examples/webenginewidgets/permissionbrowser/mainwindow.cpp
+++ b/examples/webenginewidgets/permissionbrowser/mainwindow.cpp
@@ -15,12 +15,12 @@ PermissionDialog::PermissionDialog(const QWebEngineProfile *profile, QWidget *pa
 {
     setupUi(this);
 
-    auto metaEnum = QMetaEnum::fromType<QWebEnginePermission::Feature>();
-    Q_ASSERT(metaEnum.value(QWebEnginePermission::Unsupported) == 0);
+    auto metaEnum = QMetaEnum::fromType<QWebEnginePermission::PermissionType>();
+    Q_ASSERT(metaEnum.value((quint8)QWebEnginePermission::PermissionType::Unsupported) == 0);
     for (int i = 1; i < metaEnum.keyCount(); ++i) {
-        QWebEnginePermission::Feature feature = QWebEnginePermission::Feature(metaEnum.value(i));
-        if (!QWebEnginePermission::isTransient(feature))
-            m_featureComboBox->addItem(metaEnum.valueToKey(feature), QVariant(feature));
+        QWebEnginePermission::PermissionType permissionType = QWebEnginePermission::PermissionType(metaEnum.value(i));
+        if (QWebEnginePermission::isPersistent(permissionType))
+            m_permissionTypeComboBox->addItem(metaEnum.valueToKey((quint8)permissionType), QVariant::fromValue(permissionType));
     }
 }
 
@@ -31,8 +31,8 @@ PermissionDialog::~PermissionDialog()
 
 QWebEnginePermission PermissionDialog::permission()
 {
-    return m_profile->getPermission(QUrl(m_originLineEdit->text()),
-        QWebEnginePermission::Feature(m_featureComboBox->itemData(m_featureComboBox->currentIndex()).toInt()));
+    return m_profile->queryPermission(QUrl(m_originLineEdit->text()),
+        QWebEnginePermission::PermissionType(m_permissionTypeComboBox->itemData(m_permissionTypeComboBox->currentIndex()).toInt()));
 }
 
 PermissionWidget::PermissionWidget(const QWebEnginePermission &permission, QWidget *parent)
@@ -64,23 +64,23 @@ PermissionWidget::PermissionWidget(const QWebEnginePermission &permission, QWidg
 void PermissionWidget::updateState()
 {
     switch (m_permission.state()) {
-    case QWebEnginePermission::Invalid:
+    case QWebEnginePermission::State::Invalid:
         m_stateLabel->setText("<font color='gray'>Invalid</font>");
         m_grantButton->setEnabled(false);
         m_denyButton->setEnabled(false);
         break;
-    case QWebEnginePermission::Ask:
+    case QWebEnginePermission::State::Ask:
         m_stateLabel->setText("<font color='yellow'>Waiting for response</font>");
         break;
-    case QWebEnginePermission::Granted:
+    case QWebEnginePermission::State::Granted:
         m_stateLabel->setText("<font color='green'>Granted</font>");
         break;
-    case QWebEnginePermission::Denied:
+    case QWebEnginePermission::State::Denied:
         m_stateLabel->setText("<font color='red'>Denied</font>");
         break;
     }
 
-    m_typeLabel->setText(QMetaEnum::fromType<QWebEnginePermission::Feature>().valueToKey(m_permission.feature()));
+    m_typeLabel->setText(QMetaEnum::fromType<QWebEnginePermission::PermissionType>().valueToKey((quint8)m_permission.permissionType()));
     m_originLabel->setText(m_permission.origin().toDisplayString());
 }
 
@@ -153,9 +153,9 @@ void MainWindow::handlePermissionModified(PermissionWidget *widget)
     m_pendingFrame->layout()->removeWidget(widget);
     m_pendingWidget = nullptr;
 
-    if (QWebEnginePermission::isTransient(widget->m_permission.feature())
-        || widget->m_permission.state() == QWebEnginePermission::Ask
-        || m_profile->persistentPermissionsPolicy() == QWebEngineProfile::NoPersistentPermissions) {
+    if (!QWebEnginePermission::isPersistent(widget->m_permission.permissionType())
+        || widget->m_permission.state() == QWebEnginePermission::State::Ask
+        || m_profile->persistentPermissionsPolicy() == QWebEngineProfile::PersistentPermissionsPolicy::AskEveryTime) {
 
         widget->deleteLater();
         return;
@@ -209,13 +209,13 @@ void MainWindow::handlePolicyComboBoxIndexChanged(int index)
     QWebEngineProfile::PersistentPermissionsPolicy policy;
     switch (index) {
     case 0:
-        policy = QWebEngineProfile::PersistentPermissionsOnDisk;
+        policy = QWebEngineProfile::PersistentPermissionsPolicy::AskEveryTime;
         break;
     case 1:
-        policy = QWebEngineProfile::PersistentPermissionsInMemory;
+        policy = QWebEngineProfile::PersistentPermissionsPolicy::StoreInMemory;
         break;
     case 2:
-        policy = QWebEngineProfile::NoPersistentPermissions;
+        policy = QWebEngineProfile::PersistentPermissionsPolicy::StoreOnDisk;
         break;
     }
 
@@ -261,7 +261,7 @@ PermissionWidget *MainWindow::createPermissionWidget(const QWebEnginePermission
 
 void MainWindow::loadStoredPermissions()
 {
-    QList<QWebEnginePermission> permissionsList = m_profile->listPermissions();
+    QList<QWebEnginePermission> permissionsList = m_profile->listAllPermissions();
     for (QWebEnginePermission &permission : permissionsList) {
         PermissionWidget *widget = createPermissionWidget(permission);
         if (widget)
diff --git a/examples/webenginewidgets/permissionbrowser/permissiondialog.ui b/examples/webenginewidgets/permissionbrowser/permissiondialog.ui
index a98432131a1..430df2d58b4 100644
--- a/examples/webenginewidgets/permissionbrowser/permissiondialog.ui
+++ b/examples/webenginewidgets/permissionbrowser/permissiondialog.ui
@@ -31,7 +31,7 @@
    <item row="1" column="0">
     <widget class="QLabel" name="label_2">
      <property name="text">
-      <string>Feature</string>
+      <string>Permission type</string>
      </property>
     </widget>
    </item>
@@ -70,7 +70,7 @@
     </layout>
    </item>
    <item row="1" column="1">
-    <widget class="QComboBox" name="m_featureComboBox"/>
+    <widget class="QComboBox" name="m_permissionTypeComboBox"/>
    </item>
   </layout>
  </widget>
diff --git a/examples/webenginewidgets/push-notifications/main.cpp b/examples/webenginewidgets/push-notifications/main.cpp
index 2a52ea39e0e..16465317dfc 100644
--- a/examples/webenginewidgets/push-notifications/main.cpp
+++ b/examples/webenginewidgets/push-notifications/main.cpp
@@ -22,7 +22,7 @@ int main(int argc, char *argv[])
 
     QObject::connect(view.page(), &QWebEnginePage::permissionRequested,
                      [&](QWebEnginePermission permission) {
-                         if (permission.feature() != QWebEnginePermission::Notifications)
+                         if (permission.permissionType() != QWebEnginePermission::PermissionType::Notifications)
                              return;
 
                          permission.grant();
diff --git a/examples/webenginewidgets/simplebrowser/webview.cpp b/examples/webenginewidgets/simplebrowser/webview.cpp
index 40a1508b4ef..e7538f948ca 100644
--- a/examples/webenginewidgets/simplebrowser/webview.cpp
+++ b/examples/webenginewidgets/simplebrowser/webview.cpp
@@ -71,27 +71,31 @@ WebView::~WebView()
     m_imageAnimationGroup = nullptr;
 }
 
-inline QString questionForFeature(QWebEnginePermission::Feature feature)
+inline QString questionForPermissionType(QWebEnginePermission::PermissionType permissionType)
 {
-    switch (feature) {
-    case QWebEnginePermission::Geolocation:
+    switch (permissionType) {
+    case QWebEnginePermission::PermissionType::Geolocation:
         return QObject::tr("Allow %1 to access your location information?");
-    case QWebEnginePermission::MediaAudioCapture:
+    case QWebEnginePermission::PermissionType::MediaAudioCapture:
         return QObject::tr("Allow %1 to access your microphone?");
-    case QWebEnginePermission::MediaVideoCapture:
+    case QWebEnginePermission::PermissionType::MediaVideoCapture:
         return QObject::tr("Allow %1 to access your webcam?");
-    case QWebEnginePermission::MediaAudioVideoCapture:
+    case QWebEnginePermission::PermissionType::MediaAudioVideoCapture:
         return QObject::tr("Allow %1 to access your microphone and webcam?");
-    case QWebEnginePermission::MouseLock:
+    case QWebEnginePermission::PermissionType::MouseLock:
         return QObject::tr("Allow %1 to lock your mouse cursor?");
-    case QWebEnginePermission::DesktopVideoCapture:
+    case QWebEnginePermission::PermissionType::DesktopVideoCapture:
         return QObject::tr("Allow %1 to capture video of your desktop?");
-    case QWebEnginePermission::DesktopAudioVideoCapture:
+    case QWebEnginePermission::PermissionType::DesktopAudioVideoCapture:
         return QObject::tr("Allow %1 to capture audio and video of your desktop?");
-    case QWebEnginePermission::Notifications:
+    case QWebEnginePermission::PermissionType::Notifications:
         return QObject::tr("Allow %1 to show notification on your desktop?");
-    case QWebEnginePermission::ClipboardReadWrite:
+    case QWebEnginePermission::PermissionType::ClipboardReadWrite:
         return QObject::tr("Allow %1 to read from and write to the clipboard?");
+    case QWebEnginePermission::PermissionType::LocalFontsAccess:
+        return QObject::tr("Allow %1 to access fonts stored on this machine?");
+    case QWebEnginePermission::PermissionType::Unsupported:
+        break;
     }
     return QString();
 }
@@ -312,7 +316,7 @@ void WebView::handleAuthenticationRequired(const QUrl &requestUrl, QAuthenticato
 void WebView::handlePermissionRequested(QWebEnginePermission permission)
 {
     QString title = tr("Permission Request");
-    QString question = questionForFeature(permission.feature()).arg(permission.origin().host());
+    QString question = questionForPermissionType(permission.permissionType()).arg(permission.origin().host());
     if (!question.isEmpty() && QMessageBox::question(window(), title, question) == QMessageBox::Yes)
         permission.grant();
     else
diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp
index a5c06f29ce8..433de26b072 100644
--- a/src/core/api/qwebenginepage.cpp
+++ b/src/core/api/qwebenginepage.cpp
@@ -590,22 +590,22 @@ void QWebEnginePagePrivate::showColorDialog(QSharedPointer<ColorChooserControlle
 void QWebEnginePagePrivate::runMediaAccessPermissionRequest(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags requestFlags)
 {
     Q_Q(QWebEnginePage);
-    QWebEnginePermission::Feature feature;
+    QWebEnginePermission::PermissionType permissionType;
 
     if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture)
             && requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
-        feature = QWebEnginePermission::MediaAudioVideoCapture;
+        permissionType = QWebEnginePermission::PermissionType::MediaAudioVideoCapture;
     else if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture))
-        feature = QWebEnginePermission::MediaAudioCapture;
+        permissionType = QWebEnginePermission::PermissionType::MediaAudioCapture;
     else if (requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
-        feature = QWebEnginePermission::MediaVideoCapture;
+        permissionType = QWebEnginePermission::PermissionType::MediaVideoCapture;
     else if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopAudioCapture)
             && requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture))
-        feature = QWebEnginePermission::DesktopAudioVideoCapture;
+        permissionType = QWebEnginePermission::PermissionType::DesktopAudioVideoCapture;
     else // if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture))
-        feature = QWebEnginePermission::DesktopVideoCapture;
+        permissionType = QWebEnginePermission::PermissionType::DesktopVideoCapture;
 
-    Q_EMIT q->permissionRequested(createFeaturePermissionObject(securityOrigin, feature));
+    Q_EMIT q->permissionRequested(createFeaturePermissionObject(securityOrigin, permissionType));
 
 #if QT_DEPRECATED_SINCE(6, 8)
     QT_WARNING_PUSH
@@ -633,30 +633,30 @@ void QWebEnginePagePrivate::runMediaAccessPermissionRequest(const QUrl &security
 #if QT_DEPRECATED_SINCE(6, 8)
 QT_WARNING_PUSH
 QT_WARNING_DISABLE_DEPRECATED
-static QWebEnginePage::Feature toDeprecatedFeature(QWebEnginePermission::Feature feature)
+static QWebEnginePage::Feature toDeprecatedFeature(QWebEnginePermission::PermissionType permissionType)
 {
-    switch (feature) {
-    case QWebEnginePermission::Feature::Notifications:
+    switch (permissionType) {
+    case QWebEnginePermission::PermissionType::Notifications:
         return QWebEnginePage::Notifications;
-    case QWebEnginePermission::Feature::Geolocation:
+    case QWebEnginePermission::PermissionType::Geolocation:
         return QWebEnginePage::Geolocation;
-    case QWebEnginePermission::Feature::ClipboardReadWrite:
+    case QWebEnginePermission::PermissionType::ClipboardReadWrite:
         return QWebEnginePage::ClipboardReadWrite;
-    case QWebEnginePermission::Feature::LocalFontsAccess:
+    case QWebEnginePermission::PermissionType::LocalFontsAccess:
         return QWebEnginePage::LocalFontsAccess;
-    case QWebEnginePermission::Feature::MediaAudioCapture:
+    case QWebEnginePermission::PermissionType::MediaAudioCapture:
         return QWebEnginePage::MediaAudioCapture;
-    case QWebEnginePermission::Feature::MediaVideoCapture:
+    case QWebEnginePermission::PermissionType::MediaVideoCapture:
         return QWebEnginePage::MediaVideoCapture;
-    case QWebEnginePermission::Feature::MediaAudioVideoCapture:
+    case QWebEnginePermission::PermissionType::MediaAudioVideoCapture:
         return QWebEnginePage::MediaAudioVideoCapture;
-    case QWebEnginePermission::Feature::DesktopVideoCapture:
+    case QWebEnginePermission::PermissionType::DesktopVideoCapture:
         return QWebEnginePage::DesktopVideoCapture;
-    case QWebEnginePermission::Feature::DesktopAudioVideoCapture:
+    case QWebEnginePermission::PermissionType::DesktopAudioVideoCapture:
         return QWebEnginePage::DesktopAudioVideoCapture;
-    case QWebEnginePermission::Feature::MouseLock:
+    case QWebEnginePermission::PermissionType::MouseLock:
         return QWebEnginePage::MouseLock;
-    case QWebEnginePermission::Feature::Unsupported:
+    case QWebEnginePermission::PermissionType::Unsupported:
         break;
     }
 
@@ -666,38 +666,28 @@ static QWebEnginePage::Feature toDeprecatedFeature(QWebEnginePermission::Feature
 QT_WARNING_POP
 #endif // QT_DEPRECATED_SINCE(6, 8)
 
-void QWebEnginePagePrivate::runFeaturePermissionRequest(QWebEnginePermission::Feature feature, const QUrl &securityOrigin)
+void QWebEnginePagePrivate::runFeaturePermissionRequest(QWebEnginePermission::PermissionType permissionType, const QUrl &securityOrigin)
 {
     Q_Q(QWebEnginePage);
-    switch (feature) {
-    case QWebEnginePermission::Notifications:
-    case QWebEnginePermission::Geolocation:
-    case QWebEnginePermission::ClipboardReadWrite:
-    case QWebEnginePermission::LocalFontsAccess:
-        Q_EMIT q->permissionRequested(createFeaturePermissionObject(securityOrigin, feature));
+
+    if (QWebEnginePermission::isPersistent(permissionType)) {
+        Q_EMIT q->permissionRequested(createFeaturePermissionObject(securityOrigin, permissionType));
 #if QT_DEPRECATED_SINCE(6, 8)
         QT_WARNING_PUSH
         QT_WARNING_DISABLE_DEPRECATED
-        Q_EMIT q->featurePermissionRequested(securityOrigin, toDeprecatedFeature(feature));
+        Q_EMIT q->featurePermissionRequested(securityOrigin, toDeprecatedFeature(permissionType));
         QT_WARNING_POP
 #endif // QT_DEPRECATED_SINCE(6, 8)
         return;
-    case QWebEnginePermission::MouseLock:
-    case QWebEnginePermission::MediaAudioCapture:
-    case QWebEnginePermission::MediaVideoCapture:
-    case QWebEnginePermission::MediaAudioVideoCapture:
-    case QWebEnginePermission::DesktopAudioVideoCapture:
-    case QWebEnginePermission::DesktopVideoCapture:
-    case QWebEnginePermission::Unsupported:
-        Q_UNREACHABLE();
-        return;
     }
+
+    Q_UNREACHABLE();
 }
 
 void QWebEnginePagePrivate::runMouseLockPermissionRequest(const QUrl &securityOrigin)
 {
     Q_Q(QWebEnginePage);
-    Q_EMIT q->permissionRequested(createFeaturePermissionObject(securityOrigin, QWebEnginePermission::MouseLock));
+    Q_EMIT q->permissionRequested(createFeaturePermissionObject(securityOrigin, QWebEnginePermission::PermissionType::MouseLock));
 
 #if QT_DEPRECATED_SINCE(6, 8)
     QT_WARNING_PUSH
@@ -893,9 +883,9 @@ void QWebEnginePagePrivate::showWebAuthDialog(QWebEngineWebAuthUxRequest *reques
     Q_EMIT q->webAuthUxRequested(request);
 }
 
-QWebEnginePermission QWebEnginePagePrivate::createFeaturePermissionObject(const QUrl &securityOrigin, QWebEnginePermission::Feature feature)
+QWebEnginePermission QWebEnginePagePrivate::createFeaturePermissionObject(const QUrl &securityOrigin, QWebEnginePermission::PermissionType feature)
 {
-    auto *returnPrivate = new QWebEnginePermissionPrivate{securityOrigin, feature, adapter, profileAdapter()};
+    auto *returnPrivate = new QWebEnginePermissionPrivate(securityOrigin, feature, adapter, profileAdapter());
     return QWebEnginePermission(returnPrivate);
 }
 
@@ -1857,39 +1847,39 @@ QT_WARNING_DISABLE_DEPRECATED
 void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEnginePage::Feature feature, QWebEnginePage::PermissionPolicy policy)
 {
     Q_D(QWebEnginePage);
-    QWebEnginePermission::Feature f = QWebEnginePermission::Feature::Unsupported;
+    QWebEnginePermission::PermissionType f = QWebEnginePermission::PermissionType::Unsupported;
     QWebEnginePermission::State s = QWebEnginePermission::State::Invalid;
 
     switch (feature) {
     case QWebEnginePage::Notifications:
-        f = QWebEnginePermission::Notifications;
+        f = QWebEnginePermission::PermissionType::Notifications;
         break;
     case QWebEnginePage::Geolocation:
-        f = QWebEnginePermission::Geolocation;
+        f = QWebEnginePermission::PermissionType::Geolocation;
         break;
     case QWebEnginePage::MediaAudioCapture:
-        f = QWebEnginePermission::MediaAudioCapture;
+        f = QWebEnginePermission::PermissionType::MediaAudioCapture;
         break;
     case QWebEnginePage::MediaVideoCapture:
-        f = QWebEnginePermission::MediaVideoCapture;
+        f = QWebEnginePermission::PermissionType::MediaVideoCapture;
         break;
     case QWebEnginePage::MediaAudioVideoCapture:
-        f = QWebEnginePermission::MediaAudioVideoCapture;
+        f = QWebEnginePermission::PermissionType::MediaAudioVideoCapture;
         break;
     case QWebEnginePage::MouseLock:
-        f = QWebEnginePermission::MouseLock;
+        f = QWebEnginePermission::PermissionType::MouseLock;
         break;
     case QWebEnginePage::DesktopVideoCapture:
-        f = QWebEnginePermission::DesktopVideoCapture;
+        f = QWebEnginePermission::PermissionType::DesktopVideoCapture;
         break;
     case QWebEnginePage::DesktopAudioVideoCapture:
-        f = QWebEnginePermission::DesktopAudioVideoCapture;
+        f = QWebEnginePermission::PermissionType::DesktopAudioVideoCapture;
         break;
     case QWebEnginePage::ClipboardReadWrite:
-        f = QWebEnginePermission::ClipboardReadWrite;
+        f = QWebEnginePermission::PermissionType::ClipboardReadWrite;
         break;
     case QWebEnginePage::LocalFontsAccess:
-        f = QWebEnginePermission::LocalFontsAccess;
+        f = QWebEnginePermission::PermissionType::LocalFontsAccess;
         break;
     default:
         Q_UNREACHABLE();
@@ -1897,19 +1887,19 @@ void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEngine
 
     switch (policy) {
     case QWebEnginePage::PermissionUnknown:
-        s = QWebEnginePermission::Ask;
+        s = QWebEnginePermission::State::Ask;
         break;
     case QWebEnginePage::PermissionDeniedByUser:
-        s = QWebEnginePermission::Denied;
+        s = QWebEnginePermission::State::Denied;
         break;
     case QWebEnginePage::PermissionGrantedByUser:
-        s = QWebEnginePermission::Granted;
+        s = QWebEnginePermission::State::Granted;
         break;
     default:
         Q_UNREACHABLE();
     }
 
-    d->adapter->setFeaturePermission(securityOrigin, f, s);
+    d->adapter->setPermission(securityOrigin, f, s);
 }
 QT_WARNING_POP
 #endif // QT_DEPRECATED_SINCE(6, 8)
diff --git a/src/core/api/qwebenginepage.h b/src/core/api/qwebenginepage.h
index 61c9bd990c1..8b36826725c 100644
--- a/src/core/api/qwebenginepage.h
+++ b/src/core/api/qwebenginepage.h
@@ -150,17 +150,12 @@ class Q_WEBENGINECORE_EXPORT QWebEnginePage : public QObject
     Q_ENUM(WebWindowType)
 
 #if QT_DEPRECATED_SINCE(6, 8)
-QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
-    enum QT_DEPRECATED_VERSION_X_6_8(
-        "QWebEnginePage::PermissionPolicy has been deprecated. "
-        "The updated permissions API uses QWebEnginePermission::State.")
-    PermissionPolicy {
-        PermissionUnknown,
-        PermissionGrantedByUser,
-        PermissionDeniedByUser
+    enum PermissionPolicy {
+        PermissionUnknown Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::State::Ask instead"),
+        PermissionGrantedByUser Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::State::Granted instead"),
+        PermissionDeniedByUser Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::State::Denied instead")
     };
     Q_ENUM(PermissionPolicy)
-QT_WARNING_POP
 #endif
 
     // must match WebContentsAdapterClient::NavigationType
@@ -176,24 +171,19 @@ QT_WARNING_POP
     Q_ENUM(NavigationType)
 
 #if QT_DEPRECATED_SINCE(6, 8)
-QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
-    enum QT_DEPRECATED_VERSION_X_6_8(
-        "QWebEnginePage::Feature has been deprecated. "
-        "The updated permissions API uses QWebEnginePermission::Feature.")
-    Feature {
-        Notifications = 0,
-        Geolocation = 1,
-        MediaAudioCapture = 2,
-        MediaVideoCapture,
-        MediaAudioVideoCapture,
-        MouseLock,
-        DesktopVideoCapture,
-        DesktopAudioVideoCapture,
-        ClipboardReadWrite,
-        LocalFontsAccess,
+    enum Feature {
+        Notifications Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::Notifications instead") = 0,
+        Geolocation Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::Geolocation instead") = 1,
+        MediaAudioCapture Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::MediaAudioCapture instead") = 2,
+        MediaVideoCapture Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::MediaVideoCapture instead"),
+        MediaAudioVideoCapture Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::MediaAudioVideoCapture instead"),
+        MouseLock Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::MouseLock instead"),
+        DesktopVideoCapture Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::DesktopVideoCapture instead"),
+        DesktopAudioVideoCapture Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::DesktopAudioVideoCapture instead"),
+        ClipboardReadWrite Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::ClipboardReadWrite instead"),
+        LocalFontsAccess Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::LocalFontsAccess instead"),
     };
     Q_ENUM(Feature)
-QT_WARNING_POP
 #endif
 
     // Ex-QWebFrame enum
@@ -253,10 +243,8 @@ QT_WARNING_POP
     void findText(const QString &subString, FindFlags options = {}, const std::function<void(const QWebEngineFindTextResult &)> &resultCallback = std::function<void(const QWebEngineFindTextResult &)>());
 
 #if QT_DEPRECATED_SINCE(6, 8)
-QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
     QT_DEPRECATED_VERSION_X_6_8("Setting permissions through QWebEnginePage has been deprecated. Please use QWebEnginePermission instead.")
     void setFeaturePermission(const QUrl &securityOrigin, Feature feature, PermissionPolicy policy);
-QT_WARNING_POP
 #endif
 
     bool isLoading() const;
@@ -341,17 +329,10 @@ QT_WARNING_POP
     void windowCloseRequested();
 
 #if QT_DEPRECATED_SINCE(6, 8)
-#if !defined(Q_MOC_RUN)
-QT_WARNING_PUSH
-QT_WARNING_DISABLE_DEPRECATED
-#endif // !defined(Q_MOC_RUN)
     QT_MOC_COMPAT QT_DEPRECATED_VERSION_X_6_8("The signal has been deprecated; please use permissionRequested instead.")
     void featurePermissionRequested(const QUrl &securityOrigin, QWebEnginePage::Feature feature);
     QT_MOC_COMPAT QT_DEPRECATED_VERSION_X_6_8("The signal has been deprecated, and no longer functions.")
     void featurePermissionRequestCanceled(const QUrl &securityOrigin, QWebEnginePage::Feature feature);
-#if !defined(Q_MOC_RUN)
-QT_WARNING_POP
-#endif // !defined(Q_MOC_RUN)
 #endif // QT_DEPRECATED_SINCE(6, 8)
 
     void fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest);
diff --git a/src/core/api/qwebenginepage_p.h b/src/core/api/qwebenginepage_p.h
index 77d3dd8c247..5e81a0cf91c 100644
--- a/src/core/api/qwebenginepage_p.h
+++ b/src/core/api/qwebenginepage_p.h
@@ -148,7 +148,7 @@ class Q_WEBENGINECORE_EXPORT QWebEnginePagePrivate : public QtWebEngineCore::Web
             QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) override;
     void releaseProfile() override;
     void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) override;
-    void runFeaturePermissionRequest(QWebEnginePermission::Feature feature, const QUrl &securityOrigin) override;
+    void runFeaturePermissionRequest(QWebEnginePermission::PermissionType permissionType, const QUrl &securityOrigin) override;
     void runMouseLockPermissionRequest(const QUrl &securityOrigin) override;
     void runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest) override;
     void runFileSystemAccessRequest(QWebEngineFileSystemAccessRequest) override;
@@ -180,7 +180,7 @@ class Q_WEBENGINECORE_EXPORT QWebEnginePagePrivate : public QtWebEngineCore::Web
                            const QRect &bounds, bool autoselectFirstSuggestion) override;
     void hideAutofillPopup() override;
     void showWebAuthDialog(QWebEngineWebAuthUxRequest *controller) override;
-    QWebEnginePermission createFeaturePermissionObject(const QUrl &securityOrigin, QWebEnginePermission::Feature feature) override;
+    QWebEnginePermission createFeaturePermissionObject(const QUrl &securityOrigin, QWebEnginePermission::PermissionType permissionType) override;
 
     QtWebEngineCore::ProfileAdapter *profileAdapter() override;
     QtWebEngineCore::WebContentsAdapter *webContentsAdapter() override;
diff --git a/src/core/api/qwebenginepermission.cpp b/src/core/api/qwebenginepermission.cpp
index 61e76ee4a0d..a6860b5ddff 100644
--- a/src/core/api/qwebenginepermission.cpp
+++ b/src/core/api/qwebenginepermission.cpp
@@ -10,17 +10,19 @@ QT_BEGIN_NAMESPACE
 
 QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QWebEnginePermissionPrivate)
 
+/*! \internal */
 QWebEnginePermissionPrivate::QWebEnginePermissionPrivate()
     : QSharedData()
-    , feature(QWebEnginePermission::Unsupported)
+    , permissionType(QWebEnginePermission::PermissionType::Unsupported)
 {
 }
 
-QWebEnginePermissionPrivate::QWebEnginePermissionPrivate(const QUrl &origin_, QWebEnginePermission::Feature feature_,
+/*! \internal */
+QWebEnginePermissionPrivate::QWebEnginePermissionPrivate(const QUrl &origin_, QWebEnginePermission::PermissionType permissionType_,
         QSharedPointer<QtWebEngineCore::WebContentsAdapter> webContentsAdapter_, QtWebEngineCore::ProfileAdapter *profileAdapter_)
     : QSharedData()
     , origin(origin_)
-    , feature(feature_)
+    , permissionType(permissionType_)
     , webContentsAdapter(webContentsAdapter_)
     , profileAdapter(profileAdapter_)
 {
@@ -35,32 +37,39 @@ QWebEnginePermissionPrivate::QWebEnginePermissionPrivate(const QUrl &origin_, QW
 
     The typical usage pattern is as follows:
     \list 1
-        \li A website requests a specific feature, triggering the QWebEnginePage::permissionRequested() signal;
+        \li A website requests a specific permission, triggering the QWebEnginePage::permissionRequested() signal;
         \li The signal handler triggers a prompt asking the user whether they want to grant the permission;
         \li When the user has made their decision, the application calls \l grant() or \l deny();
     \endlist
 
-    Alternatively, an application interested in modifying already granted permissions may use QWebEngineProfile::listPermissions()
-    to get a list of existing permissions associated with a profile, or QWebEngineProfile::getPermission() to get
+    Alternatively, an application interested in modifying already granted permissions may use QWebEngineProfile::listAllPermissions()
+    to get a list of existing permissions associated with a profile, or QWebEngineProfile::queryPermission() to get
     a QWebEnginePermission object for a specific permission.
 
     The \l origin() property can be used to query which origin the QWebEnginePermission is associated with, while the
-    \l feature() property describes the associated feature. A website origin is the combination of its scheme, hostname,
-    and port. Permissions are granted on a per-origin basis; thus, if the web page \c{https://www.example.com:12345/some/page.html}
-    requests a permission, it will be granted to the origin \c{https://www.example.com:12345/}.
+    \l permissionType() property describes the type of the requested permission. A website origin is the combination of
+    its scheme, hostname, and port. Permissions are granted on a per-origin basis; thus, if the web page
+    \c{https://www.example.com:12345/some/page.html} requests a permission, it will be granted to the origin
+    \c{https://www.example.com:12345/}.
+
+    \l QWebEnginePermission::PermissionType describes all the permission types Qt WebEngine supports. Only some permission types
+    are remembered between browsing sessions; they are \e persistent. Non-persistent permissions query the user every time a
+    website requests them, and cannot be granted in advance. You can check whether a permission type is persistent at runtime
+    using the static method QWebEnginePermission::isPersistent().
+
+    Persistent permissions are stored inside the active QWebEngineProfile, and their lifetime depends on the value of
+    QWebEngineProfile::persistentPermissionsPolicy(). By default, named profiles store their permissions on disk, whereas
+    off-the-record ones store them in memory (and destroy them when the profile is destroyed). A stored permission will not
+    query the user the next time a website requests it; instead it will be automatically granted or denied, depending on
+    the resolution the user picked initially. To erase a stored permission, call \l reset() on it.
 
-    \l QWebEnginePermission::Feature describes all the feature types Qt WebEngine supports. Some Features are transient;
-    in practice, this means that they are never remembered, and a website that uses them will trigger a permission
-    prompt every time the Feature is needed. Transient Features cannot be granted in advance.
+    A non-persistent permission, on the other hand, is only usable until the related QWebEnginePage performs a navigation to
+    a different URL, or is destroyed.
 
-    The usability lifetime of a QWebEnginePermission is tied either to its associated QWebEnginePage
-    (for transient feature types), or QWebEngineProfile (for permanent feature types). A transient permission is one which
-    needs to be explicitly granted or denied every time it's needed (e.g. webcam/screen sharing permission), whereas a permanent
-    one might be stored inside the current profile, depending on the value of QWebEngineProfile::persistentPermissionsPolicy().
     You can check whether a QWebEnginePermission is in a valid state using its \l isValid() property. For invalid objects, calls to \l grant(),
     \l deny(), or \l reset() will do nothing, while calls to \l state() will always return QWebEnginePermission::Invalid.
 
-    \sa QWebEnginePage::permissionRequested(), QWebEngineProfile::getPermission(), QWebEngineProfile::listPermissions()
+    \sa QWebEnginePage::permissionRequested(), QWebEngineProfile::queryPermission(), QWebEngineProfile::listAllPermissions()
 */
 
 /*! \fn QWebEnginePermission::QWebEnginePermission()
@@ -100,10 +109,10 @@ bool QWebEnginePermission::comparesEqual(const QWebEnginePermission &other) cons
     if (this == &other)
         return true;
 
-    if (d_ptr->feature != other.d_ptr->feature || d_ptr->origin != other.d_ptr->origin)
+    if (d_ptr->permissionType != other.d_ptr->permissionType || d_ptr->origin != other.d_ptr->origin)
         return false;
 
-    if (isTransient(d_ptr->feature)) {
+    if (!isPersistent(d_ptr->permissionType)) {
         if (d_ptr->webContentsAdapter != other.d_ptr->webContentsAdapter)
             return false;
     } else {
@@ -129,49 +138,49 @@ bool QWebEnginePermission::comparesEqual(const QWebEnginePermission &other) cons
     per-origin basis; thus, if the web page \c{https://www.example.com:12345/some/page.html}
     requests a permission, it will be granted to the origin \c{https://www.example.com:12345/}.
 */
-const QUrl QWebEnginePermission::origin() const
+QUrl QWebEnginePermission::origin() const
 {
     return d_ptr->origin;
 }
 
 /*!
-    \enum QWebEnginePermission::Feature
-
-    This enum type holds the type of the requested feature:
-
-    \value MediaAudioCapture Access to a microphone, or another audio source. This feature is transient.
-    \value MediaVideoCapture Access to a webcam, or another video source. This feature is transient.
-    \value MediaAudioVideoCapture Combination of \l MediaAudioCapture and \l MediaVideoCapture. This feature is transient.
-    \value DesktopVideoCapture Access to the contents of the user's screen. This feature is transient.
-    \value DesktopAudioVideoCapture Access to the contents of the user's screen, and application audio. This feature is transient.
-    \value MouseLock Locks the pointer inside an element on the web page. This feature is transient.
-    \value Notifications Allows the website to send notifications to the user.
-    \value Geolocation Access to the user's physical location.
-    \value ClipboardReadWrite Access to the user's clipboard.
-    \value LocalFontsAccess Access to the fonts installed on the user's machine. Only available on desktops.
-    \value Unsupported An unsupported feature type.
-
-    \note Transient feature types are ones that will never be remembered by the underlying storage, and will trigger
-    a permission request every time a website tries to use them. Transient Features can only be denied/granted
-    as they're needed; any attempts to pre-grant a transient Feature will fail.
+    \enum QWebEnginePermission::PermissionType
+
+    This enum type holds the type of the requested permission type:
+
+    \value MediaAudioCapture Access to a microphone, or another audio source. This permission is \e not persistent.
+    \value MediaVideoCapture Access to a webcam, or another video source. This permission is \e not persistent.
+    \value MediaAudioVideoCapture Combination of \l MediaAudioCapture and \l MediaVideoCapture. This permission is \e not persistent.
+    \value DesktopVideoCapture Access to the contents of the user's screen. This permission is \e not persistent.
+    \value DesktopAudioVideoCapture Access to the contents of the user's screen, and application audio. This permission is \e not persistent.
+    \value MouseLock Locks the pointer inside an element on the web page. This permission is \e not persistent.
+    \value Notifications Allows the website to send notifications to the user. This permission is persistent.
+    \value Geolocation Access to the user's physical location. This permission is persistent.
+    \value ClipboardReadWrite Access to the user's clipboard. This permission is persistent.
+    \value LocalFontsAccess Access to the fonts installed on the user's machine. Only available on desktops. This permission is persistent.
+    \value Unsupported An unsupported permission type.
+
+    \note Non-persistent permission types are ones that will never be remembered by the underlying storage, and will trigger
+    a permission request every time a website tries to use them. They can only be denied/granted as they're needed;
+    any attempts to pre-grant a non-persistent permission will fail.
 */
 
 /*!
-    \property QWebEnginePermission::feature
-    \brief The feature type associated with this permission.
+    \property QWebEnginePermission::permissionType
+    \brief The permission type associated with this permission.
 */
-QWebEnginePermission::Feature QWebEnginePermission::feature() const
+QWebEnginePermission::PermissionType QWebEnginePermission::permissionType() const
 {
-    return d_ptr->feature;
+    return d_ptr->permissionType;
 }
 
 /*!
     \enum QWebEnginePermission::State
 
-    This enum type holds the current state of the requested feature:
+    This enum type holds the current state of the requested permission:
 
     \value Invalid Object is in an invalid state, and any attempts to modify the described permission will fail.
-    \value Ask Either the permission has not been requested before, or the feature() is transient.
+    \value Ask Either the permission has not been requested before, or the permissionType() is not persistent.
     \value Granted Permission has already been granted.
     \value Denied Permission has already been denied.
 */
@@ -180,24 +189,24 @@ QWebEnginePermission::Feature QWebEnginePermission::feature() const
     \property QWebEnginePermission::state
     \brief The current state of the permission.
 
-    If a permission for the specified \l feature() and \l origin() has already been granted or denied,
+    If a permission for the specified \l permissionType() and \l origin() has already been granted or denied,
     the return value is QWebEnginePermission::Granted, or QWebEnginePermission::Denied, respectively.
-    When this is the first time the permission is requested, or if the \l feature() is transient,
+    When this is the first time the permission is requested, or if the \l permissionType() is non-persistent,
     the return value is QWebEnginePermission::Ask. If the object is in an invalid state, the returned
     value is QWebEnginePermission::Invalid.
 
-    \sa isValid(), isTransient()
+    \sa isValid(), isPersistent()
 */
 QWebEnginePermission::State QWebEnginePermission::state() const
 {
     if (!isValid())
-        return Invalid;
+        return State::Invalid;
     if (d_ptr->webContentsAdapter)
-        return d_ptr->webContentsAdapter.toStrongRef()->getPermissionState(origin(), feature());
+        return d_ptr->webContentsAdapter.toStrongRef()->getPermissionState(origin(), permissionType());
     if (d_ptr->profileAdapter)
-        return d_ptr->profileAdapter->getPermissionState(origin(), feature());
+        return d_ptr->profileAdapter->getPermissionState(origin(), permissionType());
     Q_UNREACHABLE();
-    return Ask;
+    return State::Ask;
 }
 
 /*!
@@ -206,19 +215,19 @@ QWebEnginePermission::State QWebEnginePermission::state() const
 
     An invalid QWebEnginePermission is either:
     \list
-        \li One whose \l feature() is unsupported;
-        \li One whose \l feature() is transient, and the associated page/view has been destroyed;
-        \li One whose \l feature() is permanent, but the associated profile has been destroyed;
+        \li One whose \l permissionType() is unsupported;
+        \li One whose \l permissionType() is non-persistent, and the user has navigated away from the web page that triggered the request;
+        \li One whose \l permissionType() is persistent, but the associated profile has been destroyed;
         \li One whose \l origin() is invalid.
     \endlist
 
-    \sa isTransient()
+    \sa isPersistent()
 */
 bool QWebEnginePermission::isValid() const
 {
-    if (feature() == Unsupported)
+    if (permissionType() == PermissionType::Unsupported)
         return false;
-    if (isTransient(feature()) && !d_ptr->webContentsAdapter)
+    if (!isPersistent(permissionType()) && !d_ptr->webContentsAdapter)
         return false;
     if (!d_ptr->profileAdapter)
         return false;
@@ -228,7 +237,7 @@ bool QWebEnginePermission::isValid() const
 }
 
 /*!
-    Allows the associated origin to access the requested feature. Does nothing when \l isValid() evaluates to false.
+    Allows the associated origin to access the requested permissionType. Does nothing when \l isValid() evaluates to false.
 
     \sa deny(), reset(), isValid()
 */
@@ -237,13 +246,13 @@ void QWebEnginePermission::grant() const
     if (!isValid())
         return;
     if (d_ptr->webContentsAdapter)
-        d_ptr->webContentsAdapter.toStrongRef()->setFeaturePermission(origin(), feature(), Granted);
+        d_ptr->webContentsAdapter.toStrongRef()->setPermission(origin(), permissionType(), State::Granted);
     else if (d_ptr->profileAdapter)
-        d_ptr->profileAdapter->setPermission(origin(), feature(), Granted);
+        d_ptr->profileAdapter->setPermission(origin(), permissionType(), State::Granted);
 }
 
 /*!
-    Stops the associated origin from accessing the requested feature. Does nothing when \l isValid() evaluates to false.
+    Stops the associated origin from accessing the requested permissionType. Does nothing when \l isValid() evaluates to false.
 
     \sa grant(), reset(), isValid()
 */
@@ -252,9 +261,9 @@ void QWebEnginePermission::deny() const
     if (!isValid())
         return;
     if (d_ptr->webContentsAdapter)
-        d_ptr->webContentsAdapter.toStrongRef()->setFeaturePermission(origin(), feature(), Denied);
+        d_ptr->webContentsAdapter.toStrongRef()->setPermission(origin(), permissionType(), State::Denied);
     else if (d_ptr->profileAdapter)
-        d_ptr->profileAdapter->setPermission(origin(), feature(), Denied);
+        d_ptr->profileAdapter->setPermission(origin(), permissionType(), State::Denied);
 }
 
 /*!
@@ -273,31 +282,31 @@ void QWebEnginePermission::reset() const
     if (!isValid())
         return;
     if (d_ptr->webContentsAdapter)
-        d_ptr->webContentsAdapter.toStrongRef()->setFeaturePermission(origin(), feature(), Ask);
+        d_ptr->webContentsAdapter.toStrongRef()->setPermission(origin(), permissionType(), State::Ask);
     else if (d_ptr->profileAdapter)
-        d_ptr->profileAdapter->setPermission(origin(), feature(), Ask);
+        d_ptr->profileAdapter->setPermission(origin(), permissionType(), State::Ask);
 }
 
 /*!
-    Returns whether \a feature is transient, meaning that a permission will be requested
-    every time the associated functionality is used by a web page.
+    Returns whether a \a permissionType is \e persistent, meaning that a permission's state will be remembered
+    and the user will not be queried the next time the website requests the same permission.
 */
-bool QWebEnginePermission::isTransient(QWebEnginePermission::Feature feature)
+bool QWebEnginePermission::isPersistent(QWebEnginePermission::PermissionType permissionType)
 {
-    switch (feature) {
-    case QWebEnginePermission::MediaAudioCapture:
-    case QWebEnginePermission::MediaVideoCapture:
-    case QWebEnginePermission::MediaAudioVideoCapture:
-    case QWebEnginePermission::DesktopVideoCapture:
-    case QWebEnginePermission::DesktopAudioVideoCapture:
-    case QWebEnginePermission::MouseLock:
+    switch (permissionType) {
+    case QWebEnginePermission::PermissionType::Notifications:
+    case QWebEnginePermission::PermissionType::Geolocation:
+    case QWebEnginePermission::PermissionType::ClipboardReadWrite:
+    case QWebEnginePermission::PermissionType::LocalFontsAccess:
         return true;
-    case QWebEnginePermission::Notifications:
-    case QWebEnginePermission::Geolocation:
-    case QWebEnginePermission::ClipboardReadWrite:
-    case QWebEnginePermission::LocalFontsAccess:
+    case QWebEnginePermission::PermissionType::MediaAudioCapture:
+    case QWebEnginePermission::PermissionType::MediaVideoCapture:
+    case QWebEnginePermission::PermissionType::MediaAudioVideoCapture:
+    case QWebEnginePermission::PermissionType::DesktopVideoCapture:
+    case QWebEnginePermission::PermissionType::DesktopAudioVideoCapture:
+    case QWebEnginePermission::PermissionType::MouseLock:
         return false;
-    case QWebEnginePermission::Unsupported:
+    case QWebEnginePermission::PermissionType::Unsupported:
         return false;
     }
 
diff --git a/src/core/api/qwebenginepermission.h b/src/core/api/qwebenginepermission.h
index 09db8ce363d..440bf788b71 100644
--- a/src/core/api/qwebenginepermission.h
+++ b/src/core/api/qwebenginepermission.h
@@ -9,8 +9,17 @@
 #include <QtCore/qurl.h>
 #include <QtCore/qshareddata.h>
 
+namespace QtWebEngineCore {
+class PermissionManagerQt;
+} // namespace
+
 QT_BEGIN_NAMESPACE
 
+class QWebEnginePagePrivate;
+class QWebEngineProfile;
+class QQuickWebEngineViewPrivate;
+class QQuickWebEngineProfile;
+
 struct QWebEnginePermissionPrivate;
 QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QWebEnginePermissionPrivate,
                                                  Q_WEBENGINECORE_EXPORT)
@@ -19,7 +28,7 @@ class QWebEnginePermission
 {
     Q_GADGET_EXPORT(Q_WEBENGINECORE_EXPORT)
     Q_PROPERTY(QUrl origin READ origin CONSTANT FINAL)
-    Q_PROPERTY(Feature feature READ feature CONSTANT FINAL)
+    Q_PROPERTY(PermissionType permissionType READ permissionType CONSTANT FINAL)
     Q_PROPERTY(State state READ state CONSTANT FINAL)
     Q_PROPERTY(bool isValid READ isValid CONSTANT FINAL)
     Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
@@ -28,14 +37,13 @@ class QWebEnginePermission
     Q_WEBENGINECORE_EXPORT QWebEnginePermission();
 
     Q_WEBENGINECORE_EXPORT QWebEnginePermission(const QWebEnginePermission &other);
-    Q_WEBENGINECORE_EXPORT QWebEnginePermission(QWebEnginePermissionPrivate *pvt);
     Q_WEBENGINECORE_EXPORT ~QWebEnginePermission();
 
     Q_WEBENGINECORE_EXPORT QWebEnginePermission &operator=(const QWebEnginePermission &other);
     QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QWebEnginePermission)
     void swap(QWebEnginePermission &other) noexcept { d_ptr.swap(other.d_ptr); }
 
-    enum Feature : quint8 {
+    enum class PermissionType : quint8 {
         Unsupported,
         MediaAudioCapture,
         MediaVideoCapture,
@@ -48,18 +56,18 @@ class QWebEnginePermission
         ClipboardReadWrite,
         LocalFontsAccess,
     };
-    Q_ENUM(Feature)
+    Q_ENUM(PermissionType)
 
-    enum State : quint8 {
+    enum class State : quint8 {
         Invalid,
         Ask,
         Granted,
-        Denied
+        Denied,
     };
     Q_ENUM(State)
 
-    Q_WEBENGINECORE_EXPORT const QUrl origin() const;
-    Q_WEBENGINECORE_EXPORT Feature feature() const;
+    Q_WEBENGINECORE_EXPORT QUrl origin() const;
+    Q_WEBENGINECORE_EXPORT PermissionType permissionType() const;
     Q_WEBENGINECORE_EXPORT State state() const;
     Q_WEBENGINECORE_EXPORT bool isValid() const;
 
@@ -67,7 +75,7 @@ class QWebEnginePermission
     Q_WEBENGINECORE_EXPORT Q_INVOKABLE void deny() const;
     Q_WEBENGINECORE_EXPORT Q_INVOKABLE void reset() const;
 
-    Q_WEBENGINECORE_EXPORT Q_INVOKABLE static bool isTransient(QWebEnginePermission::Feature feature);
+    Q_WEBENGINECORE_EXPORT Q_INVOKABLE static bool isPersistent(QWebEnginePermission::PermissionType permissionType);
 
 private:
     inline friend bool operator==(const QWebEnginePermission &lhs, const QWebEnginePermission &rhs)
@@ -78,6 +86,14 @@ class QWebEnginePermission
     Q_WEBENGINECORE_EXPORT bool comparesEqual(const QWebEnginePermission &other) const;
 
 protected:
+    friend class QWebEnginePagePrivate;
+    friend class QWebEngineProfile;
+    friend class QQuickWebEngineViewPrivate;
+    friend class QQuickWebEngineProfile;
+    friend class QtWebEngineCore::PermissionManagerQt;
+
+    Q_WEBENGINECORE_EXPORT QWebEnginePermission(QWebEnginePermissionPrivate *pvt);
+
     QExplicitlySharedDataPointer<QWebEnginePermissionPrivate> d_ptr;
 };
 
diff --git a/src/core/api/qwebenginepermission_p.h b/src/core/api/qwebenginepermission_p.h
index 94c89887391..fe4dc62f81a 100644
--- a/src/core/api/qwebenginepermission_p.h
+++ b/src/core/api/qwebenginepermission_p.h
@@ -31,11 +31,11 @@ QT_BEGIN_NAMESPACE
 struct QWebEnginePermissionPrivate : public QSharedData
 {
     Q_WEBENGINECORE_EXPORT QWebEnginePermissionPrivate();
-    Q_WEBENGINECORE_EXPORT QWebEnginePermissionPrivate(const QUrl &, QWebEnginePermission::Feature,
+    Q_WEBENGINECORE_EXPORT QWebEnginePermissionPrivate(const QUrl &, QWebEnginePermission::PermissionType,
         QSharedPointer<QtWebEngineCore::WebContentsAdapter>, QtWebEngineCore::ProfileAdapter *);
 
     QUrl origin;
-    QWebEnginePermission::Feature feature;
+    QWebEnginePermission::PermissionType permissionType;
 
     QWeakPointer<QtWebEngineCore::WebContentsAdapter> webContentsAdapter;
     QPointer<QtWebEngineCore::ProfileAdapter> profileAdapter;
diff --git a/src/core/api/qwebengineprofile.cpp b/src/core/api/qwebengineprofile.cpp
index 5d7bb5559b2..b238d32a5d9 100644
--- a/src/core/api/qwebengineprofile.cpp
+++ b/src/core/api/qwebengineprofile.cpp
@@ -113,18 +113,18 @@ using QtWebEngineCore::ProfileAdapter;
 
     This enum describes the policy for permission persistence:
 
-    \value  NoPersistentPermissions
+    \value  AskEveryTime
             The application will ask for permissions every time they're needed, regardless of
             whether they've been granted before or not. This is intended for backwards compatibility
             with existing applications, and otherwise not recommended.
-    \value  PersistentPermissionsInMemory
+    \value  StoreInMemory
             A request will be made only the first time a permission is needed. Any subsequent
             requests will be automatically granted or denied, depending on the initial user choice.
             This carries over to all pages that use the same QWebEngineProfile instance, until the
             application is shut down. This is the setting applied if \c off-the-record is set
             or no persistent data path is available.
-    \value  PersistentPermissionsOnDisk
-            Works the same way as \c PersistentPermissionsInMemory, but the permissions are saved to
+    \value  StoreOnDisk
+            Works the same way as \c StoreInMemory, but the permissions are saved to
             and restored from disk. This is the default setting.
 */
 
@@ -597,9 +597,9 @@ void QWebEngineProfile::setPersistentCookiesPolicy(QWebEngineProfile::Persistent
     Returns the current policy for persistent permissions.
 
     Off-the-record profiles are not allowed to save data to the disk, so they can only return
-    PersistentPermissionsInMemory or NoPersistentPermissions.
+    \c StoreInMemory or \c AskEveryTime.
 
-    \sa setPersistentPermissionsPolicy()
+    \sa QWebEngineProfile::PersistentPermissionsPolicy, setPersistentPermissionsPolicy()
 */
 QWebEngineProfile::PersistentPermissionsPolicy QWebEngineProfile::persistentPermissionsPolicy() const
 {
@@ -610,7 +610,7 @@ QWebEngineProfile::PersistentPermissionsPolicy QWebEngineProfile::persistentPerm
 /*!
     Sets the policy for persistent permissions to \a newPersistentPermissionsPolicy.
 
-    \sa persistentPermissionsPolicy()
+    \sa QWebEngineProfile::PersistentPermissionsPolicy, persistentPermissionsPolicy()
 */
 void QWebEngineProfile::setPersistentPermissionsPolicy(QWebEngineProfile::PersistentPermissionsPolicy newPersistentPermissionsPolicy)
 {
@@ -979,44 +979,45 @@ void QWebEngineProfile::requestIconForIconURL(const QUrl &url, int desiredSizeIn
 
 /*!
  * Returns a QWebEnginePermission object corresponding to a single permission for the provided \a securityOrigin and
- * \a feature. The object may be used to query for the current state of the permission, or to change it. It is not required
+ * \a permissionType. The object may be used to query for the current state of the permission, or to change it. It is not required
  * for a permission to already exist; the returned object may also be used to pre-grant a permission if a website is
  * known to use it.
  *
- * \note This may only be used for permanent feature types. Calling it with a transient \a feature will return an invalid object.
+ * \note This may only be used for persistent permission types. Calling it with a non-persistent type will return an invalid object.
  * \since 6.8
- * \sa listPermissions(), QWebEnginePermission::Feature
+ * \sa listAllPermissions(), listPermissionsForOrigin(), listPermissionsForPermissionType(), QWebEnginePermission::PermissionType
  */
-QWebEnginePermission QWebEngineProfile::getPermission(const QUrl &securityOrigin, QWebEnginePermission::Feature feature) const
+QWebEnginePermission QWebEngineProfile::queryPermission(const QUrl &securityOrigin, QWebEnginePermission::PermissionType permissionType) const
 {
     Q_D(const QWebEngineProfile);
 
-    if (feature == QWebEnginePermission::Unsupported) {
+    if (permissionType == QWebEnginePermission::PermissionType::Unsupported) {
         qWarning("Attempting to get unsupported permission. Returned object will be in an invalid state.");
         return QWebEnginePermission(new QWebEnginePermissionPrivate());
     }
 
-    if (QWebEnginePermission::isTransient(feature)) {
-        qWarning() << "Attempting to get permission for feature" << feature << ". Returned object will be in an invalid state.";
+    if (!QWebEnginePermission::isPersistent(permissionType)) {
+        qWarning() << "Attempting to get permission for permission type" << permissionType << ". Returned object will be in an invalid state.";
         return QWebEnginePermission(new QWebEnginePermissionPrivate());
     }
 
-    auto *pvt = new QWebEnginePermissionPrivate(securityOrigin, feature, nullptr, d->profileAdapter());
+    auto *pvt = new QWebEnginePermissionPrivate(securityOrigin, permissionType, nullptr, d->profileAdapter());
     return QWebEnginePermission(pvt);
 }
 
 /*!
  * Returns a QList of QWebEnginePermission objects, each one representing a single permission currently
  * present in the permissions store. The returned list contains all previously granted/denied permissions for this profile,
- * except for those of a transient feature type.
+ * provided they are of a \e persistent type.
  *
+ * \note When persistentPermissionPolicy() is set to \c AskEveryTime, this will return an empty list.
  * \since 6.8
- * \sa getPermission(), QWebEnginePermission::Feature
+ * \sa queryPermission(), QWebEnginePermission::PermissionType, QWebEnginePermission::isPersistent()
  */
-QList<QWebEnginePermission> QWebEngineProfile::listPermissions() const
+QList<QWebEnginePermission> QWebEngineProfile::listAllPermissions() const
 {
     Q_D(const QWebEngineProfile);
-    if (persistentPermissionsPolicy() == NoPersistentPermissions)
+    if (persistentPermissionsPolicy() == PersistentPermissionsPolicy::AskEveryTime)
         return QList<QWebEnginePermission>();
     return d->profileAdapter()->listPermissions();
 }
@@ -1024,46 +1025,49 @@ QList<QWebEnginePermission> QWebEngineProfile::listPermissions() const
 /*!
  * Returns a QList of QWebEnginePermission objects, each one representing a single permission currently
  * present in the permissions store. The returned list contains all previously granted/denied permissions associated with a
- * specific \a securityOrigin for this profile, except for those of a transient feature type.
+ * specific \a securityOrigin for this profile, provided they are of a \e persistent type.
  *
  * \note Since permissions are granted on a per-origin basis, the provided \a securityOrigin will be stripped to its
  * origin form, and the returned list will contain all permissions for the origin. Thus, passing https://www.example.com/some/page.html
  * is the same as passing just https://www.example.com/.
+ * \note When persistentPermissionPolicy() is set to \c AskEveryTime, this will return an empty list.
  * \since 6.8
- * \sa getPermission(), QWebEnginePermission::Feature
+ * \sa queryPermission(), QWebEnginePermission::PermissionType, QWebEnginePermission::isPersistent()
  */
-QList<QWebEnginePermission> QWebEngineProfile::listPermissions(const QUrl &securityOrigin) const
+QList<QWebEnginePermission> QWebEngineProfile::listPermissionsForOrigin(const QUrl &securityOrigin) const
 {
     Q_D(const QWebEngineProfile);
-    if (persistentPermissionsPolicy() == NoPersistentPermissions)
+    if (persistentPermissionsPolicy() == PersistentPermissionsPolicy::AskEveryTime)
         return QList<QWebEnginePermission>();
     return d->profileAdapter()->listPermissions(securityOrigin);
 }
 
 /*!
  * Returns a QList of QWebEnginePermission objects, each one representing a single permission currently
- * present in the permissions store. The returned list contains all previously granted/denied permissions of the \a feature
- * type for this profile. If the feature is of a transient or unsupported type, the list will be empty.
+ * present in the permissions store. The returned list contains all previously granted/denied permissions of the provided
+ * \a permissionType. If the \permissionType is non-persistent, the list will be empty.
+ *
+ * \note When persistentPermissionPolicy() is set to \c AskEveryTime, this will return an empty list.
  * \since 6.8
- * \sa getPermission(), QWebEnginePermission::Feature
+ * \sa queryPermission(), QWebEnginePermission::PermissionType, QWebEnginePermission::isPersistent()
  */
-QList<QWebEnginePermission> QWebEngineProfile::listPermissions(QWebEnginePermission::Feature feature) const
+QList<QWebEnginePermission> QWebEngineProfile::listPermissionsForPermissionType(QWebEnginePermission::PermissionType permissionType) const
 {
     Q_D(const QWebEngineProfile);
-    if (persistentPermissionsPolicy() == NoPersistentPermissions)
+    if (persistentPermissionsPolicy() == PersistentPermissionsPolicy::AskEveryTime)
         return QList<QWebEnginePermission>();
 
-    if (feature == QWebEnginePermission::Unsupported) {
+    if (permissionType == QWebEnginePermission::PermissionType::Unsupported) {
         qWarning("Attempting to get permission list for an unsupported type. Returned list will be empty.");
         return QList<QWebEnginePermission>();
     }
 
-    if (QWebEnginePermission::isTransient(feature)) {
-        qWarning() << "Attempting to get permission list for feature" << feature << ". Returned list will be empty.";
+    if (!QWebEnginePermission::isPersistent(permissionType)) {
+        qWarning() << "Attempting to get permission list for permission type" << permissionType << ". Returned list will be empty.";
         return QList<QWebEnginePermission>();
     }
 
-    return d->profileAdapter()->listPermissions(QUrl(), feature);
+    return d->profileAdapter()->listPermissions(QUrl(), permissionType);
 }
 
 /*!
diff --git a/src/core/api/qwebengineprofile.h b/src/core/api/qwebengineprofile.h
index 573f39e7dd3..c83ffbe3343 100644
--- a/src/core/api/qwebengineprofile.h
+++ b/src/core/api/qwebengineprofile.h
@@ -50,10 +50,10 @@ class Q_WEBENGINECORE_EXPORT QWebEngineProfile : public QObject
     };
     Q_ENUM(PersistentCookiesPolicy)
 
-    enum PersistentPermissionsPolicy : quint8 {
-        NoPersistentPermissions,
-        PersistentPermissionsInMemory,
-        PersistentPermissionsOnDisk,
+    enum class PersistentPermissionsPolicy : quint8 {
+        AskEveryTime = 0,
+        StoreInMemory,
+        StoreOnDisk,
     };
     Q_ENUM(PersistentPermissionsPolicy)
 
@@ -121,10 +121,10 @@ class Q_WEBENGINECORE_EXPORT QWebEngineProfile : public QObject
     void requestIconForPageURL(const QUrl &url, int desiredSizeInPixel, std::function<void(const QIcon &, const QUrl &, const QUrl &)> iconAvailableCallback) const;
     void requestIconForIconURL(const QUrl &url, int desiredSizeInPixel, std::function<void(const QIcon &, const QUrl &)> iconAvailableCallback) const;
 
-    QWebEnginePermission getPermission(const QUrl &securityOrigin, QWebEnginePermission::Feature feature) const;
-    QList<QWebEnginePermission> listPermissions() const;
-    QList<QWebEnginePermission> listPermissions(const QUrl &securityOrigin) const;
-    QList<QWebEnginePermission> listPermissions(QWebEnginePermission::Feature feature) const;
+    QWebEnginePermission queryPermission(const QUrl &securityOrigin, QWebEnginePermission::PermissionType permissionType) const;
+    QList<QWebEnginePermission> listAllPermissions() const;
+    QList<QWebEnginePermission> listPermissionsForOrigin(const QUrl &securityOrigin) const;
+    QList<QWebEnginePermission> listPermissionsForPermissionType(QWebEnginePermission::PermissionType permissionType) const;
 
     static QWebEngineProfile *defaultProfile();
 
diff --git a/src/core/doc/src/qtwebengine-features.qdoc b/src/core/doc/src/qtwebengine-features.qdoc
index 9465d75a201..c7221677cd1 100644
--- a/src/core/doc/src/qtwebengine-features.qdoc
+++ b/src/core/doc/src/qtwebengine-features.qdoc
@@ -358,9 +358,9 @@
 
     \QWE supports JavaScript Geolocation API with \l {Qt Positioning} as a
     backend. HTML5 geolocation is disabled by default. To explicitly allow it, the application
-    needs to listen to QWebEnginePage::featurePermissionRequested. Use QWebEnginePage::Geolocation
-    with a QWebEnginePage::setFeaturePermission() call or \l{WebEngineView::Feature}
-    with a \l{WebEngineView::grantFeaturePermission} {WebEngineView.grantFeaturePermission}() call
+    needs to listen to QWebEnginePage::permissionRequested. When a permission request
+    with a type of QWebEnginePermission::PermissionType::Geolocation is received,
+    you can call QWebEnginePermission::grant() on the received object
     to grant the required permission.
 
     If \QWE was built with Qt Positioning support then this feature can be
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index 1f826e7124d..b9a327d51cb 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -28,30 +28,30 @@
 
 namespace QtWebEngineCore {
 
-static QWebEnginePermission::Feature toQt(blink::PermissionType type)
+static QWebEnginePermission::PermissionType toQt(blink::PermissionType type)
 {
     switch (type) {
     case blink::PermissionType::GEOLOCATION:
-        return QWebEnginePermission::Geolocation;
+        return QWebEnginePermission::PermissionType::Geolocation;
     case blink::PermissionType::AUDIO_CAPTURE:
-        return QWebEnginePermission::MediaAudioCapture;
+        return QWebEnginePermission::PermissionType::MediaAudioCapture;
     case blink::PermissionType::VIDEO_CAPTURE:
-        return QWebEnginePermission::MediaVideoCapture;
+        return QWebEnginePermission::PermissionType::MediaVideoCapture;
     case blink::PermissionType::DISPLAY_CAPTURE:
-        return QWebEnginePermission::DesktopAudioVideoCapture;
+        return QWebEnginePermission::PermissionType::DesktopAudioVideoCapture;
         // We treat these both as read/write since we do not currently have a
-        // ClipboardSanitizedWrite feature.
+        // ClipboardSanitizedWrite permission type.
     case blink::PermissionType::CLIPBOARD_READ_WRITE:
     case blink::PermissionType::CLIPBOARD_SANITIZED_WRITE:
-        return QWebEnginePermission::ClipboardReadWrite;
+        return QWebEnginePermission::PermissionType::ClipboardReadWrite;
     case blink::PermissionType::NOTIFICATIONS:
-        return QWebEnginePermission::Notifications;
+        return QWebEnginePermission::PermissionType::Notifications;
     case blink::PermissionType::LOCAL_FONTS:
-        return QWebEnginePermission::LocalFontsAccess;
+        return QWebEnginePermission::PermissionType::LocalFontsAccess;
     case blink::PermissionType::ACCESSIBILITY_EVENTS:
     case blink::PermissionType::CAMERA_PAN_TILT_ZOOM:
     case blink::PermissionType::WINDOW_MANAGEMENT:
-        return QWebEnginePermission::Unsupported;
+        return QWebEnginePermission::PermissionType::Unsupported;
     case blink::PermissionType::MIDI_SYSEX:
     case blink::PermissionType::PROTECTED_MEDIA_IDENTIFIER:
     case blink::PermissionType::MIDI:
@@ -76,31 +76,31 @@ static QWebEnginePermission::Feature toQt(blink::PermissionType type)
         LOG(INFO) << "Unexpected unsupported Blink permission type: " << static_cast<int>(type);
         break;
     }
-    return QWebEnginePermission::Unsupported;
+    return QWebEnginePermission::PermissionType::Unsupported;
 }
 
-static blink::PermissionType toBlink(QWebEnginePermission::Feature feature)
+static blink::PermissionType toBlink(QWebEnginePermission::PermissionType permissionType)
 {
-    switch (feature) {
-    case QWebEnginePermission::Notifications:
+    switch (permissionType) {
+    case QWebEnginePermission::PermissionType::Notifications:
         return blink::PermissionType::NOTIFICATIONS;
-    case QWebEnginePermission::Geolocation:
+    case QWebEnginePermission::PermissionType::Geolocation:
         return blink::PermissionType::GEOLOCATION;
-    case QWebEnginePermission::MediaAudioCapture:
+    case QWebEnginePermission::PermissionType::MediaAudioCapture:
         return blink::PermissionType::AUDIO_CAPTURE;
-    case QWebEnginePermission::MediaVideoCapture:
+    case QWebEnginePermission::PermissionType::MediaVideoCapture:
         return blink::PermissionType::VIDEO_CAPTURE;
-    case QWebEnginePermission::DesktopVideoCapture:
-    case QWebEnginePermission::DesktopAudioVideoCapture:
+    case QWebEnginePermission::PermissionType::DesktopVideoCapture:
+    case QWebEnginePermission::PermissionType::DesktopAudioVideoCapture:
         return blink::PermissionType::DISPLAY_CAPTURE;
-    case QWebEnginePermission::ClipboardReadWrite:
+    case QWebEnginePermission::PermissionType::ClipboardReadWrite:
         return blink::PermissionType::CLIPBOARD_READ_WRITE;
-    case QWebEnginePermission::LocalFontsAccess:
+    case QWebEnginePermission::PermissionType::LocalFontsAccess:
         return blink::PermissionType::LOCAL_FONTS;
-    case QWebEnginePermission::MediaAudioVideoCapture:
-    case QWebEnginePermission::MouseLock:
-    case QWebEnginePermission::Unsupported:
-        LOG(INFO) << "Unexpected unsupported WebEngine permission type: " << static_cast<int>(feature);
+    case QWebEnginePermission::PermissionType::MediaAudioVideoCapture:
+    case QWebEnginePermission::PermissionType::MouseLock:
+    case QWebEnginePermission::PermissionType::Unsupported:
+        LOG(INFO) << "Unexpected unsupported WebEngine permission type: " << static_cast<int>(permissionType);
         return blink::PermissionType::NUM;
     }
 
@@ -111,46 +111,46 @@ static QWebEnginePermission::State toQt(blink::mojom::PermissionStatus state)
 {
     switch (state) {
     case blink::mojom::PermissionStatus::ASK:
-        return QWebEnginePermission::Ask;
+        return QWebEnginePermission::State::Ask;
     case blink::mojom::PermissionStatus::GRANTED:
-        return QWebEnginePermission::Granted;
+        return QWebEnginePermission::State::Granted;
     case blink::mojom::PermissionStatus::DENIED:
-        return QWebEnginePermission::Denied;
+        return QWebEnginePermission::State::Denied;
     }
 }
 
 static blink::mojom::PermissionStatus toBlink(QWebEnginePermission::State state)
 {
     switch (state) {
-    case QWebEnginePermission::Invalid:
-    case QWebEnginePermission::Ask:
+    case QWebEnginePermission::State::Invalid:
+    case QWebEnginePermission::State::Ask:
         return blink::mojom::PermissionStatus::ASK;
-    case QWebEnginePermission::Granted:
+    case QWebEnginePermission::State::Granted:
         return blink::mojom::PermissionStatus::GRANTED;
-    case QWebEnginePermission::Denied:
+    case QWebEnginePermission::State::Denied:
         return blink::mojom::PermissionStatus::DENIED;
     }
 }
 
-std::string featureString(QWebEnginePermission::Feature feature)
+std::string permissionTypeString(QWebEnginePermission::PermissionType permissionType)
 {
-    // This is separate from blink::featureString() for the sake of future-proofing;
+    // This is separate from blink::permissionTypeString() for the sake of future-proofing;
     // e.g. in case we add extra Features that do not correspond to a PermissionType, and
     // we need to store them.
-    switch (feature) {
-    case QWebEnginePermission::Notifications:
+    switch (permissionType) {
+    case QWebEnginePermission::PermissionType::Notifications:
         return "Notifications";
-    case QWebEnginePermission::Geolocation:
+    case QWebEnginePermission::PermissionType::Geolocation:
         return "Geolocation";
-    case QWebEnginePermission::ClipboardReadWrite:
+    case QWebEnginePermission::PermissionType::ClipboardReadWrite:
         return "ClipboardReadWrite";
-    case QWebEnginePermission::LocalFontsAccess:
+    case QWebEnginePermission::PermissionType::LocalFontsAccess:
         return "LocalFontsAccess";
-    case QWebEnginePermission::MediaAudioCapture:
+    case QWebEnginePermission::PermissionType::MediaAudioCapture:
         return "MediaAudioCapture";
-    case QWebEnginePermission::MediaVideoCapture:
+    case QWebEnginePermission::PermissionType::MediaVideoCapture:
         return "MediaVideoCapture";
-    case QWebEnginePermission::DesktopAudioVideoCapture:
+    case QWebEnginePermission::PermissionType::DesktopAudioVideoCapture:
         return "DesktopAudioVideoCapture";
     default:
         Q_UNREACHABLE();
@@ -186,7 +186,7 @@ PermissionManagerQt::PermissionManagerQt(ProfileAdapter *profileAdapter)
     auto prefRegistry = base::MakeRefCounted<PrefRegistrySimple>();
 
     auto policy = profileAdapter->persistentPermissionsPolicy();
-    if (!profileAdapter->isOffTheRecord() && policy == ProfileAdapter::PersistentPermissionsOnDisk &&
+    if (!profileAdapter->isOffTheRecord() && policy == ProfileAdapter::PersistentPermissionsPolicy::StoreOnDisk &&
             !userPrefStorePath.isEmpty() && profileAdapter->ensureDataPathExists()) {
         userPrefStorePath += QDir::separator();
         userPrefStorePath += QStringLiteral("permissions.json");
@@ -195,22 +195,22 @@ PermissionManagerQt::PermissionManagerQt(ProfileAdapter *profileAdapter)
         factory.set_user_prefs(new InMemoryPrefStore);
     }
 
-    m_featureTypes.push_back(QWebEnginePermission::Notifications);
-    m_featureTypes.push_back(QWebEnginePermission::Geolocation);
-    m_featureTypes.push_back(QWebEnginePermission::ClipboardReadWrite);
-    m_featureTypes.push_back(QWebEnginePermission::LocalFontsAccess);
+    m_permissionTypes.push_back(QWebEnginePermission::PermissionType::Notifications);
+    m_permissionTypes.push_back(QWebEnginePermission::PermissionType::Geolocation);
+    m_permissionTypes.push_back(QWebEnginePermission::PermissionType::ClipboardReadWrite);
+    m_permissionTypes.push_back(QWebEnginePermission::PermissionType::LocalFontsAccess);
 
     // Transient, but the implementation relies on them being written to storage
-    m_featureTypes.push_back(QWebEnginePermission::MediaAudioCapture);
-    m_featureTypes.push_back(QWebEnginePermission::MediaVideoCapture);
+    m_permissionTypes.push_back(QWebEnginePermission::PermissionType::MediaAudioCapture);
+    m_permissionTypes.push_back(QWebEnginePermission::PermissionType::MediaVideoCapture);
 
     // Register all preference types as keys prior to doing anything else
-    for (auto &type : m_featureTypes) {
-        prefRegistry->RegisterDictionaryPref(featureString(type));
+    for (auto &type : m_permissionTypes) {
+        prefRegistry->RegisterDictionaryPref(permissionTypeString(type));
     }
     PrefProxyConfigTrackerImpl::RegisterPrefs(prefRegistry.get());
 
-    if (policy == ProfileAdapter::NoPersistentPermissions)
+    if (policy == ProfileAdapter::PersistentPermissionsPolicy::AskEveryTime)
         m_persistence = false;
 
     {
@@ -224,22 +224,22 @@ PermissionManagerQt::~PermissionManagerQt()
     commit();
 }
 
-void PermissionManagerQt::setPermission(const QUrl &url, QWebEnginePermission::Feature feature, QWebEnginePermission::State state)
+void PermissionManagerQt::setPermission(const QUrl &url, QWebEnginePermission::PermissionType permissionType, QWebEnginePermission::State state)
 {
     // Normalize the QUrl to Chromium origin form.
     const GURL gorigin = toGurl(url).DeprecatedGetOriginAsURL();
     const QUrl origin = gorigin.is_empty() ? url : toQt(gorigin);
     if (origin.isEmpty())
         return;
-    if (state == QWebEnginePermission::Ask)
-        ResetPermission(toBlink(feature), gorigin, gorigin);
+    if (state == QWebEnginePermission::State::Ask)
+        ResetPermission(toBlink(permissionType), gorigin, gorigin);
     else
-        setPermission(toBlink(feature), gorigin, state == QWebEnginePermission::Granted);
+        setPermission(toBlink(permissionType), gorigin, state == QWebEnginePermission::State::Granted);
     blink::mojom::PermissionStatus status = toBlink(state);
-    if (state != QWebEnginePermission::Ask) {
+    if (state != QWebEnginePermission::State::Ask) {
         auto it = m_requests.begin();
         while (it != m_requests.end()) {
-            if (it->origin == origin && it->type == feature) {
+            if (it->origin == origin && it->type == permissionType) {
                 std::move(it->callback).Run(status);
                 it = m_requests.erase(it);
             } else
@@ -247,12 +247,12 @@ void PermissionManagerQt::setPermission(const QUrl &url, QWebEnginePermission::F
         }
     }
 
-    for (const auto &it: m_subscribers) {
-        if (it.second.origin == origin && it.second.type == feature)
+    for (const auto &it : m_subscribers) {
+        if (it.second.origin == origin && it.second.type == permissionType)
             it.second.callback.Run(status);
     }
 
-    if (state == QWebEnginePermission::Ask)
+    if (state == QWebEnginePermission::State::Ask)
         return;
 
     auto it = m_multiRequests.begin();
@@ -262,7 +262,7 @@ void PermissionManagerQt::setPermission(const QUrl &url, QWebEnginePermission::F
             std::vector<blink::mojom::PermissionStatus> result;
             result.reserve(it->types.size());
             for (blink::PermissionType permission : it->types) {
-                if (toQt(permission) == QWebEnginePermission::Unsupported) {
+                if (toQt(permission) == QWebEnginePermission::PermissionType::Unsupported) {
                     result.push_back(blink::mojom::PermissionStatus::DENIED);
                     continue;
                 }
@@ -276,7 +276,7 @@ void PermissionManagerQt::setPermission(const QUrl &url, QWebEnginePermission::F
 
                     result.push_back(permissionStatus);
                 } else {
-                    // Reached when the PersistentPermissionsPolicy is set to NoPersistentPermissions
+                    // Reached when the PersistentPermissionsPolicy is set to AskEveryTime
                     result.push_back(toBlink(state));
                 }
             }
@@ -290,14 +290,14 @@ void PermissionManagerQt::setPermission(const QUrl &url, QWebEnginePermission::F
     }
 }
 
-QWebEnginePermission::State PermissionManagerQt::getPermissionState(const QUrl &origin, QWebEnginePermission::Feature feature)
+QWebEnginePermission::State PermissionManagerQt::getPermissionState(const QUrl &origin, QWebEnginePermission::PermissionType permissionType)
 {
-    return toQt(GetPermissionStatus(toBlink(feature), toGurl(origin), GURL()));
+    return toQt(GetPermissionStatus(toBlink(permissionType), toGurl(origin), GURL()));
 }
 
-QList<QWebEnginePermission> PermissionManagerQt::listPermissions(const QUrl &origin, QWebEnginePermission::Feature feature)
+QList<QWebEnginePermission> PermissionManagerQt::listPermissions(const QUrl &origin, QWebEnginePermission::PermissionType permissionType)
 {
-    Q_ASSERT(origin.isEmpty() || feature == QWebEnginePermission::Unsupported);
+    Q_ASSERT(origin.isEmpty() || permissionType == QWebEnginePermission::PermissionType::Unsupported);
     QList<QWebEnginePermission> returnList;
     GURL gorigin = toGurl(origin).DeprecatedGetOriginAsURL();
     std::string originSpec = gorigin.spec();
@@ -305,19 +305,19 @@ QList<QWebEnginePermission> PermissionManagerQt::listPermissions(const QUrl &ori
     if (!origin.isEmpty() && !gorigin.is_valid())
         return returnList;
 
-    std::vector<QWebEnginePermission::Feature> types;
-    if (feature == QWebEnginePermission::Unsupported)
-        types = m_featureTypes;
+    std::vector<QWebEnginePermission::PermissionType> types;
+    if (permissionType == QWebEnginePermission::PermissionType::Unsupported)
+        types = m_permissionTypes;
     else
-        types.push_back(feature);
+        types.push_back(permissionType);
 
     for (auto &type : types) {
         // Transient types may end up in the permission store as an implementation detail,
         // but we do not want to expose them to callers.
-        if (QWebEnginePermission::isTransient(type))
+        if (!QWebEnginePermission::isPersistent(type))
             continue;
 
-        auto *pref = m_prefService->FindPreference(featureString(type));
+        auto *pref = m_prefService->FindPreference(permissionTypeString(type));
         if (!pref)
             continue;
 
@@ -360,8 +360,8 @@ void PermissionManagerQt::RequestPermissions(content::RenderFrameHost *frameHost
     std::vector<content::PermissionStatus> result;
     result.reserve(requestDescription.permissions.size());
     for (blink::PermissionType permission : requestDescription.permissions) {
-        const QWebEnginePermission::Feature feature = toQt(permission);
-        if (feature == QWebEnginePermission::Unsupported) {
+        const QWebEnginePermission::PermissionType permissionType = toQt(permission);
+        if (permissionType == QWebEnginePermission::PermissionType::Unsupported) {
             result.push_back(blink::mojom::PermissionStatus::DENIED);
             continue;
         }
@@ -391,9 +391,9 @@ void PermissionManagerQt::RequestPermissions(content::RenderFrameHost *frameHost
     auto requestOrigin = toQt(requestDescription.requesting_origin);
     m_multiRequests.push_back({ request_id, requestDescription.permissions, requestOrigin, std::move(callback) });
     for (blink::PermissionType permission : requestDescription.permissions) {
-        const QWebEnginePermission::Feature feature = toQt(permission);
-        if (!QWebEnginePermission::isTransient(feature))
-            contentsDelegate->requestFeaturePermission(feature, requestOrigin);
+        const QWebEnginePermission::PermissionType permissionType = toQt(permission);
+        if (QWebEnginePermission::isPersistent(permissionType))
+            contentsDelegate->requestFeaturePermission(permissionType, requestOrigin);
     }
 }
 
@@ -409,12 +409,12 @@ blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatus(
     const GURL& requesting_origin,
     const GURL& /*embedding_origin*/)
 {
-    const QWebEnginePermission::Feature feature = toQt(permission);
-    if (feature == QWebEnginePermission::Unsupported)
+    const QWebEnginePermission::PermissionType permissionType = toQt(permission);
+    if (permissionType == QWebEnginePermission::PermissionType::Unsupported)
         return blink::mojom::PermissionStatus::DENIED;
 
     permission = toBlink(toQt(permission)); // Filter out merged/unsupported permissions (e.g. clipboard)
-    auto *pref = m_prefService->FindPreference(featureString(toQt(permission)));
+    auto *pref = m_prefService->FindPreference(permissionTypeString(toQt(permission)));
     if (!pref)
         return blink::mojom::PermissionStatus::ASK; // Permission type not in database
 
@@ -429,7 +429,7 @@ blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatus(
     // it's checked whether the permission has been granted. By always returning ASK, we force the request to
     // come through every time.
     if (permission == blink::PermissionType::LOCAL_FONTS
-        && m_profileAdapter->persistentPermissionsPolicy() == ProfileAdapter::NoPersistentPermissions)
+        && m_profileAdapter->persistentPermissionsPolicy() == ProfileAdapter::PersistentPermissionsPolicy::AskEveryTime)
         return blink::mojom::PermissionStatus::ASK;
 
     if (requestedPermission.value())
@@ -490,11 +490,11 @@ void PermissionManagerQt::ResetPermission(
     const GURL& requesting_origin,
     const GURL& /*embedding_origin*/)
 {
-    const QWebEnginePermission::Feature feature = toQt(permission);
-    if (feature == QWebEnginePermission::Unsupported)
+    const QWebEnginePermission::PermissionType permissionType = toQt(permission);
+    if (permissionType == QWebEnginePermission::PermissionType::Unsupported)
         return;
 
-    ScopedDictPrefUpdate updater(m_prefService.get(), featureString(feature));
+    ScopedDictPrefUpdate updater(m_prefService.get(), permissionTypeString(permissionType));
     updater.Get().Remove(requesting_origin.spec());
 }
 
@@ -522,14 +522,14 @@ void PermissionManagerQt::setPermission(
     const GURL& requesting_origin,
     bool granted)
 {
-    const QWebEnginePermission::Feature feature = toQt(permission);
-    if (feature == QWebEnginePermission::Unsupported)
+    const QWebEnginePermission::PermissionType permissionType = toQt(permission);
+    if (permissionType == QWebEnginePermission::PermissionType::Unsupported)
         return;
 
-    if (!m_prefService->FindPreference(featureString(feature)))
+    if (!m_prefService->FindPreference(permissionTypeString(permissionType)))
         return;
 
-    ScopedDictPrefUpdate updater(m_prefService.get(), featureString(feature));
+    ScopedDictPrefUpdate updater(m_prefService.get(), permissionTypeString(permissionType));
     updater.Get().Set(requesting_origin.spec(), granted);
 }
 
diff --git a/src/core/permission_manager_qt.h b/src/core/permission_manager_qt.h
index 6a4df2efa80..ea69243b5f1 100644
--- a/src/core/permission_manager_qt.h
+++ b/src/core/permission_manager_qt.h
@@ -22,9 +22,9 @@ class PermissionManagerQt : public content::PermissionControllerDelegate
     PermissionManagerQt(ProfileAdapter *adapter);
     ~PermissionManagerQt();
 
-    void setPermission(const QUrl &origin, QWebEnginePermission::Feature feature, QWebEnginePermission::State state);
-    QWebEnginePermission::State getPermissionState(const QUrl &origin, QWebEnginePermission::Feature feature);
-    QList<QWebEnginePermission> listPermissions(const QUrl &origin, QWebEnginePermission::Feature feature);
+    void setPermission(const QUrl &origin, QWebEnginePermission::PermissionType permissionType, QWebEnginePermission::State state);
+    QWebEnginePermission::State getPermissionState(const QUrl &origin, QWebEnginePermission::PermissionType permissionType);
+    QList<QWebEnginePermission> listPermissions(const QUrl &origin, QWebEnginePermission::PermissionType permissionType);
 
     void commit();
 
@@ -68,7 +68,7 @@ class PermissionManagerQt : public content::PermissionControllerDelegate
 private:
     struct Request {
         int id;
-        QWebEnginePermission::Feature type;
+        QWebEnginePermission::PermissionType type;
         QUrl origin;
         base::OnceCallback<void(blink::mojom::PermissionStatus)> callback;
     };
@@ -79,7 +79,7 @@ class PermissionManagerQt : public content::PermissionControllerDelegate
         base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus>&)> callback;
     };
     struct Subscription {
-        QWebEnginePermission::Feature type;
+        QWebEnginePermission::PermissionType type;
         QUrl origin;
         base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback;
     };
@@ -90,7 +90,7 @@ class PermissionManagerQt : public content::PermissionControllerDelegate
 
     std::vector<Request> m_requests;
     std::vector<MultiRequest> m_multiRequests;
-    std::vector<QWebEnginePermission::Feature> m_featureTypes;
+    std::vector<QWebEnginePermission::PermissionType> m_permissionTypes;
     std::map<content::PermissionControllerDelegate::SubscriptionId, Subscription> m_subscribers;
     content::PermissionControllerDelegate::SubscriptionId::Generator subscription_id_generator_;
     int m_requestIdCount;
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index 1f006295322..031ee6dec87 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -63,7 +63,7 @@ ProfileAdapter::ProfileAdapter(const QString &storageName):
     , m_downloadPath(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation))
     , m_httpCacheType(DiskHttpCache)
     , m_persistentCookiesPolicy(AllowPersistentCookies)
-    , m_persistentPermissionsPolicy(PersistentPermissionsOnDisk)
+    , m_persistentPermissionsPolicy(PersistentPermissionsPolicy::StoreOnDisk)
     , m_visitedLinksPolicy(TrackVisitedLinksOnDisk)
     , m_clientHintsEnabled(true)
     , m_pushServiceEnabled(false)
@@ -265,6 +265,7 @@ void ProfileAdapter::setDataPath(const QString &path)
         return;
     m_dataPath = path;
     m_profile->setupPrefService();
+    m_profile->setupPermissionsManager();
     if (!m_profile->m_profileIOData->isClearHttpCacheInProgress())
         m_profile->m_profileIOData->resetNetworkContext();
     if (!m_offTheRecord && m_visitedLinksManager)
@@ -377,10 +378,10 @@ void ProfileAdapter::setPersistentCookiesPolicy(ProfileAdapter::PersistentCookie
 
 ProfileAdapter::PersistentPermissionsPolicy ProfileAdapter::persistentPermissionsPolicy() const
 {
-    if (m_persistentPermissionsPolicy == NoPersistentPermissions)
-        return NoPersistentPermissions;
+    if (m_persistentPermissionsPolicy == PersistentPermissionsPolicy::AskEveryTime)
+        return PersistentPermissionsPolicy::AskEveryTime;
     if (isOffTheRecord() || m_name.isEmpty())
-        return PersistentPermissionsInMemory;
+        return PersistentPermissionsPolicy::StoreInMemory;
     return m_persistentPermissionsPolicy;
 }
 
@@ -567,25 +568,25 @@ UserResourceControllerHost *ProfileAdapter::userResourceController()
     return m_userResourceController.data();
 }
 
-void ProfileAdapter::setPermission(const QUrl &origin, QWebEnginePermission::Feature feature, QWebEnginePermission::State state)
+void ProfileAdapter::setPermission(const QUrl &origin, QWebEnginePermission::PermissionType permissionType, QWebEnginePermission::State state)
 {
-    static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->setPermission(origin, feature, state);
+    static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->setPermission(origin, permissionType, state);
 }
 
-QWebEnginePermission::State ProfileAdapter::getPermissionState(const QUrl &origin, QWebEnginePermission::Feature feature)
+QWebEnginePermission::State ProfileAdapter::getPermissionState(const QUrl &origin, QWebEnginePermission::PermissionType permissionType)
 {
-    if (persistentPermissionsPolicy() == ProfileAdapter::NoPersistentPermissions)
-        return QWebEnginePermission::Ask;
+    if (persistentPermissionsPolicy() == ProfileAdapter::PersistentPermissionsPolicy::AskEveryTime)
+        return QWebEnginePermission::State::Ask;
 
-    return static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->getPermissionState(origin, feature);
+    return static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->getPermissionState(origin, permissionType);
 }
 
-QList<QWebEnginePermission> ProfileAdapter::listPermissions(const QUrl &origin, QWebEnginePermission::Feature feature)
+QList<QWebEnginePermission> ProfileAdapter::listPermissions(const QUrl &origin, QWebEnginePermission::PermissionType permissionType)
 {
-    if (persistentPermissionsPolicy() == ProfileAdapter::NoPersistentPermissions)
+    if (persistentPermissionsPolicy() == ProfileAdapter::PersistentPermissionsPolicy::AskEveryTime)
         return QList<QWebEnginePermission>();
 
-    return static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->listPermissions(origin, feature);
+    return static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->listPermissions(origin, permissionType);
 }
 
 QString ProfileAdapter::httpAcceptLanguageWithoutQualities() const
diff --git a/src/core/profile_adapter.h b/src/core/profile_adapter.h
index 6550e617696..d0194df99c7 100644
--- a/src/core/profile_adapter.h
+++ b/src/core/profile_adapter.h
@@ -128,10 +128,10 @@ class Q_WEBENGINECORE_EXPORT ProfileAdapter : public QObject
         TrackVisitedLinksOnDisk,
     };
 
-    enum PersistentPermissionsPolicy {
-        NoPersistentPermissions = 0,
-        PersistentPermissionsInMemory,
-        PersistentPermissionsOnDisk,
+    enum class PersistentPermissionsPolicy : quint8 {
+        AskEveryTime = 0,
+        StoreInMemory,
+        StoreOnDisk,
     };
 
     enum ClientHint : uchar {
@@ -172,9 +172,10 @@ class Q_WEBENGINECORE_EXPORT ProfileAdapter : public QObject
     const QList<QByteArray> customUrlSchemes() const;
     UserResourceControllerHost *userResourceController();
 
-    void setPermission(const QUrl &origin, QWebEnginePermission::Feature feature, QWebEnginePermission::State state);
-    QWebEnginePermission::State getPermissionState(const QUrl &origin, QWebEnginePermission::Feature feature);
-    QList<QWebEnginePermission> listPermissions(const QUrl &origin = QUrl(), QWebEnginePermission::Feature feature = QWebEnginePermission::Unsupported);
+    void setPermission(const QUrl &origin, QWebEnginePermission::PermissionType permissionType, QWebEnginePermission::State state);
+    QWebEnginePermission::State getPermissionState(const QUrl &origin, QWebEnginePermission::PermissionType permissionType);
+    QList<QWebEnginePermission> listPermissions(const QUrl &origin = QUrl(),
+        QWebEnginePermission::PermissionType permissionType = QWebEnginePermission::PermissionType::Unsupported);
 
     QString httpAcceptLanguageWithoutQualities() const;
     QString httpAcceptLanguage() const;
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index ed169b161e5..a40f641c11b 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -1411,26 +1411,27 @@ QSizeF WebContentsAdapter::lastContentsSize() const
     return QSizeF();
 }
 
-void WebContentsAdapter::setFeaturePermission(const QUrl &origin, QWebEnginePermission::Feature feature, QWebEnginePermission::State state)
+void WebContentsAdapter::setPermission(const QUrl &origin, QWebEnginePermission::PermissionType permissionType, QWebEnginePermission::State state)
 {
-    if (!QWebEnginePermission::isTransient(feature)) {
+    if (QWebEnginePermission::isPersistent(permissionType)) {
         // Do not check for initialization in this path so permissions can be set before first navigation
         Q_ASSERT(m_profileAdapter);
-        m_profileAdapter->setPermission(origin, feature, state);
+        m_profileAdapter->setPermission(origin, permissionType, state);
         return;
     }
 
     CHECK_INITIALIZED();
-    if (feature == QWebEnginePermission::MouseLock) {
+
+    if (permissionType == QWebEnginePermission::PermissionType::MouseLock) {
         switch (state) {
-        case QWebEnginePermission::Invalid:
-        case QWebEnginePermission::Ask:
+        case QWebEnginePermission::State::Invalid:
+        case QWebEnginePermission::State::Ask:
             // Do nothing
             break;
-        case QWebEnginePermission::Denied:
+        case QWebEnginePermission::State::Denied:
             grantMouseLockPermission(origin, false);
             break;
-        case QWebEnginePermission::Granted:
+        case QWebEnginePermission::State::Granted:
             grantMouseLockPermission(origin, true);
             break;
         }
@@ -1446,33 +1447,33 @@ void WebContentsAdapter::setFeaturePermission(const QUrl &origin, QWebEnginePerm
         WebContentsAdapterClient::MediaDesktopAudioCapture);
 
     switch (state) {
-    case QWebEnginePermission::Invalid:
-    case QWebEnginePermission::Ask:
+    case QWebEnginePermission::State::Invalid:
+    case QWebEnginePermission::State::Ask:
         // Do nothing
         return;
-    case QWebEnginePermission::Denied:
+    case QWebEnginePermission::State::Denied:
         // Deny all media access
         grantMediaAccessPermission(origin, WebContentsAdapterClient::MediaNone);
         return;
-    case QWebEnginePermission::Granted:
+    case QWebEnginePermission::State::Granted:
         // Enable only the requested capture type
         break;
     }
 
-    switch (feature) {
-    case QWebEnginePermission::MediaAudioVideoCapture:
+    switch (permissionType) {
+    case QWebEnginePermission::PermissionType::MediaAudioVideoCapture:
         grantMediaAccessPermission(origin, audioVideoCaptureFlags);
         break;
-    case QWebEnginePermission::MediaAudioCapture:
+    case QWebEnginePermission::PermissionType::MediaAudioCapture:
         grantMediaAccessPermission(origin, WebContentsAdapterClient::MediaAudioCapture);
         break;
-    case QWebEnginePermission::MediaVideoCapture:
+    case QWebEnginePermission::PermissionType::MediaVideoCapture:
         grantMediaAccessPermission(origin, WebContentsAdapterClient::MediaVideoCapture);
         break;
-    case QWebEnginePermission::DesktopAudioVideoCapture:
+    case QWebEnginePermission::PermissionType::DesktopAudioVideoCapture:
         grantMediaAccessPermission(origin, desktopAudioVideoCaptureFlags);
         break;
-    case QWebEnginePermission::DesktopVideoCapture:
+    case QWebEnginePermission::PermissionType::DesktopVideoCapture:
         grantMediaAccessPermission(origin, WebContentsAdapterClient::MediaDesktopVideoCapture);
         break;
     default:
@@ -1481,13 +1482,13 @@ void WebContentsAdapter::setFeaturePermission(const QUrl &origin, QWebEnginePerm
     }
 }
 
-QWebEnginePermission::State WebContentsAdapter::getPermissionState(const QUrl &origin, QWebEnginePermission::Feature feature)
+QWebEnginePermission::State WebContentsAdapter::getPermissionState(const QUrl &origin, QWebEnginePermission::PermissionType permissionType)
 {
-    // For now, we just return Ask for transient Features
-    if (QWebEnginePermission::isTransient(feature))
-        return QWebEnginePermission::Ask;
+    // For now, we just return Ask for transient (a.k.a non-persistent) PermissionTypes
+    if (!QWebEnginePermission::isPersistent(permissionType))
+        return QWebEnginePermission::State::Ask;
 
-    return m_profileAdapter->getPermissionState(origin, feature);
+    return m_profileAdapter->getPermissionState(origin, permissionType);
 }
 
 void WebContentsAdapter::grantMediaAccessPermission(const QUrl &origin, WebContentsAdapterClient::MediaRequestFlags flags)
@@ -1495,9 +1496,9 @@ void WebContentsAdapter::grantMediaAccessPermission(const QUrl &origin, WebConte
     CHECK_INITIALIZED();
     // Let the permission manager remember the reply.
     if (flags & WebContentsAdapterClient::MediaAudioCapture)
-        m_profileAdapter->setPermission(origin, QWebEnginePermission::MediaAudioCapture, QWebEnginePermission::Granted);
+        m_profileAdapter->setPermission(origin, QWebEnginePermission::PermissionType::MediaAudioCapture, QWebEnginePermission::State::Granted);
     if (flags & WebContentsAdapterClient::MediaVideoCapture)
-        m_profileAdapter->setPermission(origin, QWebEnginePermission::MediaVideoCapture, QWebEnginePermission::Granted);
+        m_profileAdapter->setPermission(origin, QWebEnginePermission::PermissionType::MediaVideoCapture, QWebEnginePermission::State::Granted);
     MediaCaptureDevicesDispatcher::GetInstance()->handleMediaAccessPermissionResponse(m_webContents.get(), origin, flags);
 }
 
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 66736dd2151..41a296072ba 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -179,8 +179,8 @@ class Q_WEBENGINECORE_EXPORT WebContentsAdapter : public QEnableSharedFromThis<W
     void devToolsFrontendDestroyed(DevToolsFrontendQt *frontend);
     QString devToolsId();
 
-    void setFeaturePermission(const QUrl &origin, QWebEnginePermission::Feature feature, QWebEnginePermission::State state);
-    QWebEnginePermission::State getPermissionState(const QUrl &origin, QWebEnginePermission::Feature feature);
+    void setPermission(const QUrl &origin, QWebEnginePermission::PermissionType permissionType, QWebEnginePermission::State state);
+    QWebEnginePermission::State getPermissionState(const QUrl &origin, QWebEnginePermission::PermissionType permissionType);
 
     void grantMediaAccessPermission(const QUrl &origin, WebContentsAdapterClient::MediaRequestFlags flags);
     void grantMouseLockPermission(const QUrl &origin, bool granted);
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index ca162833c81..9ce5bebfc70 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -195,7 +195,7 @@ class Q_WEBENGINECORE_EXPORT WebContentsAdapterClient {
     virtual QObject *accessibilityParentObject() = 0;
     virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) = 0;
     virtual void authenticationRequired(QSharedPointer<AuthenticationDialogController>) = 0;
-    virtual void runFeaturePermissionRequest(QWebEnginePermission::Feature, const QUrl &securityOrigin) = 0;
+    virtual void runFeaturePermissionRequest(QWebEnginePermission::PermissionType, const QUrl &securityOrigin) = 0;
     virtual void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) = 0;
     virtual void runMouseLockPermissionRequest(const QUrl &securityOrigin) = 0;
     virtual void runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest) = 0;
@@ -229,7 +229,7 @@ class Q_WEBENGINECORE_EXPORT WebContentsAdapterClient {
     virtual WebContentsAdapter* webContentsAdapter() = 0;
     virtual void releaseProfile() = 0;
     virtual void showWebAuthDialog(QWebEngineWebAuthUxRequest *request) = 0;
-    virtual QWebEnginePermission createFeaturePermissionObject(const QUrl &securityOrigin, QWebEnginePermission::Feature feature) = 0;
+    virtual QWebEnginePermission createFeaturePermissionObject(const QUrl &securityOrigin, QWebEnginePermission::PermissionType permissionType) = 0;
 };
 
 } // namespace QtWebEngineCore
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index c2cd6981ab3..2eada9d3c86 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -741,9 +741,9 @@ void WebContentsDelegateQt::selectClientCert(const QSharedPointer<ClientCertSele
     m_viewClient->selectClientCert(selectController);
 }
 
-void WebContentsDelegateQt::requestFeaturePermission(QWebEnginePermission::Feature feature, const QUrl &requestingOrigin)
+void WebContentsDelegateQt::requestFeaturePermission(QWebEnginePermission::PermissionType permissionType, const QUrl &requestingOrigin)
 {
-    m_viewClient->runFeaturePermissionRequest(feature, requestingOrigin);
+    m_viewClient->runFeaturePermissionRequest(permissionType, requestingOrigin);
 }
 
 extern WebContentsAdapterClient::NavigationType pageTransitionToNavigationType(ui::PageTransition transition);
@@ -800,9 +800,11 @@ bool WebContentsDelegateQt::CheckMediaAccessPermission(content::RenderFrameHost
 {
     switch (type) {
     case blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE:
-        return m_viewClient->profileAdapter()->getPermissionState(toQt(security_origin), QWebEnginePermission::MediaAudioCapture);
+        return m_viewClient->profileAdapter()->getPermissionState(toQt(security_origin), QWebEnginePermission::PermissionType::MediaAudioCapture)
+            == QWebEnginePermission::State::Granted;
     case blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE:
-        return m_viewClient->profileAdapter()->getPermissionState(toQt(security_origin), QWebEnginePermission::MediaVideoCapture);
+        return m_viewClient->profileAdapter()->getPermissionState(toQt(security_origin), QWebEnginePermission::PermissionType::MediaVideoCapture)
+            == QWebEnginePermission::State::Granted;
     default:
         LOG(INFO) << "WebContentsDelegateQt::CheckMediaAccessPermission: "
                   << "Unsupported media stream type checked " << type;
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index 899d46cd0c6..8188b3dea9f 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -139,7 +139,7 @@ class WebContentsDelegateQt : public content::WebContentsDelegate
     void overrideWebPreferences(content::WebContents *, blink::web_pref::WebPreferences*);
     void allowCertificateError(const QSharedPointer<CertificateErrorController> &);
     void selectClientCert(const QSharedPointer<ClientCertSelectController> &);
-    void requestFeaturePermission(QWebEnginePermission::Feature feature, const QUrl &requestingOrigin);
+    void requestFeaturePermission(QWebEnginePermission::PermissionType permissionType, const QUrl &requestingOrigin);
     void launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame, bool has_user_gesture);
     FindTextHelper *findTextHelper();
 
diff --git a/src/webenginequick/api/qquickwebengineprofile.cpp b/src/webenginequick/api/qquickwebengineprofile.cpp
index 0246eb64549..1979d18a0cd 100644
--- a/src/webenginequick/api/qquickwebengineprofile.cpp
+++ b/src/webenginequick/api/qquickwebengineprofile.cpp
@@ -102,17 +102,17 @@ QT_BEGIN_NAMESPACE
 
     This enum describes the policy for permission persistence:
 
-    \value  NoPersistentPermissions
+    \value  AskEveryTime
             The application will ask for permissions every time they're needed, regardless of
             whether they've been granted before or not. This is intended for backwards compatibility
             with existing applications, and otherwise not recommended.
-    \value  PersistentPermissionsInMemory
+    \value  StoreInMemory
             A request will be made only the first time a permission is needed. Any subsequent
             requests will be automatically granted or denied, depending on the initial user choice.
             This carries over to all pages that use the same QQuickWebEngineProfile instance, until the
             application is shut down. This is the setting applied if \c off-the-record is set
             or no persistent data path is available.
-    \value  PersistentPermissionsOnDisk
+    \value  StoreOnDisk
             Works the same way as \c PersistentPermissionsInMemory, but the permissions are saved to
             and restored from disk. This is the default setting.
 */
@@ -714,17 +714,17 @@ void QQuickWebEngineProfile::setPersistentCookiesPolicy(QQuickWebEngineProfile::
 
     This enumeration describes the policy for permission persistence:
 
-    \value  WebEngineProfile.NoPersistentPermissions
+    \value  WebEngineProfile.AskEveryTime
             The application will ask for permissions every time they're needed, regardless of
             whether they've been granted before or not. This is intended for backwards compatibility
             with existing applications, and otherwise not recommended.
-    \value  WebEngineProfile.PersistentPermissionsInMemory
+    \value  WebEngineProfile.StoreInMemory
             A request will be made only the first time a permission is needed. Any subsequent
             requests will be automatically granted or denied, depending on the initial user choice.
             This carries over to all pages using the same QWebEngineProfile instance, until the
             application is shut down. This is the setting applied if \c off-the-record is set
             or no persistent data path is available.
-    \value  WebEngineProfile.PersistentPermissionsOnDisk
+    \value  WebEngineProfile.StoreOnDisk
             Works the same way as \c PersistentPermissionsInMemory, but the permissions are saved to
             and restored from disk. This is the default setting.
 */
@@ -1130,144 +1130,149 @@ QWebEngineClientHints *QQuickWebEngineProfile::clientHints() const
 }
 
 /*!
-    \fn QQuickWebEngineProfile::getPermission(const QUrl &securityOrigin, QWebEnginePermission::Feature feature) const
+    \fn QQuickWebEngineProfile::queryPermission(const QUrl &securityOrigin, QWebEnginePermission::PermissionType permissionType) const
 
     Returns a QWebEnginePermission object corresponding to a single permission for the provided \a securityOrigin and
-    \a feature. The object may be used to query for the current state of the permission, or to change it. It is not required
+    \a permissionType. The object may be used to query for the current state of the permission, or to change it. It is not required
     for a permission to already exist; the returned object may also be used to pre-grant a permission if a website is
     known to use it.
 
-    \note This may only be used for permanent feature types. Calling it with a transient \a feature will return an invalid object.
+    \note This may only be used for persistent permission types. Calling it with a non-persistent \a permissionType will return an invalid object.
     \since 6.8
-    \sa listPermissions(), QWebEnginePermission::Feature
+    \sa listAllPermissions(), listPermissionsForOrigin(), listPermissionsForPermissionType(), QWebEnginePermission::PermissionType
  */
 
 /*!
-    \qmlmethod void WebEngineProfile::getPermission(url securityOrigin, WebEnginePermission.Feature feature) const
+    \qmlmethod void WebEngineProfile::queryPermission(url securityOrigin, WebEnginePermission.PermissionType permissionType) const
 
     Returns a webEnginePermission object corresponding to a single permission for the provided \a securityOrigin and
-    \a feature. The object may be used to query for the current state of the permission, or to change it. It is not required
+    \a permissionType. The object may be used to query for the current state of the permission, or to change it. It is not required
     for a permission to already exist; the returned object may also be used to pre-grant a permission if a website is
     known to use it.
 
-    \note This may only be used for permanent feature types. Calling it with a transient \a feature will return an invalid object.
+    \note This may only be used for persistent permission types. Calling it with a non-persistent \a permissionType will return an invalid object.
     \since 6.8
-    \sa listPermissions()
+    \sa listAllPermissions(), listPermissionsForOrigin(), listPermissionsForPermissionType()
  */
-QWebEnginePermission QQuickWebEngineProfile::getPermission(const QUrl &securityOrigin, QWebEnginePermission::Feature feature) const
+QWebEnginePermission QQuickWebEngineProfile::queryPermission(const QUrl &securityOrigin, QWebEnginePermission::PermissionType permissionType) const
 {
     Q_D(const QQuickWebEngineProfile);
 
-    if (feature == QWebEnginePermission::Unsupported) {
+    if (permissionType == QWebEnginePermission::PermissionType::Unsupported) {
         qWarning("Attempting to get unsupported permission. Returned object will be in an invalid state.");
         return QWebEnginePermission(new QWebEnginePermissionPrivate());
     }
 
-    if (QWebEnginePermission::isTransient(feature)) {
-        qWarning() << "Attempting to get permission for feature" << feature << ". Returned object will be in an invalid state.";
+    if (!QWebEnginePermission::isPersistent(permissionType)) {
+        qWarning() << "Attempting to get permission for permission type" << permissionType << ". Returned object will be in an invalid state.";
         return QWebEnginePermission(new QWebEnginePermissionPrivate());
     }
 
-    auto *pvt = new QWebEnginePermissionPrivate(securityOrigin, feature, nullptr, d->profileAdapter());
+    auto *pvt = new QWebEnginePermissionPrivate(securityOrigin, permissionType, nullptr, d->profileAdapter());
     return QWebEnginePermission(pvt);
 }
 
 /*!
-    \qmlmethod list<webEnginePermission> WebEngineProfile::listPermissions() const
+    \qmlmethod list<webEnginePermission> WebEngineProfile::listAllPermissions() const
 
     Returns a \l list of webEnginePermission objects, each one representing a single permission currently
     present in the permissions store. The returned list contains all previously granted/denied permissions for this profile,
-    except for those of a transient feature type.
+    provided they are of a \e persistent type.
 
+    \note When the persistentPermissionPolicy property is set to \c AskEveryTime, this will return an empty list.
     \since 6.8
-    \sa getPermission()
+    \sa queryPermission(), listPermissionsForOrigin(), listPermissionsForPermissionType(), webEnginePermission::isPersistent()
  */
 
 /*!
     Returns a QList of QWebEnginePermission objects, each one representing a single permission currently
     present in the permissions store. The returned list contains all previously granted/denied permissions for this profile,
-    except for those of a transient feature type.
+    provided they are of a \e persistent type.
 
+    \note When persistentPermissionPolicy() is set to \c AskEveryTime, this will return an empty list.
     \since 6.8
-    \sa getPermission()
+    \sa queryPermission(), listPermissionsForOrigin(), listPermissionsForPermissionType(), QWebEnginePermission::isPersistent()
  */
-QList<QWebEnginePermission> QQuickWebEngineProfile::listPermissions() const
+QList<QWebEnginePermission> QQuickWebEngineProfile::listAllPermissions() const
 {
     Q_D(const QQuickWebEngineProfile);
-    if (persistentPermissionsPolicy() == NoPersistentPermissions)
+    if (persistentPermissionsPolicy() == PersistentPermissionsPolicy::AskEveryTime)
         return QList<QWebEnginePermission>();
     return d->profileAdapter()->listPermissions();
 }
 
 /*!
-    \qmlmethod list<webEnginePermission> WebEngineProfile::listPermissions(url securityOrigin) const
+    \qmlmethod list<webEnginePermission> WebEngineProfile::listPermissionsForOrigin(url securityOrigin) const
 
     Returns a \l list of webEnginePermission objects, each one representing a single permission currently
     present in the permissions store. The returned list contains all previously granted/denied permissions associated with a
-    specific \a securityOrigin for this profile, except for those of a transient feature type.
+    specific \a securityOrigin for this profile, provided they are of a \e persistent type.
 
     \note Since permissions are granted on a per-origin basis, the provided \a securityOrigin will be stripped to its
     origin form, and the returned list will contain all permissions for the origin. Thus, passing https://www.example.com/some/page.html
     is the same as passing just https://www.example.com/.
+    \note When persistentPermissionPolicy() is set to \c AskEveryTime, this will return an empty list.
     \since 6.8
-    \sa getPermission()
+    \sa queryPermission(), listAllPermissions(), listPermissionsForPermissionType(), webEnginePermission::isPersistent()
  */
 
 /*!
     Returns a QList of QWebEnginePermission objects, each one representing a single permission currently
     present in the permissions store. The returned list contains all previously granted/denied permissions associated with a
-    specific \a securityOrigin for this profile, except for those of a transient feature type.
+    specific \a securityOrigin for this profile, provided they are of a \e persistent type.
 
     \note Since permissions are granted on a per-origin basis, the provided \a securityOrigin will be stripped to its
     origin form, and the returned list will contain all permissions for the origin. Thus, passing https://www.example.com/some/page.html
     is the same as passing just https://www.example.com/.
     \since 6.8
-    \sa getPermission()
+    \sa queryPermission(), listAllPermissions(), listPermissionsForPermissionType(), QWebEnginePermission::isPersistent()
  */
-QList<QWebEnginePermission> QQuickWebEngineProfile::listPermissions(const QUrl &securityOrigin) const
+QList<QWebEnginePermission> QQuickWebEngineProfile::listPermissionsForOrigin(const QUrl &securityOrigin) const
 {
     Q_D(const QQuickWebEngineProfile);
-    if (persistentPermissionsPolicy() == NoPersistentPermissions)
+    if (persistentPermissionsPolicy() == PersistentPermissionsPolicy::AskEveryTime)
         return QList<QWebEnginePermission>();
     return d->profileAdapter()->listPermissions(securityOrigin);
 }
 
 /*!
-    \qmlmethod list<webEnginePermission> WebEngineProfile::listPermissions(WebEnginePermission.Feature feature) const
+    \qmlmethod list<webEnginePermission> WebEngineProfile::listPermissionsForPermissionType(WebEnginePermission.PermissionType permissionType) const
 
     Returns a \l list of webEnginePermission objects, each one representing a single permission currently
-    present in the permissions store. The returned list contains all previously granted/denied permissions of the \a feature
-    type for this profile. If the feature is of a transient or unsupported type, the list will be empty.
+    present in the permissions store. The returned list contains all previously granted/denied permissions of the provided
+    \a permissionType. If the \permissionType is non-persistent, the list will be empty.
 
+    \note When persistentPermissionPolicy() is set to \c AskEveryTime, this will return an empty list.
     \since 6.8
-    \sa getPermission()
+    \sa queryPermission(), listAllPermissions(), listPermissionsForOrigin(), webEnginePermission::isPersistent()
  */
 
 /*!
     Returns a QList of QWebEnginePermission objects, each one representing a single permission currently
-    present in the permissions store. The returned list contains all previously granted/denied permissions of the \a feature
-    type for this profile. If the feature is of a transient or unsupported type, the list will be empty.
+    present in the permissions store. The returned list contains all previously granted/denied permissions of the provided
+    \a permissionType. If the \permissionType is non-persistent, the list will be empty.
 
+    \note When persistentPermissionPolicy() is set to \c AskEveryTime, this will return an empty list.
     \since 6.8
-    \sa getPermission(), QWebEnginePermission::Feature
+    \sa queryPermission(), listAllPermissions(), listPermissionsForOrigin(), QWebEnginePermission::PermissionType, QWebEnginePermission::isPersistent()
  */
-QList<QWebEnginePermission> QQuickWebEngineProfile::listPermissions(QWebEnginePermission::Feature feature) const
+QList<QWebEnginePermission> QQuickWebEngineProfile::listPermissionsForPermissionType(QWebEnginePermission::PermissionType permissionType) const
 {
     Q_D(const QQuickWebEngineProfile);
-    if (persistentPermissionsPolicy() == NoPersistentPermissions)
+    if (persistentPermissionsPolicy() == PersistentPermissionsPolicy::AskEveryTime)
         return QList<QWebEnginePermission>();
 
-    if (feature == QWebEnginePermission::Unsupported) {
+    if (permissionType == QWebEnginePermission::PermissionType::Unsupported) {
         qWarning("Attempting to get permission list for an unsupported type. Returned list will be empty.");
         return QList<QWebEnginePermission>();
     }
 
-    if (QWebEnginePermission::isTransient(feature)) {
-        qWarning() << "Attempting to get permission list for feature" << feature << ". Returned list will be empty.";
+    if (!QWebEnginePermission::isPersistent(permissionType)) {
+        qWarning() << "Attempting to get permission list for permission type" << permissionType << ". Returned list will be empty.";
         return QList<QWebEnginePermission>();
     }
 
-    return d->profileAdapter()->listPermissions(QUrl(), feature);
+    return d->profileAdapter()->listPermissions(QUrl(), permissionType);
 }
 
 void QQuickWebEngineProfile::ensureQmlContext(const QObject *object)
diff --git a/src/webenginequick/api/qquickwebengineprofile.h b/src/webenginequick/api/qquickwebengineprofile.h
index f5b7ce8e7e0..27ce9d9fcec 100644
--- a/src/webenginequick/api/qquickwebengineprofile.h
+++ b/src/webenginequick/api/qquickwebengineprofile.h
@@ -64,10 +64,10 @@ class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineProfile : public QObject {
     };
     Q_ENUM(PersistentCookiesPolicy)
 
-    enum PersistentPermissionsPolicy : quint8 {
-        NoPersistentPermissions,
-        PersistentPermissionsInMemory,
-        PersistentPermissionsOnDisk,
+    enum class PersistentPermissionsPolicy : quint8 {
+        AskEveryTime = 0,
+        StoreInMemory,
+        StoreOnDisk,
     };
     Q_ENUM(PersistentPermissionsPolicy)
 
@@ -129,10 +129,10 @@ class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineProfile : public QObject {
     QWebEngineClientCertificateStore *clientCertificateStore();
     QWebEngineClientHints *clientHints() const;
 
-    Q_REVISION(6,8) Q_INVOKABLE QWebEnginePermission getPermission(const QUrl &securityOrigin, QWebEnginePermission::Feature feature) const;
-    Q_REVISION(6,8) Q_INVOKABLE QList<QWebEnginePermission> listPermissions() const;
-    Q_REVISION(6,8) Q_INVOKABLE QList<QWebEnginePermission> listPermissions(const QUrl &securityOrigin) const;
-    Q_REVISION(6,8) Q_INVOKABLE QList<QWebEnginePermission> listPermissions(QWebEnginePermission::Feature feature) const;
+    Q_REVISION(6,8) Q_INVOKABLE QWebEnginePermission queryPermission(const QUrl &securityOrigin, QWebEnginePermission::PermissionType permissionType) const;
+    Q_REVISION(6,8) Q_INVOKABLE QList<QWebEnginePermission> listAllPermissions() const;
+    Q_REVISION(6,8) Q_INVOKABLE QList<QWebEnginePermission> listPermissionsForOrigin(const QUrl &securityOrigin) const;
+    Q_REVISION(6,8) Q_INVOKABLE QList<QWebEnginePermission> listPermissionsForPermissionType(QWebEnginePermission::PermissionType permissionType) const;
 
     static QQuickWebEngineProfile *defaultProfile();
 
diff --git a/src/webenginequick/api/qquickwebenginesettings.cpp b/src/webenginequick/api/qquickwebenginesettings.cpp
index 4a66605d6da..50fb5c3b0f8 100644
--- a/src/webenginequick/api/qquickwebenginesettings.cpp
+++ b/src/webenginequick/api/qquickwebenginesettings.cpp
@@ -79,7 +79,7 @@ bool QQuickWebEngineSettings::javascriptCanOpenWindows() const
 
     Since unrestricted clipboard access is a potential security concern, it is
     recommended that applications leave this disabled and instead respond to
-    \l{WebEnginePermission::ClipboardReadWrite}{ClipboardReadWrite} feature permission requests.
+    \l{webEnginePermission::permissionType}{ClipboardReadWrite} feature permission requests.
 
     Disabled by default.
 */
@@ -389,7 +389,7 @@ bool QQuickWebEngineSettings::webRTCPublicInterfacesOnly() const
 
     Since unrestricted clipboard access is a potential security concern, it is
     recommended that applications leave this disabled and instead respond to
-    \l{WebEnginePermission::ClipboardReadWrite}{ClipboardReadWrite} feature permission requests.
+    \l{webEnginePermission::permissionType}{ClipboardReadWrite} feature permission requests.
 
     Disabled by default.
 */
diff --git a/src/webenginequick/api/qquickwebengineview.cpp b/src/webenginequick/api/qquickwebengineview.cpp
index 852d00c7642..56b5963f61d 100644
--- a/src/webenginequick/api/qquickwebengineview.cpp
+++ b/src/webenginequick/api/qquickwebengineview.cpp
@@ -489,29 +489,29 @@ void QQuickWebEngineViewPrivate::selectClientCert(
 #if QT_DEPRECATED_SINCE(6, 8)
 QT_WARNING_PUSH
 QT_WARNING_DISABLE_DEPRECATED
-static QQuickWebEngineView::Feature toDeprecatedFeature(QWebEnginePermission::Feature feature)
+static QQuickWebEngineView::Feature toDeprecatedFeature(QWebEnginePermission::PermissionType permissionType)
 {
-    switch (feature) {
-    case QWebEnginePermission::Feature::Notifications:
+    switch (permissionType) {
+    case QWebEnginePermission::PermissionType::Notifications:
         return QQuickWebEngineView::Notifications;
-    case QWebEnginePermission::Feature::Geolocation:
+    case QWebEnginePermission::PermissionType::Geolocation:
         return QQuickWebEngineView::Geolocation;
-    case QWebEnginePermission::Feature::ClipboardReadWrite:
+    case QWebEnginePermission::PermissionType::ClipboardReadWrite:
         return QQuickWebEngineView::ClipboardReadWrite;
-    case QWebEnginePermission::Feature::LocalFontsAccess:
+    case QWebEnginePermission::PermissionType::LocalFontsAccess:
         return QQuickWebEngineView::LocalFontsAccess;
-    case QWebEnginePermission::Feature::MediaAudioCapture:
+    case QWebEnginePermission::PermissionType::MediaAudioCapture:
         return QQuickWebEngineView::MediaAudioCapture;
-    case QWebEnginePermission::Feature::MediaVideoCapture:
+    case QWebEnginePermission::PermissionType::MediaVideoCapture:
         return QQuickWebEngineView::MediaVideoCapture;
-    case QWebEnginePermission::Feature::MediaAudioVideoCapture:
+    case QWebEnginePermission::PermissionType::MediaAudioVideoCapture:
         return QQuickWebEngineView::MediaAudioVideoCapture;
-    case QWebEnginePermission::Feature::DesktopVideoCapture:
+    case QWebEnginePermission::PermissionType::DesktopVideoCapture:
         return QQuickWebEngineView::DesktopVideoCapture;
-    case QWebEnginePermission::Feature::DesktopAudioVideoCapture:
+    case QWebEnginePermission::PermissionType::DesktopAudioVideoCapture:
         return QQuickWebEngineView::DesktopAudioVideoCapture;
-    case QWebEnginePermission::Feature::MouseLock:
-    case QWebEnginePermission::Feature::Unsupported:
+    case QWebEnginePermission::PermissionType::MouseLock:
+    case QWebEnginePermission::PermissionType::Unsupported:
         break;
     }
 
@@ -521,32 +521,22 @@ static QQuickWebEngineView::Feature toDeprecatedFeature(QWebEnginePermission::Fe
 QT_WARNING_POP
 #endif // QT_DEPRECATED_SINCE(6, 8)
 
-void QQuickWebEngineViewPrivate::runFeaturePermissionRequest(QWebEnginePermission::Feature feature, const QUrl &url)
+void QQuickWebEngineViewPrivate::runFeaturePermissionRequest(QWebEnginePermission::PermissionType permissionType, const QUrl &securityOrigin)
 {
     Q_Q(QQuickWebEngineView);
-    switch (feature) {
-    case QWebEnginePermission::Notifications:
-    case QWebEnginePermission::Geolocation:
-    case QWebEnginePermission::ClipboardReadWrite:
-    case QWebEnginePermission::LocalFontsAccess:
-        Q_EMIT q->permissionRequested(createFeaturePermissionObject(url, feature));
+
+    if (QWebEnginePermission::isPersistent(permissionType)) {
+        Q_EMIT q->permissionRequested(createFeaturePermissionObject(securityOrigin, permissionType));
 #if QT_DEPRECATED_SINCE(6, 8)
         QT_WARNING_PUSH
         QT_WARNING_DISABLE_DEPRECATED
-        Q_EMIT q->featurePermissionRequested(url, toDeprecatedFeature(feature));
+        Q_EMIT q->featurePermissionRequested(securityOrigin, toDeprecatedFeature(permissionType));
         QT_WARNING_POP
 #endif // QT_DEPRECATED_SINCE(6, 8)
         return;
-    case QWebEnginePermission::MouseLock:
-    case QWebEnginePermission::MediaAudioCapture:
-    case QWebEnginePermission::MediaVideoCapture:
-    case QWebEnginePermission::MediaAudioVideoCapture:
-    case QWebEnginePermission::DesktopAudioVideoCapture:
-    case QWebEnginePermission::DesktopVideoCapture:
-    case QWebEnginePermission::Unsupported:
-        Q_UNREACHABLE();
-        return;
     }
+
+    Q_UNREACHABLE();
 }
 
 void QQuickWebEngineViewPrivate::showColorDialog(QSharedPointer<ColorChooserController> controller)
@@ -824,19 +814,19 @@ void QQuickWebEngineViewPrivate::runMediaAccessPermissionRequest(const QUrl &sec
     Q_Q(QQuickWebEngineView);
     if (!requestFlags)
         return;
-    QWebEnginePermission::Feature feature;
+    QWebEnginePermission::PermissionType permissionType;
     if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture) && requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
-        feature = QWebEnginePermission::MediaAudioVideoCapture;
+        permissionType = QWebEnginePermission::PermissionType::MediaAudioVideoCapture;
     else if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture))
-        feature = QWebEnginePermission::MediaAudioCapture;
+        permissionType = QWebEnginePermission::PermissionType::MediaAudioCapture;
     else if (requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
-        feature = QWebEnginePermission::MediaVideoCapture;
+        permissionType = QWebEnginePermission::PermissionType::MediaVideoCapture;
     else if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopAudioCapture) &&
              requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture))
-        feature = QWebEnginePermission::DesktopAudioVideoCapture;
+        permissionType = QWebEnginePermission::PermissionType::DesktopAudioVideoCapture;
     else // if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture))
-        feature = QWebEnginePermission::DesktopVideoCapture;
-    Q_EMIT q->permissionRequested(createFeaturePermissionObject(securityOrigin, feature));
+        permissionType = QWebEnginePermission::PermissionType::DesktopVideoCapture;
+    Q_EMIT q->permissionRequested(createFeaturePermissionObject(securityOrigin, permissionType));
 
 #if QT_DEPRECATED_SINCE(6, 8)
     QT_WARNING_PUSH
@@ -1528,9 +1518,9 @@ void QQuickWebEngineViewPrivate::showWebAuthDialog(QWebEngineWebAuthUxRequest *r
     Q_EMIT q->webAuthUxRequested(request);
 }
 
-QWebEnginePermission QQuickWebEngineViewPrivate::createFeaturePermissionObject(const QUrl &securityOrigin, QWebEnginePermission::Feature feature)
+QWebEnginePermission QQuickWebEngineViewPrivate::createFeaturePermissionObject(const QUrl &securityOrigin, QWebEnginePermission::PermissionType permissionType)
 {
-    auto *returnPrivate = new QWebEnginePermissionPrivate(securityOrigin, feature, adapter, profileAdapter());
+    auto *returnPrivate = new QWebEnginePermissionPrivate(securityOrigin, permissionType, adapter, profileAdapter());
     return QWebEnginePermission(returnPrivate);
 }
 
@@ -1834,41 +1824,42 @@ QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
 void QQuickWebEngineView::grantFeaturePermission(const QUrl &securityOrigin, QQuickWebEngineView::Feature feature, bool granted)
 {
     Q_D(QQuickWebEngineView);
-    QWebEnginePermission::Feature f;
+    QWebEnginePermission::PermissionType permissionType;
 
     switch (feature) {
     case QQuickWebEngineView::Notifications:
-        f = QWebEnginePermission::Notifications;
+        permissionType = QWebEnginePermission::PermissionType::Notifications;
         break;
     case QQuickWebEngineView::Geolocation:
-        f = QWebEnginePermission::Geolocation;
+        permissionType = QWebEnginePermission::PermissionType::Geolocation;
         break;
     case QQuickWebEngineView::MediaAudioCapture:
-        f = QWebEnginePermission::MediaAudioCapture;
+        permissionType = QWebEnginePermission::PermissionType::MediaAudioCapture;
         break;
     case QQuickWebEngineView::MediaVideoCapture:
-        f = QWebEnginePermission::MediaVideoCapture;
+        permissionType = QWebEnginePermission::PermissionType::MediaVideoCapture;
         break;
     case QQuickWebEngineView::MediaAudioVideoCapture:
-        f = QWebEnginePermission::MediaAudioVideoCapture;
+        permissionType = QWebEnginePermission::PermissionType::MediaAudioVideoCapture;
         break;
     case QQuickWebEngineView::DesktopVideoCapture:
-        f = QWebEnginePermission::DesktopVideoCapture;
+        permissionType = QWebEnginePermission::PermissionType::DesktopVideoCapture;
         break;
     case QQuickWebEngineView::DesktopAudioVideoCapture:
-        f = QWebEnginePermission::DesktopAudioVideoCapture;
+        permissionType = QWebEnginePermission::PermissionType::DesktopAudioVideoCapture;
         break;
     case QQuickWebEngineView::ClipboardReadWrite:
-        f = QWebEnginePermission::ClipboardReadWrite;
+        permissionType = QWebEnginePermission::PermissionType::ClipboardReadWrite;
         break;
     case QQuickWebEngineView::LocalFontsAccess:
-        f = QWebEnginePermission::LocalFontsAccess;
+        permissionType = QWebEnginePermission::PermissionType::LocalFontsAccess;
         break;
     default:
         Q_UNREACHABLE();
     }
 
-    d->adapter->setFeaturePermission(securityOrigin, f, granted ? QWebEnginePermission::Granted : QWebEnginePermission::Denied);
+    d->adapter->setPermission(securityOrigin, permissionType,
+        granted ? QWebEnginePermission::State::Granted : QWebEnginePermission::State::Denied);
 }
 QT_WARNING_POP
 #endif // QT_DEPRECATED_SINCE(6, 8)
diff --git a/src/webenginequick/api/qquickwebengineview_p.h b/src/webenginequick/api/qquickwebengineview_p.h
index ea09dff9faf..d15b8e82cc4 100644
--- a/src/webenginequick/api/qquickwebengineview_p.h
+++ b/src/webenginequick/api/qquickwebengineview_p.h
@@ -168,23 +168,18 @@ QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
 QT_WARNING_POP
 #endif
 #if QT_DEPRECATED_SINCE(6, 8)
-QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
-    enum QT_DEPRECATED_VERSION_X_6_8(
-        "WebEnginePage::Feature has been deprecated. "
-        "The updated permissions API uses WebEnginePermission::Feature.")
-    Feature {
-        MediaAudioCapture,
-        MediaVideoCapture,
-        MediaAudioVideoCapture,
-        Geolocation,
-        DesktopVideoCapture,
-        DesktopAudioVideoCapture,
-        Notifications,
-        ClipboardReadWrite,
-        LocalFontsAccess,
+    enum Feature {
+        MediaAudioCapture Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::MediaAudioCapture instead"),
+        MediaVideoCapture Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::MediaVideoCapture instead"),
+        MediaAudioVideoCapture Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::MediaAudioVideoCapture instead"),
+        Geolocation Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::Geolocation instead"),
+        DesktopVideoCapture Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::DesktopVideoCapture instead"),
+        DesktopAudioVideoCapture Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::DesktopAudioVideoCapture instead"),
+        Notifications Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::Notifications instead"),
+        ClipboardReadWrite Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::ClipboardReadWrite instead"),
+        LocalFontsAccess Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::LocalFontsAccess instead"),
     };
     Q_ENUM(Feature)
-QT_WARNING_POP
 #endif
 
     enum WebAction {
@@ -497,15 +492,8 @@ public Q_SLOTS:
     Q_REVISION(1,1) void findText(const QString &subString, FindFlags options = { }, const QJSValue &callback = QJSValue());
     Q_REVISION(1,1) void fullScreenCancelled();
 #if QT_DEPRECATED_SINCE(6, 8)
-#if !defined(Q_MOC_RUN)
-QT_WARNING_PUSH
-QT_WARNING_DISABLE_DEPRECATED
-#endif // !defined(Q_MOC_RUN)
     QT_DEPRECATED_VERSION_X_6_8("Setting permissions through WebEngineView has been deprecated. Please use WebEnginePermission instead.")
     Q_REVISION(1,1) void grantFeaturePermission(const QUrl &securityOrigin, QQuickWebEngineView::Feature, bool granted);
-#if !defined(Q_MOC_RUN)
-QT_WARNING_POP
-#endif // !defined(Q_MOC_RUN)
 #endif // QT_DEPRECATED_SINCE(6, 8)
     Q_REVISION(1,2) void setActiveFocusOnPress(bool arg);
     Q_REVISION(1,2) void triggerWebAction(WebAction action);
diff --git a/src/webenginequick/api/qquickwebengineview_p_p.h b/src/webenginequick/api/qquickwebengineview_p_p.h
index e61f32bcb09..d781575971b 100644
--- a/src/webenginequick/api/qquickwebengineview_p_p.h
+++ b/src/webenginequick/api/qquickwebengineview_p_p.h
@@ -114,7 +114,7 @@ class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineViewPrivate : public QtWebEngineCor
     void allowCertificateError(const QWebEngineCertificateError &error) override;
     void selectClientCert(const QSharedPointer<QtWebEngineCore::ClientCertSelectController>
                                   &selectController) override;
-    void runFeaturePermissionRequest(QWebEnginePermission::Feature feature, const QUrl &securityOrigin) override;
+    void runFeaturePermissionRequest(QWebEnginePermission::PermissionType permissionType, const QUrl &securityOrigin) override;
     void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode) override;
     void requestGeometryChange(const QRect &geometry, const QRect &frameGeometry) override;
     void updateScrollPosition(const QPointF &position) override;
@@ -139,7 +139,7 @@ class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineViewPrivate : public QtWebEngineCor
                            const QRect &bounds, bool autoselectFirstSuggestion) override;
     void hideAutofillPopup() override;
     void showWebAuthDialog(QWebEngineWebAuthUxRequest *request) override;
-    QWebEnginePermission createFeaturePermissionObject(const QUrl &securityOrigin, QWebEnginePermission::Feature feature) override;
+    QWebEnginePermission createFeaturePermissionObject(const QUrl &securityOrigin, QWebEnginePermission::PermissionType permissionType) override;
 
     void updateAction(QQuickWebEngineView::WebAction) const;
     bool adoptWebContents(QtWebEngineCore::WebContentsAdapter *webContents);
diff --git a/src/webenginequick/doc/src/webengine_permission.qdoc b/src/webenginequick/doc/src/webengine_permission.qdoc
index f59f57fa07f..e36264240dd 100644
--- a/src/webenginequick/doc/src/webengine_permission.qdoc
+++ b/src/webenginequick/doc/src/webengine_permission.qdoc
@@ -15,26 +15,34 @@
         \li When the user has made their decision, the application calls \l grant() or \l deny();
     \endlist
 
-    Alternatively, an application interested in modifying already granted permissions may use WebEngineProfile::listPermissions()
-    to get a list of existing permissions associated with a profile, or WebEngineProfile::getPermission() to get
+    Alternatively, an application interested in modifying already granted permissions may use WebEngineProfile::listAllPermissions()
+    to get a list of existing permissions associated with a profile, or WebEngineProfile::queryPermission() to get
     a webEnginePermission object for a specific permission.
 
     The \l origin property can be used to query which origin the webEnginePermission is associated with, while the
-    \l feature property describes the associated feature. A website origin is the combination of its scheme, hostname,
+    \l permissionType property describes the associated feature. A website origin is the combination of its scheme, hostname,
     and port. Permissions are granted on a per-origin basis; thus, if the web page \c{https://www.example.com:12345/some/page.html}
     requests a permission, it will be granted to the origin \c{https://www.example.com:12345/}.
 
-    The usability lifetime of a webEnginePermission is tied either to its associated WebEngineView
-    (for transient feature types), or WebEngineProfile (for permanent feature types). A transient permission is one which
-    needs to be explicitly granted or denied every time it's needed (e.g. webcam/screen sharing permission), whereas a permanent
-    one might be stored inside the current profile, depending on the value of WebEngineProfile::persistentPermissionsPolicy.
-    You can check whether a webEnginePermission is in a valid state using its \l isValid() property. For invalid objects, calls to \l grant(),
-    \l deny(), or \l reset() will do nothing, and their \l state() will always be WebEnginePermission.Invalid.
+    The \l permissionType enumeration describes all the permission types Qt WebEngine supports. Only some permission types
+    are remembered between browsing sessions; they are \e persistent. Non-persistent permissions query the user every time a
+    website requests them, and cannot be granted in advance. You can check whether a permission type is persistent at runtime
+    using the static method WebEnginePermission::isPersistent().
 
-    The feature types Qt WebEngine supports are described in \l feature.
+    Persistent permissions are stored inside the active WebEngineProfile, and their lifetime depends on the value of
+    WebEngineProfile::persistentPermissionsPolicy. By default, named profiles store their permissions on disk, whereas
+    off-the-record ones store them in memory (and destroy them when the profile is destroyed). A stored permission will not
+    query the user the next time a website requests it; instead it will be automatically granted or denied, depending on
+    the resolution the user picked initially. To erase a stored permission, call \l reset() on it.
 
-    \sa WebEngineView::permissionRequested, WebEngineProfile::getPermission(),
-    WebEngineProfile::listPermissions()
+    A non-persistent permission, on the other hand, is only usable until the related WebEngineView performs a navigation to
+    a different URL, or is destroyed.
+
+    You can check whether a WebEnginePermission is in a valid state using its \l isValid property. For invalid objects, calls to \l grant(),
+    \l deny(), or \l reset() will do nothing, while calls to \l state will always return WebEnginePermission::Invalid.
+
+    \sa WebEngineView::permissionRequested, WebEngineProfile::queryPermission(),
+    WebEngineProfile::listAllPermissions()
 */
 
 /*!
@@ -47,23 +55,24 @@
 */
 
 /*!
-    \qmlproperty enumeration webEnginePermission::feature
-    \brief The feature type associated with this permission.
-
-    \value WebEnginePermission.MediaAudioCapture Access to a microphone, or another audio source. This feature is transient.
-    \value WebEnginePermission.MediaVideoCapture Access to a webcam, or another video source. This feature is transient.
-    \value WebEnginePermission.MediaAudioVideoCapture Combination of \l MediaAudioCapture and \l MediaVideoCapture. This feature is transient.
-    \value WebEnginePermission.DesktopVideoCapture Access to the contents of the user's screen. This feature is transient.
-    \value WebEnginePermission.DesktopAudioVideoCapture Access to the contents of the user's screen, and application audio. This feature is transient.
-    \value WebEnginePermission.MouseLock Locks the pointer inside an element on the web page. This feature is transient.
-    \value WebEnginePermission.Notifications Allows the website to send notifications to the user.
-    \value WebEnginePermission.Geolocation Access to the user's physical location.
-    \value WebEnginePermission.ClipboardReadWrite Access to the user's clipboard.
-    \value WebEnginePermission.LocalFontsAccess Access to the fonts installed on the user's machine. Only available on desktops.
+    \qmlproperty enumeration webEnginePermission::permissionType
+    \brief The permission type associated with this permission.
+
+    \value WebEnginePermission.MediaAudioCapture Access to a microphone, or another audio source. This permission is \e not persistent.
+    \value WebEnginePermission.MediaVideoCapture Access to a webcam, or another video source. This permission is \e not persistent.
+    \value WebEnginePermission.MediaAudioVideoCapture Combination of \e MediaAudioCapture and \e MediaVideoCapture. This permission is \e not persistent.
+    \value WebEnginePermission.DesktopVideoCapture Access to the contents of the user's screen. This permission is \e not persistent.
+    \value WebEnginePermission.DesktopAudioVideoCapture Access to the contents of the user's screen, and application audio. This permission is \e not persistent.
+    \value WebEnginePermission.Notifications Allows the website to send notifications to the user. This permission is persistent.
+    \value WebEnginePermission.Geolocation Access to the user's physical location. This permission is persistent.
+    \value WebEnginePermission.ClipboardReadWrite Access to the user's clipboard. This permission is persistent.
+    \value WebEnginePermission.LocalFontsAccess Access to the fonts installed on the user's machine. Only available on desktops. This permission is persistent.
     \value WebEnginePermission.Unsupported An unsupported feature type.
+    \omitvalue WebEnginePermission.MouseLock
 
-    \note Transient feature types are ones that will never be remembered by the underlying storage, and will trigger
-    a permission request every time a website tries to use them.
+    \note Non-persistent permission types are ones that will never be remembered by the underlying storage, and will trigger
+    a permission request every time a website tries to use them. They can only be denied/granted as they're needed;
+    any attempts to pre-grant a non-persistent permission will fail.
 */
 
 /*!
@@ -71,17 +80,17 @@
     \brief The current state of the permission.
 
     \value WebEnginePermission.Invalid Object is in an invalid state, and any attempts to modify the described permission will fail.
-    \value WebEnginePermission.Ask Either the permission has not been requested before, or the feature() is transient.
+    \value WebEnginePermission.Ask Either the permission has not been requested before, or the \l permissionType is not persistent.
     \value WebEnginePermission.Granted Permission has already been granted.
     \value WebEnginePermission.Denied Permission has already been denied.
 
-    If a permission for the specified \l feature and \l origin has already been granted or denied,
+    If a permission for the specified \l permissionType and \l origin has already been granted or denied,
     the return value is WebEnginePermission.Granted, or WebEnginePermission.Denied, respectively.
-    When this is the first time the permission is requested, or if the \l feature is transient,
+    When this is the first time the permission is requested, or if the \l permissionType is non-persistent,
     the return value is WebEnginePermission.Ask. If the object is in an invalid state, the returned
     value is WebEnginePermission.Invalid.
 
-    \sa isValid, isTransient
+    \sa isValid, isPersistent
 */
 
 /*!
@@ -90,19 +99,19 @@
 
     An invalid webEnginePermission is either:
     \list
-        \li One whose \l feature is unsupported;
-        \li One whose \l feature is transient, and the associated page/view has been destroyed;
-        \li One whose \l feature is permanent, but the associated profile has been destroyed;
+        \li One whose \l permissionType is unsupported;
+        \li One whose \l permissionType is non-persistent, and the user has navigated away from the web page that triggered the request;
+        \li One whose \l permissionType is persistent, but the associated profile has been destroyed;
         \li One whose \l origin is invalid.
     \endlist
 
-    \sa isTransient
+    \sa isPersistent
 */
 
 /*!
     \qmlmethod void webEnginePermission::grant()
 
-    Allows the associated origin to access the requested feature. Does nothing when \l isValid evaluates to false.
+    Allows the associated origin to access the requested per. Does nothing when \l isValid evaluates to false.
 
     \sa deny, reset, isValid
 */
@@ -130,8 +139,8 @@
 */
 
 /*!
-    \qmlmethod void webEnginePermission::isTransient(WebEnginePermission.Feature feature)
+    \qmlmethod void webEnginePermission::isPersistent(WebEnginePermission.PermissionType permissionType)
 
-    Returns whether \a feature is transient, meaning that a permission will be requested
-    every time the associated functionality is used by a web page.
+    Returns whether a \a permissionType is \e persistent, meaning that a permission's state will be remembered
+    and the user will not be queried the next time the website requests the same permission.
 */
diff --git a/src/webenginequick/doc/src/webengineview_lgpl.qdoc b/src/webenginequick/doc/src/webengineview_lgpl.qdoc
index f7b17fa7b62..ac90bb0183c 100644
--- a/src/webenginequick/doc/src/webengineview_lgpl.qdoc
+++ b/src/webenginequick/doc/src/webengineview_lgpl.qdoc
@@ -513,9 +513,9 @@
     \qmlsignal WebEngineView::permissionRequested(webEnginePermission permission)
     \since QtWebEngine 6.8
 
-    This signal is emitted when a web site requests to make use of a feature (e.g. geolocation access,
+    This signal is emitted when a web site fires a permission request (e.g. geolocation access,
     permission to send notifications). The \a permission object can queried for the requesting URL
-    and the \c{WebEnginePermission.Feature} it's asking for, as well as to grant or deny permission.
+    and the \c{WebEnginePermission.PermissionType} it's asking for, as well as to grant or deny permission.
 */
 
 /*!
@@ -854,7 +854,7 @@
 
 /*!
     \qmlproperty enumeration WebEngineView::Feature
-    \deprecated [6.8] Replaced by WebEnginePermission.Feature.
+    \deprecated [6.8] Replaced by WebEnginePermission.PermissionType.
 
     Describes the platform feature access categories that the user may be asked to grant or deny
     access to:
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index f27515c51c3..6abaac31567 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -86,7 +86,7 @@ static const QList<const QMetaObject *> typesToCheck = QList<const QMetaObject *
 
 static QList<QMetaEnum> knownEnumNames = QList<QMetaEnum>()
     << QWebEngineDownloadRequest::staticMetaObject.enumerator(QWebEngineDownloadRequest::staticMetaObject.indexOfEnumerator("SavePageFormat"))
-    << QWebEnginePermission::staticMetaObject.enumerator(QWebEnginePermission::staticMetaObject.indexOfEnumerator("Feature"))
+    << QWebEnginePermission::staticMetaObject.enumerator(QWebEnginePermission::staticMetaObject.indexOfEnumerator("PermissionType"))
     ;
 
 static const QStringList hardcodedTypes = QStringList()
@@ -371,29 +371,29 @@ static const QStringList expectedAPI = QStringList()
     << "QWebEngineNewWindowRequest.InNewDialog --> DestinationType"
     << "QWebEngineNewWindowRequest.InNewTab --> DestinationType"
     << "QWebEngineNewWindowRequest.InNewWindow --> DestinationType"
-    << "QWebEnginePermission.Unsupported --> Feature"
-    << "QWebEnginePermission.MediaAudioCapture --> Feature"
-    << "QWebEnginePermission.MediaVideoCapture --> Feature"
-    << "QWebEnginePermission.MediaAudioVideoCapture --> Feature"
-    << "QWebEnginePermission.DesktopVideoCapture --> Feature"
-    << "QWebEnginePermission.DesktopAudioVideoCapture --> Feature"
-    << "QWebEnginePermission.MouseLock --> Feature"
-    << "QWebEnginePermission.Notifications --> Feature"
-    << "QWebEnginePermission.Geolocation --> Feature"
-    << "QWebEnginePermission.ClipboardReadWrite --> Feature"
-    << "QWebEnginePermission.LocalFontsAccess --> Feature"
-    << "QWebEnginePermission.Invalid --> State"
-    << "QWebEnginePermission.Ask --> State"
-    << "QWebEnginePermission.Granted --> State"
-    << "QWebEnginePermission.Denied --> State"
+    << "QWebEnginePermission.PermissionType.Unsupported --> PermissionType"
+    << "QWebEnginePermission.PermissionType.MediaAudioCapture --> PermissionType"
+    << "QWebEnginePermission.PermissionType.MediaVideoCapture --> PermissionType"
+    << "QWebEnginePermission.PermissionType.MediaAudioVideoCapture --> PermissionType"
+    << "QWebEnginePermission.PermissionType.DesktopVideoCapture --> PermissionType"
+    << "QWebEnginePermission.PermissionType.DesktopAudioVideoCapture --> PermissionType"
+    << "QWebEnginePermission.PermissionType.MouseLock --> PermissionType"
+    << "QWebEnginePermission.PermissionType.Notifications --> PermissionType"
+    << "QWebEnginePermission.PermissionType.Geolocation --> PermissionType"
+    << "QWebEnginePermission.PermissionType.ClipboardReadWrite --> PermissionType"
+    << "QWebEnginePermission.PermissionType.LocalFontsAccess --> PermissionType"
+    << "QWebEnginePermission.State.Invalid --> State"
+    << "QWebEnginePermission.State.Ask --> State"
+    << "QWebEnginePermission.State.Granted --> State"
+    << "QWebEnginePermission.State.Denied --> State"
     << "QWebEnginePermission.origin --> QUrl"
-    << "QWebEnginePermission.feature --> QWebEnginePermission::Feature"
+    << "QWebEnginePermission.permissionType --> QWebEnginePermission::PermissionType"
     << "QWebEnginePermission.state --> QWebEnginePermission::State"
     << "QWebEnginePermission.isValid --> bool"
     << "QWebEnginePermission.grant() --> void"
     << "QWebEnginePermission.deny() --> void"
     << "QWebEnginePermission.reset() --> void"
-    << "QWebEnginePermission.isTransient(QWebEnginePermission::Feature) --> bool"
+    << "QWebEnginePermission.isPersistent(QWebEnginePermission::PermissionType) --> bool"
     << "QQuickWebEngineNewWindowRequest.openIn(QQuickWebEngineView*) --> void"
     << "QQuickWebEngineProfile.AllowPersistentCookies --> PersistentCookiesPolicy"
     << "QQuickWebEngineProfile.DiskHttpCache --> HttpCacheType"
@@ -401,9 +401,9 @@ static const QStringList expectedAPI = QStringList()
     << "QQuickWebEngineProfile.MemoryHttpCache --> HttpCacheType"
     << "QQuickWebEngineProfile.NoCache --> HttpCacheType"
     << "QQuickWebEngineProfile.NoPersistentCookies --> PersistentCookiesPolicy"
-    << "QQuickWebEngineProfile.NoPersistentPermissions --> PersistentPermissionsPolicy"
-    << "QQuickWebEngineProfile.PersistentPermissionsInMemory --> PersistentPermissionsPolicy"
-    << "QQuickWebEngineProfile.PersistentPermissionsOnDisk --> PersistentPermissionsPolicy"
+    << "QQuickWebEngineProfile.PersistentPermissionsPolicy.AskEveryTime --> PersistentPermissionsPolicy"
+    << "QQuickWebEngineProfile.PersistentPermissionsPolicy.StoreInMemory --> PersistentPermissionsPolicy"
+    << "QQuickWebEngineProfile.PersistentPermissionsPolicy.StoreOnDisk --> PersistentPermissionsPolicy"
     << "QQuickWebEngineProfile.cachePath --> QString"
     << "QQuickWebEngineProfile.cachePathChanged() --> void"
     << "QQuickWebEngineProfile.clearHttpCache() --> void"
@@ -413,10 +413,10 @@ static const QStringList expectedAPI = QStringList()
     << "QQuickWebEngineProfile.downloadRequested(QQuickWebEngineDownloadRequest*) --> void"
     << "QQuickWebEngineProfile.downloadPath --> QString"
     << "QQuickWebEngineProfile.downloadPathChanged() --> void"
-    << "QQuickWebEngineProfile.getPermission(QUrl,QWebEnginePermission::Feature) --> QWebEnginePermission"
-    << "QQuickWebEngineProfile.listPermissions() --> QList<QWebEnginePermission>"
-    << "QQuickWebEngineProfile.listPermissions(QUrl) --> QList<QWebEnginePermission>"
-    << "QQuickWebEngineProfile.listPermissions(QWebEnginePermission::Feature) --> QList<QWebEnginePermission>"
+    << "QQuickWebEngineProfile.queryPermission(QUrl,QWebEnginePermission::PermissionType) --> QWebEnginePermission"
+    << "QQuickWebEngineProfile.listAllPermissions() --> QList<QWebEnginePermission>"
+    << "QQuickWebEngineProfile.listPermissionsForOrigin(QUrl) --> QList<QWebEnginePermission>"
+    << "QQuickWebEngineProfile.listPermissionsForPermissionType(QWebEnginePermission::PermissionType) --> QList<QWebEnginePermission>"
     << "QQuickWebEngineProfile.persistentPermissionsPolicy --> QQuickWebEngineProfile::PersistentPermissionsPolicy"
     << "QQuickWebEngineProfile.persistentPermissionsPolicyChanged() --> void"
     << "QQuickWebEngineProfile.presentNotification(QWebEngineNotification*) --> void"
diff --git a/tests/auto/quick/qmltests/data/tst_geopermission.qml b/tests/auto/quick/qmltests/data/tst_geopermission.qml
index 1eb68749738..2957367edb1 100644
--- a/tests/auto/quick/qmltests/data/tst_geopermission.qml
+++ b/tests/auto/quick/qmltests/data/tst_geopermission.qml
@@ -13,7 +13,7 @@ TestWebEngineView {
     property bool deniedGeolocation: false
     property bool geoPermissionRequested: false
 
-    profile.persistentPermissionsPolicy: WebEngineProfile.NoPersistentPermissions
+    profile.persistentPermissionsPolicy: WebEngineProfile.PersistentPermissionsPolicy.AskEveryTime
 
     SignalSpy {
         id: permissionSpy
@@ -22,7 +22,7 @@ TestWebEngineView {
     }
 
     onPermissionRequested: function(perm) {
-        if (perm.feature === WebEnginePermission.Geolocation) {
+        if (perm.permissionType === WebEnginePermission.PermissionType.Geolocation) {
             geoPermissionRequested = true
             if (deniedGeolocation) {
                 perm.deny()
@@ -63,17 +63,17 @@ TestWebEngineView {
         function test_geoPermissionRequest() {
             compare(permissionSpy.count, 0)
             webEngineView.url = Qt.resolvedUrl("geolocation.html")
-            permissionSpy.wait()
+            tryCompare(permissionSpy, "count", 1)
             verify(geoPermissionRequested)
-            compare(permissionSpy.count, 1)
             tryVerify(isHandled, 5000)
             verify(getErrorMessage() === "")
         }
 
         function test_deniedGeolocationByUser() {
+            compare(permissionSpy.count, 0)
             deniedGeolocation = true
             webEngineView.url = Qt.resolvedUrl("geolocation.html")
-            permissionSpy.wait()
+            tryCompare(permissionSpy, "count", 1)
             tryVerify(isHandled, 5000)
             compare(getErrorMessage(), "User denied Geolocation")
         }
diff --git a/tests/auto/quick/qmltests/data/tst_getUserMedia.qml b/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
index fbc863a45f6..371977ac737 100644
--- a/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
+++ b/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
@@ -11,7 +11,7 @@ TestWebEngineView {
     height: 400
 
     settings.screenCaptureEnabled: true
-    profile.persistentPermissionsPolicy: WebEngineProfile.NoPersistentPermissions
+    profile.persistentPermissionsPolicy: WebEngineProfile.PersistentPermissionsPolicy.AskEveryTime
 
     TestCase {
         name: "GetUserMedia"
@@ -22,17 +22,17 @@ TestWebEngineView {
                 {
                     tag: "device audio",
                     constraints: { audio: true },
-                    feature: WebEnginePermission.MediaAudioCapture,
+                    feature: WebEnginePermission.PermissionType.MediaAudioCapture,
                 },
                 {
                     tag: "device video",
                     constraints: { video: true },
-                    feature: WebEnginePermission.MediaVideoCapture,
+                    feature: WebEnginePermission.PermissionType.MediaVideoCapture,
                 },
                 {
                     tag: "device audio+video",
                     constraints: { audio: true, video: true },
-                    feature: WebEnginePermission.MediaAudioVideoCapture,
+                    feature: WebEnginePermission.PermissionType.MediaAudioVideoCapture,
                 },
                 {
                     tag: "desktop video",
@@ -43,7 +43,7 @@ TestWebEngineView {
                             }
                         }
                     },
-                    feature: WebEnginePermission.DesktopVideoCapture,
+                    feature: WebEnginePermission.PermissionType.DesktopVideoCapture,
                 },
                 {
                     tag: "desktop audio+video",
@@ -59,7 +59,7 @@ TestWebEngineView {
                             }
                         }
                     },
-                    feature: WebEnginePermission.DesktopAudioVideoCapture,
+                    feature: WebEnginePermission.PermissionType.DesktopAudioVideoCapture,
                 }
             ]
         }
@@ -123,7 +123,7 @@ TestWebEngineView {
     }
 
     function gotFeatureRequest(expectedFeature) {
-        return permissionObject && permissionObject.feature == expectedFeature
+        return permissionObject && permissionObject.permissionType == expectedFeature
     }
 
     function acceptPendingRequest() {
diff --git a/tests/auto/quick/qmltests/data/tst_notification.qml b/tests/auto/quick/qmltests/data/tst_notification.qml
index 4f064af3d3c..4795ac31d68 100644
--- a/tests/auto/quick/qmltests/data/tst_notification.qml
+++ b/tests/auto/quick/qmltests/data/tst_notification.qml
@@ -15,7 +15,7 @@ TestWebEngineView {
     property bool grantPermission: false
     property var permissionObject
 
-    profile.persistentPermissionsPolicy: WebEngineProfile.NoPersistentPermissions
+    profile.persistentPermissionsPolicy: WebEngineProfile.PersistentPermissionsPolicy.AskEveryTime
 
     signal consoleMessage(string message)
 
@@ -26,7 +26,7 @@ TestWebEngineView {
     }
 
     onPermissionRequested: function(perm) {
-        if (perm.feature === WebEnginePermission.Notifications) {
+        if (perm.permissionType === WebEnginePermission.PermissionType.Notifications) {
             view.permissionRequested = true
             view.permissionObject = perm
             if (grantPermission)
@@ -70,9 +70,8 @@ TestWebEngineView {
             tryCompare(result, 'permission', 'default')
 
             view.runJavaScript('requestPermission()')
-            spyRequest.wait()
+            tryCompare(spyRequest, "count", 1)
             verify(permissionRequested)
-            compare(spyRequest.count, 1)
 
             view.runJavaScript('getPermission()', function (permission) { result.permission = permission })
             tryCompare(result, 'permission', data.permission)
@@ -85,7 +84,7 @@ TestWebEngineView {
             view.waitForLoadSucceeded()
 
             view.runJavaScript('requestPermission()')
-            spyRequest.wait()
+            tryCompare(spyRequest, "count", 1)
             verify(permissionRequested)
 
             let title = 'Title', message = 'Message', notification = null
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 5af1e9ff9ff..dfb4fe5bf94 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -486,7 +486,7 @@ void tst_QWebEnginePage::geolocationRequestJS()
     QWebEngineView view;
     JSTestPage *newPage = new JSTestPage(&view);
     view.setPage(newPage);
-    newPage->profile()->setPersistentPermissionsPolicy(QWebEngineProfile::NoPersistentPermissions);
+    newPage->profile()->setPersistentPermissionsPolicy(QWebEngineProfile::PersistentPermissionsPolicy::AskEveryTime);
     newPage->setGeolocationPermission(allowed);
 
     connect(newPage, SIGNAL(permissionRequested(QWebEnginePermission)),
@@ -1663,7 +1663,7 @@ Q_OBJECT
         connect(this, &QWebEnginePage::loadFinished, [this](bool success){
             m_loadSucceeded = success;
         });
-        profile()->setPersistentPermissionsPolicy(QWebEngineProfile::NoPersistentPermissions);
+        profile()->setPersistentPermissionsPolicy(QWebEngineProfile::PersistentPermissionsPolicy::AskEveryTime);
         // We need to load content from a resource in order for the securityOrigin to be valid.
         load(QUrl("qrc:///resources/content.html"));
     }
@@ -1708,9 +1708,9 @@ Q_OBJECT
         m_gotRequest = false;
     }
 
-    bool gotFeatureRequest(QWebEnginePermission::Feature feature)
+    bool gotFeatureRequest(QWebEnginePermission::PermissionType permissionType)
     {
-        return m_gotRequest && m_permission && m_permission->feature() == feature;
+        return m_gotRequest && m_permission && m_permission->permissionType() == permissionType;
     }
 
     bool gotFeatureRequest() const
@@ -1739,32 +1739,33 @@ private Q_SLOTS:
 void tst_QWebEnginePage::getUserMediaRequest_data()
 {
     QTest::addColumn<QString>("call");
-    QTest::addColumn<QWebEnginePermission::Feature>("feature");
+    QTest::addColumn<QWebEnginePermission::PermissionType>("permissionType");
 
     QTest::addRow("device audio")
-        << "getUserMedia({audio: true})" << QWebEnginePermission::MediaAudioCapture;
+        << "getUserMedia({audio: true})" << QWebEnginePermission::PermissionType::MediaAudioCapture;
     QTest::addRow("device video")
-        << "getUserMedia({video: true})" << QWebEnginePermission::MediaVideoCapture;
+        << "getUserMedia({video: true})" << QWebEnginePermission::PermissionType::MediaVideoCapture;
     QTest::addRow("device audio+video")
-        << "getUserMedia({audio: true, video: true})" << QWebEnginePermission::MediaAudioVideoCapture;
+        << "getUserMedia({audio: true, video: true})" << QWebEnginePermission::PermissionType::MediaAudioVideoCapture;
     QTest::addRow("desktop video")
         << "getUserMedia({video: { mandatory: { chromeMediaSource: 'desktop' }}})"
-        << QWebEnginePermission::DesktopVideoCapture;
+        << QWebEnginePermission::PermissionType::DesktopVideoCapture;
     QTest::addRow("desktop audio+video")
         << "getUserMedia({audio: { mandatory: { chromeMediaSource: 'desktop' }}, video: { mandatory: { chromeMediaSource: 'desktop' }}})"
-        << QWebEnginePermission::DesktopAudioVideoCapture;
+        << QWebEnginePermission::PermissionType::DesktopAudioVideoCapture;
     QTest::addRow("display video")
-        << "getDisplayMedia()" << QWebEnginePermission::DesktopVideoCapture;
+        << "getDisplayMedia()" << QWebEnginePermission::PermissionType::DesktopVideoCapture;
 }
 
 void tst_QWebEnginePage::getUserMediaRequest()
 {
     QFETCH(QString, call);
-    QFETCH(QWebEnginePermission::Feature, feature);
+    QFETCH(QWebEnginePermission::PermissionType, permissionType);
 
     GetUserMediaTestPage page;
     QWebEngineView view;
-    if (feature == QWebEnginePermission::DesktopVideoCapture || feature == QWebEnginePermission::DesktopAudioVideoCapture) {
+    if (permissionType == QWebEnginePermission::PermissionType::DesktopVideoCapture
+            || permissionType == QWebEnginePermission::PermissionType::DesktopAudioVideoCapture) {
         // Desktop capture needs to be on a desktop.
         view.setPage(&page);
         view.resize(640, 480);
@@ -1777,7 +1778,7 @@ void tst_QWebEnginePage::getUserMediaRequest()
 
     // 1. Rejecting request on C++ side should reject promise on JS side.
     page.jsGetMedia(call);
-    QTRY_VERIFY(page.gotFeatureRequest(feature));
+    QTRY_VERIFY(page.gotFeatureRequest(permissionType));
     page.rejectPendingRequest();
     QTRY_VERIFY(!page.jsPromiseFulfilled() && page.jsPromiseRejected());
 
@@ -1787,13 +1788,13 @@ void tst_QWebEnginePage::getUserMediaRequest()
     // always be fulfilled, however in this case an error should be returned to
     // JS instead of leaving the Promise in limbo.
     page.jsGetMedia(call);
-    QTRY_VERIFY(page.gotFeatureRequest(feature));
+    QTRY_VERIFY(page.gotFeatureRequest(permissionType));
     page.acceptPendingRequest();
     QTRY_VERIFY(page.jsPromiseFulfilled() || page.jsPromiseRejected());
 
-    // 3. Media feature permissions are not remembered.
+    // 3. Media permissions are not remembered.
     page.jsGetMedia(call);
-    QTRY_VERIFY(page.gotFeatureRequest(feature));
+    QTRY_VERIFY(page.gotFeatureRequest(permissionType));
     page.acceptPendingRequest();
     QTRY_VERIFY(page.jsPromiseFulfilled() || page.jsPromiseRejected());
 }
@@ -1834,7 +1835,7 @@ void tst_QWebEnginePage::getUserMediaRequestSettingDisabled()
 void tst_QWebEnginePage::getUserMediaRequestDesktopVideoManyPages()
 {
     const QString constraints = QStringLiteral("{video: { mandatory: { chromeMediaSource: 'desktop' }}}");
-    const QWebEnginePermission::Feature feature = QWebEnginePermission::DesktopVideoCapture;
+    const QWebEnginePermission::PermissionType permissionType = QWebEnginePermission::PermissionType::DesktopVideoCapture;
     std::vector<GetUserMediaTestPage> pages(10);
 
     // Desktop capture needs to be on a desktop
@@ -1855,7 +1856,7 @@ void tst_QWebEnginePage::getUserMediaRequestDesktopVideoManyPages()
     for (GetUserMediaTestPage &page : pages)
         page.jsGetUserMedia(constraints);
     for (GetUserMediaTestPage &page : pages)
-        QTRY_VERIFY(page.gotFeatureRequest(feature));
+        QTRY_VERIFY(page.gotFeatureRequest(permissionType));
     for (GetUserMediaTestPage &page : pages)
         page.acceptPendingRequest();
     for (GetUserMediaTestPage &page : pages)
@@ -1867,7 +1868,7 @@ void tst_QWebEnginePage::getUserMediaRequestDesktopVideoManyPages()
 void tst_QWebEnginePage::getUserMediaRequestDesktopVideoManyRequests()
 {
     const QString constraints = QStringLiteral("{video: { mandatory: { chromeMediaSource: 'desktop' }}}");
-    const QWebEnginePermission::Feature feature = QWebEnginePermission::DesktopVideoCapture;
+    const QWebEnginePermission::PermissionType permissionType = QWebEnginePermission::PermissionType::DesktopVideoCapture;
     GetUserMediaTestPage page;
 
     // Desktop capture needs to be on a desktop
@@ -1881,7 +1882,7 @@ void tst_QWebEnginePage::getUserMediaRequestDesktopVideoManyRequests()
     page.settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true);
     for (int i = 0; i != 100; ++i) {
         page.jsGetUserMedia(constraints);
-        QTRY_VERIFY(page.gotFeatureRequest(feature));
+        QTRY_VERIFY(page.gotFeatureRequest(permissionType));
         page.acceptPendingRequest();
         QTRY_VERIFY(page.jsPromiseFulfilled() || page.jsPromiseRejected());
     }
@@ -3804,21 +3805,21 @@ struct NotificationPage : ConsolePage {
 
         connect(this, &QWebEnginePage::permissionRequested,
                 [this] (QWebEnginePermission permission) {
-            if (permission.feature() != QWebEnginePermission::Notifications)
+            if (permission.permissionType() != QWebEnginePermission::PermissionType::Notifications)
                 return;
             if (spyRequest.wasCalled())
                 QFAIL("request executed twise!");
             switch (policy) {
-            case QWebEnginePermission::Granted:
+            case QWebEnginePermission::State::Granted:
                 permission.grant();
                 break;
-            case QWebEnginePermission::Denied:
+            case QWebEnginePermission::State::Denied:
                 permission.deny();
                 break;
-            case QWebEnginePermission::Ask:
+            case QWebEnginePermission::State::Ask:
                 permission.reset();
                 break;
-            default:
+            case QWebEnginePermission::State::Invalid:
                 break;
             }
             spyRequest.ref()(permission.origin());
@@ -3843,10 +3844,10 @@ void tst_QWebEnginePage::notificationPermission_data()
     QTest::addColumn<bool>("setOnInit");
     QTest::addColumn<QWebEnginePermission::State>("policy");
     QTest::addColumn<QString>("permission");
-    QTest::newRow("denyOnInit")  << true  << QWebEnginePermission::Denied << "denied";
-    QTest::newRow("deny")        << false << QWebEnginePermission::Denied << "denied";
-    QTest::newRow("grant")       << false << QWebEnginePermission::Granted << "granted";
-    QTest::newRow("grantOnInit") << true  << QWebEnginePermission::Granted << "granted";
+    QTest::newRow("denyOnInit")  << true  << QWebEnginePermission::State::Denied << "denied";
+    QTest::newRow("deny")        << false << QWebEnginePermission::State::Denied << "denied";
+    QTest::newRow("grant")       << false << QWebEnginePermission::State::Granted << "granted";
+    QTest::newRow("grantOnInit") << true  << QWebEnginePermission::State::Granted << "granted";
 }
 
 void tst_QWebEnginePage::notificationPermission()
@@ -3856,14 +3857,14 @@ void tst_QWebEnginePage::notificationPermission()
     QFETCH(QString, permission);
 
     QWebEngineProfile otr;
-    otr.setPersistentPermissionsPolicy(QWebEngineProfile::NoPersistentPermissions);
+    otr.setPersistentPermissionsPolicy(QWebEngineProfile::PersistentPermissionsPolicy::AskEveryTime);
     QWebEnginePage page(&otr, nullptr);
 
     QUrl baseUrl("https://www.example.com/somepage.html");
 
     bool permissionRequested = false, errorState = false;
     connect(&page, &QWebEnginePage::permissionRequested, &page, [&] (QWebEnginePermission permission) {
-        if (permission.feature() != QWebEnginePermission::Notifications)
+        if (permission.permissionType() != QWebEnginePermission::PermissionType::Notifications)
             return;
         if (permissionRequested || permission.origin() != baseUrl.url(QUrl::RemoveFilename)) {
             qWarning() << "Unexpected case. Can't proceed." << setOnInit << permissionRequested << permission.origin();
@@ -3872,15 +3873,15 @@ void tst_QWebEnginePage::notificationPermission()
         }
         permissionRequested = true;
 
-        if (policy == QWebEnginePermission::Granted)
+        if (policy == QWebEnginePermission::State::Granted)
             permission.grant();
         else
             permission.deny();
     });
 
-    QWebEnginePermission permissionObject = otr.getPermission(baseUrl, QWebEnginePermission::Notifications);
+    QWebEnginePermission permissionObject = otr.queryPermission(baseUrl, QWebEnginePermission::PermissionType::Notifications);
     if (setOnInit) {
-        if (policy == QWebEnginePermission::Granted)
+        if (policy == QWebEnginePermission::State::Granted)
             permissionObject.grant();
         else
             permissionObject.deny();
@@ -3893,7 +3894,7 @@ void tst_QWebEnginePage::notificationPermission()
     QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("Notification.permission")), setOnInit ? permission : QLatin1String("default"));
 
     if (!setOnInit) {
-        if (policy == QWebEnginePermission::Granted)
+        if (policy == QWebEnginePermission::State::Granted)
             permissionObject.grant();
         else
             permissionObject.deny();
@@ -3910,7 +3911,7 @@ void tst_QWebEnginePage::notificationPermission()
 
 void tst_QWebEnginePage::sendNotification()
 {
-    NotificationPage page(QWebEnginePermission::Granted);
+    NotificationPage page(QWebEnginePermission::State::Granted);
     QVERIFY(page.spyLoad.waitForResult());
 
     page.resetPermission();
@@ -3976,7 +3977,7 @@ void tst_QWebEnginePage::clipboardReadWritePermissionInitialState()
     QFETCH(QString, permission);
 
     QWebEngineProfile otr;
-    otr.setPersistentPermissionsPolicy(QWebEngineProfile::NoPersistentPermissions);
+    otr.setPersistentPermissionsPolicy(QWebEngineProfile::PersistentPermissionsPolicy::AskEveryTime);
     QWebEngineView view(&otr);
     QWebEnginePage &page = *view.page();
     view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
@@ -4004,28 +4005,28 @@ void tst_QWebEnginePage::clipboardReadWritePermission_data()
     QTest::addColumn<QString>("finalPermission");
 
     QTest::newRow("noAccessGrantGrant")
-            << false << QWebEnginePermission::Granted << "granted"
-            << QWebEnginePermission::Granted << "granted";
+            << false << QWebEnginePermission::State::Granted << "granted"
+            << QWebEnginePermission::State::Granted << "granted";
     QTest::newRow("noAccessGrantDeny")
-            << false << QWebEnginePermission::Granted << "granted"
-            << QWebEnginePermission::Denied << "denied";
+            << false << QWebEnginePermission::State::Granted << "granted"
+            << QWebEnginePermission::State::Denied << "denied";
     QTest::newRow("noAccessDenyGrant")
-            << false << QWebEnginePermission::Denied << "denied"
-            << QWebEnginePermission::Granted << "granted";
-    QTest::newRow("noAccessDenyDeny") << false << QWebEnginePermission::Denied << "denied"
-                                      << QWebEnginePermission::Denied << "denied";
-    QTest::newRow("noAccessAskGrant") << false << QWebEnginePermission::Ask << "prompt"
-                                      << QWebEnginePermission::Granted << "granted";
+            << false << QWebEnginePermission::State::Denied << "denied"
+            << QWebEnginePermission::State::Granted << "granted";
+    QTest::newRow("noAccessDenyDeny") << false << QWebEnginePermission::State::Denied << "denied"
+                                      << QWebEnginePermission::State::Denied << "denied";
+    QTest::newRow("noAccessAskGrant") << false << QWebEnginePermission::State::Ask << "prompt"
+                                      << QWebEnginePermission::State::Granted << "granted";
 
     // All policies are ignored and overridden by setting JsCanAccessClipboard and JsCanPaste to
     // true
     QTest::newRow("accessGrantGrant")
-            << true << QWebEnginePermission::Granted << "granted"
-            << QWebEnginePermission::Granted << "granted";
-    QTest::newRow("accessDenyDeny") << true << QWebEnginePermission::Denied << "granted"
-                                    << QWebEnginePermission::Denied << "granted";
-    QTest::newRow("accessAskAsk") << true << QWebEnginePermission::Ask << "granted"
-                                  << QWebEnginePermission::Ask << "granted";
+            << true << QWebEnginePermission::State::Granted << "granted"
+            << QWebEnginePermission::State::Granted << "granted";
+    QTest::newRow("accessDenyDeny") << true << QWebEnginePermission::State::Denied << "granted"
+                                    << QWebEnginePermission::State::Denied << "granted";
+    QTest::newRow("accessAskAsk") << true << QWebEnginePermission::State::Ask << "granted"
+                                  << QWebEnginePermission::State::Ask << "granted";
 }
 
 void tst_QWebEnginePage::clipboardReadWritePermission()
@@ -4037,7 +4038,7 @@ void tst_QWebEnginePage::clipboardReadWritePermission()
     QFETCH(QString, finalPermission);
 
     QWebEngineProfile otr;
-    otr.setPersistentPermissionsPolicy(QWebEngineProfile::NoPersistentPermissions);
+    otr.setPersistentPermissionsPolicy(QWebEngineProfile::PersistentPermissionsPolicy::AskEveryTime);
     QWebEngineView view(&otr);
     QWebEnginePage &page = *view.page();
     view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
@@ -4053,7 +4054,7 @@ void tst_QWebEnginePage::clipboardReadWritePermission()
     // if JavascriptCanAccessClipboard is true, this never fires
     connect(&page, &QWebEnginePage::permissionRequested, &page,
             [&](QWebEnginePermission permission) {
-                if (permission.feature() != QWebEnginePermission::ClipboardReadWrite)
+                if (permission.permissionType() != QWebEnginePermission::PermissionType::ClipboardReadWrite)
                     return;
                 if (permission.origin() != baseUrl.url(QUrl::RemoveFilename)) {
                     qWarning() << "Unexpected case. Can't proceed." << permission.origin();
@@ -4062,13 +4063,13 @@ void tst_QWebEnginePage::clipboardReadWritePermission()
                 }
                 permissionRequestCount++;
                 switch (requestPolicy) {
-                case QWebEnginePermission::Granted:
+                case QWebEnginePermission::State::Granted:
                     permission.grant();
                     break;
-                case QWebEnginePermission::Denied:
+                case QWebEnginePermission::State::Denied:
                     permission.deny();
                     break;
-                case QWebEnginePermission::Ask:
+                case QWebEnginePermission::State::Ask:
                     permission.reset();
                     break;
                 default:
@@ -4076,18 +4077,18 @@ void tst_QWebEnginePage::clipboardReadWritePermission()
                 }
             });
 
-    QWebEnginePermission permissionObject = otr.getPermission(baseUrl, QWebEnginePermission::ClipboardReadWrite);
+    QWebEnginePermission permissionObject = otr.queryPermission(baseUrl, QWebEnginePermission::PermissionType::ClipboardReadWrite);
     switch (initialPolicy) {
-    case QWebEnginePermission::Granted:
+    case QWebEnginePermission::State::Granted:
         permissionObject.grant();
         break;
-    case QWebEnginePermission::Denied:
+    case QWebEnginePermission::State::Denied:
         permissionObject.deny();
         break;
-    case QWebEnginePermission::Ask:
+    case QWebEnginePermission::State::Ask:
         permissionObject.reset();
         break;
-    default:
+    case QWebEnginePermission::State::Invalid:
         break;
     }
 
@@ -4153,9 +4154,9 @@ void tst_QWebEnginePage::localFontAccessPermission_data()
     QTest::addColumn<bool>("ignore");
     QTest::addColumn<bool>("shouldBeEmpty");
 
-    QTest::newRow("ignore")   << QWebEnginePermission::Denied  << true  << true;
-    QTest::newRow("setDeny")  << QWebEnginePermission::Denied  << false << true;
-    QTest::newRow("setGrant") << QWebEnginePermission::Granted << false << false;
+    QTest::newRow("ignore")   << QWebEnginePermission::State::Denied  << true  << true;
+    QTest::newRow("setDeny")  << QWebEnginePermission::State::Denied  << false << true;
+    QTest::newRow("setGrant") << QWebEnginePermission::State::Granted << false << false;
 }
 
 void tst_QWebEnginePage::localFontAccessPermission() {
@@ -4165,15 +4166,15 @@ void tst_QWebEnginePage::localFontAccessPermission() {
 
     QWebEngineView view;
     QWebEnginePage page(&view);
-    page.profile()->setPersistentPermissionsPolicy(QWebEngineProfile::NoPersistentPermissions);
+    page.profile()->setPersistentPermissionsPolicy(QWebEngineProfile::PersistentPermissionsPolicy::AskEveryTime);
     view.setPage(&page);
 
     connect(&page, &QWebEnginePage::permissionRequested, &page, [&] (QWebEnginePermission permission) {
-        if (permission.feature() != QWebEnginePermission::LocalFontsAccess)
+        if (permission.permissionType() != QWebEnginePermission::PermissionType::LocalFontsAccess)
             return;
 
         if (!ignore) {
-            if (policy == QWebEnginePermission::Granted)
+            if (policy == QWebEnginePermission::State::Granted)
                 permission.grant();
             else
                 permission.deny();
@@ -5777,7 +5778,7 @@ void tst_QWebEnginePage::chooseDesktopMedia()
     QWebEnginePage page;
     QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
     page.settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true);
-    page.profile()->setPersistentPermissionsPolicy(QWebEngineProfile::NoPersistentPermissions);
+    page.profile()->setPersistentPermissionsPolicy(QWebEngineProfile::PersistentPermissionsPolicy::AskEveryTime);
 
     bool desktopMediaRequested = false;
     bool permissionRequested = false;
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index 5303d99fc6c..6c9af17271a 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -58,8 +58,8 @@ private Q_SLOTS:
     void badDeleteOrder();
     void permissionPersistence_data();
     void permissionPersistence();
-    void getPermission_data();
-    void getPermission();
+    void queryPermission_data();
+    void queryPermission();
     void listPermissions();
     void qtbug_71895(); // this should be the last test
 };
@@ -1025,10 +1025,10 @@ void tst_QWebEngineProfile::permissionPersistence_data()
     QTest::addColumn<QWebEngineProfile::PersistentPermissionsPolicy>("policy");
     QTest::addColumn<bool>("granted");
 
-    QTest::newRow("noPersistenceNotificationsNoGrant")      << QWebEngineProfile::NoPersistentPermissions       << false;
-    QTest::newRow("noPersistenceNotificationsGrant")        << QWebEngineProfile::NoPersistentPermissions       << true;
-    QTest::newRow("memoryPersistenceNotificationsNoGrant")  << QWebEngineProfile::PersistentPermissionsInMemory << false;
-    QTest::newRow("diskPersistenceNotificationsGrant")      << QWebEngineProfile::PersistentPermissionsOnDisk   << true;
+    QTest::newRow("noPersistenceNotificationsNoGrant")      << QWebEngineProfile::PersistentPermissionsPolicy::AskEveryTime  << false;
+    QTest::newRow("noPersistenceNotificationsGrant")        << QWebEngineProfile::PersistentPermissionsPolicy::AskEveryTime  << true;
+    QTest::newRow("memoryPersistenceNotificationsNoGrant")  << QWebEngineProfile::PersistentPermissionsPolicy::StoreInMemory << false;
+    QTest::newRow("diskPersistenceNotificationsGrant")      << QWebEngineProfile::PersistentPermissionsPolicy::StoreOnDisk   << true;
 }
 
 void tst_QWebEngineProfile::permissionPersistence()
@@ -1055,7 +1055,7 @@ void tst_QWebEngineProfile::permissionPersistence()
     QVariant variant = granted ? "granted" : "denied";
     QVariant defaultVariant = "default";
 
-    QWebEnginePermission permissionObject = profile->getPermission(server.url("/hedgehog.html"), QWebEnginePermission::Notifications);
+    QWebEnginePermission permissionObject = profile->queryPermission(server.url("/hedgehog.html"), QWebEnginePermission::PermissionType::Notifications);
     if (granted)
         permissionObject.grant();
     else
@@ -1067,7 +1067,7 @@ void tst_QWebEngineProfile::permissionPersistence()
     loadSpy.reset();
 
     bool expectSame = false;
-    if (policy == QWebEngineProfile::PersistentPermissionsOnDisk) {
+    if (policy == QWebEngineProfile::PersistentPermissionsPolicy::StoreOnDisk) {
         expectSame = true;
 
         // File is written asynchronously, wait for it to be created
@@ -1085,7 +1085,7 @@ void tst_QWebEngineProfile::permissionPersistence()
         expectSame ? variant : defaultVariant);
 
     // Re-acquire the permission, since deleting the Profile makes it invalid
-    permissionObject = profile->getPermission(server.url("/hedgehog.html"), QWebEnginePermission::Notifications);
+    permissionObject = profile->queryPermission(server.url("/hedgehog.html"), QWebEnginePermission::PermissionType::Notifications);
     permissionObject.reset();
     QCOMPARE(evaluateJavaScriptSync(page.get(), "Notification.permission"), defaultVariant);
 
@@ -1093,7 +1093,7 @@ void tst_QWebEngineProfile::permissionPersistence()
     profile.reset();
     loadSpy.reset();
 
-    if (policy == QWebEngineProfile::PersistentPermissionsOnDisk) {
+    if (policy == QWebEngineProfile::PersistentPermissionsPolicy::StoreOnDisk) {
         // Wait for file to be written to before deleting
         QTest::qWait(1000);
         storageDir.remove("permissions.json");
@@ -1102,81 +1102,86 @@ void tst_QWebEngineProfile::permissionPersistence()
     QTRY_VERIFY(server.stop());
 }
 
-void tst_QWebEngineProfile::getPermission_data()
+void tst_QWebEngineProfile::queryPermission_data()
 {
-    QTest::addColumn<QWebEnginePermission::Feature>("feature");
+    QTest::addColumn<QWebEnginePermission::PermissionType>("permissionType");
     QTest::addColumn<QUrl>("url");
     QTest::addColumn<bool>("expectedValid");
 
-    QTest::newRow("badUrl") << QWebEnginePermission::Notifications << QUrl(QStringLiteral("//:bad-url")) << false;
-    QTest::newRow("badFeature") << QWebEnginePermission::Unsupported << QUrl(QStringLiteral("qrc:/resources/hedgehog.html")) << false;
-    QTest::newRow("transientFeature") << QWebEnginePermission::MouseLock << QUrl(QStringLiteral("qrc:/resources/hedgehog.html")) << false;
-    QTest::newRow("good") << QWebEnginePermission::Notifications << QUrl(QStringLiteral("qrc:/resources/hedgehog.html")) << true;
+    QTest::newRow("badUrl")
+        << QWebEnginePermission::PermissionType::Notifications << QUrl(QStringLiteral("//:bad-url"))                   << false;
+    QTest::newRow("badFeature")
+        << QWebEnginePermission::PermissionType::Unsupported   << QUrl(QStringLiteral("qrc:/resources/hedgehog.html")) << false;
+    QTest::newRow("transientFeature")
+        << QWebEnginePermission::PermissionType::MouseLock     << QUrl(QStringLiteral("qrc:/resources/hedgehog.html")) << false;
+    QTest::newRow("good")
+        << QWebEnginePermission::PermissionType::Notifications << QUrl(QStringLiteral("qrc:/resources/hedgehog.html")) << true;
 }
 
-void tst_QWebEngineProfile::getPermission()
+void tst_QWebEngineProfile::queryPermission()
 {
-    QFETCH(QWebEnginePermission::Feature, feature);
+    QFETCH(QWebEnginePermission::PermissionType, permissionType);
     QFETCH(QUrl, url);
     QFETCH(bool, expectedValid);
 
     QWebEngineProfile profile;
     // In-memory is the default for otr profiles
-    QVERIFY(profile.persistentPermissionsPolicy() == QWebEngineProfile::PersistentPermissionsInMemory);
+    QVERIFY(profile.persistentPermissionsPolicy() == QWebEngineProfile::PersistentPermissionsPolicy::StoreInMemory);
 
-    QWebEnginePermission permission = profile.getPermission(url, feature);
+    QWebEnginePermission permission = profile.queryPermission(url, permissionType);
     bool valid = permission.isValid();
     QVERIFY(valid == expectedValid);
     if (!valid)
-        QVERIFY(permission.state() == QWebEnginePermission::Invalid);
+        QVERIFY(permission.state() == QWebEnginePermission::State::Invalid);
 
     // Verify that we can grant a valid permission, and we can't grant an invalid one...
     permission.grant();
-    QVERIFY(permission.state() == (valid ? QWebEnginePermission::Granted : QWebEnginePermission::Invalid));
+    QVERIFY(permission.state() == (valid ? QWebEnginePermission::State::Granted : QWebEnginePermission::State::Invalid));
 
     // ...and that doing so twice doesn't mess up the state...
     permission.grant();
-    QVERIFY(permission.state() == (valid ? QWebEnginePermission::Granted : QWebEnginePermission::Invalid));
+    QVERIFY(permission.state() == (valid ? QWebEnginePermission::State::Granted : QWebEnginePermission::State::Invalid));
 
     // ...and that the same thing applies to denying them...
     permission.deny();
-    QVERIFY(permission.state() == (valid ? QWebEnginePermission::Denied : QWebEnginePermission::Invalid));
+    QVERIFY(permission.state() == (valid ? QWebEnginePermission::State::Denied : QWebEnginePermission::State::Invalid));
     permission.deny();
-    QVERIFY(permission.state() == (valid ? QWebEnginePermission::Denied : QWebEnginePermission::Invalid));
+    QVERIFY(permission.state() == (valid ? QWebEnginePermission::State::Denied : QWebEnginePermission::State::Invalid));
 
     // ...and that resetting works
     permission.reset();
-    QVERIFY(permission.state() == (valid ? QWebEnginePermission::Ask : QWebEnginePermission::Invalid));
+    QVERIFY(permission.state() == (valid ? QWebEnginePermission::State::Ask : QWebEnginePermission::State::Invalid));
     permission.reset();
-    QVERIFY(permission.state() == (valid ? QWebEnginePermission::Ask : QWebEnginePermission::Invalid));
+    QVERIFY(permission.state() == (valid ? QWebEnginePermission::State::Ask : QWebEnginePermission::State::Invalid));
 }
 
 void tst_QWebEngineProfile::listPermissions()
 {
     QWebEngineProfile profile;
     // In-memory is the default for otr profiles
-    QVERIFY(profile.persistentPermissionsPolicy() == QWebEngineProfile::PersistentPermissionsInMemory);
+    QVERIFY(profile.persistentPermissionsPolicy() == QWebEngineProfile::PersistentPermissionsPolicy::StoreInMemory);
 
     QUrl commonUrl = QUrl(QStringLiteral("http://www.bing.com/maps"));
-    QWebEnginePermission::Feature commonFeature = QWebEnginePermission::Notifications;
+    QWebEnginePermission::PermissionType commonType = QWebEnginePermission::PermissionType::Notifications;
 
     // First, set several permissions at once
-    profile.getPermission(commonUrl, QWebEnginePermission::Geolocation).deny();
-    profile.getPermission(commonUrl, QWebEnginePermission::Unsupported).grant(); // Invalid
-    profile.getPermission(commonUrl, commonFeature).grant();
-    profile.getPermission(QUrl(QStringLiteral("http://www.google.com/translate")), commonFeature).grant();
+    profile.queryPermission(commonUrl, QWebEnginePermission::PermissionType::Geolocation).deny();
+    profile.queryPermission(commonUrl, QWebEnginePermission::PermissionType::Unsupported).grant(); // Invalid
+    profile.queryPermission(commonUrl, commonType).grant();
+    profile.queryPermission(QUrl(QStringLiteral("http://www.google.com/translate")), commonType).grant();
 
-    QList<QWebEnginePermission> permissionsListAll = profile.listPermissions();
-    QList<QWebEnginePermission> permissionsListUrl = profile.listPermissions(commonUrl);
-    QList<QWebEnginePermission> permissionsListFeature = profile.listPermissions(commonFeature);
+    QList<QWebEnginePermission> permissionsListAll = profile.listAllPermissions();
+    QList<QWebEnginePermission> permissionsListUrl = profile.listPermissionsForOrigin(commonUrl);
+    QList<QWebEnginePermission> permissionsListFeature = profile.listPermissionsForPermissionType(commonType);
 
     // Order of returned permissions is not guaranteed, so we must iterate until we find the one we need
     auto findInList = [](QList<QWebEnginePermission> list, const QUrl &url,
-        QWebEnginePermission::Feature feature, QWebEnginePermission::State state)
+        QWebEnginePermission::PermissionType permissionType, QWebEnginePermission::State state)
     {
         bool found = false;
         for (auto &permission : list) {
-            if (permission.origin().adjusted(QUrl::RemovePath) == url.adjusted(QUrl::RemovePath) && permission.feature() == feature && permission.state() == state) {
+            if (permission.origin().adjusted(QUrl::RemovePath) == url.adjusted(QUrl::RemovePath)
+                    && permission.permissionType() == permissionType && permission.state() == state) {
                 found = true;
                 break;
             }
@@ -1186,19 +1191,19 @@ void tst_QWebEngineProfile::listPermissions()
 
     // Check full list
     QVERIFY(permissionsListAll.size() == 3);
-    QVERIFY(findInList(permissionsListAll, commonUrl, QWebEnginePermission::Geolocation, QWebEnginePermission::Denied));
-    QVERIFY(findInList(permissionsListAll, commonUrl, commonFeature, QWebEnginePermission::Granted));
-    QVERIFY(findInList(permissionsListAll, QUrl(QStringLiteral("http://www.google.com")), commonFeature, QWebEnginePermission::Granted));
+    QVERIFY(findInList(permissionsListAll, commonUrl, QWebEnginePermission::PermissionType::Geolocation, QWebEnginePermission::State::Denied));
+    QVERIFY(findInList(permissionsListAll, commonUrl, commonType, QWebEnginePermission::State::Granted));
+    QVERIFY(findInList(permissionsListAll, QUrl(QStringLiteral("http://www.google.com")), commonType, QWebEnginePermission::State::Granted));
 
     // Check list filtered by URL
     QVERIFY(permissionsListUrl.size() == 2);
-    QVERIFY(findInList(permissionsListUrl, commonUrl, QWebEnginePermission::Geolocation, QWebEnginePermission::Denied));
-    QVERIFY(findInList(permissionsListAll, commonUrl, commonFeature, QWebEnginePermission::Granted));
+    QVERIFY(findInList(permissionsListUrl, commonUrl, QWebEnginePermission::PermissionType::Geolocation, QWebEnginePermission::State::Denied));
+    QVERIFY(findInList(permissionsListAll, commonUrl, commonType, QWebEnginePermission::State::Granted));
 
     // Check list filtered by feature
     QVERIFY(permissionsListFeature.size() == 2);
-    QVERIFY(findInList(permissionsListAll, commonUrl, commonFeature, QWebEnginePermission::Granted));
-    QVERIFY(findInList(permissionsListAll, QUrl(QStringLiteral("http://www.google.com")), commonFeature, QWebEnginePermission::Granted));
+    QVERIFY(findInList(permissionsListAll, commonUrl, commonType, QWebEnginePermission::State::Granted));
+    QVERIFY(findInList(permissionsListAll, QUrl(QStringLiteral("http://www.google.com")), commonType, QWebEnginePermission::State::Granted));
 }
 
 void tst_QWebEngineProfile::qtbug_71895()
diff --git a/tests/manual/quick/geopermission/tst_geopermission.qml b/tests/manual/quick/geopermission/tst_geopermission.qml
index 6d6f4de8bc8..ff9c79f1d06 100644
--- a/tests/manual/quick/geopermission/tst_geopermission.qml
+++ b/tests/manual/quick/geopermission/tst_geopermission.qml
@@ -14,7 +14,7 @@ WebEngineView {
     property bool geoPermissionRequested: false
 
     onPermissionRequested: function(perm) {
-        if (perm.feature === WebEnginePermission.Geolocation) {
+        if (perm.permissionType === WebEnginePermission.PermissionType.Geolocation) {
             geoPermissionRequested = true
             if (deniedGeolocation) {
                 perm.deny()

From 96c8ebd25c04e314fb6bec15b9f4d919675bae8a Mon Sep 17 00:00:00 2001
From: Szabolcs David <davidsz@inf.u-szeged.hu>
Date: Mon, 1 Jul 2024 16:58:12 +0200
Subject: [PATCH 052/356] Allow pressing the print button of PDF viewer
 multiple times

Chromium started to protect ongoing print jobs by a print_in_progress_
flag in PrintRenderFrameHelper. Now we have to properly close requested
print previews before starting a new one.

Fixes: QTBUG-125096
Change-Id: I83fec883d717756d97dc65e3b55363b0cac0fbef
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit ea2012c56952cd0378d13a4257eebade4e3c736d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/printing/print_view_manager_qt.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/core/printing/print_view_manager_qt.cpp b/src/core/printing/print_view_manager_qt.cpp
index 42bade52bdd..41f2cd999a6 100644
--- a/src/core/printing/print_view_manager_qt.cpp
+++ b/src/core/printing/print_view_manager_qt.cpp
@@ -364,6 +364,11 @@ void PrintViewManagerQt::RequestPrintPreview(printing::mojom::RequestPrintPrevie
         content::WebContentsView *view = static_cast<content::WebContentsImpl*>(web_contents()->GetOutermostWebContents())->GetView();
         if (WebContentsAdapterClient *client = WebContentsViewQt::from(view)->client())
             client->printRequested();
+
+        content::GlobalRenderFrameHostId rfhId = GetCurrentTargetFrame()->GetGlobalId();
+        auto *renderFrameHost = content::RenderFrameHost::FromID(rfhId);
+        if (renderFrameHost && renderFrameHost->IsRenderFrameLive())
+            GetPrintRenderFrame(renderFrameHost)->OnPrintPreviewDialogClosed();
         return;
     }
 

From e4cd2608f2cae33b0e95031dbe0f71cd375dbf80 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucie=20G=C3=A9rard?= <lucie.gerard@qt.io>
Date: Tue, 2 Jul 2024 11:36:36 +0200
Subject: [PATCH 053/356] Correct license for examples file
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Example takes precedence over build system file type.
According to QUIP-18 [1], all examples file should be
LicenseRef-Qt-Commercial OR BSD-3-Clause

[1]: https://contribute.qt-project.org/quips/18

Task-number: QTBUG-121787
Change-Id: Ifb33a2b284ef234648b50d2333e83f7015023405
Reviewed-by: Kai Köhne <kai.koehne@qt.io>
Reviewed-by: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
(cherry picked from commit d66b248444c6ee523594edd21d37db5300ff4423)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 examples/webenginewidgets/permissionbrowser/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/examples/webenginewidgets/permissionbrowser/CMakeLists.txt b/examples/webenginewidgets/permissionbrowser/CMakeLists.txt
index 0a92691ba1f..c4d8f9cd43e 100644
--- a/examples/webenginewidgets/permissionbrowser/CMakeLists.txt
+++ b/examples/webenginewidgets/permissionbrowser/CMakeLists.txt
@@ -1,5 +1,5 @@
 # Copyright (C) 2024 The Qt Company Ltd.
-# SPDX-License-Identifier: BSD-3-Clause
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
 
 cmake_minimum_required(VERSION 3.5)
 project(permissionbrowser LANGUAGES CXX)

From 686eb71d22529f170715822af1c95c4cea3e9fd9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucie=20G=C3=A9rard?= <lucie.gerard@qt.io>
Date: Thu, 4 Apr 2024 18:05:03 +0200
Subject: [PATCH 054/356] Correct license for module and plugin files
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Those files partially come from Chromium and
are made available only under BSD-3-Clause

Pick-to: 6.7
Task-number: QTBUG-121787
Change-Id: Iba17543d385f157a648959dcd2b46eaf0e43a7f1
Reviewed-by: Kai Köhne <kai.koehne@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit e8f074f3c318b7ececb02e6ed5ba34a869327f40)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/clipboard_util_win.cpp                 | 2 +-
 src/core/common/qt_messages.cpp                 | 2 +-
 src/core/common/qt_messages.h                   | 2 +-
 src/core/tools/qwebengine_convert_dict/main.cpp | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/core/clipboard_util_win.cpp b/src/core/clipboard_util_win.cpp
index 601e4418026..2dbd173d3c8 100644
--- a/src/core/clipboard_util_win.cpp
+++ b/src/core/clipboard_util_win.cpp
@@ -1,6 +1,6 @@
 // Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+// SPDX-License-Identifier: BSD-3-Clause
 
 #include <string>
 
diff --git a/src/core/common/qt_messages.cpp b/src/core/common/qt_messages.cpp
index bc3a1560d3b..aaaddf83010 100644
--- a/src/core/common/qt_messages.cpp
+++ b/src/core/common/qt_messages.cpp
@@ -1,5 +1,5 @@
 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+// SPDX-License-Identifier: BSD-3-Clause
 
 // Get basic type definitions.
 #define IPC_MESSAGE_IMPL
diff --git a/src/core/common/qt_messages.h b/src/core/common/qt_messages.h
index 17adcbb0da1..eaf3d03f23b 100644
--- a/src/core/common/qt_messages.h
+++ b/src/core/common/qt_messages.h
@@ -1,5 +1,5 @@
 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+// SPDX-License-Identifier: BSD-3-Clause
 
 // Multiply-included file, no traditional include guard.
 
diff --git a/src/core/tools/qwebengine_convert_dict/main.cpp b/src/core/tools/qwebengine_convert_dict/main.cpp
index a82947ddc35..17dd3eec6aa 100644
--- a/src/core/tools/qwebengine_convert_dict/main.cpp
+++ b/src/core/tools/qwebengine_convert_dict/main.cpp
@@ -7,7 +7,7 @@
 ** Modified work:
 ** Copyright (C) 2016 The Qt Company Ltd.
 **
-** SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+** SPDX-License-Identifier: BSD-3-Clause
 **
 ** This tool converts Hunspell .aff/.dic pairs to a combined binary dictionary
 ** format (.bdic). This format is more compact, and can be more efficiently

From b88e8bc197aa8b40575faf9b1f5ffe6922dc8fa5 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Mon, 8 Jul 2024 22:40:10 +0000
Subject: [PATCH 055/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Ie6f8cd5ec7d035333dc312ccdddc679debeb7612
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index d9a5ed195c7..e87c805d4c0 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: df193621ede18ee1166281435750fc1980b3bc1f
+    ref: e9f904aaf2bc17d46709a6a32a6ee22a0eeaf909
     required: true
   ../qtpositioning:
-    ref: 31a8040367a3d79f1970799d283acb1be8e4f23b
+    ref: fb6aa84a86ef5238bc78e1016045bf6ead024947
     required: false
   ../qttools:
-    ref: a5a69456bf87773b671aca85373085a948408ff9
+    ref: 81114e34cf4fd0438c0b7500dec5127e7acc5acc
     required: false
   ../qtwebchannel:
-    ref: abad90db61a76dc0e1faaa2034837a8612bcdd83
+    ref: 1e1b3285624ad11e40765304900cfa2feb262988
     required: false

From 5313ab65edb681571175c03114b479a32474d3c8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucie=20G=C3=A9rard?= <lucie.gerard@qt.io>
Date: Thu, 4 Apr 2024 18:22:59 +0200
Subject: [PATCH 056/356] Add a licenseRule.json file for checking of SPDX
 license identifiers
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The license test in qtqa reads this file
in order to check the validity of the license used.
This file reproduce the QUIP-18 [1] rules, with some exceptions.

Each entry in the file corresponds to a set of licensing rules.

A set of licensing rules can depend on the file ending,
registered in "file_pattern_ending". The last entry in the
file has no "file_pattern_ending", it sets the rules for the
files whose licensing does not depend on their ending.

The license to be used depends on the location
of the file within the Qt module repository.
Let's call this "<true_location>".
The  "<true_location>" can also correspond to a file name,
offering flexibility for exceptions to the rule.
The "<true_location>" are registered in "location".

For each "<true_location>" there is a
"file type" entry and a "spdx" entry.
The "spdx" entry gives the rule:
the expected license tag(s) in SPDX format
for the file ending (if applicable) and "<true_location>".
The "file type" informs on the QUIP-18 type
the tested file corresponds to. It is purely informational
for the reader.

The set of rules are tested in order of appearance
in the json file. For this reason, a more constraining
ending (like "special.txt") needs to appear in
a "file_pattern_ending" located before
the "file_pattern_ending" of a less constraining ending (like ".txt").
Also, a file ending cannot be present in two "file_pattern_ending".

"file_pattern_ending" and "spdx" should list strings.
"<true_location>" can be regular expressions.

During the test the deeper "<true_location>" are
checked first. The order is which they appear in the json file
does not matter.

To test this file, run
QT_MODULE_TO_TEST=../qtwebengine perl tests/prebuild/license/tst_licenses.pl

[1]: https://contribute.qt-project.org/quips/18

Pick-to: 6.7
Task-number: QTBUG-121039
Change-Id: I4c6c5a78ca17e3afb20023e7339b1b6caf04be83
Reviewed-by: Kai Köhne <kai.koehne@qt.io>
(cherry picked from commit 5693d073d1478967362d8f81f29b7f57ba88da66)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 licenseRule.json | 104 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 104 insertions(+)
 create mode 100644 licenseRule.json

diff --git a/licenseRule.json b/licenseRule.json
new file mode 100644
index 00000000000..5f78a7dc8c1
--- /dev/null
+++ b/licenseRule.json
@@ -0,0 +1,104 @@
+[
+    {
+        "comment" : ["file_pattern_ending: strings matched against the end of a file name.",
+                     "location keys: regular expression matched against the beginning of",
+                     "the file path (relative to the git submodule root).",
+                     "spdx: list of SPDX-License-Expression's allowed in the matching files.",
+                     "-------------------------------------------------------",
+                     "Files with the following endings are Build System licensed,",
+                     "unless they are examples",
+                     "Files with other endings can also be build system files"
+                     ],
+        "file_pattern_ending" : ["CMakeLists.txt", ".cmake", ".pro", ".pri", ".prf",
+                     "configure", "configure.bat", "cmake.in", "plist.in", "CMakeLists.txt.in", ".clang-format"],
+        "location" : {
+            "" : {
+                "comment" : "Default",
+                "file type" : "build system",
+                "spdx"      : ["BSD-3-Clause"]
+            },
+            "(.*)(examples/|snippets/)" : {
+                "comment" : "Example takes precedence",
+                "file type" : "examples and snippets",
+                "spdx" : ["LicenseRef-Qt-Commercial OR BSD-3-Clause"]
+            }
+        }
+    },
+    {
+        "comments" : ["Files with the following endings are Tool licensed,",
+                      "unless they are examples.",
+                      "Files with other endings can also be tool files."],
+        "file_pattern_ending" : [".sh", ".py", ".pl", ".bat", ".ps1"],
+        "location" :{
+            "" : {
+                "comment" : "Default",
+                "file type" : "tools and utils",
+                "spdx"      : ["LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0"]
+            },
+            "(.*)(examples/|snippets/)" : {
+                "comment" : "Example takes precedence",
+                "file type" : "examples and snippets",
+                "spdx" : ["LicenseRef-Qt-Commercial OR BSD-3-Clause"]
+            }
+        }
+    },
+    {
+        "comment" : "Files with the following endings are Documentation licensed.",
+        "file_pattern_ending" : [".qdoc", ".qdoc.in", ".qdocinc" , ".qdocconf", ".txt", "README", "qt_attribution.json"],
+        "location" :{
+            "" : {
+                "comment" : "",
+                "file type" : "documentation",
+                "spdx"      : ["LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"]
+            }
+        }
+    },
+    {
+        "comment" : ["All other files",
+                     "The licensing is defined only by the file location in the Qt module repository.",
+                     "NO <file_pattern_ending> key for this case!",
+                     "This needs to be the last entry of the file."],
+        "location" : {
+            "" : {
+                "comment" : "Default",
+                "file type" : "module and plugin",
+                "spdx"      : ["LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only"]
+            },
+            "src/" : {
+                "comment" : "Default",
+                "file type" : "module and plugin",
+                "spdx"      : ["LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only"]
+            },
+            "tests/" : {
+                "comment" : "Default",
+                "file type" : "test",
+                "spdx" : ["LicenseRef-Qt-Commercial OR GPL-3.0-only"]
+            },
+            "(.*)(examples/|snippets/)" : {
+                "comment" : "Default",
+                "file type" : "examples and snippets",
+                "spdx" : ["LicenseRef-Qt-Commercial OR BSD-3-Clause"]
+            },
+            "src/host/config\\.tests/" : {
+                "comment" : "Default",
+                "file type" : "build system",
+                "spdx" : ["BSD-3-Clause"]
+            },
+            "src/core/clipboard_util_win.cpp" : {
+                "comment" : "Partially from Chromium",
+                "file type" : "module and plugin",
+                "spdx" : ["BSD-3-Clause"]
+            },
+            "src/core/common/qt_messages.*" : {
+                "comment" : "Partially from Chromium",
+                "file type" : "module and plugin",
+                "spdx" : ["BSD-3-Clause"]
+            },
+            "src/core/tools/qwebengine_convert_dict/main.cpp" : {
+                "comment" : "Partially from Chromium",
+                "file type" : "module and plugin",
+                "spdx" : ["BSD-3-Clause"]
+            }
+        }
+    }
+]

From 83e85bebcb5257a29402b6d4f64925b63ac3d3a1 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Tue, 2 Jul 2024 10:43:22 +0200
Subject: [PATCH 057/356] Add more vendors to GPU detection

This change expands the list of GPU vendors in the web engine context
creation code. The original list was based on code inside Dawn,
whereas this change adds entries from an equivalent list in ANGLE.
This removes some startup warnings for a few more exotic system
configurations (e.g. VMWare virtual machines).

Fixes: QTBUG-126722
Pick-to: 6.7
Change-Id: I5548cc0677f80e02439e7c4cfc3ab1d680d10971
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
(cherry picked from commit 791ee8106f7a6c8f9c0bf13a46721df2a6cde651)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/web_engine_context.cpp | 42 +++++++++++++++++++++++++++------
 1 file changed, 35 insertions(+), 7 deletions(-)

diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index bf6a06ae5af..d1504a6851c 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -135,6 +135,8 @@ class GPUInfo
 public:
     enum Vendor {
         Unknown = -1,
+
+        // PCI-SIG-registered vendors
         AMD,
         Apple,
         ARM,
@@ -142,10 +144,20 @@ class GPUInfo
         ImgTec,
         Intel,
         Microsoft,
-        Mesa,
         Nvidia,
         Qualcomm,
-        Samsung
+        Samsung,
+        Broadcom,
+        VMWare,
+        VirtIO,
+
+        // Khronos-registered vendors
+        Vivante,
+        VeriSilicon,
+        Kazan,
+        CodePlay,
+        Mesa,
+        PoCL,
     };
 
     static GPUInfo *instance()
@@ -157,7 +169,7 @@ class GPUInfo
     static Vendor vendorIdToVendor(quint64 vendorId)
     {
         // clang-format off
-        // Based on //third_party/dawn/src/dawn/gpu_info.json
+        // Based on //third_party/angle/src/gpu_info_util/SystemInfo.h
         static const std::map<quint64, Vendor> vendorIdMap = {
             {0x0, Unknown},
             {0x1002, AMD},
@@ -166,11 +178,19 @@ class GPUInfo
             {0x1AE0, Google},
             {0x1010, ImgTec},
             {0x8086, Intel},
-            {0x10005, Mesa},
             {0x1414, Microsoft},
             {0x10DE, Nvidia},
             {0x5143, Qualcomm},
-            {0x144D, Samsung}
+            {0x144D, Samsung},
+            {0x14E4, Broadcom},
+            {0x15AD, VMWare},
+            {0x1AF4, VirtIO},
+            {0x10001, Vivante},
+            {0x10002, VeriSilicon},
+            {0x10003, Kazan},
+            {0x10004, CodePlay},
+            {0x10005, Mesa},
+            {0x10006, PoCL},
         };
         // clang-format on
 
@@ -216,11 +236,19 @@ class GPUInfo
             {Google, "Google"},
             {ImgTec, "Img Tec"},
             {Intel, "Intel"},
-            {Mesa, "Mesa"},
             {Microsoft, "Microsoft"},
             {Nvidia, "Nvidia"},
             {Qualcomm, "Qualcomm"},
-            {Samsung, "Samsung"}
+            {Samsung, "Samsung"},
+            {Broadcom, "Broadcom"},
+            {VMWare, "VMWare"},
+            {VirtIO, "VirtIO"},
+            {Vivante, "Vivante"},
+            {VeriSilicon, "VeriSilicon"},
+            {Kazan, "Kazan"},
+            {CodePlay, "CodePlay"},
+            {Mesa, "Mesa"},
+            {PoCL, "PoCL"},
         };
         // clang-format on
 

From 27455f47da86b635f2b940aa81084c8ab8a30283 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Tue, 9 Jul 2024 10:57:39 +0200
Subject: [PATCH 058/356] Write permissions and preferences to disk whenever
 they're modified

Previously, permissions and user prefs would only get committed to disk
when the application closed, and only if it did so with no errors.
This could obviously lead to data loss when the application crashes,
so this change adds calls to PrefService::SchedulePendingLossyWrites()
whenever a permission or user pref is modified. This way, the data
will be written to disk quickly after it's modified inside the
PrefService.

Change-Id: I8aa7c22f9a8b701f697f39132bf3e82ae3c66cc0
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 06507fd00502a1260c088302e36c5ffd355c805f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/permission_manager_qt.cpp | 2 ++
 src/core/pref_service_adapter.cpp  | 4 ++++
 2 files changed, 6 insertions(+)

diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index b9a327d51cb..2792a07edf1 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -531,6 +531,8 @@ void PermissionManagerQt::setPermission(
 
     ScopedDictPrefUpdate updater(m_prefService.get(), permissionTypeString(permissionType));
     updater.Get().Set(requesting_origin.spec(), granted);
+
+    m_prefService->SchedulePendingLossyWrites();
 }
 
 } // namespace QtWebEngineCore
diff --git a/src/core/pref_service_adapter.cpp b/src/core/pref_service_adapter.cpp
index d561cab4fbc..72eb850e7b9 100644
--- a/src/core/pref_service_adapter.cpp
+++ b/src/core/pref_service_adapter.cpp
@@ -150,6 +150,8 @@ void PrefServiceAdapter::setup(const ProfileAdapter &profileAdapter)
     m_prefService->ClearPref(spellcheck::prefs::kSpellCheckEnable);
     m_prefService->ClearPref(spellcheck::prefs::kSpellCheckDictionaries);
 #endif // QT_CONFIG(webengine_spellchecker)
+
+    m_prefService->SchedulePendingLossyWrites();
 }
 
 void PrefServiceAdapter::commit()
@@ -185,6 +187,7 @@ void PrefServiceAdapter::setSpellCheckLanguages(const QStringList &languages)
     for (const auto &language : languages)
         dictionaries.push_back(language.toStdString());
     dictionaries_pref.SetValue(dictionaries);
+    m_prefService->SchedulePendingLossyWrites();
 }
 
 QStringList PrefServiceAdapter::spellCheckLanguages() const
@@ -201,6 +204,7 @@ QStringList PrefServiceAdapter::spellCheckLanguages() const
 void PrefServiceAdapter::setSpellCheckEnabled(bool enabled)
 {
     m_prefService->SetBoolean(spellcheck::prefs::kSpellCheckEnable, enabled);
+    m_prefService->SchedulePendingLossyWrites();
 }
 
 bool PrefServiceAdapter::isSpellCheckEnabled() const

From 26b166183e7c0d78396d8e26e06b149be6c86f23 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Mon, 1 Jul 2024 16:00:47 +0200
Subject: [PATCH 059/356] Update Chromium
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Submodule src/3rdparty 28f666ec..95fda5a0:
* Work around MSVC 17.10 bug
* Modify .gitattributes to stop PDF file line ending changes
* FIXUP: Silence most warnings
* FIXUP: Fix vaapi support for QtWebEngine

Change-Id: I0ce1df66cab625260b491bb86e3414a3b1313251
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
(cherry picked from commit 27b3312102ce9f2d72d63a26072159c700161655)
---
 src/3rdparty | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/3rdparty b/src/3rdparty
index e2c589700c3..95fda5a0e06 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit e2c589700c312d35a503a15c30ea6432d77cbca2
+Subproject commit 95fda5a0e06d39e23be741dbd52bd8d6597ff86e

From d698419f73f8f125f806b95cb3fb9c203122565d Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Fri, 12 Jul 2024 18:20:52 +0000
Subject: [PATCH 060/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I28ef77db8280c845a44454d4377564d63677ef65
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index e87c805d4c0..91fa28f2627 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: e9f904aaf2bc17d46709a6a32a6ee22a0eeaf909
+    ref: 6b21cd12e3d20af2c374e5fbe4a8e3021a7addd3
     required: true
   ../qtpositioning:
-    ref: fb6aa84a86ef5238bc78e1016045bf6ead024947
+    ref: fde5b24156d54a646e5f19fca7a0ac3e01f9b175
     required: false
   ../qttools:
-    ref: 81114e34cf4fd0438c0b7500dec5127e7acc5acc
+    ref: 0cabf7a4f3b7d9ee300d22613a7545a63a522d06
     required: false
   ../qtwebchannel:
-    ref: 1e1b3285624ad11e40765304900cfa2feb262988
+    ref: bc034a51e65392d03458b6068a3a121a3a60a3d2
     required: false

From d4435b47ada2d2f14e980c30d390b9a99dff80f5 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Tue, 9 Jul 2024 13:14:13 +0200
Subject: [PATCH 061/356] Remove usage of non-standard swprintf

WebEngineLibraryInfo::isRemoteDrivePath usea an MSVC-only, non-standard
version of swprintf which doesn't have a len argument, triggering a
compiler warning. This change adds the len argument, which fixes
the warning.

Pick-to: 6.7
Change-Id: I7124e5e5260ed39e46f7df4dc4dfc39521d6374d
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit f4b3399471112ae5f6df86c649df2c6e25c99410)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/web_engine_library_info.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp
index e7115389962..8b69bec3c92 100644
--- a/src/core/web_engine_library_info.cpp
+++ b/src/core/web_engine_library_info.cpp
@@ -429,7 +429,7 @@ std::string WebEngineLibraryInfo::getApplicationLocale()
 bool WebEngineLibraryInfo::isRemoteDrivePath(const QString &path)
 {
     WCHAR wDriveLetter[4] = { 0 };
-    swprintf(wDriveLetter, L"%S", path.mid(0, 3).toStdString().c_str());
+    swprintf(wDriveLetter, 4, L"%S", path.mid(0, 3).toStdString().c_str());
     return GetDriveType(wDriveLetter) == DRIVE_REMOTE;
 }
 

From 3036e77a156c6770716e95b196e0afcf00275cca Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Mon, 15 Jul 2024 17:21:23 +0000
Subject: [PATCH 062/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Icf45392574a50287277b986a8d886a27765767ba
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 91fa28f2627..740679e5b86 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 6b21cd12e3d20af2c374e5fbe4a8e3021a7addd3
+    ref: 321c8a88eb575749cca8d5116b2a131c7932f74d
     required: true
   ../qtpositioning:
-    ref: fde5b24156d54a646e5f19fca7a0ac3e01f9b175
+    ref: ea75bd6c9a1df3f91c718e7a6a20f582405bd913
     required: false
   ../qttools:
-    ref: 0cabf7a4f3b7d9ee300d22613a7545a63a522d06
+    ref: eedf2f68c5918074443b556183ab4068d7255d01
     required: false
   ../qtwebchannel:
-    ref: bc034a51e65392d03458b6068a3a121a3a60a3d2
+    ref: 40451b711429d04347cdd010b904699303d311a4
     required: false

From 63a801b7d3e8e3f92fe63d02d9bb5129ac7eb3ac Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Thu, 4 Jul 2024 13:32:01 +0200
Subject: [PATCH 063/356] QWebEngineFrame: hold weak ref to adapter

This is a bit safer as it prevents crashes when the adapter/page
is no longer around.

This also adds a getter for the adapterClient on WebContentsAdapter.

Change-Id: I50690fd7bf3e5fe60568c565ce0fff20a832351f
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit aa7c32734ca0b05440d01ffd6b943ce435825947)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebengineframe.cpp              | 50 +++++++++++++------
 src/core/api/qwebengineframe.h                | 11 ++--
 src/core/api/qwebenginepage.cpp               |  6 +--
 src/core/web_contents_adapter.cpp             |  5 ++
 src/core/web_contents_adapter.h               |  1 +
 .../api/qquickwebengineview.cpp               |  6 +--
 6 files changed, 52 insertions(+), 27 deletions(-)

diff --git a/src/core/api/qwebengineframe.cpp b/src/core/api/qwebengineframe.cpp
index fa2cbb507b3..6eb628ffabf 100644
--- a/src/core/api/qwebengineframe.cpp
+++ b/src/core/api/qwebengineframe.cpp
@@ -13,6 +13,11 @@
 
 QT_BEGIN_NAMESPACE
 
+#define LOCK_ADAPTER(adapter_variable, return_value)                                               \
+    auto adapter = m_adapter.lock();                                                               \
+    if (!adapter)                                                                                  \
+    return return_value
+
 /*!
     \class QWebEngineFrame
     \brief The QWebEngineFrame class gives information about and control over a page frame.
@@ -34,8 +39,9 @@ QT_BEGIN_NAMESPACE
 
 /*! \internal
  */
-QWebEngineFrame::QWebEngineFrame(QtWebEngineCore::WebContentsAdapterClient *adapter, quint64 id)
-    : m_adapterClient(adapter), m_id(id)
+QWebEngineFrame::QWebEngineFrame(QWeakPointer<QtWebEngineCore::WebContentsAdapter> adapter,
+                                 quint64 id)
+    : m_adapter(std::move(adapter)), m_id(id)
 {
 }
 
@@ -46,7 +52,8 @@ QWebEngineFrame::QWebEngineFrame(QtWebEngineCore::WebContentsAdapterClient *adap
 */
 bool QWebEngineFrame::isValid() const
 {
-    return m_adapterClient->webContentsAdapter()->hasFrame(m_id);
+    LOCK_ADAPTER(adapter, false);
+    return adapter->hasFrame(m_id);
 }
 
 /*!
@@ -58,7 +65,8 @@ bool QWebEngineFrame::isValid() const
 */
 QString QWebEngineFrame::name() const
 {
-    return m_adapterClient->webContentsAdapter()->frameName(m_id);
+    LOCK_ADAPTER(adapter, QString());
+    return adapter->frameName(m_id);
 }
 
 /*!
@@ -70,7 +78,8 @@ QString QWebEngineFrame::name() const
 */
 QString QWebEngineFrame::htmlName() const
 {
-    return m_adapterClient->webContentsAdapter()->frameHtmlName(m_id);
+    LOCK_ADAPTER(adapter, QString());
+    return adapter->frameHtmlName(m_id);
 }
 
 /*!
@@ -80,9 +89,10 @@ QString QWebEngineFrame::htmlName() const
  */
 QList<QWebEngineFrame> QWebEngineFrame::children() const
 {
+    LOCK_ADAPTER(adapter, {});
     QList<QWebEngineFrame> result;
-    for (auto childId : m_adapterClient->webContentsAdapter()->frameChildren(m_id))
-        result.push_back(QWebEngineFrame{ m_adapterClient, childId });
+    for (auto childId : adapter->frameChildren(m_id))
+        result.push_back(QWebEngineFrame{ m_adapter, childId });
     return result;
 }
 
@@ -93,7 +103,8 @@ QList<QWebEngineFrame> QWebEngineFrame::children() const
  */
 QUrl QWebEngineFrame::url() const
 {
-    return m_adapterClient->webContentsAdapter()->frameUrl(m_id);
+    LOCK_ADAPTER(adapter, QUrl());
+    return adapter->frameUrl(m_id);
 }
 
 /*!
@@ -103,7 +114,8 @@ QUrl QWebEngineFrame::url() const
  */
 QSizeF QWebEngineFrame::size() const
 {
-    return m_adapterClient->webContentsAdapter()->frameSize(m_id);
+    LOCK_ADAPTER(adapter, QSizeF());
+    return adapter->frameSize(m_id);
 }
 
 /*!
@@ -111,7 +123,8 @@ QSizeF QWebEngineFrame::size() const
 */
 bool QWebEngineFrame::isMainFrame() const
 {
-    return m_adapterClient->webContentsAdapter()->mainFrameId() == m_id;
+    LOCK_ADAPTER(adapter, false);
+    return adapter->mainFrameId() == m_id;
 }
 
 /*! \fn void QWebEngineFrame::runJavaScript(const QString &script, const std::function<void(const QVariant &)> &callback)
@@ -153,7 +166,8 @@ void QWebEngineFrame::runJavaScript(const QString &script,
 void QWebEngineFrame::runJavaScript(const QString &script, quint32 worldId,
                                     const std::function<void(const QVariant &)> &callback)
 {
-    m_adapterClient->runJavaScript(script, worldId, m_id, callback);
+    LOCK_ADAPTER(adapter, );
+    adapter->runJavaScript(script, worldId, m_id, callback);
 }
 
 void QWebEngineFrame::runJavaScript(const QString &script, quint32 worldId)
@@ -169,9 +183,10 @@ void QWebEngineFrame::runJavaScript(const QString &script, const QJSValue &callb
 void QWebEngineFrame::runJavaScript(const QString &script, quint32 worldId,
                                     const QJSValue &callback)
 {
+    LOCK_ADAPTER(adapter, );
     std::function<void(const QVariant &)> wrappedCallback;
     if (!callback.isUndefined()) {
-        const QObject *holdingObject = m_adapterClient->holdingQObject();
+        const QObject *holdingObject = adapter->adapterClient()->holdingQObject();
         wrappedCallback = [holdingObject, callback](const QVariant &result) {
             if (auto engine = qmlEngine(holdingObject)) {
                 QJSValueList args;
@@ -203,8 +218,9 @@ void QWebEngineFrame::runJavaScript(const QString &script, quint32 worldId,
  */
 void QWebEngineFrame::printToPdf(const QString &filePath)
 {
+    LOCK_ADAPTER(adapter, );
     QPageLayout layout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF());
-    m_adapterClient->printToPdf(filePath, layout, QPageRanges(), m_id);
+    adapter->adapterClient()->printToPdf(filePath, layout, QPageRanges(), m_id);
 }
 
 /*!
@@ -219,19 +235,21 @@ void QWebEngineFrame::printToPdf(const QString &filePath)
 */
 void QWebEngineFrame::printToPdf(const std::function<void(const QByteArray &)> &callback)
 {
+    LOCK_ADAPTER(adapter, );
     std::function wrappedCallback = [callback](QSharedPointer<QByteArray> result) {
         if (callback)
             callback(result ? *result : QByteArray());
     };
     QPageLayout layout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF());
-    m_adapterClient->printToPdf(std::move(wrappedCallback), layout, QPageRanges(), m_id);
+    adapter->adapterClient()->printToPdf(std::move(wrappedCallback), layout, QPageRanges(), m_id);
 }
 
 void QWebEngineFrame::printToPdf(const QJSValue &callback)
 {
+    LOCK_ADAPTER(adapter, );
     std::function<void(QSharedPointer<QByteArray>)> wrappedCallback;
     if (!callback.isUndefined()) {
-        const QObject *holdingObject = m_adapterClient->holdingQObject();
+        const QObject *holdingObject = adapter->adapterClient()->holdingQObject();
         wrappedCallback = [holdingObject, callback](QSharedPointer<QByteArray> result) {
             if (auto engine = qmlEngine(holdingObject)) {
                 QJSValueList args;
@@ -243,7 +261,7 @@ void QWebEngineFrame::printToPdf(const QJSValue &callback)
         };
     }
     QPageLayout layout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF());
-    m_adapterClient->printToPdf(std::move(wrappedCallback), layout, QPageRanges(), m_id);
+    adapter->adapterClient()->printToPdf(std::move(wrappedCallback), layout, QPageRanges(), m_id);
 }
 
 /*! \fn bool QWebEngineFrame::operator==(const QWebEngineFrame &left, const QWebEngineFrame &right) noexcept
diff --git a/src/core/api/qwebengineframe.h b/src/core/api/qwebengineframe.h
index 85b02407a4d..02f442f4f47 100644
--- a/src/core/api/qwebengineframe.h
+++ b/src/core/api/qwebengineframe.h
@@ -12,9 +12,10 @@
 #include <QtCore/QSizeF>
 #include <QtCore/QString>
 #include <QtCore/QUrl>
+#include <QtCore/QWeakPointer>
 
 namespace QtWebEngineCore {
-class WebContentsAdapterClient;
+class WebContentsAdapter;
 }
 
 QT_BEGIN_NAMESPACE
@@ -61,7 +62,7 @@ class QWebEngineFrame
     friend inline bool comparesEqual(const QWebEngineFrame &lhs,
                                      const QWebEngineFrame &rhs) noexcept
     {
-        return lhs.m_adapterClient == rhs.m_adapterClient && lhs.m_id == rhs.m_id;
+        return lhs.m_adapter == rhs.m_adapter && lhs.m_id == rhs.m_id;
     }
 
     Q_DECLARE_EQUALITY_COMPARABLE(QWebEngineFrame);
@@ -72,10 +73,10 @@ class QWebEngineFrame
     friend class QQuickWebEngineView;
     friend class QQuickWebEngineViewPrivate;
 
-    Q_WEBENGINECORE_EXPORT QWebEngineFrame(QtWebEngineCore::WebContentsAdapterClient *page,
-                                           quint64 id);
+    Q_WEBENGINECORE_EXPORT
+    QWebEngineFrame(QWeakPointer<QtWebEngineCore::WebContentsAdapter> adapter, quint64 id);
 
-    QtWebEngineCore::WebContentsAdapterClient *m_adapterClient;
+    QWeakPointer<QtWebEngineCore::WebContentsAdapter> m_adapter;
     quint64 m_id;
 };
 
diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp
index 433de26b072..c125b3aca47 100644
--- a/src/core/api/qwebenginepage.cpp
+++ b/src/core/api/qwebenginepage.cpp
@@ -1768,7 +1768,7 @@ void QWebEnginePagePrivate::printRequested()
 void QWebEnginePagePrivate::printRequestedByFrame(quint64 frameId)
 {
     Q_Q(QWebEnginePage);
-    QWebEngineFrame frame(this, frameId);
+    QWebEngineFrame frame(adapter, frameId);
     QTimer::singleShot(0, q, [q, frame]() { Q_EMIT q->printRequestedByFrame(frame); });
     if (view)
         view->printRequestedByFrame(frame);
@@ -2555,7 +2555,7 @@ void QWebEnginePage::setVisible(bool visible)
 QWebEngineFrame QWebEnginePage::mainFrame()
 {
     Q_D(QWebEnginePage);
-    return QWebEngineFrame(d, d->adapter->mainFrameId());
+    return QWebEngineFrame(d->adapter, d->adapter->mainFrameId());
 }
 
 /*!
@@ -2568,7 +2568,7 @@ std::optional<QWebEngineFrame> QWebEnginePage::findFrameByName(QAnyStringView na
 {
     Q_D(QWebEnginePage);
     if (auto maybeId = d->adapter->findFrameIdByName(name.toString())) {
-        return QWebEngineFrame(d, *maybeId);
+        return QWebEngineFrame(d->adapter, *maybeId);
     }
     return {};
 }
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index a40f641c11b..c49331f1e76 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -1561,6 +1561,11 @@ content::WebContents *WebContentsAdapter::guestWebContents() const
     return !innerWebContents.empty() ? innerWebContents[0] : nullptr;
 }
 
+WebContentsAdapterClient *WebContentsAdapter::adapterClient()
+{
+    return m_adapterClient;
+}
+
 #if QT_CONFIG(webengine_webchannel)
 QWebChannel *WebContentsAdapter::webChannel() const
 {
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 41a296072ba..44ee7823dde 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -238,6 +238,7 @@ class Q_WEBENGINECORE_EXPORT WebContentsAdapter : public QEnableSharedFromThis<W
     void initialize(content::SiteInstance *site);
     content::WebContents *webContents() const;
     content::WebContents *guestWebContents() const;
+    WebContentsAdapterClient *adapterClient();
     void updateRecommendedState();
     void setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor);
     QWebEngineUrlRequestInterceptor* requestInterceptor() const;
diff --git a/src/webenginequick/api/qquickwebengineview.cpp b/src/webenginequick/api/qquickwebengineview.cpp
index 56b5963f61d..56985780859 100644
--- a/src/webenginequick/api/qquickwebengineview.cpp
+++ b/src/webenginequick/api/qquickwebengineview.cpp
@@ -898,7 +898,7 @@ void QQuickWebEngineViewPrivate::printRequestedByFrame(quint64 frameId)
 {
     Q_Q(QQuickWebEngineView);
     QTimer::singleShot(0, q, [this, q, frameId]() {
-        Q_EMIT q->printRequestedByFrame(QWebEngineFrame(this, frameId));
+        Q_EMIT q->printRequestedByFrame(QWebEngineFrame(this->adapter, frameId));
     });
 }
 
@@ -2597,14 +2597,14 @@ QQmlComponent *QQuickWebEngineView::touchHandleDelegate() const
 QWebEngineFrame QQuickWebEngineView::mainFrame()
 {
     Q_D(QQuickWebEngineView);
-    return QWebEngineFrame(d, d->adapter->mainFrameId());
+    return QWebEngineFrame(d->adapter, d->adapter->mainFrameId());
 }
 
 QWebEngineFrame QQuickWebEngineView::findFrameByName(const QString &name)
 {
     Q_D(QQuickWebEngineView);
     auto maybeId = d->adapter->findFrameIdByName(name);
-    return QWebEngineFrame(d, maybeId.value_or(WebContentsAdapter::kInvalidFrameId));
+    return QWebEngineFrame(d->adapter, maybeId.value_or(WebContentsAdapter::kInvalidFrameId));
 }
 
 void QQuickWebEngineView::save(const QString &filePath,

From 3339c5eeeb88994118971ccda8ae54a6d3f0c8b3 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Thu, 11 Jul 2024 10:55:36 +0200
Subject: [PATCH 064/356] Fix deprecations in QQuickWebEngineView

Add a missing QT_MOC_COMPAT macro in grantFeaturePermission, and remove
the leftover moc workaround macro magic in featurePermissionRequested.
Found in API review.

Change-Id: I480b22accd076abc7e30f12f9d65ee323c08839c
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 944a92d9da346f5a4059d928678412e4c8e066ff)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/webenginequick/api/qquickwebengineview_p.h | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/src/webenginequick/api/qquickwebengineview_p.h b/src/webenginequick/api/qquickwebengineview_p.h
index d15b8e82cc4..53f81f776ea 100644
--- a/src/webenginequick/api/qquickwebengineview_p.h
+++ b/src/webenginequick/api/qquickwebengineview_p.h
@@ -492,7 +492,7 @@ public Q_SLOTS:
     Q_REVISION(1,1) void findText(const QString &subString, FindFlags options = { }, const QJSValue &callback = QJSValue());
     Q_REVISION(1,1) void fullScreenCancelled();
 #if QT_DEPRECATED_SINCE(6, 8)
-    QT_DEPRECATED_VERSION_X_6_8("Setting permissions through WebEngineView has been deprecated. Please use WebEnginePermission instead.")
+    QT_MOC_COMPAT QT_DEPRECATED_VERSION_X_6_8("Setting permissions through WebEngineView has been deprecated. Please use WebEnginePermission instead.")
     Q_REVISION(1,1) void grantFeaturePermission(const QUrl &securityOrigin, QQuickWebEngineView::Feature, bool granted);
 #endif // QT_DEPRECATED_SINCE(6, 8)
     Q_REVISION(1,2) void setActiveFocusOnPress(bool arg);
@@ -521,17 +521,10 @@ private Q_SLOTS:
     Q_REVISION(1,1) void fullScreenRequested(const QWebEngineFullScreenRequest &request);
     Q_REVISION(1,1) void isFullScreenChanged();
 #if QT_DEPRECATED_SINCE(6, 8)
-#if !defined(Q_MOC_RUN)
-QT_WARNING_PUSH
-QT_WARNING_DISABLE_DEPRECATED
-#endif // !defined(Q_MOC_RUN)
     QT_MOC_COMPAT QT_DEPRECATED_VERSION_X_6_8("The signal has been deprecated; please use permissionRequested instead.")
     Q_REVISION(1, 1)
     void featurePermissionRequested(const QUrl &securityOrigin,
                                     QQuickWebEngineView::Feature feature);
-#if !defined(Q_MOC_RUN)
-QT_WARNING_POP
-#endif // !defined(Q_MOC_RUN)
 #endif // QT_DEPRECATED_SINCE(6, 8)
     Q_REVISION(1,1) void zoomFactorChanged(qreal arg);
     Q_REVISION(1,1) void profileChanged();

From 523aeb9ced2b8ffd78453469e4d094a5b6fa2ce3 Mon Sep 17 00:00:00 2001
From: Ivan Solovev <ivan.solovev@qt.io>
Date: Thu, 4 Jul 2024 09:42:12 +0200
Subject: [PATCH 065/356] QWebEnginePermission: fix the name of comparison
 helper

Do not use comparesEqual() as a name of a 1-arg member function, as
it is used in the C++20 comparison framework and should be a 2-arg
hidden friend.
Rename the exported member function to equals(), thus leaving the
possibility to use the comparison helper macros later, if needed.

Amends 00d7de830a43a84a431511a55525f04c21b8ba49.

Found in Qt 6.8 API review.

Change-Id: I0ed9bf9ee08418da2f489ed328aecee412486fd0
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit ba5199f362b2362bb9b9d8e05aad9ef0129c8e22)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebenginepermission.cpp | 2 +-
 src/core/api/qwebenginepermission.h   | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/core/api/qwebenginepermission.cpp b/src/core/api/qwebenginepermission.cpp
index a6860b5ddff..9cef4bf9684 100644
--- a/src/core/api/qwebenginepermission.cpp
+++ b/src/core/api/qwebenginepermission.cpp
@@ -104,7 +104,7 @@ QWebEnginePermission &QWebEnginePermission::operator=(const QWebEnginePermission
     return *this;
 }
 
-bool QWebEnginePermission::comparesEqual(const QWebEnginePermission &other) const
+bool QWebEnginePermission::equals(const QWebEnginePermission &other) const
 {
     if (this == &other)
         return true;
diff --git a/src/core/api/qwebenginepermission.h b/src/core/api/qwebenginepermission.h
index 440bf788b71..a6a767aeb9f 100644
--- a/src/core/api/qwebenginepermission.h
+++ b/src/core/api/qwebenginepermission.h
@@ -79,11 +79,11 @@ class QWebEnginePermission
 
 private:
     inline friend bool operator==(const QWebEnginePermission &lhs, const QWebEnginePermission &rhs)
-        { return lhs.comparesEqual(rhs); };
+        { return lhs.equals(rhs); };
     inline friend bool operator!=(const QWebEnginePermission &lhs, const QWebEnginePermission &rhs)
-        { return !lhs.comparesEqual(rhs); };
+        { return !lhs.equals(rhs); };
 
-    Q_WEBENGINECORE_EXPORT bool comparesEqual(const QWebEnginePermission &other) const;
+    Q_WEBENGINECORE_EXPORT bool equals(const QWebEnginePermission &other) const;
 
 protected:
     friend class QWebEnginePagePrivate;

From bcb95b58086c9126dcc38fffe7dbd309f212f1f2 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Fri, 5 Jul 2024 10:53:00 +0200
Subject: [PATCH 066/356] Remove use_vaapi_x11 from GN argument list

No longer available after 122-based update.
See, https://crrev.com/c/3646633

Change-Id: I4698f186f315a0d105f9f01df413fc360a90d486
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 4ba69b273d33462fdf1984f574597668b02a53a0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/CMakeLists.txt | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index d43188813db..c5ff65405ac 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -510,10 +510,6 @@ foreach(arch ${archs})
                 ARGS rtc_use_x11
                 CONDITION QT_FEATURE_webengine_ozone_x11 AND QT_FEATURE_webengine_webrtc
             )
-            extend_gn_list(gnArgArg
-                ARGS use_vaapi_x11
-                CONDITION QT_FEATURE_webengine_ozone_x11 AND QT_FEATURE_webengine_vaapi
-            )
 
             if(QT_FEATURE_webengine_kerberos)
                 list(APPEND gnArgArg

From 133dbd5d2a8d36be811cf95a93e813b56c65bce3 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Wed, 3 Jul 2024 15:05:12 +0200
Subject: [PATCH 067/356] Fix restoring EGL context in EGLHelper

In case of ANGLE, the gl::GLContext::MakeCurrent() makes the ANGLE
context current and not the underlying native context. Use native
eglMakeCurrent() instead.

Change-Id: I84a0cb77478e906ad8926db8813b0c3386521bf3
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 55d0379824cc92cb850f656039c2d13275104b55)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/ozone/gl_context_qt.cpp | 42 +++++++++++++++++++++++++-------
 src/core/ozone/gl_context_qt.h   |  8 ++++++
 2 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/src/core/ozone/gl_context_qt.cpp b/src/core/ozone/gl_context_qt.cpp
index 634e2aa0f64..08729a78a12 100644
--- a/src/core/ozone/gl_context_qt.cpp
+++ b/src/core/ozone/gl_context_qt.cpp
@@ -162,11 +162,16 @@ bool GLContextHelper::isCreateContextRobustnessSupported()
 class ScopedGLContext
 {
 public:
-    ScopedGLContext(QOffscreenSurface *surface)
-        : m_context(new QOpenGLContext())
-        , m_previousContext(gl::GLContext::GetCurrent())
-        , m_previousSurface(gl::GLSurface::GetCurrent())
+    ScopedGLContext(QOffscreenSurface *surface) : m_context(new QOpenGLContext())
     {
+        if (gl::GLContext::GetCurrent()) {
+            auto eglFun = EGLHelper::instance()->functions();
+            m_previousEGLContext = eglFun->eglGetCurrentContext();
+            m_previousEGLDrawSurface = eglFun->eglGetCurrentSurface(EGL_DRAW);
+            m_previousEGLReadSurface = eglFun->eglGetCurrentSurface(EGL_READ);
+            m_previousEGLDisplay = eglFun->eglGetCurrentDisplay();
+        }
+
         if (!m_context->create()) {
             qWarning("Failed to create OpenGL context.");
             return;
@@ -186,8 +191,18 @@ class ScopedGLContext
             glFun->glDeleteTextures(m_textures.size(), m_textures.data());
         }
 
-        if (m_previousContext)
-            m_previousContext->MakeCurrent(m_previousSurface);
+        if (m_previousEGLContext) {
+            // Make sure the scoped context is not current when restoring the previous
+            // EGL context otherwise the QOpenGLContext destructor resets the restored
+            // current context.
+            m_context->doneCurrent();
+
+            auto eglFun = EGLHelper::instance()->functions();
+            eglFun->eglMakeCurrent(m_previousEGLDisplay, m_previousEGLDrawSurface,
+                                   m_previousEGLReadSurface, m_previousEGLContext);
+            if (eglFun->eglGetError() != EGL_SUCCESS)
+                qWarning("Failed to restore EGL context.");
+        }
     }
 
     bool isValid() const { return m_context->isValid() && (m_context->surface() != nullptr); }
@@ -223,8 +238,10 @@ class ScopedGLContext
 
 private:
     QScopedPointer<QOpenGLContext> m_context;
-    gl::GLContext *m_previousContext;
-    gl::GLSurface *m_previousSurface;
+    EGLContext m_previousEGLContext = nullptr;
+    EGLSurface m_previousEGLDrawSurface = nullptr;
+    EGLSurface m_previousEGLReadSurface = nullptr;
+    EGLDisplay m_previousEGLDisplay = nullptr;
     std::vector<uint> m_textures;
 };
 
@@ -235,11 +252,18 @@ EGLHelper::EGLFunctions::EGLFunctions()
 
     eglCreateImage = reinterpret_cast<PFNEGLCREATEIMAGEPROC>(getProcAddress("eglCreateImage"));
     eglDestroyImage = reinterpret_cast<PFNEGLDESTROYIMAGEPROC>(getProcAddress("eglDestroyImage"));
-    eglGetError = reinterpret_cast<PFNEGLGETERRORPROC>(getProcAddress("eglGetError"));
     eglExportDMABUFImageMESA = reinterpret_cast<PFNEGLEXPORTDMABUFIMAGEMESAPROC>(
             getProcAddress("eglExportDMABUFImageMESA"));
     eglExportDMABUFImageQueryMESA = reinterpret_cast<PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC>(
             getProcAddress("eglExportDMABUFImageQueryMESA"));
+    eglGetCurrentContext =
+            reinterpret_cast<PFNEGLGETCURRENTCONTEXTPROC>(getProcAddress("eglGetCurrentContext"));
+    eglGetCurrentDisplay =
+            reinterpret_cast<PFNEGLGETCURRENTDISPLAYPROC>(getProcAddress("eglGetCurrentDisplay"));
+    eglGetCurrentSurface =
+            reinterpret_cast<PFNEGLGETCURRENTSURFACEPROC>(getProcAddress("eglGetCurrentSurface"));
+    eglGetError = reinterpret_cast<PFNEGLGETERRORPROC>(getProcAddress("eglGetError"));
+    eglMakeCurrent = reinterpret_cast<PFNEGLMAKECURRENTPROC>(getProcAddress("eglMakeCurrent"));
     eglQueryString = reinterpret_cast<PFNEGLQUERYSTRINGPROC>(getProcAddress("eglQueryString"));
 }
 
diff --git a/src/core/ozone/gl_context_qt.h b/src/core/ozone/gl_context_qt.h
index 1607284331b..81c08a65073 100644
--- a/src/core/ozone/gl_context_qt.h
+++ b/src/core/ozone/gl_context_qt.h
@@ -50,7 +50,11 @@ class GLContextHelper : public QObject {
 #undef eglDestroyImage
 #undef eglExportDMABUFImageMESA
 #undef eglExportDMABUFImageQueryMESA
+#undef eglGetCurrentContext
+#undef eglGetCurrentDisplay
+#undef eglGetCurrentSurface
 #undef eglGetError
+#undef eglMakeCurrent
 #undef eglQueryString
 
 class EGLHelper
@@ -64,7 +68,11 @@ class EGLHelper
         PFNEGLDESTROYIMAGEPROC eglDestroyImage;
         PFNEGLEXPORTDMABUFIMAGEMESAPROC eglExportDMABUFImageMESA;
         PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC eglExportDMABUFImageQueryMESA;
+        PFNEGLGETCURRENTCONTEXTPROC eglGetCurrentContext;
+        PFNEGLGETCURRENTDISPLAYPROC eglGetCurrentDisplay;
+        PFNEGLGETCURRENTSURFACEPROC eglGetCurrentSurface;
         PFNEGLGETERRORPROC eglGetError;
+        PFNEGLMAKECURRENTPROC eglMakeCurrent;
         PFNEGLQUERYSTRINGPROC eglQueryString;
     };
 

From df6e6d17f2e8958e722a7845c79513d96e42f81f Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Fri, 12 Jan 2024 12:46:08 +0100
Subject: [PATCH 068/356] Support ANGLE to EGL/GLX painting

Enable it with: --webEngineArgs --use-gl=angle --use-angle=gl-egl

Task-number: QTBUG-112281
Change-Id: I224bbcb486489450635010400053318f3ec04c97
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 32e16d24c556fcba380f10f5f1284dad7162e891)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/CMakeLists.txt                       |   2 +
 .../compositor/native_skia_output_device.cpp  |   7 +-
 .../native_skia_output_device_opengl.cpp      | 236 +++++++++++++++++-
 src/core/ozone/gl_ozone_angle_qt.cpp          | 119 +++++++++
 src/core/ozone/gl_ozone_angle_qt.h            |  41 +++
 src/core/ozone/surface_factory_qt.cpp         |  36 ++-
 src/core/ozone/surface_factory_qt.h           |   3 +-
 7 files changed, 425 insertions(+), 19 deletions(-)
 create mode 100644 src/core/ozone/gl_ozone_angle_qt.cpp
 create mode 100644 src/core/ozone/gl_ozone_angle_qt.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index c5ff65405ac..24ccdacbbf4 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -149,6 +149,7 @@ foreach(arch ${archs})
                 net/version_ui_qt.cpp net/version_ui_qt.h
                 net/webui_controller_factory_qt.cpp net/webui_controller_factory_qt.h
                 ozone/gl_context_qt.cpp ozone/gl_context_qt.h
+                ozone/gl_ozone_angle_qt.cpp ozone/gl_ozone_angle_qt.h
                 ozone/gl_ozone_egl_qt.cpp ozone/gl_ozone_egl_qt.h
                 ozone/gl_share_context_qt.cpp ozone/gl_share_context_qt.h
                 ozone/gl_surface_egl_qt.cpp ozone/gl_surface_egl_qt.h
@@ -427,6 +428,7 @@ foreach(arch ${archs})
 
         if(LINUX)
             list(APPEND gnArgArg
+                angle_enable_gl=true
                 use_gtk=false # GTK toolkit bindings
                 use_qt=false # Qt5 toolkit bindings
                 use_cups=false
diff --git a/src/core/compositor/native_skia_output_device.cpp b/src/core/compositor/native_skia_output_device.cpp
index 708692df7d5..4420e8d59aa 100644
--- a/src/core/compositor/native_skia_output_device.cpp
+++ b/src/core/compositor/native_skia_output_device.cpp
@@ -222,9 +222,12 @@ NativeSkiaOutputDevice::Buffer::~Buffer()
 // found in the LICENSE file.
 bool NativeSkiaOutputDevice::Buffer::initialize()
 {
-    static const uint32_t kDefaultSharedImageUsage = gpu::SHARED_IMAGE_USAGE_SCANOUT
-            | gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_DISPLAY_WRITE
+    uint32_t kDefaultSharedImageUsage = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ
+            | gpu::SHARED_IMAGE_USAGE_DISPLAY_WRITE
             | gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT;
+    if (m_parent->m_isNativeBufferSupported)
+        kDefaultSharedImageUsage |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
+
     auto mailbox = gpu::Mailbox::GenerateForSharedImage();
 
     SkColorType skColorType = m_shape.imageInfo.colorType();
diff --git a/src/core/compositor/native_skia_output_device_opengl.cpp b/src/core/compositor/native_skia_output_device_opengl.cpp
index 058573b9e55..c8430f0f7d6 100644
--- a/src/core/compositor/native_skia_output_device_opengl.cpp
+++ b/src/core/compositor/native_skia_output_device_opengl.cpp
@@ -1,6 +1,10 @@
 // Copyright (C) 2024 The Qt Company Ltd.
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
 
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE.Chromium file.
+
 #include "native_skia_output_device_opengl.h"
 
 #include <QtGui/qopenglcontext.h>
@@ -8,8 +12,107 @@
 #include <QtQuick/qquickwindow.h>
 #include <QtQuick/qsgtexture.h>
 
+#include "ui/base/ozone_buildflags.h"
+#include "ui/gl/gl_implementation.h"
+
+#if defined(USE_OZONE)
+#include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h"
+#include "ui/gfx/linux/drm_util_linux.h"
+#include "ui/gfx/linux/native_pixmap_dmabuf.h"
+
+#if BUILDFLAG(IS_OZONE_X11)
+#include "base/posix/eintr_wrapper.h"
+#include "ui/gfx/x/connection.h"
+#include "ui/gfx/x/dri3.h"
+#include "ui/gfx/x/future.h"
+#include "ui/gfx/x/glx.h"
+#include "ui/gfx/x/xproto.h"
+
+#include "ui/gl/gl_bindings.h"
+#undef glBindTexture
+#undef glDeleteTextures
+#undef glGenTextures
+#endif // BUILDFLAG(IS_OZONE_X11)
+
+// Keep it at the end.
+#include "ozone/gl_context_qt.h"
+#endif // defined(USE_OZONE)
+
 namespace QtWebEngineCore {
 
+#if BUILDFLAG(IS_OZONE_X11)
+namespace {
+
+// Based on //ui/ozone/platform/x11/native_pixmap_egl_x11_binding.cc
+x11::Pixmap XPixmapFromNativePixmap(const gfx::NativePixmap &nativePixmap)
+{
+    // Hard coded values for gfx::BufferFormat::BGRA_8888:
+    const uint8_t depth = 32;
+    const uint8_t bpp = 32;
+
+    const int dmaBufFd = HANDLE_EINTR(dup(nativePixmap.GetDmaBufFd(0)));
+    if (dmaBufFd < 0) {
+        qWarning("Could not import the dma-buf as an XPixmap because the FD couldn't be dup()ed.");
+        return x11::Pixmap::None;
+    }
+    x11::RefCountedFD refCountedFD(dmaBufFd);
+
+    uint32_t size = base::checked_cast<uint32_t>(nativePixmap.GetDmaBufPlaneSize(0));
+    uint16_t width = base::checked_cast<uint16_t>(nativePixmap.GetBufferSize().width());
+    uint16_t height = base::checked_cast<uint16_t>(nativePixmap.GetBufferSize().height());
+    uint16_t stride = base::checked_cast<uint16_t>(nativePixmap.GetDmaBufPitch(0));
+
+    auto *connection = x11::Connection::Get();
+    const x11::Pixmap pixmapId = connection->GenerateId<x11::Pixmap>();
+    if (pixmapId == x11::Pixmap::None) {
+        qWarning("Could not import the dma-buf as an XPixmap because an ID couldn't be generated.");
+        return x11::Pixmap::None;
+    }
+
+    auto response = connection->dri3()
+                            .PixmapFromBuffer(pixmapId, connection->default_root(), size, width,
+                                              height, stride, depth, bpp, refCountedFD)
+                            .Sync();
+
+    if (response.error) {
+        qWarning() << "Could not import the dma-buf as an XPixmap because "
+                      "PixmapFromBuffer() failed; error: "
+                   << response.error->ToString();
+        return x11::Pixmap::None;
+    }
+
+    return pixmapId;
+}
+
+GLXFBConfig GetFBConfig(Display *display)
+{
+    // clang-format off
+    static const int configAttribs[] = {
+        GLX_RED_SIZE, 8,
+        GLX_GREEN_SIZE, 8,
+        GLX_BLUE_SIZE, 8,
+        GLX_ALPHA_SIZE, 8,
+        GLX_BUFFER_SIZE, 32,
+        GLX_BIND_TO_TEXTURE_RGBA_EXT, 1,
+        GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
+        GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
+        GLX_DOUBLEBUFFER, 0,
+        GLX_Y_INVERTED_EXT, GLX_DONT_CARE,
+        0
+    };
+    // clang-format on
+
+    int numConfigs = 0;
+    GLXFBConfig *configs = glXChooseFBConfig(display, /* screen */ 0, configAttribs, &numConfigs);
+    if (!configs || numConfigs < 1)
+        qFatal("GLX: Failed to find frame buffer configuration for pixmap.");
+
+    return configs[0];
+}
+
+} // namespace
+#endif // BUILDFLAG(IS_OZONE_X11)
+
 NativeSkiaOutputDeviceOpenGL::NativeSkiaOutputDeviceOpenGL(
         scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
         gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
@@ -21,6 +124,11 @@ NativeSkiaOutputDeviceOpenGL::NativeSkiaOutputDeviceOpenGL(
                              didSwapBufferCompleteCallback)
 {
     SkColorType skColorType = kRGBA_8888_SkColorType;
+#if BUILDFLAG(IS_OZONE_X11)
+    if (GLContextHelper::getGlxPlatformInterface())
+        skColorType = kBGRA_8888_SkColorType;
+#endif // BUILDFLAG(IS_OZONE_X11)
+
     capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBA_8888)] = skColorType;
     capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBX_8888)] = skColorType;
     capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRA_8888)] = skColorType;
@@ -39,10 +147,43 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
         return nullptr;
 
 #if defined(USE_OZONE)
+    Q_ASSERT(m_contextState->gr_context_type() == gpu::GrContextType::kGL);
+
+    GrGLTextureInfo glTextureInfo;
     scoped_refptr<gfx::NativePixmap> nativePixmap = m_frontBuffer->nativePixmap();
     if (!nativePixmap) {
-        qWarning("No native pixmap.");
-        return nullptr;
+        if (m_isNativeBufferSupported) {
+            qWarning("No native pixmap.");
+            return nullptr;
+        }
+
+        sk_sp<SkImage> skImage = m_frontBuffer->skImage();
+        if (!skImage) {
+            qWarning("No SkImage.");
+            return nullptr;
+        }
+
+        if (!skImage->isTextureBacked()) {
+            qWarning("SkImage is not backed by GPU texture.");
+            return nullptr;
+        }
+
+        GrBackendTexture backendTexture;
+        bool success = SkImages::GetBackendTextureFromImage(skImage, &backendTexture, false);
+        if (!success || !backendTexture.isValid()) {
+            qWarning("Failed to retrieve backend texture from SkImage.");
+            return nullptr;
+        }
+
+        if (backendTexture.backend() != GrBackendApi::kOpenGL) {
+            qWarning("Backend texture is not a OpenGL texture.");
+            return nullptr;
+        }
+
+        if (!GrBackendTextures::GetGLTextureInfo(backendTexture, &glTextureInfo)) {
+            qWarning("Unable to access OpenGL texture.");
+            return nullptr;
+        }
     }
 #elif defined(Q_OS_WIN)
     auto overlayImage = m_frontBuffer->overlayImage();
@@ -62,8 +203,95 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
     QSGTexture *texture = nullptr;
 
 #if defined(USE_OZONE)
-    // TODO(QTBUG-112281): Add ANGLE support to Linux.
-    QT_NOT_YET_IMPLEMENTED
+    QOpenGLContext *glContext = QOpenGLContext::currentContext();
+    auto glFun = glContext->functions();
+    GLuint glTexture = 0;
+
+    if (nativePixmap) {
+#if BUILDFLAG(IS_OZONE_X11)
+        if (GLContextHelper::getGlxPlatformInterface()) {
+            x11::Pixmap pixmapId =
+                    XPixmapFromNativePixmap(*(gfx::NativePixmapDmaBuf *)nativePixmap.get());
+            if (pixmapId == x11::Pixmap::None)
+                qFatal("GLX: Failed to import XPixmap.");
+
+            // clang-format off
+            static const int pixmapAttribs[] = {
+                 GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
+                 GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT,
+                 0
+            };
+            // clang-format on
+
+            Display *display = static_cast<Display *>(GLContextHelper::getXDisplay());
+            GLXPixmap glxPixmap = glXCreatePixmap(display, GetFBConfig(display),
+                                                  static_cast<::Pixmap>(pixmapId), pixmapAttribs);
+
+            glFun->glGenTextures(1, &glTexture);
+            glFun->glBindTexture(GL_TEXTURE_2D, glTexture);
+            glXBindTexImageEXT(display, glxPixmap, GLX_FRONT_LEFT_EXT, nullptr);
+            glFun->glBindTexture(GL_TEXTURE_2D, 0);
+
+            m_frontBuffer->textureCleanupCallback = [glFun, glTexture, display, glxPixmap]() {
+                glFun->glDeleteTextures(1, &glTexture);
+                glXDestroyGLXPixmap(display, glxPixmap);
+            };
+        }
+#endif // BUILDFLAG(IS_OZONE_X11)
+
+        if (GLContextHelper::getEglPlatformInterface()) {
+            EGLHelper *eglHelper = EGLHelper::instance();
+            auto *eglFun = eglHelper->functions();
+
+            const int dmaBufFd = HANDLE_EINTR(dup(nativePixmap->GetDmaBufFd(0)));
+            if (dmaBufFd < 0) {
+                qFatal("Could not import the dma-buf as an EGLImage because the FD couldn't be "
+                       "dup()ed.");
+            }
+            base::ScopedFD scopedFd(dmaBufFd);
+
+            int drmFormat = ui::GetFourCCFormatFromBufferFormat(nativePixmap->GetBufferFormat());
+            uint64_t modifier = nativePixmap->GetBufferFormatModifier();
+
+            // clang-format off
+            EGLAttrib const attributeList[] = {
+                EGL_WIDTH, size().width(),
+                EGL_HEIGHT, size().height(),
+                EGL_LINUX_DRM_FOURCC_EXT, drmFormat,
+                EGL_DMA_BUF_PLANE0_FD_EXT, scopedFd.get(),
+                EGL_DMA_BUF_PLANE0_OFFSET_EXT, nativePixmap->GetDmaBufOffset(0),
+                EGL_DMA_BUF_PLANE0_PITCH_EXT, nativePixmap->GetDmaBufPitch(0),
+                EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, modifier & 0xffffffff,
+                EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, modifier >> 32,
+                EGL_NONE
+            };
+            // clang-format on
+            EGLImage eglImage = eglFun->eglCreateImage(GLContextHelper::getEGLDisplay(),
+                                                       EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT,
+                                                       (EGLClientBuffer)NULL, attributeList);
+            Q_ASSERT(eglImage != EGL_NO_IMAGE_KHR);
+
+            static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC imageTargetTexture =
+                    (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)glContext->getProcAddress(
+                            "glEGLImageTargetTexture2DOES");
+
+            glFun->glGenTextures(1, &glTexture);
+            glFun->glBindTexture(GL_TEXTURE_2D, glTexture);
+            imageTargetTexture(GL_TEXTURE_2D, eglImage);
+            glFun->glBindTexture(GL_TEXTURE_2D, 0);
+
+            m_frontBuffer->textureCleanupCallback = [glFun, eglFun, glTexture, eglImage]() {
+                glFun->glDeleteTextures(1, &glTexture);
+                eglFun->eglDestroyImage(GLContextHelper::getEGLDisplay(), eglImage);
+            };
+        }
+    } else {
+        // TODO: Import texture into Qt's context.
+        qWarning("ANGLE is not yet supported without NativePixmap.");
+        glTexture = glTextureInfo.fID;
+    }
+
+    texture = QNativeInterface::QSGOpenGLTexture::fromNative(glTexture, win, size(), texOpts);
 #elif defined(Q_OS_WIN)
     // TODO: Add WGL support over ANGLE.
     QT_NOT_YET_IMPLEMENTED
diff --git a/src/core/ozone/gl_ozone_angle_qt.cpp b/src/core/ozone/gl_ozone_angle_qt.cpp
new file mode 100644
index 00000000000..66692ed09a6
--- /dev/null
+++ b/src/core/ozone/gl_ozone_angle_qt.cpp
@@ -0,0 +1,119 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#if defined(USE_OZONE)
+#include "gl_context_qt.h"
+#include "gl_ozone_angle_qt.h"
+#include "gl_surface_egl_qt.h"
+
+#include "ui/base/ozone_buildflags.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_display.h"
+#include "ui/gl/gl_surface.h"
+#include "ui/gl/gl_utils.h"
+#include "ui/ozone/common/native_pixmap_egl_binding.h"
+
+#if BUILDFLAG(IS_OZONE_X11)
+#include "ui/gl/gl_glx_api_implementation.h"
+#endif
+
+extern "C" {
+typedef void (*__eglMustCastToProperFunctionPointerType)(void);
+extern __eglMustCastToProperFunctionPointerType EGL_GetProcAddress(const char *procname);
+}
+
+namespace ui {
+
+bool GLOzoneANGLEQt::LoadGLES2Bindings(const gl::GLImplementationParts & /*implementation*/)
+{
+    gl::SetGLGetProcAddressProc(&EGL_GetProcAddress);
+    return true;
+}
+
+bool GLOzoneANGLEQt::InitializeStaticGLBindings(const gl::GLImplementationParts &implementation)
+{
+    bool res = GLOzoneEGL::InitializeStaticGLBindings(implementation);
+
+#if BUILDFLAG(IS_OZONE_X11)
+    if (GLContextHelper::getGlxPlatformInterface()) {
+        gl::SetGLGetProcAddressProc(reinterpret_cast<gl::GLGetProcAddressProc>(
+                GLContextHelper::getGlXGetProcAddress()));
+        gl::InitializeStaticGLBindingsGLX();
+        gl::SetGLGetProcAddressProc(&EGL_GetProcAddress);
+    }
+#endif
+
+    return res;
+}
+
+bool GLOzoneANGLEQt::InitializeExtensionSettingsOneOffPlatform(gl::GLDisplay *display)
+{
+    bool res = GLOzoneEGL::InitializeExtensionSettingsOneOffPlatform(
+            static_cast<gl::GLDisplayEGL *>(display));
+
+#if BUILDFLAG(IS_OZONE_X11)
+    if (GLContextHelper::getGlxPlatformInterface()) {
+        gl::SetGLGetProcAddressProc(reinterpret_cast<gl::GLGetProcAddressProc>(
+                GLContextHelper::getGlXGetProcAddress()));
+        std::string extensions =
+                glXQueryExtensionsString((struct _XDisplay *)GLContextHelper::getXDisplay(), 0);
+        gl::g_driver_glx.InitializeExtensionBindings(extensions.c_str());
+        gl::SetGLGetProcAddressProc(&EGL_GetProcAddress);
+    }
+#endif
+
+    return res;
+}
+
+scoped_refptr<gl::GLSurface> GLOzoneANGLEQt::CreateViewGLSurface(gl::GLDisplay *display,
+                                                                 gfx::AcceleratedWidget window)
+{
+    Q_UNUSED(display);
+    Q_UNUSED(window);
+    return nullptr;
+}
+
+// based on GLOzoneEGLX11::CreateOffscreenGLSurface() (x11_surface_factory.cc)
+scoped_refptr<gl::GLSurface> GLOzoneANGLEQt::CreateOffscreenGLSurface(gl::GLDisplay *display,
+                                                                      const gfx::Size &size)
+{
+    gl::GLDisplayEGL *eglDisplay = display->GetAs<gl::GLDisplayEGL>();
+
+    if (eglDisplay->IsEGLSurfacelessContextSupported() && size.width() == 0 && size.height() == 0)
+        return InitializeGLSurface(new gl::SurfacelessEGL(eglDisplay, size));
+
+    return InitializeGLSurface(new gl::PbufferGLSurfaceEGL(eglDisplay, size));
+}
+
+gl::EGLDisplayPlatform GLOzoneANGLEQt::GetNativeDisplay()
+{
+#if BUILDFLAG(IS_OZONE_X11)
+    void *xdisplay = GLContextHelper::getXDisplay();
+    if (xdisplay)
+        return gl::EGLDisplayPlatform(reinterpret_cast<EGLNativeDisplayType>(xdisplay));
+#endif
+
+    if (gl::g_driver_egl.client_ext.b_EGL_MESA_platform_surfaceless)
+        return gl::EGLDisplayPlatform(EGL_DEFAULT_DISPLAY, EGL_PLATFORM_SURFACELESS_MESA);
+
+    return gl::EGLDisplayPlatform(EGL_DEFAULT_DISPLAY);
+}
+
+bool GLOzoneANGLEQt::CanImportNativePixmap()
+{
+    return gl::GLSurfaceEGL::GetGLDisplayEGL()->ext->b_EGL_EXT_image_dma_buf_import;
+}
+
+std::unique_ptr<NativePixmapGLBinding>
+GLOzoneANGLEQt::ImportNativePixmap(scoped_refptr<gfx::NativePixmap> pixmap,
+                                   gfx::BufferFormat plane_format, gfx::BufferPlane plane,
+                                   gfx::Size plane_size, const gfx::ColorSpace &color_space,
+                                   GLenum target, GLuint texture_id)
+{
+    return NativePixmapEGLBinding::Create(pixmap, plane_format, plane, plane_size, color_space,
+                                          target, texture_id);
+}
+
+} // namespace ui
+
+#endif // defined(USE_OZONE)
diff --git a/src/core/ozone/gl_ozone_angle_qt.h b/src/core/ozone/gl_ozone_angle_qt.h
new file mode 100644
index 00000000000..bba276fc09b
--- /dev/null
+++ b/src/core/ozone/gl_ozone_angle_qt.h
@@ -0,0 +1,41 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef GL_OZONE_ANGLE_QT_H
+#define GL_OZONE_ANGLE_QT_H
+
+#if defined(USE_OZONE)
+#include "ui/ozone/common/gl_ozone_egl.h"
+
+namespace ui {
+
+class GLOzoneANGLEQt : public GLOzoneEGL
+{
+public:
+    bool InitializeStaticGLBindings(const gl::GLImplementationParts &implementation) override;
+    bool InitializeExtensionSettingsOneOffPlatform(gl::GLDisplay *display) override;
+    scoped_refptr<gl::GLSurface> CreateViewGLSurface(gl::GLDisplay *display,
+                                                     gfx::AcceleratedWidget window) override;
+    scoped_refptr<gl::GLSurface> CreateOffscreenGLSurface(gl::GLDisplay *display,
+                                                          const gfx::Size &size) override;
+    bool CanImportNativePixmap() override;
+    std::unique_ptr<NativePixmapGLBinding>
+    ImportNativePixmap(scoped_refptr<gfx::NativePixmap> pixmap, gfx::BufferFormat plane_format,
+                       gfx::BufferPlane plane, gfx::Size plane_size,
+                       const gfx::ColorSpace &color_space, GLenum target,
+                       GLuint texture_id) override;
+
+protected:
+    // Returns native platform display handle. This is used to obtain the EGL
+    // display connection for the native display.
+    gl::EGLDisplayPlatform GetNativeDisplay() override;
+
+    // Sets up GL bindings for the native surface.
+    bool LoadGLES2Bindings(const gl::GLImplementationParts &implementation) override;
+};
+
+} // namespace ui
+
+#endif // defined(USE_OZONE)
+
+#endif // GL_OZONE_ANGLE_QT_H
diff --git a/src/core/ozone/surface_factory_qt.cpp b/src/core/ozone/surface_factory_qt.cpp
index 1bfa49c6006..726c2c0465f 100644
--- a/src/core/ozone/surface_factory_qt.cpp
+++ b/src/core/ozone/surface_factory_qt.cpp
@@ -6,7 +6,9 @@
 
 #include "qtwebenginecoreglobal_p.h"
 #include "ozone/gl_context_qt.h"
+#include "ozone/gl_ozone_angle_qt.h"
 #include "ozone/gl_ozone_egl_qt.h"
+#include "qtwebenginecoreglobal_p.h"
 
 #include "media/gpu/buildflags.h"
 #include "ui/base/ozone_buildflags.h"
@@ -34,30 +36,42 @@ SurfaceFactoryQt::SurfaceFactoryQt()
 {
 #if BUILDFLAG(IS_OZONE_X11)
     if (GLContextHelper::getGlxPlatformInterface()) {
-        m_impl = { gl::GLImplementationParts(gl::kGLImplementationDesktopGL),
-                   gl::GLImplementationParts(gl::kGLImplementationDisabled) };
-        m_ozone.reset(new ui::GLOzoneGLXQt());
+        m_impls.push_back({ gl::GLImplementationParts(gl::kGLImplementationDesktopGL),
+                            std::make_unique<ui::GLOzoneGLXQt>() });
     } else
 #endif
     if (GLContextHelper::getEglPlatformInterface()) {
-        m_impl = { gl::GLImplementationParts(gl::kGLImplementationEGLGLES2),
-                   gl::GLImplementationParts(gl::kGLImplementationDesktopGL),
-                   gl::GLImplementationParts(gl::kGLImplementationDisabled) };
-        m_ozone.reset(new ui::GLOzoneEGLQt());
-    } else {
-        m_impl = { gl::GLImplementationParts(gl::kGLImplementationDisabled) };
+        m_impls.push_back({ gl::GLImplementationParts(gl::kGLImplementationEGLGLES2),
+                            std::make_unique<ui::GLOzoneEGLQt>() });
+        m_impls.push_back({ gl::GLImplementationParts(gl::kGLImplementationDesktopGL),
+                            std::make_unique<ui::GLOzoneEGLQt>() });
     }
+
+    m_impls.push_back({ gl::GLImplementationParts(gl::kGLImplementationEGLANGLE),
+                        std::make_unique<ui::GLOzoneANGLEQt>() });
+    m_impls.push_back({ gl::GLImplementationParts(gl::kGLImplementationDisabled), nullptr });
 }
 
 std::vector<gl::GLImplementationParts> SurfaceFactoryQt::GetAllowedGLImplementations()
 {
-    return m_impl;
+    std::vector<gl::GLImplementationParts> allowed;
+    for (const auto &impl : m_impls)
+        allowed.push_back(impl.first);
+
+    return allowed;
 }
 
 ui::GLOzone *SurfaceFactoryQt::GetGLOzone(const gl::GLImplementationParts &implementation)
 {
-    return m_ozone.get();
+    for (const auto &impl : m_impls) {
+        if (impl.first.gl == implementation.gl)
+            return impl.second.get();
+    }
+
+    qFatal() << "GLOzone not found for" << gl::GetGLImplementationGLName(implementation);
+    return nullptr;
 }
+
 #if BUILDFLAG(ENABLE_VULKAN)
 std::unique_ptr<gpu::VulkanImplementation>
 SurfaceFactoryQt::CreateVulkanImplementation(bool /*allow_protected_memory*/,
diff --git a/src/core/ozone/surface_factory_qt.h b/src/core/ozone/surface_factory_qt.h
index d69467a26ab..557bda09148 100644
--- a/src/core/ozone/surface_factory_qt.h
+++ b/src/core/ozone/surface_factory_qt.h
@@ -43,8 +43,7 @@ class SurfaceFactoryQt : public ui::SurfaceFactoryOzone
     static bool SupportsNativePixmaps();
 
 private:
-    std::vector<gl::GLImplementationParts> m_impl;
-    std::unique_ptr<ui::GLOzone> m_ozone;
+    std::vector<std::pair<gl::GLImplementationParts, std::unique_ptr<ui::GLOzone>>> m_impls;
 };
 
 } // namespace QtWebEngineCore

From 048c5bee84a38e50c5731077ca4350052a0ca79b Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Tue, 16 Apr 2024 12:58:20 +0200
Subject: [PATCH 069/356] Disable ANGLE without NativePixmap support

Fallback to Vulkan rendering instead.

This is a workaround for rendering with Nvidia when ANGLE is enabled in
Chromium and Qt RHI is backed by OpenGL.

Task-number: QTBUG-112281
Change-Id: I0ab8915875d7f8781aa267a30b584c7c4c751819
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 8ce04357b4ce39b8c4c2243991eae70f78f9b61b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/compositor/display_overrides.cpp     |   8 +-
 .../native_skia_output_device_opengl.cpp      | 104 ++++++++++++++++--
 src/core/web_engine_context.cpp               |  20 ++++
 3 files changed, 118 insertions(+), 14 deletions(-)

diff --git a/src/core/compositor/display_overrides.cpp b/src/core/compositor/display_overrides.cpp
index ebaa96dbb56..feb3dafa148 100644
--- a/src/core/compositor/display_overrides.cpp
+++ b/src/core/compositor/display_overrides.cpp
@@ -43,9 +43,11 @@ viz::SkiaOutputSurfaceImplOnGpu::CreateOutputDevice()
     if (graphicsApi == QSGRendererInterface::OpenGL) {
         if (gl::GetGLImplementation() != gl::kGLImplementationEGLANGLE) {
 #if !defined(Q_OS_MACOS)
-            return std::make_unique<QtWebEngineCore::DisplaySkiaOutputDevice>(
-                    context_state_, renderer_settings_.requires_alpha_channel,
-                    shared_gpu_deps_->memory_tracker(), GetDidSwapBuffersCompleteCallback());
+            if (context_state_->gr_context_type() == gpu::GrContextType::kGL) {
+                return std::make_unique<QtWebEngineCore::DisplaySkiaOutputDevice>(
+                        context_state_, renderer_settings_.requires_alpha_channel,
+                        shared_gpu_deps_->memory_tracker(), GetDidSwapBuffersCompleteCallback());
+            }
 #else
             qFatal("macOS only supports ANGLE.");
 #endif // !defined(Q_OS_MACOS)
diff --git a/src/core/compositor/native_skia_output_device_opengl.cpp b/src/core/compositor/native_skia_output_device_opengl.cpp
index c8430f0f7d6..07c68ffff65 100644
--- a/src/core/compositor/native_skia_output_device_opengl.cpp
+++ b/src/core/compositor/native_skia_output_device_opengl.cpp
@@ -30,10 +30,29 @@
 
 #include "ui/gl/gl_bindings.h"
 #undef glBindTexture
+#undef glCreateMemoryObjectsEXT
+#undef glDeleteMemoryObjectsEXT
 #undef glDeleteTextures
 #undef glGenTextures
+#undef glGetError
+#undef glImportMemoryFdEXT
+#undef glTextureStorageMem2DEXT
 #endif // BUILDFLAG(IS_OZONE_X11)
 
+#if BUILDFLAG(ENABLE_VULKAN)
+#if BUILDFLAG(IS_OZONE_X11)
+// We need to define USE_VULKAN_XCB for proper vulkan function pointers.
+// Avoiding it may lead to call wrong vulkan functions.
+// This is originally defined in chromium/gpu/vulkan/BUILD.gn.
+#define USE_VULKAN_XCB
+#endif // BUILDFLAG(IS_OZONE_X11)
+#include "components/viz/common/gpu/vulkan_context_provider.h"
+#include "gpu/vulkan/vulkan_device_queue.h"
+#include "gpu/vulkan/vulkan_function_pointers.h"
+#include "third_party/skia/include/gpu/vk/GrVkTypes.h"
+#include "third_party/skia/include/gpu/ganesh/vk/GrVkBackendSurface.h"
+#endif // BUILDFLAG(ENABLE_VULKAN)
+
 // Keep it at the end.
 #include "ozone/gl_context_qt.h"
 #endif // defined(USE_OZONE)
@@ -125,8 +144,10 @@ NativeSkiaOutputDeviceOpenGL::NativeSkiaOutputDeviceOpenGL(
 {
     SkColorType skColorType = kRGBA_8888_SkColorType;
 #if BUILDFLAG(IS_OZONE_X11)
-    if (GLContextHelper::getGlxPlatformInterface())
+    if (GLContextHelper::getGlxPlatformInterface()
+        && m_contextState->gr_context_type() == gpu::GrContextType::kGL) {
         skColorType = kBGRA_8888_SkColorType;
+    }
 #endif // BUILDFLAG(IS_OZONE_X11)
 
     capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBA_8888)] = skColorType;
@@ -147,10 +168,9 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
         return nullptr;
 
 #if defined(USE_OZONE)
-    Q_ASSERT(m_contextState->gr_context_type() == gpu::GrContextType::kGL);
-
-    GrGLTextureInfo glTextureInfo;
     scoped_refptr<gfx::NativePixmap> nativePixmap = m_frontBuffer->nativePixmap();
+#if BUILDFLAG(ENABLE_VULKAN)
+    GrVkImageInfo vkImageInfo;
     if (!nativePixmap) {
         if (m_isNativeBufferSupported) {
             qWarning("No native pixmap.");
@@ -175,16 +195,23 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
             return nullptr;
         }
 
-        if (backendTexture.backend() != GrBackendApi::kOpenGL) {
-            qWarning("Backend texture is not a OpenGL texture.");
+        if (backendTexture.backend() != GrBackendApi::kVulkan) {
+            qWarning("Backend texture is not a Vulkan texture.");
             return nullptr;
         }
 
-        if (!GrBackendTextures::GetGLTextureInfo(backendTexture, &glTextureInfo)) {
-            qWarning("Unable to access OpenGL texture.");
+        GrBackendTextures::GetVkImageInfo(backendTexture, &vkImageInfo);
+        if (vkImageInfo.fAlloc.fMemory == VK_NULL_HANDLE) {
+            qWarning("Unable to access Vulkan memory.");
             return nullptr;
         }
     }
+#else
+    if (!nativePixmap) {
+        qWarning("No native pixmap.");
+        return nullptr;
+    }
+#endif // BUILDFLAG(ENABLE_VULKAN)
 #elif defined(Q_OS_WIN)
     auto overlayImage = m_frontBuffer->overlayImage();
     if (!overlayImage) {
@@ -208,6 +235,8 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
     GLuint glTexture = 0;
 
     if (nativePixmap) {
+        Q_ASSERT(m_contextState->gr_context_type() == gpu::GrContextType::kGL);
+
 #if BUILDFLAG(IS_OZONE_X11)
         if (GLContextHelper::getGlxPlatformInterface()) {
             x11::Pixmap pixmapId =
@@ -286,12 +315,65 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
             };
         }
     } else {
-        // TODO: Import texture into Qt's context.
-        qWarning("ANGLE is not yet supported without NativePixmap.");
-        glTexture = glTextureInfo.fID;
+#if BUILDFLAG(ENABLE_VULKAN)
+        Q_ASSERT(m_contextState->gr_context_type() == gpu::GrContextType::kVulkan);
+
+        gpu::VulkanFunctionPointers *vfp = gpu::GetVulkanFunctionPointers();
+        gpu::VulkanDeviceQueue *vulkanDeviceQueue =
+                m_contextState->vk_context_provider()->GetDeviceQueue();
+        VkDevice vulkanDevice = vulkanDeviceQueue->GetVulkanDevice();
+
+        VkDeviceMemory importedImageMemory = vkImageInfo.fAlloc.fMemory;
+        VkDeviceSize importedImageSize = vkImageInfo.fAlloc.fSize;
+
+        VkMemoryGetFdInfoKHR exportInfo = { VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR };
+        exportInfo.pNext = nullptr;
+        exportInfo.memory = importedImageMemory;
+        exportInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
+
+        int fd = -1;
+        if (vfp->vkGetMemoryFdKHR(vulkanDevice, &exportInfo, &fd) != VK_SUCCESS)
+            qFatal("VULKAN: Unable to extract file descriptor out of external VkImage.");
+
+        static PFNGLCREATEMEMORYOBJECTSEXTPROC glCreateMemoryObjectsEXT =
+                (PFNGLCREATEMEMORYOBJECTSEXTPROC)glContext->getProcAddress(
+                        "glCreateMemoryObjectsEXT");
+        static PFNGLIMPORTMEMORYFDEXTPROC glImportMemoryFdEXT =
+                (PFNGLIMPORTMEMORYFDEXTPROC)glContext->getProcAddress("glImportMemoryFdEXT");
+        static PFNGLTEXTURESTORAGEMEM2DEXTPROC glTextureStorageMem2DEXT =
+                (PFNGLTEXTURESTORAGEMEM2DEXTPROC)glContext->getProcAddress(
+                        "glTextureStorageMem2DEXT");
+
+        GLuint glMemoryObject;
+        glFun->glGenTextures(1, &glTexture);
+        glFun->glBindTexture(GL_TEXTURE_2D, glTexture);
+        glCreateMemoryObjectsEXT(1, &glMemoryObject);
+        glImportMemoryFdEXT(glMemoryObject, importedImageSize, GL_HANDLE_TYPE_OPAQUE_FD_EXT, fd);
+        glTextureStorageMem2DEXT(glTexture, 1, GL_RGBA8_OES, size().width(), size().height(),
+                                 glMemoryObject, 0);
+        glFun->glBindTexture(GL_TEXTURE_2D, 0);
+
+        m_frontBuffer->textureCleanupCallback = [glTexture, glMemoryObject]() {
+            QOpenGLContext *glContext = QOpenGLContext::currentContext();
+            if (!glContext)
+                return;
+            auto glFun = glContext->functions();
+            Q_ASSERT(glFun->glGetError() == GL_NO_ERROR);
+
+            static PFNGLDELETEMEMORYOBJECTSEXTPROC glDeleteMemoryObjectsEXT =
+                    (PFNGLDELETEMEMORYOBJECTSEXTPROC)glContext->getProcAddress(
+                            "glDeleteMemoryObjectsEXT");
+
+            glDeleteMemoryObjectsEXT(1, &glMemoryObject);
+            glFun->glDeleteTextures(1, &glTexture);
+        };
+#else
+        Q_UNREACHABLE();
+#endif // BUILDFLAG(ENABLE_VULKAN)
     }
 
     texture = QNativeInterface::QSGOpenGLTexture::fromNative(glTexture, win, size(), texOpts);
+    Q_ASSERT(glFun->glGetError() == GL_NO_ERROR);
 #elif defined(Q_OS_WIN)
     // TODO: Add WGL support over ANGLE.
     QT_NOT_YET_IMPLEMENTED
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index d1504a6851c..5c06a0879ed 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -962,6 +962,26 @@ WebEngineContext::WebEngineContext()
     }
 
 #if QT_CONFIG(webengine_vulkan)
+    if (QQuickWindow::graphicsApi() == QSGRendererInterface::OpenGL) {
+        // FIXME: We assume that ANGLE is explicitly enabled on Linux.
+        //        Make sure to reimplement fallback if ANGLE becomes the default.
+        bool usingANGLE = false;
+        if (parsedCommandLine->HasSwitch(switches::kUseGL))
+            usingANGLE = (parsedCommandLine->GetSwitchValueASCII(switches::kUseGL)
+                          == gl::kGLImplementationANGLEName);
+        if (usingANGLE && GPUInfo::instance()->vendor() == GPUInfo::Nvidia) {
+            qWarning("Disable ANGLE because GBM is not supported with the current configuration. "
+                     "Fallback to Vulkan rendering in Chromium.");
+            parsedCommandLine->RemoveSwitch(switches::kUseANGLE);
+            parsedCommandLine->RemoveSwitch(switches::kUseGL);
+            parsedCommandLine->AppendSwitchASCII(switches::kUseGL,
+                                                 gl::kGLImplementationDesktopName);
+            parsedCommandLine->AppendSwitchASCII(switches::kUseVulkan,
+                                                 switches::kVulkanImplementationNameNative);
+            enableFeatures.push_back(features::kVulkan.name);
+        }
+    }
+
     if (QQuickWindow::graphicsApi() == QSGRendererInterface::Vulkan) {
         enableFeatures.push_back(features::kVulkan.name);
         parsedCommandLine->AppendSwitchASCII(switches::kUseVulkan,

From 28feb6efd7a803c76bb58e46e83527354ef0d3b5 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Thu, 11 Jul 2024 10:59:20 +0200
Subject: [PATCH 070/356] Add line breaks to public header files

Adding deprecation warnings resulted in lines deemed too long. This
change wraps those lines. Found in API review.

Change-Id: I3e1f8647c046e2a6042cc8201424b803d4f95d23
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit e7f17dc5a7e43b481e1e78d9f1f76409bedc0d77)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebenginepage.h                 | 48 ++++++++++++-------
 .../api/qquickwebengineview_p.h               |  6 ++-
 2 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/src/core/api/qwebenginepage.h b/src/core/api/qwebenginepage.h
index 8b36826725c..ada0af9dab9 100644
--- a/src/core/api/qwebenginepage.h
+++ b/src/core/api/qwebenginepage.h
@@ -151,9 +151,12 @@ class Q_WEBENGINECORE_EXPORT QWebEnginePage : public QObject
 
 #if QT_DEPRECATED_SINCE(6, 8)
     enum PermissionPolicy {
-        PermissionUnknown Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::State::Ask instead"),
-        PermissionGrantedByUser Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::State::Granted instead"),
-        PermissionDeniedByUser Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::State::Denied instead")
+        PermissionUnknown Q_DECL_ENUMERATOR_DEPRECATED_X(
+            "Use QWebEnginePermission::State::Ask instead"),
+        PermissionGrantedByUser Q_DECL_ENUMERATOR_DEPRECATED_X(
+            "Use QWebEnginePermission::State::Granted instead"),
+        PermissionDeniedByUser Q_DECL_ENUMERATOR_DEPRECATED_X(
+            "Use QWebEnginePermission::State::Denied instead")
     };
     Q_ENUM(PermissionPolicy)
 #endif
@@ -172,16 +175,26 @@ class Q_WEBENGINECORE_EXPORT QWebEnginePage : public QObject
 
 #if QT_DEPRECATED_SINCE(6, 8)
     enum Feature {
-        Notifications Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::Notifications instead") = 0,
-        Geolocation Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::Geolocation instead") = 1,
-        MediaAudioCapture Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::MediaAudioCapture instead") = 2,
-        MediaVideoCapture Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::MediaVideoCapture instead"),
-        MediaAudioVideoCapture Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::MediaAudioVideoCapture instead"),
-        MouseLock Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::MouseLock instead"),
-        DesktopVideoCapture Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::DesktopVideoCapture instead"),
-        DesktopAudioVideoCapture Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::DesktopAudioVideoCapture instead"),
-        ClipboardReadWrite Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::ClipboardReadWrite instead"),
-        LocalFontsAccess Q_DECL_ENUMERATOR_DEPRECATED_X("Use QWebEnginePermission::PermissionType::LocalFontsAccess instead"),
+        Notifications Q_DECL_ENUMERATOR_DEPRECATED_X(
+            "Use QWebEnginePermission::PermissionType::Notifications instead") = 0,
+        Geolocation Q_DECL_ENUMERATOR_DEPRECATED_X(
+            "Use QWebEnginePermission::PermissionType::Geolocation instead") = 1,
+        MediaAudioCapture Q_DECL_ENUMERATOR_DEPRECATED_X(
+            "Use QWebEnginePermission::PermissionType::MediaAudioCapture instead") = 2,
+        MediaVideoCapture Q_DECL_ENUMERATOR_DEPRECATED_X(
+            "Use QWebEnginePermission::PermissionType::MediaVideoCapture instead"),
+        MediaAudioVideoCapture Q_DECL_ENUMERATOR_DEPRECATED_X(
+            "Use QWebEnginePermission::PermissionType::MediaAudioVideoCapture instead"),
+        MouseLock Q_DECL_ENUMERATOR_DEPRECATED_X(
+            "Use QWebEnginePermission::PermissionType::MouseLock instead"),
+        DesktopVideoCapture Q_DECL_ENUMERATOR_DEPRECATED_X(
+            "Use QWebEnginePermission::PermissionType::DesktopVideoCapture instead"),
+        DesktopAudioVideoCapture Q_DECL_ENUMERATOR_DEPRECATED_X(
+            "Use QWebEnginePermission::PermissionType::DesktopAudioVideoCapture instead"),
+        ClipboardReadWrite Q_DECL_ENUMERATOR_DEPRECATED_X(
+            "Use QWebEnginePermission::PermissionType::ClipboardReadWrite instead"),
+        LocalFontsAccess Q_DECL_ENUMERATOR_DEPRECATED_X(
+            "Use QWebEnginePermission::PermissionType::LocalFontsAccess instead"),
     };
     Q_ENUM(Feature)
 #endif
@@ -243,7 +256,8 @@ class Q_WEBENGINECORE_EXPORT QWebEnginePage : public QObject
     void findText(const QString &subString, FindFlags options = {}, const std::function<void(const QWebEngineFindTextResult &)> &resultCallback = std::function<void(const QWebEngineFindTextResult &)>());
 
 #if QT_DEPRECATED_SINCE(6, 8)
-    QT_DEPRECATED_VERSION_X_6_8("Setting permissions through QWebEnginePage has been deprecated. Please use QWebEnginePermission instead.")
+    QT_DEPRECATED_VERSION_X_6_8(
+        "Setting permissions through QWebEnginePage has been deprecated. Please use QWebEnginePermission instead.")
     void setFeaturePermission(const QUrl &securityOrigin, Feature feature, PermissionPolicy policy);
 #endif
 
@@ -329,9 +343,11 @@ class Q_WEBENGINECORE_EXPORT QWebEnginePage : public QObject
     void windowCloseRequested();
 
 #if QT_DEPRECATED_SINCE(6, 8)
-    QT_MOC_COMPAT QT_DEPRECATED_VERSION_X_6_8("The signal has been deprecated; please use permissionRequested instead.")
+    QT_MOC_COMPAT QT_DEPRECATED_VERSION_X_6_8(
+        "The signal has been deprecated; please use permissionRequested instead.")
     void featurePermissionRequested(const QUrl &securityOrigin, QWebEnginePage::Feature feature);
-    QT_MOC_COMPAT QT_DEPRECATED_VERSION_X_6_8("The signal has been deprecated, and no longer functions.")
+    QT_MOC_COMPAT QT_DEPRECATED_VERSION_X_6_8(
+        "The signal has been deprecated, and no longer functions.")
     void featurePermissionRequestCanceled(const QUrl &securityOrigin, QWebEnginePage::Feature feature);
 #endif // QT_DEPRECATED_SINCE(6, 8)
 
diff --git a/src/webenginequick/api/qquickwebengineview_p.h b/src/webenginequick/api/qquickwebengineview_p.h
index 53f81f776ea..95635d19c9b 100644
--- a/src/webenginequick/api/qquickwebengineview_p.h
+++ b/src/webenginequick/api/qquickwebengineview_p.h
@@ -492,7 +492,8 @@ public Q_SLOTS:
     Q_REVISION(1,1) void findText(const QString &subString, FindFlags options = { }, const QJSValue &callback = QJSValue());
     Q_REVISION(1,1) void fullScreenCancelled();
 #if QT_DEPRECATED_SINCE(6, 8)
-    QT_MOC_COMPAT QT_DEPRECATED_VERSION_X_6_8("Setting permissions through WebEngineView has been deprecated. Please use WebEnginePermission instead.")
+    QT_MOC_COMPAT QT_DEPRECATED_VERSION_X_6_8(
+        "Setting permissions through WebEngineView has been deprecated. Please use WebEnginePermission instead.")
     Q_REVISION(1,1) void grantFeaturePermission(const QUrl &securityOrigin, QQuickWebEngineView::Feature, bool granted);
 #endif // QT_DEPRECATED_SINCE(6, 8)
     Q_REVISION(1,2) void setActiveFocusOnPress(bool arg);
@@ -521,7 +522,8 @@ private Q_SLOTS:
     Q_REVISION(1,1) void fullScreenRequested(const QWebEngineFullScreenRequest &request);
     Q_REVISION(1,1) void isFullScreenChanged();
 #if QT_DEPRECATED_SINCE(6, 8)
-    QT_MOC_COMPAT QT_DEPRECATED_VERSION_X_6_8("The signal has been deprecated; please use permissionRequested instead.")
+    QT_MOC_COMPAT QT_DEPRECATED_VERSION_X_6_8(
+        "The signal has been deprecated; please use permissionRequested instead.")
     Q_REVISION(1, 1)
     void featurePermissionRequested(const QUrl &securityOrigin,
                                     QQuickWebEngineView::Feature feature);

From 64732c2327d19213edfaaf0be90e28673ea6b00b Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Thu, 11 Jul 2024 13:45:56 +0200
Subject: [PATCH 071/356] QWebEnginePermission: Add move constructor and
 nullptr checks

A move assignment existed for the class, but not a move constructor.
Since both of those can leave a QWebEnginePermission object in
a state where the d_ptr is null, this change also adds checks to
ensure using a moved-from object won't crash the application.
Found in API review.

Change-Id: I977927c18094d06ea63840bb80c88b50c4b19b73
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Reviewed-by: Moss Heim <moss.heim@qt.io>
(cherry picked from commit 2a84d23c69b0db9a8b050f8e6667972ce337c611)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebenginepermission.cpp | 14 ++++++++++++--
 src/core/api/qwebenginepermission.h   |  1 +
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/src/core/api/qwebenginepermission.cpp b/src/core/api/qwebenginepermission.cpp
index 9cef4bf9684..0cee6506b8a 100644
--- a/src/core/api/qwebenginepermission.cpp
+++ b/src/core/api/qwebenginepermission.cpp
@@ -93,6 +93,11 @@ QWebEnginePermission::QWebEnginePermission(const QWebEnginePermission &other)
 {
 }
 
+QWebEnginePermission::QWebEnginePermission(QWebEnginePermission &&other)
+    : d_ptr(std::move(other.d_ptr))
+{
+}
+
 QWebEnginePermission::~QWebEnginePermission() = default;
 
 QWebEnginePermission &QWebEnginePermission::operator=(const QWebEnginePermission &other)
@@ -109,6 +114,9 @@ bool QWebEnginePermission::equals(const QWebEnginePermission &other) const
     if (this == &other)
         return true;
 
+    if (!d_ptr || !other.d_ptr)
+        return false;
+
     if (d_ptr->permissionType != other.d_ptr->permissionType || d_ptr->origin != other.d_ptr->origin)
         return false;
 
@@ -140,7 +148,7 @@ bool QWebEnginePermission::equals(const QWebEnginePermission &other) const
 */
 QUrl QWebEnginePermission::origin() const
 {
-    return d_ptr->origin;
+    return d_ptr ? d_ptr->origin : QUrl();
 }
 
 /*!
@@ -171,7 +179,7 @@ QUrl QWebEnginePermission::origin() const
 */
 QWebEnginePermission::PermissionType QWebEnginePermission::permissionType() const
 {
-    return d_ptr->permissionType;
+    return d_ptr ? d_ptr->permissionType : PermissionType::Unsupported;
 }
 
 /*!
@@ -225,6 +233,8 @@ QWebEnginePermission::State QWebEnginePermission::state() const
 */
 bool QWebEnginePermission::isValid() const
 {
+    if (!d_ptr)
+        return false;
     if (permissionType() == PermissionType::Unsupported)
         return false;
     if (!isPersistent(permissionType()) && !d_ptr->webContentsAdapter)
diff --git a/src/core/api/qwebenginepermission.h b/src/core/api/qwebenginepermission.h
index a6a767aeb9f..bb74e6a2052 100644
--- a/src/core/api/qwebenginepermission.h
+++ b/src/core/api/qwebenginepermission.h
@@ -37,6 +37,7 @@ class QWebEnginePermission
     Q_WEBENGINECORE_EXPORT QWebEnginePermission();
 
     Q_WEBENGINECORE_EXPORT QWebEnginePermission(const QWebEnginePermission &other);
+    Q_WEBENGINECORE_EXPORT QWebEnginePermission(QWebEnginePermission &&other);
     Q_WEBENGINECORE_EXPORT ~QWebEnginePermission();
 
     Q_WEBENGINECORE_EXPORT QWebEnginePermission &operator=(const QWebEnginePermission &other);

From 2f1add47bbad80a404a7488f0646b17b31a56b20 Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Wed, 20 Mar 2024 13:05:29 +0100
Subject: [PATCH 072/356] Fix typos in comments & docs

POINTER instead of ACTION in enum value names

Correct type and name for WebEngineScript::runsOnSubFrames

Correct return type for WebEngineScriptCollection::contains

\sa notes in docs: insert and remove should point to each other,
as should find and contains. This is closer to documentation for
QList, QMap, etc.

Change-Id: I1ac31fb53bd3fa53463f37e1bb4b6ef3b8fba65b
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 2f5e631d2870208f054b613cac0cba761903f833)
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
---
 src/core/render_widget_host_view_qt_delegate_client.cpp   | 4 ++--
 .../api/qquickwebenginescriptcollection.cpp               | 8 ++++----
 src/webenginequick/doc/src/webenginescript.qdoc           | 2 +-
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/core/render_widget_host_view_qt_delegate_client.cpp b/src/core/render_widget_host_view_qt_delegate_client.cpp
index 02ad9b039e0..ad4da26fcb7 100644
--- a/src/core/render_widget_host_view_qt_delegate_client.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_client.cpp
@@ -76,8 +76,8 @@ class MotionEventQt : public ui::MotionEvent
         , flags(flagsFromModifiers(modifiers))
         , index(index)
     {
-        // index is only valid for ACTION_DOWN and ACTION_UP and should correspond to the point causing it
-        // see blink_event_util.cc:ToWebTouchPointState for details
+        // index is only valid for POINTER_DOWN and POINTER_UP and should correspond to the point
+        // causing it see blink_event_util.cc:ToWebTouchPointState for details
         Q_ASSERT_X((action != Action::POINTER_DOWN && action != Action::POINTER_UP && index == -1)
                 || (action == Action::POINTER_DOWN && index >= 0 && touchPoint(index).state() == QEventPoint::Pressed)
                 || (action == Action::POINTER_UP && index >= 0 && touchPoint(index).state() == QEventPoint::Released),
diff --git a/src/webenginequick/api/qquickwebenginescriptcollection.cpp b/src/webenginequick/api/qquickwebenginescriptcollection.cpp
index a58d9783219..00ddb78e5db 100644
--- a/src/webenginequick/api/qquickwebenginescriptcollection.cpp
+++ b/src/webenginequick/api/qquickwebenginescriptcollection.cpp
@@ -117,7 +117,7 @@ QQuickWebEngineScriptCollection::QQuickWebEngineScriptCollection(QQuickWebEngine
 QQuickWebEngineScriptCollection::~QQuickWebEngineScriptCollection() { }
 
 /*!
-    \qmlmethod void WebEngineScriptCollection::contains(WebEngineScript script)
+    \qmlmethod bool WebEngineScriptCollection::contains(WebEngineScript script)
     \since QtWebEngine 6.2
     Checks if the specified \a script is in the collection.
     \sa find()
@@ -132,7 +132,7 @@ bool QQuickWebEngineScriptCollection::contains(const QWebEngineScript &value) co
     \qmlmethod list<WebEngineScript> WebEngineScriptCollection::find(string name)
     \since QtWebEngine 6.2
     Returns a list of all user script objects with the given \a name.
-    \sa find()
+    \sa contains()
 */
 QList<QWebEngineScript> QQuickWebEngineScriptCollection::find(const QString &name) const
 {
@@ -143,7 +143,7 @@ QList<QWebEngineScript> QQuickWebEngineScriptCollection::find(const QString &nam
     \qmlmethod void WebEngineScriptCollection::insert(WebEngineScript script)
     \since QtWebEngine 6.2
     Inserts a single \a script into the collection.
-    \sa find()
+    \sa remove()
 */
 void QQuickWebEngineScriptCollection::insert(const QWebEngineScript &s)
 {
@@ -154,7 +154,7 @@ void QQuickWebEngineScriptCollection::insert(const QWebEngineScript &s)
     \qmlmethod void WebEngineScriptCollection::insert(list<WebEngineScript> list)
     \since QtWebEngine 6.2
     Inserts a \a list of WebEngineScript values into the user script collection.
-    \sa find()
+    \sa remove()
 */
 void QQuickWebEngineScriptCollection::insert(const QList<QWebEngineScript> &list)
 {
diff --git a/src/webenginequick/doc/src/webenginescript.qdoc b/src/webenginequick/doc/src/webenginescript.qdoc
index 9708ffbf814..493873f891e 100644
--- a/src/webenginequick/doc/src/webenginescript.qdoc
+++ b/src/webenginequick/doc/src/webenginescript.qdoc
@@ -90,7 +90,7 @@
 */
 
 /*!
-    \qmlproperty int WebEngineScript::runOnSubframes
+    \qmlproperty bool WebEngineScript::runsOnSubFrames
 
     Set this property to \c true if the script is executed on every frame in the page, or \c false
     if it is only ran for the main frame.

From a56bd1740e5ba837b46cd8328e63acd1179216ba Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Thu, 18 Jul 2024 16:24:43 +0000
Subject: [PATCH 073/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Ia9deb535356b28a21479a48ba5720ec6e06b34bf
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 740679e5b86..6bfba13bee6 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 321c8a88eb575749cca8d5116b2a131c7932f74d
+    ref: 49909e8b8a4fcbeb7c8e57c052ce2b4574e621d5
     required: true
   ../qtpositioning:
-    ref: ea75bd6c9a1df3f91c718e7a6a20f582405bd913
+    ref: ae72e98b7ec0a16ab16b169eeda04ab245dfc65c
     required: false
   ../qttools:
-    ref: eedf2f68c5918074443b556183ab4068d7255d01
+    ref: 3f5bef070a824e2afa6269ac2803f54790de2948
     required: false
   ../qtwebchannel:
-    ref: 40451b711429d04347cdd010b904699303d311a4
+    ref: 47d44416816aacaeae2c4d33d15fabe42b830160
     required: false

From 152894283800a27f6e6a6b3d0937f13ef4b396a3 Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Mon, 13 May 2024 11:00:50 +0200
Subject: [PATCH 074/356] Use host paths when finding and running GN

Suggested patch from F S

Matches similar usage in qtbase/src/corelib/Qt6AndroidMacros.cmake, for
example.

Fixes: QTBUG-124172
Change-Id: Icac1e4511019e4d3ef9e80e6351490beab0f1ce7
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 0249011d7f0f6d9606afd8387f3f387acb44a441)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 cmake/FindGn.cmake    | 4 ++--
 cmake/Functions.cmake | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/cmake/FindGn.cmake b/cmake/FindGn.cmake
index fd03b7346d0..f30edcd3649 100644
--- a/cmake/FindGn.cmake
+++ b/cmake/FindGn.cmake
@@ -6,11 +6,11 @@ if(NOT DEFINED WEBENGINE_ROOT_BUILD_DIR)
 endif()
 find_program(Gn_EXECUTABLE NAMES gn PATHS "${WEBENGINE_ROOT_BUILD_DIR}/install/bin" NO_DEFAULT_PATH)
 if(NOT QT_HOST_PATH STREQUAL "")
-   find_program(Gn_EXECUTABLE NAMES gn PATHS ${QT_HOST_PATH}/${INSTALL_LIBEXECDIR} NO_DEFAULT_PATH)
+   find_program(Gn_EXECUTABLE NAMES gn PATHS ${QT_HOST_PATH}/${QT6_HOST_INFO_LIBEXECDIR} NO_DEFAULT_PATH)
    # note: mingw installs with INSTALL_LIBEXECDIR = bin,
    # however android on windows has INSTALL_LIBEXECDIR = libexec,
    # so cover this case also
-   find_program(Gn_EXECUTABLE NAMES gn PATHS ${QT_HOST_PATH}/${INSTALL_BINDIR} NO_DEFAULT_PATH)
+   find_program(Gn_EXECUTABLE NAMES gn PATHS ${QT_HOST_PATH}/${QT6_HOST_INFO_BINDIR} NO_DEFAULT_PATH)
 endif()
 find_program(Gn_EXECUTABLE NAMES gn)
 
diff --git a/cmake/Functions.cmake b/cmake/Functions.cmake
index 6cc8a401ea3..412d1eb3bbc 100644
--- a/cmake/Functions.cmake
+++ b/cmake/Functions.cmake
@@ -1266,8 +1266,8 @@ function(add_gn_command)
              -DSOURCE_DIR=${CMAKE_CURRENT_LIST_DIR}
              -DMODULE=${arg_MODULE}
              -DQT_HOST_PATH=${QT_HOST_PATH}
-             -DINSTALL_LIBEXECDIR=${INSTALL_LIBEXECDIR}
-             -DINSTALL_BINDIR=${INSTALL_BINDIR}
+             -DQT6_HOST_INFO_LIBEXECDIR=${QT6_HOST_INFO_LIBEXECDIR}
+             -DQT6_HOST_INFO_BINDIR=${QT6_HOST_INFO_BINDIR}
              -DPython3_EXECUTABLE=${Python3_EXECUTABLE}
              -DGN_THREADS=$ENV{QTWEBENGINE_GN_THREADS}
              -DQT_ALLOW_SYMLINK_IN_PATHS=${QT_ALLOW_SYMLINK_IN_PATHS}

From d8cb9ae856e4fb03bc1f1dc0b7c65d4bc5187faa Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Fri, 21 Jun 2024 16:13:54 +0200
Subject: [PATCH 075/356] Partially stabilize QML favicon tests

It seems that the pattern...
1. trigger action
2. start wait()-ing on a signal spy
3. continue after the signal is received
...is somewhat cursed in QML, since the signal may trigger inbetween
steps 1 and 2, which will cause the wait() to never return true. This
change removes that pattern from the favicon tests, which will
hopefully reduce the tests' flakiness.

Pick-to: 6.7
Change-Id: I65cd3b8c8ae5fc855138eec94821eb932d999c3b
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
(cherry picked from commit 7cdcdb10915455c8ccb7f470158de0cc2fe66223)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 tests/auto/quick/qmltests/data/tst_favicon.qml | 18 ++++++------------
 .../qmltests/data/tst_faviconDatabase.qml      |  4 +---
 2 files changed, 7 insertions(+), 15 deletions(-)

diff --git a/tests/auto/quick/qmltests/data/tst_favicon.qml b/tests/auto/quick/qmltests/data/tst_favicon.qml
index fcc24dfb7de..d4b5c805366 100644
--- a/tests/auto/quick/qmltests/data/tst_favicon.qml
+++ b/tests/auto/quick/qmltests/data/tst_favicon.qml
@@ -68,8 +68,7 @@ TestWebEngineView {
             webEngineView.url = url
             verify(webEngineView.waitForLoadSucceeded())
 
-            iconChangedSpy.wait()
-            compare(iconChangedSpy.count, 1)
+            tryCompare(iconChangedSpy, "count", 1)
 
             tryCompare(favicon, "status", Image.Ready)
             compare(favicon.width, 32)
@@ -91,8 +90,7 @@ TestWebEngineView {
             webEngineView.url = url
             verify(webEngineView.waitForLoadSucceeded())
 
-            iconChangedSpy.wait()
-            compare(iconChangedSpy.count, 1)
+            tryCompare(iconChangedSpy, "count", 1)
 
             tryCompare(favicon, "status", Image.Ready)
             compare(favicon.width, 32)
@@ -298,8 +296,7 @@ TestWebEngineView {
             webEngineView.url = url
             verify(webEngineView.waitForLoadSucceeded())
 
-            iconChangedSpy.wait()
-            compare(iconChangedSpy.count, 1)
+            tryCompare(iconChangedSpy, "count", 1)
 
             iconUrl = removeFaviconProviderPrefix(webEngineView.icon)
             // Touch icon is ignored
@@ -352,10 +349,9 @@ TestWebEngineView {
             webEngineView.url = url
             verify(webEngineView.waitForLoadSucceeded())
 
-            iconChangedSpy.wait()
+            tryCompare(iconChangedSpy, "count", 1)
             iconUrl = removeFaviconProviderPrefix(webEngineView.icon)
             compare(iconUrl, Qt.resolvedUrl("icons/qt144.png"))
-            compare(iconChangedSpy.count, 1)
             tryCompare(favicon, "status", Image.Ready)
             compare(favicon.width, 144)
             compare(favicon.height, 144)
@@ -376,8 +372,7 @@ TestWebEngineView {
             webEngineView.url = url
             verify(webEngineView.waitForLoadSucceeded())
 
-            iconChangedSpy.wait()
-            compare(iconChangedSpy.count, 1)
+            tryCompare(iconChangedSpy, "count", 1)
             tryCompare(favicon, "status", Image.Ready)
             compare(favicon.width, 32)
             compare(favicon.height, 32)
@@ -517,8 +512,7 @@ TestWebEngineView {
             webEngineView.url = row.url
             verify(webEngineView.waitForLoadSucceeded())
 
-            iconChangedSpy.wait()
-            compare(iconChangedSpy.count, 1)
+            tryCompare(iconChangedSpy, "count", 1)
 
             var iconUrl = removeFaviconProviderPrefix(webEngineView.icon)
             compare(iconUrl, row.expectedIconUrl)
diff --git a/tests/auto/quick/qmltests/data/tst_faviconDatabase.qml b/tests/auto/quick/qmltests/data/tst_faviconDatabase.qml
index c1679000107..22250852048 100644
--- a/tests/auto/quick/qmltests/data/tst_faviconDatabase.qml
+++ b/tests/auto/quick/qmltests/data/tst_faviconDatabase.qml
@@ -101,8 +101,7 @@ TestWebEngineView {
             webEngineView.url = Qt.resolvedUrl("favicon.html"); // favicon.png -> 165
             verify(webEngineView.waitForLoadSucceeded());
 
-            iconChangedSpy.wait();
-            compare(iconChangedSpy.count, 1);
+            tryCompare(iconChangedSpy, "count", 1);
 
             var previousIcon = webEngineView.icon;
             iconChangedSpy.clear();
@@ -213,4 +212,3 @@ TestWebEngineView {
         }
     }
 }
-

From f375deab83f3bbeb891492d7d10aca3a824f723e Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Thu, 18 Jul 2024 11:35:59 +0200
Subject: [PATCH 076/356] Fix narrowing conversions

-Wc++11-narrowing under some GL versions and clang 18

Change-Id: I86433dd8da36aeb24a6cb79d630b7984906ae556
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit f916ff7d41ff4e065eaa6cfa943516046121d843)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/compositor/native_skia_output_device_opengl.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/core/compositor/native_skia_output_device_opengl.cpp b/src/core/compositor/native_skia_output_device_opengl.cpp
index 07c68ffff65..137bc3e2113 100644
--- a/src/core/compositor/native_skia_output_device_opengl.cpp
+++ b/src/core/compositor/native_skia_output_device_opengl.cpp
@@ -116,7 +116,7 @@ GLXFBConfig GetFBConfig(Display *display)
         GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
         GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
         GLX_DOUBLEBUFFER, 0,
-        GLX_Y_INVERTED_EXT, GLX_DONT_CARE,
+        GLX_Y_INVERTED_EXT, static_cast<int>(GLX_DONT_CARE),
         0
     };
     // clang-format on
@@ -288,10 +288,10 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
                 EGL_HEIGHT, size().height(),
                 EGL_LINUX_DRM_FOURCC_EXT, drmFormat,
                 EGL_DMA_BUF_PLANE0_FD_EXT, scopedFd.get(),
-                EGL_DMA_BUF_PLANE0_OFFSET_EXT, nativePixmap->GetDmaBufOffset(0),
+                EGL_DMA_BUF_PLANE0_OFFSET_EXT, static_cast<EGLAttrib>(nativePixmap->GetDmaBufOffset(0)),
                 EGL_DMA_BUF_PLANE0_PITCH_EXT, nativePixmap->GetDmaBufPitch(0),
-                EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, modifier & 0xffffffff,
-                EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, modifier >> 32,
+                EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, static_cast<EGLAttrib>(modifier & 0xffffffff),
+                EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, static_cast<EGLAttrib>(modifier >> 32),
                 EGL_NONE
             };
             // clang-format on

From f9d8018eb5fb9707ea5eeb006464d2a9f17446ee Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Mon, 22 Jul 2024 14:18:50 +0200
Subject: [PATCH 077/356] Add BUILD_ONLY_GN option

Simply wrap gn build call so it can be used in form of:
qt-configrue-module path/to/qtwebengine -- -DBUILD_ONLY_GN=TRUE

Drop all config sanity checks.

Fixes: QTBUG-113636
Change-Id: I2763bc1304032b36917288431770229c0e8890fb
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit 4bb470c40dd96e9d8e9e117460f0145a52c8f133)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 CMakeLists.txt        |  6 ++++++
 cmake/Functions.cmake | 33 +++++++++++++++++++++++++++++++++
 src/CMakeLists.txt    | 11 +----------
 3 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7d4638139cb..7388dd55bd8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,6 +13,12 @@ include(cmake/Functions.cmake)
 project(QtWebEngineDummy)
 find_package(Qt6 6.5 CONFIG REQUIRED COMPONENTS BuildInternals Core)
 
+# Sepcial case of just doing gn build
+if(DEFINED BUILD_ONLY_GN)
+    qt_webengine_build_and_install_gn()
+    return()
+endif()
+
 project(QtWebEngine
     VERSION ${Qt6Core_VERSION}
     DESCRIPTION "QtWebEngine and QtPdf modules"
diff --git a/cmake/Functions.cmake b/cmake/Functions.cmake
index 412d1eb3bbc..03eafadb420 100644
--- a/cmake/Functions.cmake
+++ b/cmake/Functions.cmake
@@ -1405,3 +1405,36 @@ function(add_code_attributions_target)
      )
      add_custom_target(${arg_TARGET} DEPENDS ${arg_OUTPUT})
 endfunction()
+
+macro(qt_webengine_build_and_install_gn)
+    set(suppress_warning "${BUILD_ONLY_GN} ${QT_INTERNAL_CALLED_FROM_CONFIGURE}")
+    qt_internal_project_setup()
+    qt_webengine_externalproject_add(gn
+        SOURCE_DIR  ${CMAKE_CURRENT_LIST_DIR}/src/gn
+        BINARY_DIR  ${CMAKE_CURRENT_BINARY_DIR}/src/gn
+        INSTALL_DIR ${PROJECT_BINARY_DIR}/install
+    )
+    qt_internal_set_cmake_build_type()
+    get_install_config(install_config)
+    qt_install(
+        PROGRAMS "${PROJECT_BINARY_DIR}/install/bin/gn${CMAKE_EXECUTABLE_SUFFIX}"
+        CONFIGURATIONS ${install_config}
+        RUNTIME DESTINATION "${INSTALL_LIBEXECDIR}"
+    )
+    unset(suppress_warning)
+    unset(install_config)
+endmacro()
+
+macro(qt_webengine_externalproject_add)
+    externalproject_add(${ARGN}
+        PREFIX      gn
+        USES_TERMINAL_BUILD TRUE
+        CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release
+                   -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
+                   -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
+                   -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+                   -DCMAKE_PREFIX_PATH:PATH=<INSTALL_DIR>
+                   -DWEBENGINE_ROOT_BUILD_DIR=${PROJECT_BINARY_DIR}
+                   -DQT_ALLOW_SYMLINK_IN_PATHS=${QT_ALLOW_SYMLINK_IN_PATHS}
+    )
+endmacro()
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0084697f21f..eb36e70539d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -129,20 +129,11 @@ if(CMAKE_CROSSCOMPILING AND NOT Gn_FOUND)
 endif()
 
 if(NOT Gn_FOUND)
-    externalproject_add(gn
+    qt_webengine_externalproject_add(gn
         SOURCE_DIR  ${CMAKE_CURRENT_LIST_DIR}/gn
         BINARY_DIR  ${CMAKE_CURRENT_BINARY_DIR}/gn
         INSTALL_DIR ${installDir}
-        PREFIX      gn
-        USES_TERMINAL_BUILD TRUE
         EXCLUDE_FROM_ALL TRUE
-        CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release
-                   -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-                   -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-                   -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
-                   -DCMAKE_PREFIX_PATH:PATH=<INSTALL_DIR>
-                   -DWEBENGINE_ROOT_BUILD_DIR=${PROJECT_BINARY_DIR}
-                   -DQT_ALLOW_SYMLINK_IN_PATHS=${QT_ALLOW_SYMLINK_IN_PATHS}
     )
     if(QT_FEATURE_qtwebengine_core_build)
         add_dependencies(run_core_GnReady gn)

From 37966380b3d231a359e34acd29957e5377d60bff Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Mon, 22 Jul 2024 16:23:23 +0200
Subject: [PATCH 078/356] Fix whitespace in webrtc manual test

Change-Id: I6aeaff890cb8c3ef4e362ab81cde50470083d39e
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit 1e3232e398c68b4b24a3bd00856a4538dee8e67c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 tests/manual/widgets/webrtc/main.cpp | 42 ++++++++++++++--------------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/tests/manual/widgets/webrtc/main.cpp b/tests/manual/widgets/webrtc/main.cpp
index c1742445a4c..7eecf0735a0 100644
--- a/tests/manual/widgets/webrtc/main.cpp
+++ b/tests/manual/widgets/webrtc/main.cpp
@@ -52,27 +52,27 @@ void Page::handlePermissionRequest(QWebEnginePermission permission)
 
 void Page::handleDesktopMediaRequest(const QWebEngineDesktopMediaRequest &request)
 {
-        Ui::MediaPickerDialog mediaPickerDialog;
-        QDialog dialog;
-        dialog.setModal(true);
-        mediaPickerDialog.setupUi(&dialog);
-
-        auto *screensView = mediaPickerDialog.screensView;
-        auto *windowsView = mediaPickerDialog.windowsView;
-        auto *screensModel = request.screensModel();
-        auto *windowsModel = request.windowsModel();
-
-        screensView->setModel(screensModel);
-        windowsView->setModel(windowsModel);
-
-        if (dialog.exec() == QDialog::Accepted) {
-            if (mediaPickerDialog.tabWidget->currentIndex() == 0)
-                request.selectWindow(windowsView->selectionModel()->selectedIndexes().first());
-            else
-                request.selectScreen(screensView->selectionModel()->selectedIndexes().first());
-        } else {
-            request.cancel();
-        }
+    Ui::MediaPickerDialog mediaPickerDialog;
+    QDialog dialog;
+    dialog.setModal(true);
+    mediaPickerDialog.setupUi(&dialog);
+
+    auto *screensView = mediaPickerDialog.screensView;
+    auto *windowsView = mediaPickerDialog.windowsView;
+    auto *screensModel = request.screensModel();
+    auto *windowsModel = request.windowsModel();
+
+    screensView->setModel(screensModel);
+    windowsView->setModel(windowsModel);
+
+    if (dialog.exec() == QDialog::Accepted) {
+        if (mediaPickerDialog.tabWidget->currentIndex() == 0)
+            request.selectWindow(windowsView->selectionModel()->selectedIndexes().first());
+        else
+            request.selectScreen(screensView->selectionModel()->selectedIndexes().first());
+    } else {
+        request.cancel();
+    }
 }
 
 int main(int argc, char *argv[])

From e23a577e15e72fc57b3972f8311ee43988429cf6 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Thu, 18 Jul 2024 11:31:37 +0200
Subject: [PATCH 079/356] Find text: Start new search when toggling case
 sensitivity

Only toggling case sensitivity, without changing the text that's
being looked up, would keep the helper in "find next" state, which
in turn would keep otherwise invalid matches highlighted on screen.
This change ensures that a new text search is initiated in cases
like this.

Fixes: QTBUG-127318
Pick-to: 6.7
Change-Id: I95b410b123dc09851f5aaefc8470f0656a88bb0d
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit 7f47a253ba7bce2d76f41079c34bc9468ec142aa)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/find_text_helper.cpp                 |  4 +++-
 src/core/find_text_helper.h                   |  1 +
 .../auto/quick/qmltests/data/tst_findText.qml | 21 +++++++++++++++++++
 .../qwebenginepage/tst_qwebenginepage.cpp     | 17 +++++++++++++++
 4 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/src/core/find_text_helper.cpp b/src/core/find_text_helper.cpp
index 5dc12fab7db..cc52e65c14a 100644
--- a/src/core/find_text_helper.cpp
+++ b/src/core/find_text_helper.cpp
@@ -19,6 +19,7 @@ FindTextHelper::FindTextHelper(content::WebContents *webContents, WebContentsAda
     , m_viewClient(viewClient)
     , m_currentFindRequestId(m_findRequestIdCounter++)
     , m_lastCompletedFindRequestId(m_currentFindRequestId)
+    , m_previousCaseSensitively(false)
 {
 }
 
@@ -64,7 +65,7 @@ void FindTextHelper::startFinding(const QString &findText, bool caseSensitively,
 {
     Q_ASSERT(!findText.isEmpty());
 
-    const bool findNext = !m_previousFindText.isEmpty() && findText == m_previousFindText;
+    const bool findNext = !m_previousFindText.isEmpty() && findText == m_previousFindText && caseSensitively == m_previousCaseSensitively;
     if (isFindTextInProgress()) {
         // There are cases where the render process will overwrite a previous request
         // with the new search and we'll have a dangling callback, leaving the application
@@ -83,6 +84,7 @@ void FindTextHelper::startFinding(const QString &findText, bool caseSensitively,
     options->match_case = caseSensitively;
     options->new_session = !findNext;
     m_previousFindText = findText;
+    m_previousCaseSensitively = caseSensitively;
 
     m_currentFindRequestId = m_findRequestIdCounter++;
     m_webContents->Find(m_currentFindRequestId, toString16(findText), std::move(options), /*skip_delay=*/true);
diff --git a/src/core/find_text_helper.h b/src/core/find_text_helper.h
index 6d2e48b632a..fa3ea08d33d 100644
--- a/src/core/find_text_helper.h
+++ b/src/core/find_text_helper.h
@@ -61,6 +61,7 @@ class Q_WEBENGINECORE_EXPORT FindTextHelper {
     int m_lastCompletedFindRequestId;
 
     QString m_previousFindText;
+    bool m_previousCaseSensitively;
 
     QMap<int, QJSValue> m_quickCallbacks;
     QMap<int, std::function<void(const QWebEngineFindTextResult &)>> m_widgetCallbacks;
diff --git a/tests/auto/quick/qmltests/data/tst_findText.qml b/tests/auto/quick/qmltests/data/tst_findText.qml
index bd2bfbb480b..8bf50d9138e 100644
--- a/tests/auto/quick/qmltests/data/tst_findText.qml
+++ b/tests/auto/quick/qmltests/data/tst_findText.qml
@@ -105,6 +105,27 @@ TestWebEngineView {
             compare(findTextSpy.signalArguments[0][0].activeMatch, 1)
         }
 
+        function test_toggleCaseSensitivity() {
+            var findFlags = 0
+            webEngineView.url = Qt.resolvedUrl("test1.html")
+            verify(webEngineView.waitForLoadSucceeded())
+
+            webEngineView.clear()
+            webEngineView.findText("heLLo", findFlags, webEngineView.findTextCallback)
+            tryCompare(webEngineView, "matchCount", 1)
+            verify(!findFailed)
+            tryCompare(findTextSpy, "count", 1)
+            compare(findTextSpy.signalArguments[0][0].numberOfMatches, 1)
+            compare(findTextSpy.signalArguments[0][0].activeMatch, 1)
+
+            findTextSpy.clear()
+            webEngineView.clear()
+            findFlags = WebEngineView.FindCaseSensitively
+            webEngineView.findText("heLLo", findFlags, webEngineView.findTextCallback)
+            tryCompare(findTextSpy, "count", 1)
+            compare(findTextSpy.signalArguments[0][0].numberOfMatches, 0)
+        }
+
         function test_findTextManyMatches() {
             var findFlags = 0
             webEngineView.url = Qt.resolvedUrl("test4.html")
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index dfb4fe5bf94..090c7dde0f1 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -1199,6 +1199,23 @@ void tst_QWebEnginePage::findText()
         QTRY_VERIFY(m_view->selectedText().isEmpty());
     }
 
+    // Toggling case sensitivity without changing the text that's being looked up
+    // will clear previously found text
+    {
+        auto *callbackSpy = new CallbackSpy<QWebEngineFindTextResult>();
+        QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
+        m_view->findText("FOO", {}, callbackSpy->ref());
+        QVERIFY(callbackSpy->waitForResult().numberOfMatches() > 0);
+        QTRY_COMPARE(signalSpy.size(), 1);
+        delete callbackSpy;
+        callbackSpy = new CallbackSpy<QWebEngineFindTextResult>();
+        m_view->findText("FOO", QWebEnginePage::FindCaseSensitively, callbackSpy->ref());
+        QVERIFY(callbackSpy->waitForResult().numberOfMatches() == 0);
+        QVERIFY(callbackSpy->wasCalled());
+        QTRY_COMPARE(signalSpy.size(), 2);
+        delete callbackSpy;
+    }
+
     // Select whole page contents again.
     m_view->page()->triggerAction(QWebEnginePage::SelectAll);
     QTRY_COMPARE(m_view->hasSelection(), true);

From c1369837ac825567eabe9cf5ff818c4656942bb0 Mon Sep 17 00:00:00 2001
From: Martin Negyokru <negyokru@inf.u-szeged.hu>
Date: Wed, 10 Jul 2024 16:21:58 +0200
Subject: [PATCH 080/356] Bump the minimum FFmpeg version to 6.1

Change-Id: Ie406728d6c52de5ea6d033072998c0ee627aeee6
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 6f18a71b15f1a9f3f1a9bdd5b230e63813bae2d4)
---
 configure.cmake | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/configure.cmake b/configure.cmake
index dedd11cff8b..9fff6c3d507 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -52,7 +52,10 @@ if(PkgConfig_FOUND)
     pkg_check_modules(LCMS2 lcms2)
     pkg_check_modules(FREETYPE freetype2 IMPORTED_TARGET)
     pkg_check_modules(LIBXML2 libxml-2.0 libxslt IMPORTED_TARGET)
-    pkg_check_modules(FFMPEG libavcodec libavformat libavutil IMPORTED_TARGET)
+    pkg_check_modules(FFMPEG libavcodec>=60.31.102
+                             libavformat>=60.16.100
+                             libavutil>=58.29.100
+                             IMPORTED_TARGET)
     pkg_check_modules(OPUS opus>=1.3.1)
     pkg_check_modules(VPX vpx>=1.10.0 IMPORTED_TARGET)
     pkg_check_modules(LIBPCI libpci)

From bed6a834b3a95538417bc61bdcdabf52da26c372 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Fri, 5 Jul 2024 14:19:57 +0200
Subject: [PATCH 081/356] Fix compiler warnings in tests and examples

Change-Id: If371441d9b0d93fbd7a3e3e37e4f3780ddb52eb0
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit da4b139b97e47764a6d4aa1752e996d8bd41ae00)
---
 examples/pdfwidgets/pdfviewer/mainwindow.cpp  |  7 ++--
 .../tst_qwebengineglobalsettings.cpp          |  2 --
 .../pdfpageimage/tst_pdfpageimage.cpp         |  6 ++--
 .../tst_qquickwebengineview.cpp               | 28 ++++++++--------
 .../qwebenginepage/tst_qwebenginepage.cpp     | 32 +++++++++++--------
 tests/manual/widgets/webgl/main.cpp           |  5 +--
 6 files changed, 43 insertions(+), 37 deletions(-)

diff --git a/examples/pdfwidgets/pdfviewer/mainwindow.cpp b/examples/pdfwidgets/pdfviewer/mainwindow.cpp
index ce19359fc58..25c2cbaab99 100644
--- a/examples/pdfwidgets/pdfviewer/mainwindow.cpp
+++ b/examples/pdfwidgets/pdfviewer/mainwindow.cpp
@@ -19,6 +19,8 @@
 #include <QStandardPaths>
 #include <QtMath>
 
+using namespace Qt::StringLiterals;
+
 const qreal zoomMultiplier = qSqrt(2.0);
 
 Q_LOGGING_CATEGORY(lcExample, "qt.examples.pdfviewer")
@@ -115,8 +117,9 @@ void MainWindow::pageSelected(int page)
     const auto documentTitle = m_document->metaData(QPdfDocument::MetaDataField::Title).toString();
     setWindowTitle(!documentTitle.isEmpty() ? documentTitle : QStringLiteral("PDF Viewer"));
     setWindowTitle(tr("%1: page %2 (%3 of %4)")
-                   .arg(documentTitle.isEmpty() ? u"PDF Viewer"_qs : documentTitle,
-                        m_pageSelector->currentPageLabel(), QString::number(page + 1), QString::number(m_document->pageCount())));
+                           .arg(documentTitle.isEmpty() ? u"PDF Viewer"_s : documentTitle,
+                                m_pageSelector->currentPageLabel(), QString::number(page + 1),
+                                QString::number(m_document->pageCount())));
 }
 
 void MainWindow::searchResultSelected(const QModelIndex &current, const QModelIndex &previous)
diff --git a/tests/auto/core/qwebengineglobalsettings/tst_qwebengineglobalsettings.cpp b/tests/auto/core/qwebengineglobalsettings/tst_qwebengineglobalsettings.cpp
index 3e46a823e2a..c7e9df51a7f 100644
--- a/tests/auto/core/qwebengineglobalsettings/tst_qwebengineglobalsettings.cpp
+++ b/tests/auto/core/qwebengineglobalsettings/tst_qwebengineglobalsettings.cpp
@@ -32,8 +32,6 @@ private Q_SLOTS:
     void dnsOverHttps();
 };
 
-Q_LOGGING_CATEGORY(lc, "qt.webengine.tests")
-
 void tst_QWebEngineGlobalSettings::dnsOverHttps_data()
 {
     QTest::addColumn<QWebEngineGlobalSettings::SecureDnsMode>("dnsMode");
diff --git a/tests/auto/pdfquick/pdfpageimage/tst_pdfpageimage.cpp b/tests/auto/pdfquick/pdfpageimage/tst_pdfpageimage.cpp
index 3f98025fa71..c8ad4bdaa8b 100644
--- a/tests/auto/pdfquick/pdfpageimage/tst_pdfpageimage.cpp
+++ b/tests/auto/pdfquick/pdfpageimage/tst_pdfpageimage.cpp
@@ -11,10 +11,12 @@
 
 using namespace Qt::StringLiterals;
 
-Q_LOGGING_CATEGORY(lcTests, "qt.pdf.tests")
-
 // #define DEBUG_WRITE_OUTPUT
 
+#ifdef DEBUG_WRITE_OUTPUT
+Q_LOGGING_CATEGORY(lcTests, "qt.pdf.tests")
+#endif
+
 class tst_PdfPageImage : public QQuickDataTest
 {
     Q_OBJECT
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index abe5e1f3da5..2a96061fbce 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -800,7 +800,7 @@ void tst_QQuickWebEngineView::setZoomFactor()
     view->setZoomFactor(2.5);
     QCOMPARE(view->zoomFactor(), 2.5);
 
-    const QUrl url1 = urlFromTestPath("html/basic_page.html"), url2 = urlFromTestPath("html/basic_page2.html");
+    const QUrl url1 = urlFromTestPath("html/basic_page.html");
 
     view->setUrl(url1);
     QVERIFY(waitForLoadSucceeded(view));
@@ -817,20 +817,22 @@ void tst_QQuickWebEngineView::setZoomFactor()
     view2->setParentItem(m_window->contentItem());
 
     // try loading different url and check new values after load
-    for (auto &&p : {
-            qMakePair(view, 2.5), // navigating away to different url should keep zoom
-            qMakePair(view2.get(), 1.0), // same url navigation in diffent page shouldn't be affected
-        }) {
-        auto &&view = p.first; auto zoomFactor = p.second;
-        view->setUrl(url2);
-        QVERIFY(waitForLoadSucceeded(view));
-        QCOMPARE(view->zoomFactor(), zoomFactor);
-    }
+    const QUrl url2 = urlFromTestPath("html/basic_page2.html");
+
+    // navigating away to different url should keep zoom
+    view->setUrl(url2);
+    QVERIFY(waitForLoadSucceeded(view));
+    QCOMPARE(view->zoomFactor(), 2.5);
+
+    // same url navigation in different view shouldn't be affected
+    view2->setUrl(url2);
+    QVERIFY(waitForLoadSucceeded(view2.get()));
+    QCOMPARE(view2->zoomFactor(), 1.0);
 
-    // should have no influence on first page
+    // should have no influence on first view
     view2->setZoomFactor(3.5);
-    for (auto &&p : { qMakePair(view, 2.5), qMakePair(view2.get(), 3.5), })
-        QCOMPARE(p.first->zoomFactor(), p.second);
+    QCOMPARE(view->zoomFactor(), 2.5);
+    QCOMPARE(view2->zoomFactor(), 3.5);
 }
 
 void tst_QQuickWebEngineView::printToPdf()
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 090c7dde0f1..24a2e348be8 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -3252,13 +3252,13 @@ void tst_QWebEnginePage::toPlainTextLoadFinishedRace()
 
 void tst_QWebEnginePage::setZoomFactor()
 {
-    TestBasePage page, page2;
+    TestBasePage page;
 
     QCOMPARE(page.zoomFactor(), 1.0);
     page.setZoomFactor(2.5);
     QCOMPARE(page.zoomFactor(), 2.5);
 
-    const QUrl url1("qrc:/resources/test1.html"), url2(QUrl("qrc:/resources/test2.html"));
+    const QUrl url1("qrc:/resources/test1.html");
 
     page.load(url1);
     QTRY_COMPARE(page.loadSpy.size(), 1);
@@ -3272,22 +3272,26 @@ void tst_QWebEnginePage::setZoomFactor()
     QCOMPARE(page.zoomFactor(), 2.5);
 
     // try loading different url and check new values after load
+    const QUrl url2(QUrl("qrc:/resources/test2.html"));
+
+    // navigating away to different url should keep zoom
     page.loadSpy.clear();
-    for (auto &&p : {
-            qMakePair(&page, 2.5), // navigating away to different url should keep zoom
-            qMakePair(&page2, 1.0), // same url navigation in diffent page shouldn't be affected
-        }) {
-        auto &&page = *p.first; auto zoomFactor = p.second;
-        page.load(url2);
-        QTRY_COMPARE(page.loadSpy.size(), 1);
-        QVERIFY(page.loadSpy.last().first().toBool());
-        QCOMPARE(page.zoomFactor(), zoomFactor);
-    }
+    page.load(url2);
+    QTRY_COMPARE(page.loadSpy.size(), 1);
+    QVERIFY(page.loadSpy.last().first().toBool());
+    QCOMPARE(page.zoomFactor(), 2.5);
+
+    // same url navigation in different page shouldn't be affected
+    TestBasePage page2;
+    page2.load(url2);
+    QTRY_COMPARE(page2.loadSpy.size(), 1);
+    QVERIFY(page2.loadSpy.last().first().toBool());
+    QCOMPARE(page2.zoomFactor(), 1.0);
 
     // should have no influence on first page
     page2.setZoomFactor(3.5);
-    for (auto &&p : { qMakePair(&page, 2.5), qMakePair(&page2, 3.5), })
-        QCOMPARE(p.first->zoomFactor(), p.second);
+    QCOMPARE(page.zoomFactor(), 2.5);
+    QCOMPARE(page2.zoomFactor(), 3.5);
 }
 
 void tst_QWebEnginePage::mouseButtonTranslation()
diff --git a/tests/manual/widgets/webgl/main.cpp b/tests/manual/widgets/webgl/main.cpp
index e9b4c285afc..cca1dbb160a 100644
--- a/tests/manual/widgets/webgl/main.cpp
+++ b/tests/manual/widgets/webgl/main.cpp
@@ -24,7 +24,7 @@ class MainWindow : public QMainWindow
     Q_OBJECT
 public:
     explicit MainWindow(QWidget *parent = nullptr);
-    QSize sizeHint() const;
+    QSize sizeHint() const override;
 
 private:
     QWebEngineView *view = nullptr;
@@ -103,9 +103,6 @@ int main(int argc, char *argv[])
     const QString gles3 = QStringLiteral("gles3"); // ANGLE on Windows.
     const QString softwareGL = QStringLiteral("software");
 
-    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
-    QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
-
     QString glType = qEnvironmentVariable("QTWEBENGINE_GL_TYPE");
     if (glType.isEmpty()) {
         if (isWindows())

From f540fe3b3a871f54eb05b720b5b8b751305c28dc Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Tue, 23 Jul 2024 12:25:25 +0200
Subject: [PATCH 082/356] cmake: Quote list element with escaped quotes

While technically correct cmake syntax, this breaks syntax highlighting
in neovim and gerrit and also just looks a bit odd.

Change-Id: Ia8a62ad9ad139bf3091b46949786579666dc9417
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit a7ad4591a92258ad46252808ddd458acdc1f3a80)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 cmake/Functions.cmake | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/cmake/Functions.cmake b/cmake/Functions.cmake
index 03eafadb420..f87fd5de316 100644
--- a/cmake/Functions.cmake
+++ b/cmake/Functions.cmake
@@ -872,7 +872,7 @@ macro(append_build_type_setup)
     if(QT_FEATURE_webengine_jumbo_build)
         list(APPEND gnArgArg jumbo_file_merge_limit=${QT_FEATURE_webengine_jumbo_file_merge_limit})
         if(QT_FEATURE_webengine_jumbo_file_merge_limit LESS_EQUAL 8)
-            list(APPEND gnArgArg jumbo_build_excluded=[\"browser\"])
+            list(APPEND gnArgArg "jumbo_build_excluded=[\"browser\"]")
         endif()
     endif()
 

From 2ec2daad25156072bbee401420771c0fdb063e81 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Thu, 25 Jul 2024 09:28:24 +0000
Subject: [PATCH 083/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Iae5fd9fef4a48b6589b95d3fbcbfd05407c3025c
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 6bfba13bee6..f55af2592f4 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 49909e8b8a4fcbeb7c8e57c052ce2b4574e621d5
+    ref: 97a77aa53435bae6e8b3de6c0c1af0631f6e9e8a
     required: true
   ../qtpositioning:
-    ref: ae72e98b7ec0a16ab16b169eeda04ab245dfc65c
+    ref: 498f49315d2a82881141df179c3456e3cf7bf24e
     required: false
   ../qttools:
-    ref: 3f5bef070a824e2afa6269ac2803f54790de2948
+    ref: d5c328f71aff66f88133715abeffeb66bee6127b
     required: false
   ../qtwebchannel:
-    ref: 47d44416816aacaeae2c4d33d15fabe42b830160
+    ref: 4e9162619e853c40693a0cd16d0a500a92da278f
     required: false

From 2692773d3fe801f2855fa49e88c62a101a1307ea Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Fri, 26 Jul 2024 13:23:28 +0200
Subject: [PATCH 084/356] Permission browser example: Use QLatin1StringView

Removes ambiguous conversion of string types.

Fixes: QTBUG-127544
Change-Id: I53d444b641c4b5190c1e391d9df21ccd7076ef13
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit c8b34851faf4eb5116cf01ca810565d02b21e2a2)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 examples/webenginewidgets/permissionbrowser/main.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/examples/webenginewidgets/permissionbrowser/main.cpp b/examples/webenginewidgets/permissionbrowser/main.cpp
index c1e2c25660e..5efc8c6f96a 100644
--- a/examples/webenginewidgets/permissionbrowser/main.cpp
+++ b/examples/webenginewidgets/permissionbrowser/main.cpp
@@ -10,7 +10,7 @@ int main(int argc, char *argv[])
 {
     QCoreApplication::setOrganizationName("QtExamples");
     QApplication app(argc, argv);
-    app.setWindowIcon(QIcon(QString(u":AppLogoColor.png")));
+    app.setWindowIcon(QIcon(QString(QLatin1StringView(":AppLogoColor.png"))));
     MainWindow window(QUrl("qrc:/landing.html"));
     window.resize(1024, 768);
     window.show();

From bd8bcff50124dd61e765834de9ffe5d671bd65fd Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Wed, 17 Jul 2024 14:17:34 +0200
Subject: [PATCH 085/356] Do not warn needlessly about missing dictionaries
 directory

Dictionaries are only required if spellchecking is enabled,
therefore make sure we print out the warning in the
right time. Do not enable spellchecker if dictionary
directory is not present.

This change amends d86ddb74877342d82c36cb9f47cccb53bf339e23

Fixes: QTBUG-124110
Pick-to: 6.7
Change-Id: I49fb191d40c81252e1a17835988621fa2e01ff79
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit 47a076e58301ba51f0aa428145939a77fe657501)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/pref_service_adapter.cpp    |  8 ++++++--
 src/core/web_engine_library_info.cpp | 26 +++++++++++++++++++-------
 src/core/web_engine_library_info.h   |  2 +-
 3 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/src/core/pref_service_adapter.cpp b/src/core/pref_service_adapter.cpp
index 72eb850e7b9..2512c3c44f3 100644
--- a/src/core/pref_service_adapter.cpp
+++ b/src/core/pref_service_adapter.cpp
@@ -6,7 +6,9 @@
 #include "profile_adapter.h"
 #include "type_conversion.h"
 #include "web_engine_context.h"
+#include "web_engine_library_info.h"
 
+#include "base/base_paths.h"
 #include "base/threading/thread_restrictions.h"
 #include "chrome/browser/prefs/chrome_command_line_pref_store.h"
 #include "content/public/browser/browser_thread.h"
@@ -203,8 +205,10 @@ QStringList PrefServiceAdapter::spellCheckLanguages() const
 
 void PrefServiceAdapter::setSpellCheckEnabled(bool enabled)
 {
-    m_prefService->SetBoolean(spellcheck::prefs::kSpellCheckEnable, enabled);
-    m_prefService->SchedulePendingLossyWrites();
+    if (!WebEngineLibraryInfo::getPath(base::DIR_APP_DICTIONARIES, true).empty()) {
+        m_prefService->SetBoolean(spellcheck::prefs::kSpellCheckEnable, enabled);
+        m_prefService->SchedulePendingLossyWrites();
+    }
 }
 
 bool PrefServiceAdapter::isSpellCheckEnabled() const
diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp
index 8b69bec3c92..b6b8fc76340 100644
--- a/src/core/web_engine_library_info.cpp
+++ b/src/core/web_engine_library_info.cpp
@@ -241,9 +241,10 @@ QString localesPath()
 }
 
 #if QT_CONFIG(webengine_spellchecker)
-QString dictionariesPath()
+QString dictionariesPath(bool showWarnings)
 {
     static QString potentialDictionariesPath;
+    static QStringList warningMessage;
     static bool initialized = false;
     QStringList candidatePaths;
     if (!initialized) {
@@ -284,14 +285,25 @@ QString dictionariesPath()
                 break;
             }
         }
-
         if (potentialDictionariesPath.isEmpty()) {
-            // return path for error message
-            potentialDictionariesPath = QCoreApplication::applicationDirPath() % QDir::separator()
-                    % QLatin1String("qtwebengine_dictionaries");
+            warningMessage.append(QStringLiteral(
+                    "The following paths were searched for Qt WebEngine dictionaries:"));
+            for (const QString &candidate : std::as_const(candidatePaths))
+                warningMessage.append(QStringLiteral("  ") % candidate);
+            warningMessage.append(QStringLiteral("but could not find it."));
+            if (fromEnv.isEmpty()) {
+                warningMessage.append(
+                        QStringLiteral("You may override the default search path by using "
+                                       "QTWEBENGINE_DICTIONARIES_PATH environment variable."));
+            }
+            warningMessage.append(QStringLiteral("Spellchecking can not be enabled."));
         }
     }
 
+    if (showWarnings && !warningMessage.isEmpty()) {
+        qWarning("%s", qPrintable(warningMessage.join('\n')));
+    }
+
     return potentialDictionariesPath;
 }
 #endif // QT_CONFIG(webengine_spellchecker)
@@ -346,7 +358,7 @@ QString resourcesPath()
 }
 } // namespace
 
-base::FilePath WebEngineLibraryInfo::getPath(int key)
+base::FilePath WebEngineLibraryInfo::getPath(int key, bool showWarnings)
 {
     QString directory;
     switch (key) {
@@ -382,7 +394,7 @@ base::FilePath WebEngineLibraryInfo::getPath(int key)
         return toFilePath(localesPath());
 #if QT_CONFIG(webengine_spellchecker)
     case base::DIR_APP_DICTIONARIES:
-        return toFilePath(dictionariesPath());
+        return toFilePath(dictionariesPath(showWarnings));
 #endif
     case base::DIR_ASSETS:
         return toFilePath(resourcesPath());
diff --git a/src/core/web_engine_library_info.h b/src/core/web_engine_library_info.h
index b7503f2df0a..a675172af48 100644
--- a/src/core/web_engine_library_info.h
+++ b/src/core/web_engine_library_info.h
@@ -18,7 +18,7 @@ enum {
 
 class WebEngineLibraryInfo {
 public:
-    static base::FilePath getPath(int key);
+    static base::FilePath getPath(int key, bool showWarnings = false);
     // Called by localized_error in our custom chrome layer
     static std::u16string getApplicationName();
     static std::string getResolvedLocale();

From 76b5ab01a93c64f8644b2e0bf2c6f0ead939c05e Mon Sep 17 00:00:00 2001
From: Martin Negyokru <negyokru@inf.u-szeged.hu>
Date: Wed, 28 Feb 2024 15:01:44 +0100
Subject: [PATCH 086/356] Workaround for setCursor issue with embedded views

QQuickItem::setCursor maps the cursor position to the window
while the Item's position is mapped to the View.
If the View is moved inside its container, the offset is ignored
on the Item. Ergo View.pos != Item.pos breaking hittesting of setCursor.

Fix this by forwarding Item::setCursor calls to the View.
It is safe since the Item shares its coordinate system
with chromium and works as a proxy to the View.

Fixes: QTBUG-111927
Fixes: QTBUG-123889
Fixes: QTBUG-115929
Pick-to: 6.7 6.6
Change-Id: Idee5ba043774952b554874ce654279cb5029ef1d
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 5043f4ddff206d2ffcb4684fb791ec689c2538f0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 ...nder_widget_host_view_qt_delegate_item.cpp |  2 +
 ...render_widget_host_view_qt_delegate_item.h |  1 +
 src/webenginewidgets/api/qwebengineview.cpp   |  5 ++
 tests/auto/widgets/qwebengineview/BLACKLIST   |  3 +
 .../qwebengineview/tst_qwebengineview.cpp     | 61 +++++++++++++++++++
 5 files changed, 72 insertions(+)

diff --git a/src/core/render_widget_host_view_qt_delegate_item.cpp b/src/core/render_widget_host_view_qt_delegate_item.cpp
index a9f872220ad..aafa7556aa8 100644
--- a/src/core/render_widget_host_view_qt_delegate_item.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_item.cpp
@@ -126,6 +126,8 @@ void RenderWidgetHostViewQtDelegateItem::readyToSwap()
 
 void RenderWidgetHostViewQtDelegateItem::updateCursor(const QCursor &cursor)
 {
+    if (m_widgetDelegate)
+        m_widgetDelegate->SetCursor(cursor);
     setCursor(cursor);
 }
 
diff --git a/src/core/render_widget_host_view_qt_delegate_item.h b/src/core/render_widget_host_view_qt_delegate_item.h
index 0da6b494834..65fbeeb175e 100644
--- a/src/core/render_widget_host_view_qt_delegate_item.h
+++ b/src/core/render_widget_host_view_qt_delegate_item.h
@@ -35,6 +35,7 @@ class WidgetDelegate
     virtual void Destroy() = 0;
     virtual void Resize(int, int) { }
     virtual QWindow *Window() { return nullptr; }
+    virtual void SetCursor(const QCursor &) { }
     virtual void unhandledWheelEvent(QWheelEvent *) { }
 };
 
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index 9dab3a45b22..0ef881b5ae7 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -199,6 +199,11 @@ class WebEngineQuickWidget : public QQuickWidget, public WidgetDelegate
             qApp->notify(parentWidget, ev);
         }
     }
+    void SetCursor(const QCursor &cursor) override
+    {
+        if (auto parentWidget = QQuickWidget::parentWidget())
+            parentWidget->setCursor(cursor);
+    }
 
 protected:
     void closeEvent(QCloseEvent *event) override
diff --git a/tests/auto/widgets/qwebengineview/BLACKLIST b/tests/auto/widgets/qwebengineview/BLACKLIST
index 26f2da4bbe8..f9ad091840f 100644
--- a/tests/auto/widgets/qwebengineview/BLACKLIST
+++ b/tests/auto/widgets/qwebengineview/BLACKLIST
@@ -10,3 +10,6 @@ windows
 [horizontalScrollbarTest]
 macos
 rhel # flaky
+
+[setCursorOnEmbeddedView]
+macos # QTest::mousemove is not reliable
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 3b481402e7e..2eec0901a69 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -190,6 +190,7 @@ private Q_SLOTS:
     void longKeyEventText();
     void pageWithPaintListeners();
     void deferredDelete();
+    void setCursorOnEmbeddedView();
 };
 
 // This will be called before the first test function is executed.
@@ -4021,5 +4022,65 @@ void tst_QWebEngineView::deferredDelete()
     QCOMPARE(QApplication::allWidgets().size(), 0);
 }
 
+// QTBUG-111927
+void tst_QWebEngineView::setCursorOnEmbeddedView()
+{
+    if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
+        QSKIP("Wayland: Can't manipulate the mouse cursor in auto test.");
+
+    const QString html(QStringLiteral("<html><body"
+                                      " style=\"cursor:pointer;"
+                                      "        background-color:green;"
+                                      "        text-align:center;\">"
+                                      "Pointer"
+                                      "</body>"
+                                      "</html>"));
+    QWidget parentWidget;
+    QWebEngineView view(&parentWidget);
+    PageWithPaintListeners page;
+    view.setPage(&page);
+
+    // Move the view to it's parent rightBottom corner
+    parentWidget.resize(600, 600);
+    view.resize(150, 150);
+    view.move(450, 450);
+
+    QSignalSpy firstPaintSpy(&page, &PageWithPaintListeners::largestContentfulPaint);
+    view.setHtml(html);
+    parentWidget.show();
+    view.show();
+
+    QVERIFY(QTest::qWaitForWindowExposed(&parentWidget));
+    QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+    QTRY_VERIFY(firstPaintSpy.size());
+
+    const QPoint step = QPoint(25, 25);
+    QPoint cursorPos = view.pos() - step;
+
+    // Single QTest::mouseMove may not move the cursor on macOS.
+    for (int i = 0; i < 5; i++) {
+        QTest::mouseMove(&parentWidget, cursorPos);
+        cursorPos += step;
+    }
+
+    QQuickWidget *webEngineQuickWidget = qobject_cast<QQuickWidget *>(view.focusProxy());
+    QVERIFY(webEngineQuickWidget);
+    QTRY_COMPARE(webEngineQuickWidget->hasFocus(), true);
+
+    QQuickItem *root = webEngineQuickWidget->rootObject();
+    // The root item should not has focus, otherwise it would handle mouse events
+    // instead of the RenderWidgetHostViewQtDelegateItem.
+    QVERIFY(!root->hasFocus());
+
+    QCOMPARE(root->childItems().size(), 1);
+    QQuickItem *renderWidgetHostViewQtDelegateItem = root->childItems().at(0);
+    QVERIFY(renderWidgetHostViewQtDelegateItem);
+    QTRY_COMPARE(renderWidgetHostViewQtDelegateItem->hasFocus(), true);
+
+    QTRY_COMPARE(renderWidgetHostViewQtDelegateItem->cursor().shape(), Qt::PointingHandCursor);
+    QTRY_COMPARE(view.cursor().shape(), Qt::PointingHandCursor);
+}
+
 QTEST_MAIN(tst_QWebEngineView)
 #include "tst_qwebengineview.moc"

From 5258b46bab75d62e048f3d931c73434d7006053f Mon Sep 17 00:00:00 2001
From: Topi Reinio <topi.reinio@qt.io>
Date: Mon, 29 Jul 2024 13:39:44 +0000
Subject: [PATCH 087/356] Doc: Fix link to Qt Widgets Designer

'Qt Designer' has been renamed to 'Qt Widgets Designer'.

Change-Id: Iebb09d61b0b600acee71a17e0cb80855e68ad0be
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
(cherry picked from commit ac70cdbec9caa10baa88b598e1409baf8afb44c0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc b/examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc
index b56958a9f28..6fb0fe65f19 100644
--- a/examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc
+++ b/examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc
@@ -15,11 +15,12 @@
     \e {PDF Viewer} demonstrates how to use the QPdfView class to render
     PDF documents and the QPdfPageNavigator class to navigate them.
 
-    Qt Creator and the integrated Qt Designer were used to create the example
-    UI and to connect it to the code. This affects the code, which might be
-    somewhat different to what you would typically write by hand.
-    For more information about using Qt Designer, see \l{Qt Designer Manual}
-    and \l{Qt Creator: Creating a Qt Widget Based Application}.
+    Qt Creator and the integrated Qt Widgets Designer were used to create the
+    example UI and to connect it to the code. This affects the code, which
+    might be somewhat different to what you would typically write by hand.
+    For more information about using Qt Widgets Designer, see
+    \l{Qt Widgets Designer Manual} and
+    \l{Qt Creator: Creating a Qt Widget Based Application}.
 
     \include examples-run.qdocinc
 

From 68c386f613304dafb5fd12122d90b80287ce19f7 Mon Sep 17 00:00:00 2001
From: Alexandru Croitor <alexandru.croitor@qt.io>
Date: Wed, 17 Jul 2024 17:34:58 +0200
Subject: [PATCH 088/356] CMake: Mark WebEngineCore and Pdf SBOM as incomplete
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The build system doesn't know about all the Chromium dependencies to
automatically add them to the generated SBOM, so mark those modules as
containing incomplete information regarding 3rd party dependencies.

Task-number: QTBUG-122899
Change-Id: I9475e02a0633e0f6eaa86e1d7d2335e949c7dc97
Reviewed-by: Kai Köhne <kai.koehne@qt.io>
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit 5ae7396128a16cc177c024779dddf1373d7e584a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/CMakeLists.txt | 1 +
 src/pdf/CMakeLists.txt      | 1 +
 2 files changed, 2 insertions(+)

diff --git a/src/core/api/CMakeLists.txt b/src/core/api/CMakeLists.txt
index 2a06baec664..916c219d0a3 100644
--- a/src/core/api/CMakeLists.txt
+++ b/src/core/api/CMakeLists.txt
@@ -64,6 +64,7 @@ qt_internal_add_module(WebEngineCore
     EXTRA_CMAKE_FILES
         "${CMAKE_CURRENT_LIST_DIR}/${INSTALL_CMAKE_NAMESPACE}WebEngineCoreDeploySupport.cmake"
     NO_GENERATE_CPP_EXPORTS
+    SBOM_INCOMPLETE_3RD_PARTY_DEPENDENCIES
 )
 
 set_target_properties(WebEngineCore PROPERTIES QTWEBENGINEPROCESS_NAME ${qtWebEngineProcessName})
diff --git a/src/pdf/CMakeLists.txt b/src/pdf/CMakeLists.txt
index 41018e7da3b..eeb84a8e1c7 100644
--- a/src/pdf/CMakeLists.txt
+++ b/src/pdf/CMakeLists.txt
@@ -38,6 +38,7 @@ qt_internal_add_module(Pdf
     PUBLIC_LIBRARIES
         Qt::Core
         Qt::Gui
+    SBOM_INCOMPLETE_3RD_PARTY_DEPENDENCIES
 )
 
 add_subdirectory(plugins/imageformats/pdf)

From 26e2dcfd6d4bdfcd1e8e2ff71db135cb1b588051 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Wed, 31 Jul 2024 14:56:23 +0000
Subject: [PATCH 089/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I287e2c816340602449a8cca59c648b397b1a7da9
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index f55af2592f4..57bcc2da1bf 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 97a77aa53435bae6e8b3de6c0c1af0631f6e9e8a
+    ref: 523cca30bb6e0aaa1e3f7ebd26328613b893c174
     required: true
   ../qtpositioning:
-    ref: 498f49315d2a82881141df179c3456e3cf7bf24e
+    ref: 62b231fd7081a4211d5aff7908c0b83f1dcc79fd
     required: false
   ../qttools:
-    ref: d5c328f71aff66f88133715abeffeb66bee6127b
+    ref: 912881b3dac1b2ec0b9444f64836fc1a3d703805
     required: false
   ../qtwebchannel:
-    ref: 4e9162619e853c40693a0cd16d0a500a92da278f
+    ref: 0e8015fcce752ed01c80ee6a546108caec0dd663
     required: false

From a88641175a6897c8e9cac2b00a1e202e17088f9c Mon Sep 17 00:00:00 2001
From: Marc Mutz <marc.mutz@qt.io>
Date: Thu, 18 Jul 2024 16:44:36 +0200
Subject: [PATCH 090/356] Port to std::snprintf() and mark the module
 qsnprintf()-clean

Task-number: QTBUG-127110
Change-Id: I3f6cd72e3781b8cf0cc6ba1032eccf4ce485f989
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 95f7e7cb09296ddcba93377cd80804e8d00f5d04)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 .cmake.conf                                | 1 +
 tests/auto/quick/qmltests/tst_qmltests.cpp | 4 +++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/.cmake.conf b/.cmake.conf
index 8c2e0e6728c..7bf893be9ee 100644
--- a/.cmake.conf
+++ b/.cmake.conf
@@ -3,3 +3,4 @@ set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1")
 set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_WEBENGINE "3.19")
 set(QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_NO_AS_CONST=1")
 list(APPEND QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_NO_FOREACH=1")
+list(APPEND QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_NO_QSNPRINTF=1")
diff --git a/tests/auto/quick/qmltests/tst_qmltests.cpp b/tests/auto/quick/qmltests/tst_qmltests.cpp
index 01a657e8b44..79c9965a25d 100644
--- a/tests/auto/quick/qmltests/tst_qmltests.cpp
+++ b/tests/auto/quick/qmltests/tst_qmltests.cpp
@@ -19,6 +19,8 @@
 #include <QtWebEngineQuick/qtwebenginequickglobal.h>
 #include <qt_webengine_quicktest.h>
 
+#include <cstdio>
+
 #if defined(Q_OS_LINUX) && defined(QT_DEBUG)
 #include <fcntl.h>
 #include <signal.h>
@@ -75,7 +77,7 @@ static void stackTrace()
 
     fprintf(stderr, "\n========= Received signal, dumping stack ==============\n");
     char cmd[512];
-    qsnprintf(cmd, 512, "gdb --pid %d 2>/dev/null <<EOF\n"
+    std::snprintf(cmd, 512, "gdb --pid %d 2>/dev/null <<EOF\n"
                         "set prompt\n"
                         "set height 0\n"
                         "thread apply all where full\n"

From 8071c23a794ce138255506145e9da66a6c8169ea Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Thu, 27 Jun 2024 16:22:34 +0200
Subject: [PATCH 091/356] Call QtWebEngineQuick::initialize() earlier in tests

We don't need to call it at all when the test is registered with
W_QTEST_MAIN, and for QTEST_MAIN we should call it within the static
initMain() function called prior to test object instantiation.

Change-Id: I92874d0ac2feede3ed687db52ca1e6f0358ec527
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit e508021e2553029d47bec5ca4912cdb0068bd7be)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 tests/auto/quick/inspectorserver/tst_inspectorserver.cpp  | 8 +++++++-
 .../tst_qquickwebenginedefaultsurfaceformat.cpp           | 2 +-
 .../quick/qquickwebengineview/tst_qquickwebengineview.cpp | 1 -
 tests/auto/quick/qtbug-70248/tst_qtbug-70248.cpp          | 8 ++++++--
 tests/auto/quick/uidelegates/tst_uidelegates.cpp          | 8 +++++++-
 5 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp b/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp
index 32683ad1df5..b025c4eaafd 100644
--- a/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp
+++ b/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp
@@ -17,6 +17,8 @@ static const QUrl s_inspectorServerHttpBaseUrl("http://localhost:" INSPECTOR_SER
 class tst_InspectorServer : public QObject {
     Q_OBJECT
 public:
+    static void initMain();
+
     tst_InspectorServer();
 
 private Q_SLOTS:
@@ -36,11 +38,15 @@ private Q_SLOTS:
     QScopedPointer<QQmlComponent> m_component;
 };
 
+void tst_InspectorServer::initMain()
+{
+    QtWebEngineQuick::initialize();
+}
+
 tst_InspectorServer::tst_InspectorServer()
 {
     qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--remote-allow-origins=*");
     qputenv("QTWEBENGINE_REMOTE_DEBUGGING", INSPECTOR_SERVER_PORT);
-    QtWebEngineQuick::initialize();
     QQuickWebEngineProfile::defaultProfile()->setOffTheRecord(true);
     prepareWebViewComponent();
 }
diff --git a/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp
index 64c1cfaa4ec..5b5ef04f252 100644
--- a/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp
+++ b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp
@@ -90,8 +90,8 @@ void tst_QQuickWebEngineDefaultSurfaceFormat::customDefaultSurfaceFormat()
     format.setProfile( QSurfaceFormat::CoreProfile );
     QSurfaceFormat::setDefaultFormat( format );
 
-    QGuiApplication app(argc, argv);
     QtWebEngineQuick::initialize();
+    QGuiApplication app(argc, argv);
 
     initEngineAndViewComponent();
     initWindow();
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index 2a96061fbce..7e90b58b8ec 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -98,7 +98,6 @@ private Q_SLOTS:
 
 tst_QQuickWebEngineView::tst_QQuickWebEngineView()
 {
-    QtWebEngineQuick::initialize();
 
     QVERIFY(QQuickWebEngineProfile::defaultProfile()->isOffTheRecord());
 
diff --git a/tests/auto/quick/qtbug-70248/tst_qtbug-70248.cpp b/tests/auto/quick/qtbug-70248/tst_qtbug-70248.cpp
index 1cf62e80086..7368309c959 100644
--- a/tests/auto/quick/qtbug-70248/tst_qtbug-70248.cpp
+++ b/tests/auto/quick/qtbug-70248/tst_qtbug-70248.cpp
@@ -11,14 +11,18 @@
 class tst_qtbug_70248: public QObject {
     Q_OBJECT
 public:
-    tst_qtbug_70248(){}
+    static void initMain();
 private slots:
     void test();
 };
 
-void tst_qtbug_70248::test()
+void tst_qtbug_70248::initMain()
 {
     QtWebEngineQuick::initialize();
+}
+
+void tst_qtbug_70248::test()
+{
     QScopedPointer<QQmlApplicationEngine> engine;
     QQuickWebEngineProfile::defaultProfile()->setOffTheRecord(true);
     engine.reset(new QQmlApplicationEngine());
diff --git a/tests/auto/quick/uidelegates/tst_uidelegates.cpp b/tests/auto/quick/uidelegates/tst_uidelegates.cpp
index 1c3024d949f..419f2f877fb 100644
--- a/tests/auto/quick/uidelegates/tst_uidelegates.cpp
+++ b/tests/auto/quick/uidelegates/tst_uidelegates.cpp
@@ -16,6 +16,8 @@ class tst_UIDelegates : public QObject
 {
     Q_OBJECT
 public:
+    static void initMain();
+
     tst_UIDelegates();
 
 private Q_SLOTS:
@@ -39,9 +41,13 @@ private Q_SLOTS:
     QScopedPointer<QQmlComponent> m_component;
 };
 
-tst_UIDelegates::tst_UIDelegates()
+void tst_UIDelegates::initMain()
 {
     QtWebEngineQuick::initialize();
+}
+
+tst_UIDelegates::tst_UIDelegates()
+{
     static QQmlEngine *engine = new QQmlEngine(this);
     m_component.reset(new QQmlComponent(engine, this));
     m_component->setData(QByteArrayLiteral("import QtQuick\n"

From 7fbbcbb33b641393068c05afcce94d6d55c5397d Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Mon, 5 Aug 2024 21:58:27 +0000
Subject: [PATCH 092/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Ibdb2e72b9f433e3707b5d278467d4c88a9d18dda
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 57bcc2da1bf..cbd2d6aca8b 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 523cca30bb6e0aaa1e3f7ebd26328613b893c174
+    ref: ec89e7c3986fdfbb91acbb1cbe5594a8a1b5da73
     required: true
   ../qtpositioning:
-    ref: 62b231fd7081a4211d5aff7908c0b83f1dcc79fd
+    ref: 5d8f1f6d222dd467cd892953dfa4695776666c5b
     required: false
   ../qttools:
-    ref: 912881b3dac1b2ec0b9444f64836fc1a3d703805
+    ref: 020b796b547328360023bc871453eaa01990e180
     required: false
   ../qtwebchannel:
-    ref: 0e8015fcce752ed01c80ee6a546108caec0dd663
+    ref: eb217a03daa2b8fd18325d92e45a9b454d5dea62
     required: false

From 3807839e2b0d31e1fd1858d5ea0a7e0073dd41f9 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Tue, 6 Aug 2024 11:56:46 +0200
Subject: [PATCH 093/356] Fix embedded build without x11
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Fix compilation issue when doing ozone build without x11,
deals with:

"error: 'HANDLE_EINTR' was not declared in this scope"

Add also missing proxy channel include.

"note: forward declaration of ‘class IPC::ChannelProxy’"

Task-number: QTBUG-126655
Change-Id: I3d06e7d4ce7afbfa86bb9535a2016bfc4e5586a5
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
(cherry picked from commit 3c79245d74710a3f7948afff209359f0f838d278)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/compositor/native_skia_output_device_opengl.cpp | 2 +-
 src/core/content_browser_client_qt.cpp                   | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/core/compositor/native_skia_output_device_opengl.cpp b/src/core/compositor/native_skia_output_device_opengl.cpp
index 137bc3e2113..017d1714d75 100644
--- a/src/core/compositor/native_skia_output_device_opengl.cpp
+++ b/src/core/compositor/native_skia_output_device_opengl.cpp
@@ -16,12 +16,12 @@
 #include "ui/gl/gl_implementation.h"
 
 #if defined(USE_OZONE)
+#include "base/posix/eintr_wrapper.h"
 #include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h"
 #include "ui/gfx/linux/drm_util_linux.h"
 #include "ui/gfx/linux/native_pixmap_dmabuf.h"
 
 #if BUILDFLAG(IS_OZONE_X11)
-#include "base/posix/eintr_wrapper.h"
 #include "ui/gfx/x/connection.h"
 #include "ui/gfx/x/dri3.h"
 #include "ui/gfx/x/future.h"
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index 341c4629588..642c534e17b 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -32,6 +32,7 @@
 #include "content/public/common/content_switches.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/common/user_agent.h"
+#include "ipc/ipc_channel_proxy.h"
 #include "extensions/buildflags/buildflags.h"
 #include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
 #include "pdf/buildflags.h"

From 5ee7901bc6d7fc44af19a464074413de1a836881 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Tue, 6 Aug 2024 23:54:45 +0000
Subject: [PATCH 094/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I091439bb1a5322cf7c159b02140b5d18d8104bb9
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index cbd2d6aca8b..c3dd5b9136a 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: ec89e7c3986fdfbb91acbb1cbe5594a8a1b5da73
+    ref: 1746bff970ef338c4c6ad48651a82878769675bc
     required: true
   ../qtpositioning:
-    ref: 5d8f1f6d222dd467cd892953dfa4695776666c5b
+    ref: 0e5943c80db8620b7577452d88ee1720bc67a27c
     required: false
   ../qttools:
-    ref: 020b796b547328360023bc871453eaa01990e180
+    ref: 959cd4c2f091440d49cd1d03ccb3b5268e4b0f19
     required: false
   ../qtwebchannel:
-    ref: eb217a03daa2b8fd18325d92e45a9b454d5dea62
+    ref: 78a37dad3e3c859eb5726037916d358ad55e4a8a
     required: false

From 57ba058ac34b6b7582a3b329bf3f5f8ee253e4e7 Mon Sep 17 00:00:00 2001
From: Anu Aliyas <anu.aliyas@qt.io>
Date: Thu, 1 Aug 2024 11:29:59 +0200
Subject: [PATCH 095/356] Avoid crash on WebEngineView destruction with ASAN
 enabled
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The chromium's raw_ptr implementation sets the pointer to null on
destruction if ASAN is enabled. This will lead to crash when trying to
access m_factory which is null from the NativeSkiaOutputDevice::Buffer
destructor. Both buffer and m_factory are members of the class
NativeSkiaOutputDevice. Member variables are deleted in bottom-to-top
order based on their declaration. So, by the time the buffer
destructor is invoked, m_factory is set to null. Used C++ raw pointer
instead of chromium’s raw_ptr and added a nullptr check.

Change-Id: Idfad2f5b1bb2adf8923a8fab872fdbaedf6c49f9
Pick-to: 6.7
Fixes: QTBUG-127611
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
(cherry picked from commit 9bcb567b6799bffe90b6d9f90da42fc331684947)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/compositor/native_skia_output_device.cpp | 2 +-
 src/core/compositor/native_skia_output_device.h   | 9 ++++-----
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/src/core/compositor/native_skia_output_device.cpp b/src/core/compositor/native_skia_output_device.cpp
index 4420e8d59aa..3c916d114ff 100644
--- a/src/core/compositor/native_skia_output_device.cpp
+++ b/src/core/compositor/native_skia_output_device.cpp
@@ -212,7 +212,7 @@ NativeSkiaOutputDevice::Buffer::~Buffer()
     if (m_scopedSkiaWriteAccess)
         endWriteSkia(false);
 
-    if (!m_mailbox.IsZero())
+    if (!m_mailbox.IsZero() && m_parent->m_factory)
         m_parent->m_factory->DestroySharedImage(m_mailbox);
 }
 
diff --git a/src/core/compositor/native_skia_output_device.h b/src/core/compositor/native_skia_output_device.h
index 2c35cef77b4..d2101c0fbf2 100644
--- a/src/core/compositor/native_skia_output_device.h
+++ b/src/core/compositor/native_skia_output_device.h
@@ -164,18 +164,17 @@ class NativeSkiaOutputDevice : public viz::SkiaOutputDevice, public Compositor
 
     void SwapBuffersFinished();
 
+    bool m_requiresAlpha;
+    gpu::SharedImageFactory *const m_factory;
+    gpu::SharedImageRepresentationFactory *const m_representationFactory;
+    viz::SkiaOutputSurfaceDependency *const m_deps;
     mutable QMutex m_mutex;
     Shape m_shape;
     std::unique_ptr<Buffer> m_middleBuffer;
     std::unique_ptr<Buffer> m_backBuffer;
     viz::OutputSurfaceFrame m_frame;
     bool m_readyToUpdate = false;
-    bool m_requiresAlpha;
     scoped_refptr<base::SingleThreadTaskRunner> m_gpuTaskRunner;
-
-    const raw_ptr<gpu::SharedImageFactory> m_factory;
-    const raw_ptr<gpu::SharedImageRepresentationFactory> m_representationFactory;
-    const raw_ptr<viz::SkiaOutputSurfaceDependency> m_deps;
 };
 
 } // namespace QtWebEngineCore

From 446385fd971016efae38079d7fe660afe287892f Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Thu, 8 Aug 2024 02:24:24 +0000
Subject: [PATCH 096/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I67d8163c1d58443486e5cd9cbe358928d4c1c34b
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index c3dd5b9136a..6e2865b074b 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 1746bff970ef338c4c6ad48651a82878769675bc
+    ref: c948d354e00b5f2b3866bc8e39d546dfa475adbc
     required: true
   ../qtpositioning:
-    ref: 0e5943c80db8620b7577452d88ee1720bc67a27c
+    ref: ab2757138c785bb976ffe8196d01a43eb4681507
     required: false
   ../qttools:
-    ref: 959cd4c2f091440d49cd1d03ccb3b5268e4b0f19
+    ref: 453dbf701588b4f91bd1dfced5f5fc256af36b0f
     required: false
   ../qtwebchannel:
-    ref: 78a37dad3e3c859eb5726037916d358ad55e4a8a
+    ref: 63b7cf3b8df497845738969e95b6c74b90371fb3
     required: false

From ef42464fb2ed4d37beced79edee2f9568e399b05 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Fri, 9 Aug 2024 16:56:11 +0000
Subject: [PATCH 097/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Ie26502f6626dbf0999ada55502224e4c8d9a98f7
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 6e2865b074b..7282ef2ccc0 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: c948d354e00b5f2b3866bc8e39d546dfa475adbc
+    ref: 10d00aca5e9da3973bca4b8d083ea11d5b0f1775
     required: true
   ../qtpositioning:
-    ref: ab2757138c785bb976ffe8196d01a43eb4681507
+    ref: 9891aed7411ddb70a3f07d92fca43e59149dc1d4
     required: false
   ../qttools:
-    ref: 453dbf701588b4f91bd1dfced5f5fc256af36b0f
+    ref: b7ca1c6048043a3e0de84729067db18f78b5f92f
     required: false
   ../qtwebchannel:
-    ref: 63b7cf3b8df497845738969e95b6c74b90371fb3
+    ref: 56ad85728e9396cfd917e59011d6e1d72fc25392
     required: false

From 7f5ef6861312fc13a39f056edeb6b12f47f1e3ae Mon Sep 17 00:00:00 2001
From: Topi Reinio <topi.reinio@qt.io>
Date: Sat, 10 Aug 2024 09:34:54 +0000
Subject: [PATCH 098/356] Doc: Fix qhp subproject for examples

Qt WebEngine examples have been divided into two subgroups, Quick and
Widgets -based examples. Modify the qhp subprojects in
qtwebengine.qdocconf to reflect this.

Fixes the following QDoc warning:
    Failed to find qhp.QtWebEngine.subprojects.examples.indexTitle
    'Qt WebEngine Examples'

Change-Id: Ic991e0a53e3c46f1dced0427d20aca3376a1d310
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
(cherry picked from commit 4214333f968446ecb7fe84114b7f6dc52a502a5c)
---
 src/core/doc/qtwebengine.qdocconf | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/src/core/doc/qtwebengine.qdocconf b/src/core/doc/qtwebengine.qdocconf
index 89136314743..4a869b96e15 100644
--- a/src/core/doc/qtwebengine.qdocconf
+++ b/src/core/doc/qtwebengine.qdocconf
@@ -13,7 +13,7 @@ qhp.QtWebEngine.virtualFolder       = qtwebengine
 qhp.QtWebEngine.indexTitle          = Qt WebEngine
 qhp.QtWebEngine.indexRoot           =
 
-qhp.QtWebEngine.subprojects         = classes qmltypes examples
+qhp.QtWebEngine.subprojects         = classes qmltypes examples widgetexamples
 
 qhp.QtWebEngine.subprojects.classes.title = C++ Classes and Namespaces
 qhp.QtWebEngine.subprojects.classes.indexTitle = Qt WebEngine C++ Classes and Namespaces
@@ -25,11 +25,16 @@ qhp.QtWebEngine.subprojects.qmltypes.indexTitle = Qt WebEngine QML Types
 qhp.QtWebEngine.subprojects.qmltypes.selectors = qmltype
 qhp.QtWebEngine.subprojects.qmltypes.sortPages = true
 
-qhp.QtWebEngine.subprojects.examples.title = Examples
-qhp.QtWebEngine.subprojects.examples.indexTitle = Qt WebEngine Examples
-qhp.QtWebEngine.subprojects.examples.selectors = doc:example
+qhp.QtWebEngine.subprojects.examples.title = Examples (Quick)
+qhp.QtWebEngine.subprojects.examples.indexTitle = Qt WebEngine Quick Examples
+qhp.QtWebEngine.subprojects.examples.selectors = group:webengine-examples
 qhp.QtWebEngine.subprojects.examples.sortPages = true
 
+qhp.QtWebEngine.subprojects.widgetexamples.title = Examples (Widgets)
+qhp.QtWebEngine.subprojects.widgetexamples.indexTitle = Qt WebEngine Widgets Examples
+qhp.QtWebEngine.subprojects.widgetexamples.selectors = group:webengine-widgetexamples
+qhp.QtWebEngine.subprojects.widgetexamples.sortPages = true
+
 manifestmeta.highlighted.names += "QtWebEngine/WebEngine Widgets Simple Browser Example" \
                 "QtWebEngine/WebEngine Quick Nano Browser" \
                 "QtWebEngine/Recipe Browser"

From b6d619ef94566f74baa33d8514bf54819c63b839 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Wed, 26 Jun 2024 13:07:47 +0200
Subject: [PATCH 099/356] Mention need for --webEngineArgs also in command line
 options section

We are referring to the command line options section from other sections, so it makes sense to mention the need to use --webEngineArgs there.

Pick-to: 6.7 6.5
Fixes: QTBUG-124878
Change-Id: I600bfcd8cf2d8aada53b883608e2a10ea932bdc2
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 4f2c8c194b535b54b1cba0f0f0e47a9f9e707cf2)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/doc/src/qtwebengine-debugging.qdoc | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/core/doc/src/qtwebengine-debugging.qdoc b/src/core/doc/src/qtwebengine-debugging.qdoc
index 3dd4d9276c3..1d996ad7dc8 100644
--- a/src/core/doc/src/qtwebengine-debugging.qdoc
+++ b/src/core/doc/src/qtwebengine-debugging.qdoc
@@ -90,6 +90,14 @@
             sandboxing of the network service though.
     \endlist
 
+    Any WebEngine command line options should be specified after the
+    \c {--webEngineArgs} option, which is used to separate the user's application
+    specific options from the WebEngine's ones.
+
+    \badcode
+    --webEngineArgs [WebEngine specific options]
+    \endcode
+
     Alternatively, the environment variable QTWEBENGINE_CHROMIUM_FLAGS can be
     set. For example, the following value could be set to disable logging while
     debugging an application called \e mybrowser:

From 227da48ad32159d820185223e680b7b4adf88240 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Tue, 6 Aug 2024 14:23:50 +0200
Subject: [PATCH 100/356] Use proper COM coding in Direct3D implementations

Inspired by
https://learn.microsoft.com/en-us/windows/win32/learnwin32/com-coding-practices
https://learn.microsoft.com/en-us/windows/win32/learnwin32/error-handling-in-com

Change-Id: Ia5b8545af434ca105d87e7634eabc39f731968f6
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 6306c67780038ff6b6c0c43037261475b143248f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 .../native_skia_output_device_direct3d11.cpp  | 57 +++++++++++--------
 .../native_skia_output_device_vulkan.cpp      | 28 ++++-----
 2 files changed, 47 insertions(+), 38 deletions(-)

diff --git a/src/core/compositor/native_skia_output_device_direct3d11.cpp b/src/core/compositor/native_skia_output_device_direct3d11.cpp
index 2f1ed5f61ee..2f9d1dffcc2 100644
--- a/src/core/compositor/native_skia_output_device_direct3d11.cpp
+++ b/src/core/compositor/native_skia_output_device_direct3d11.cpp
@@ -37,43 +37,50 @@ QSGTexture *NativeSkiaOutputDeviceDirect3D11::texture(QQuickWindow *win, uint32_
 
     absl::optional<gl::DCLayerOverlayImage> overlayImage = m_frontBuffer->overlayImage();
     if (!overlayImage) {
-        qWarning("No overlay image.");
+        qWarning("D3D: No overlay image.");
         return nullptr;
     }
 
-    QSGRendererInterface *ri = win->rendererInterface();
-
-    HRESULT status = S_OK;
-    HANDLE sharedHandle = nullptr;
-    IDXGIResource1 *resource = nullptr;
-    if (!overlayImage->nv12_texture()) {
-        qWarning("No D3D texture.");
+    Q_ASSERT(overlayImage->type() == gl::DCLayerOverlayType::kNV12Texture);
+    Microsoft::WRL::ComPtr<ID3D11Texture2D> chromeTexture = overlayImage->nv12_texture();
+    if (!chromeTexture) {
+        qWarning("D3D: No D3D texture.");
         return nullptr;
     }
-    status = overlayImage->nv12_texture()->QueryInterface(__uuidof(IDXGIResource1),
-                                                          (void **)&resource);
-    Q_ASSERT(status == S_OK);
-    status = resource->CreateSharedHandle(NULL, DXGI_SHARED_RESOURCE_READ, NULL, &sharedHandle);
-    Q_ASSERT(status == S_OK);
-    Q_ASSERT(sharedHandle);
-    resource->Release();
+
+    HRESULT hr;
+
+    Microsoft::WRL::ComPtr<IDXGIResource1> dxgiResource;
+    hr = chromeTexture->QueryInterface(IID_PPV_ARGS(&dxgiResource));
+    Q_ASSERT(SUCCEEDED(hr));
+
+    HANDLE sharedHandle = INVALID_HANDLE_VALUE;
+    hr = dxgiResource->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ, nullptr,
+                                          &sharedHandle);
+    Q_ASSERT(SUCCEEDED(hr));
+    Q_ASSERT(sharedHandle != INVALID_HANDLE_VALUE);
 
     // Pass texture between two D3D devices:
-    ID3D11Device1 *device = static_cast<ID3D11Device1 *>(
+    QSGRendererInterface *ri = win->rendererInterface();
+    ID3D11Device *device = static_cast<ID3D11Device *>(
             ri->getResource(win, QSGRendererInterface::DeviceResource));
-
-    ID3D11Texture2D *qtTexture;
-    status = device->OpenSharedResource1(sharedHandle, __uuidof(ID3D11Texture2D),
-                                         (void **)&qtTexture);
-    if (status != S_OK) {
-        qWarning("Failed to share D3D11 texture (%s). This will result in failed rendering. Report "
-                 "the bug, and try restarting with QTWEBENGINE_CHROMIUM_FLAGS=--disble-gpu",
-                 qPrintable(QSystemError::windowsComString(status)));
+    Q_ASSERT(device);
+
+    Microsoft::WRL::ComPtr<ID3D11Device1> device1;
+    hr = device->QueryInterface(IID_PPV_ARGS(&device1));
+    Q_ASSERT(SUCCEEDED(hr));
+
+    ID3D11Texture2D *qtTexture = nullptr;
+    hr = device1->OpenSharedResource1(sharedHandle, IID_PPV_ARGS(&qtTexture));
+    if (FAILED(hr)) {
+        qWarning("D3D: Failed to share D3D11 texture (%s). This will result in failed rendering. "
+                 "Report the bug, and try restarting with QTWEBENGINE_CHROMIUM_FLAGS=--disble-gpu",
+                 qPrintable(QSystemError::windowsComString(hr)));
         ::CloseHandle(sharedHandle);
         return nullptr;
     }
-
     Q_ASSERT(qtTexture);
+
     QQuickWindow::CreateTextureOptions texOpts(textureOptions);
     QSGTexture *texture =
             QNativeInterface::QSGD3D11Texture::fromNative(qtTexture, win, size(), texOpts);
diff --git a/src/core/compositor/native_skia_output_device_vulkan.cpp b/src/core/compositor/native_skia_output_device_vulkan.cpp
index b775276f665..60ceea00d8e 100644
--- a/src/core/compositor/native_skia_output_device_vulkan.cpp
+++ b/src/core/compositor/native_skia_output_device_vulkan.cpp
@@ -177,22 +177,24 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
     externalMemoryImageCreateInfo.pNext = nullptr;
     externalMemoryImageCreateInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT;
 
-    HRESULT status = S_OK;
-    HANDLE sharedHandle = nullptr;
-    IDXGIResource1 *resource = nullptr;
-    if (!overlayImage->nv12_texture()) {
+    Q_ASSERT(overlayImage->type() == gl::DCLayerOverlayType::kNV12Texture);
+    Microsoft::WRL::ComPtr<ID3D11Texture2D> chromeTexture = overlayImage->nv12_texture();
+    if (!chromeTexture) {
         qWarning("VULKAN: No D3D texture.");
         return nullptr;
     }
-    status = overlayImage->nv12_texture()->QueryInterface(__uuidof(IDXGIResource1),
-                                                          (void **)&resource);
-    Q_ASSERT(status == S_OK);
-    status = resource->CreateSharedHandle(NULL, DXGI_SHARED_RESOURCE_READ, NULL, &sharedHandle);
-    Q_ASSERT(status == S_OK);
-    resource->Release();
-
-    if (!sharedHandle)
-        qFatal("VULKAN: Unable to extract shared handle.");
+
+    HRESULT hr;
+
+    Microsoft::WRL::ComPtr<IDXGIResource1> dxgiResource;
+    hr = chromeTexture->QueryInterface(IID_PPV_ARGS(&dxgiResource));
+    Q_ASSERT(SUCCEEDED(hr));
+
+    HANDLE sharedHandle = INVALID_HANDLE_VALUE;
+    hr = dxgiResource->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ, nullptr,
+                                          &sharedHandle);
+    Q_ASSERT(SUCCEEDED(hr));
+    Q_ASSERT(sharedHandle != INVALID_HANDLE_VALUE);
 #endif
 
     constexpr VkImageUsageFlags kUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT

From b7b49831cd9fd556eb83bae3671786637f9a4049 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Wed, 7 Aug 2024 10:59:12 +0200
Subject: [PATCH 101/356] Remove kGLImplementationEGLGLES2 cases for Windows

Native EGL/GLES2 is no longer an allowed GL implementation on Windows
since https://crrev.com/c/1686700

Change-Id: Ic4e74c7f929341ddc42c1db19ea3834caecbe4ca
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 21b0b3431d38b18e02c992c749143daddef5385a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/ozone/gl_context_qt.cpp | 1 -
 src/core/ozone/gl_surface_qt.cpp | 4 +---
 2 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/src/core/ozone/gl_context_qt.cpp b/src/core/ozone/gl_context_qt.cpp
index 08729a78a12..b65f5c75694 100644
--- a/src/core/ozone/gl_context_qt.cpp
+++ b/src/core/ozone/gl_context_qt.cpp
@@ -391,7 +391,6 @@ scoped_refptr<GLContext> CreateGLContext(GLShareGroup *share_group,
         return context;
     }
     case kGLImplementationEGLANGLE:
-    case kGLImplementationEGLGLES2:
         return InitializeGLContext(new GLContextEGL(share_group),
                                    compatible_surface, attribs);
     case kGLImplementationDisabled:
diff --git a/src/core/ozone/gl_surface_qt.cpp b/src/core/ozone/gl_surface_qt.cpp
index cebeb8b67f2..b6f3fa7f6d6 100644
--- a/src/core/ozone/gl_surface_qt.cpp
+++ b/src/core/ozone/gl_surface_qt.cpp
@@ -102,7 +102,6 @@ gl::GLDisplay *InitializeGLOneOffPlatform(gl::GpuPreference gpu_preference)
     GLDisplayEGL *display = GetDisplayEGL(gpu_preference);
     switch (GetGLImplementation()) {
     case kGLImplementationEGLANGLE:
-    case kGLImplementationEGLGLES2:
         if (!InitializeDisplay(display, EGLDisplayPlatform(GetDC(nullptr)))) {
             LOG(ERROR) << "GLDisplayEGL::Initialize failed.";
             return nullptr;
@@ -139,8 +138,7 @@ scoped_refptr<GLSurface> CreateOffscreenGLSurface(GLDisplay *display, const gfx:
             return surface;
         break;
     }
-    case kGLImplementationEGLANGLE:
-    case kGLImplementationEGLGLES2: {
+    case kGLImplementationEGLANGLE: {
         GLDisplayEGL *display_egl = display->GetAs<gl::GLDisplayEGL>();
         if (display_egl->IsEGLSurfacelessContextSupported() && size.width() == 0 && size.height() == 0)
             return InitializeGLSurface(new SurfacelessEGL(display_egl, size));

From 6462c894a141155bbf9a62b11438a0ca081c2935 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Fri, 9 Aug 2024 16:13:19 +0200
Subject: [PATCH 102/356] Update Chromium

Submodule src/3rdparty 95fda5a0..23009a64:
  * [Backport] CVE-2024-7532: Out of bounds memory access in ANGLE (2/2)
  * [Backport] CVE-2024-7532: Out of bounds memory access in ANGLE (1/2)
  * [Backport] CVE-2024-7550: Type Confusion in V8
  * [Backport] CVE-2024-7536: Use after free in WebAudio
  * [Backport] Dependency for CVE-2024-7536
  * [Backport] CVE-2024-7535: Inappropriate implementation in V8
  * [Backport] Security bugs 40063014 and 40068800
  * [Backport] Security bug 340895241 (2/2)
  * [Backport] Security bug 340895241 (1/2)
  * [Backport] Security bug 333453962
  * [Backport] Security bug 341640868
  * [Backport] CVE-2024-7000: Use after free in CSS
  * [Backport] CVE-2024-6999: Inappropriate implementation in FedCM
  * [Backport] CVE-2024-6996: Race in Frames
  * [Backport] CVE-2024-6993: Inappropriate implementation in Canvas
  * [Backport] CVE-2024-6992: Out of bounds memory access in ANGLE
  * [Backport] CVE-2024-6991: Use after free in Dawn
  * [Backport] CVE-2024-6989: Use after free in Loader
  * [Backport] CVE-2024-6778: Race in DevTools
  * [Backport] CVE-2024-6779: Out of bounds memory access in V8
  * [Backport] CVE-2024-6777: Use after free in Navigation
  * [Backport] CVE-2024-6774: Use after free in Screen Capture
  * [Backport] CVE-2024-6776: Use after free in Audio
  * [Backport] CVE-2024-6101: Inappropriate implementation in WebAssembly
  * [Backport] CVE-2024-6103: Use after free in Dawn
  * [Backport] CVE-2024-6100: Type Confusion in V8
  * [Backport] CVE-2024-5836: Inappropriate Implementation in DevTools (3/3)
  * [Backport] CVE-2024-5836: Inappropriate Implementation in DevTools (2/3)
  * [Backport] CVE-2024-5836: Inappropriate Implementation in DevTools (1/3)
  * [Backport] Security bug 332724843
  * Reduce memory pool max size to 1GiB on iOS for QtPDF
  * Fixup: Fix building with system ffmpeg
  * Disable the DisplayLock console messages by default
  * [Backport] CVE-2024-5833: Type Confusion in V8
  * [Backport] CVE-2024-5834: Inappropriate implementation in Dawn.
  * [Backport] Remove usage of AVCodecContext::reordered_opaque
  * [Backport] Roll FFmpeg dep
  * [Backport] Replace deprecated use of AVCodecContext::reordered_opaque
  * [Backport] CVE-2024-4060: Use after free in Dawn
  * [Backport]  CVE-2024-6293: Use after free in Dawn
  * [Backport] CVE-2024-6292: Use after free in Dawn
  * [Backport] CVE-2024-6291: Use after free in Swiftshader
  * [Backport] CVE-2024-6290: Use after free in Dawn
  * [Backport] Security bug 346197738
  * [Backport] Security bug 336214779
  * [Backport] CVE-2024-5840: Policy Bypass in CORS
  * [Backport] CVE-2024-5841: Use after free in V8
  * [Backport] CVE-2024-5845: Use after free in Audio
  * [Backport] CVE-2024-5847: Use after free in PDFium
  * [Backport] CVE-2024-5846: Use after free in PDFium
  * [Backport] CVE-2024-5831: Use after free in Dawn (2/2)
  * [Backport] CVE-2024-5831: Use after free in Dawn (1/2)
  * [Backport] CVE-2024-5832: Use after free in Dawn
  * [Backport] Remove 3PCD console messages issued from RFH
  * [Backport]Add message to console when 3PCD issue gets created

Fixes: QTBUG-127159
Fixes: QTBUG-127901
Fixes: QTBUG-127902
Fixes: QTBUG-127903
Fixes: QTBUG-127893
Fixes: QTBUG-127894
Change-Id: Ie5bfb60deac77d69dcc3205c67edd5c482cff6b8
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit 3986c5041dddd0a4d7cee4b7cab14bcb89d51ba2)
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
---
 CHROMIUM_VERSION                | 2 +-
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index 39028d6d975..ffb8180d5dd 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
 Based on Chromium version:                                      122.0.6261.171
-Patched with security patches up to Chromium version:           124.0.6367.202
+Patched with security patches up to Chromium version:           127.0.6533.99
diff --git a/src/3rdparty b/src/3rdparty
index 95fda5a0e06..23009a64b01 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit 95fda5a0e06d39e23be741dbd52bd8d6597ff86e
+Subproject commit 23009a64b01fa6ee40e04d60ee35bb835dcd1951
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 5c06a0879ed..ccbd333d1f2 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1259,7 +1259,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "124.0.6367.202"; // FIXME: Remember to update
+    return "127.0.6533.99"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From 26bf8a6561e26345307fde23a74a63a289530ad5 Mon Sep 17 00:00:00 2001
From: Allan Sandfeld Jensen <allan.jensen@qt.io>
Date: Mon, 12 Aug 2024 10:27:40 +0200
Subject: [PATCH 103/356] Do not use system re2 by default

It is now more likely to be incompatible than compatible.

Pick-to: 6.7
Fixes: QTBUG-124274
Change-Id: Id0d257afc8964dd7ec7bce2f059b91dfd6391197
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
Reviewed-by: Moss Heim <moss.heim@qt.io>
(cherry picked from commit dcd7664ab873b6476de1bb6cfcb5043fba9aaf3c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 configure.cmake | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configure.cmake b/configure.cmake
index 9fff6c3d507..81b1c95bbe5 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -313,6 +313,7 @@ qt_feature("webengine-developer-build" PRIVATE
 )
 qt_feature("webengine-system-re2" PRIVATE
     LABEL "re2"
+    AUTODETECT FALSE
     CONDITION UNIX AND TEST_re2
 )
 qt_feature("webengine-system-icu" PRIVATE

From b282e4b03709dbfc3b4abab722173fc51d8579e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Mon, 12 Aug 2024 11:39:25 +0200
Subject: [PATCH 104/356] Document Microsoft CRT version runtime requirement

Pick-to: 6.7 6.5
Fixes: QTBUG-125300
Change-Id: Idd9e61b7d081c09e32f44b79c9e49ead982acbc7
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
(cherry picked from commit 112efa88b70a1503fe781035e07e96f5af913539)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/doc/src/qtwebengine-deploying.qdoc | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/core/doc/src/qtwebengine-deploying.qdoc b/src/core/doc/src/qtwebengine-deploying.qdoc
index 3d8a976c8f0..e79d7e1a3fb 100644
--- a/src/core/doc/src/qtwebengine-deploying.qdoc
+++ b/src/core/doc/src/qtwebengine-deploying.qdoc
@@ -29,6 +29,8 @@
         \li On Windows, \QWE only supports Windows Vista or newer as
             target platform. Due to use of newer API in Chromium, Windows XP is
             not supported. WinRT is not supported, either.
+        \li On Windows, the Visual C++ Redistributable version 14.28 or higher
+            is needed to run \QWE applications.
     \endlist
 
     \section1 Deploying Applications Manually

From 5b7570636c57a22822f4181fb878abeee1e3de2c Mon Sep 17 00:00:00 2001
From: Topi Reinio <topi.reinio@qt.io>
Date: Mon, 29 Jul 2024 13:20:17 +0000
Subject: [PATCH 105/356] Doc: Fix linking warnings for Qt WebEngine

Fixes the following warnings:

src/core/doc/src/qwebenginepage_lgpl.qdoc:464:
  (qdoc) warning: Can't link to 'QWebEnginePage::action(WebAction action)'
src/core/api/qwebenginewebauthuxrequest.cpp:109:
  (qdoc) warning: Can't link to
    'WebEngineWebAuthUxRequest.PinEntryReason.Challenge'
src/core/api/qwebenginewebauthuxrequest.cpp:113:
  (qdoc) warning: Can't link to
    'WebEngineWebAuthUxRequest.WebAuthUxState.CollectPin'
src/core/api/qwebenginewebauthuxrequest.cpp:141:
  (qdoc) warning: Can't link to
    'WebEngineWebAuthUxRequest.PinEntryReason.Challenge'
src/webenginequick/api/qquickwebengineprofile.cpp:498:
  (qdoc) warning: Can't link to 'storageName()'
src/webenginequick/api/qquickwebenginescriptcollection.cpp:119:
  (qdoc) warning: Undocumented return value
src/webenginequick/doc/src/webengineview_lgpl.qdoc:879:
  (qdoc) warning: Can't link to 'WebEngineSettings::JavascriptCanPaste'
src/webenginequick/doc/src/webengineview_lgpl.qdoc:880:
  (qdoc) warning: Can't link to
    'WebEngineSettings::JavascriptCanAccessClipboard'

In addition, drop remaining references to 'Pepper Plugin API' as that
documentation was removed in 9d5f94b7f4b954bbe7e261d184420e237c704557.

Change-Id: I41fcddcc909b703705f2c32c2c3860872da60a72
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
(cherry picked from commit 08d9c610cda3571cbec4cf5f0f993e20c3b0acd9)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebenginewebauthuxrequest.cpp                | 4 ++--
 src/core/doc/src/qwebenginepage_lgpl.qdoc                  | 2 +-
 src/core/doc/src/qwebenginesettings_lgpl.qdoc              | 1 -
 src/webenginequick/api/qquickwebengineprofile.cpp          | 2 +-
 src/webenginequick/api/qquickwebenginescriptcollection.cpp | 3 ++-
 src/webenginequick/api/qquickwebenginesettings.cpp         | 2 --
 src/webenginequick/doc/src/webengineview_lgpl.qdoc         | 6 +++---
 7 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/src/core/api/qwebenginewebauthuxrequest.cpp b/src/core/api/qwebenginewebauthuxrequest.cpp
index 1f09e55bba2..8ae856af559 100644
--- a/src/core/api/qwebenginewebauthuxrequest.cpp
+++ b/src/core/api/qwebenginewebauthuxrequest.cpp
@@ -106,7 +106,7 @@
     \li The error details for the PIN prompt.
     \li The number of attempts remaining before a hard lock. Should be ignored unless
         \l{WebEngineWebAuthPinRequest::reason} is
-        \l{WebEngineWebAuthUxRequest.PinEntryReason.Challenge}.
+        \c{WebEngineWebAuthUxRequest.PinEntryReason.Challenge}.
     \li The minimum PIN length that the authenticator will accept for the PIN.
     \endlist
     Use this structure to update the WebAuth UX dialog when the WebAuth UX state is \l
@@ -138,7 +138,7 @@
     \qmlproperty int WebEngineWebAuthPinRequest::remainingAttempts
     \brief The number of attempts remaining before a hard lock. Should be ignored unless
            \l{WebEngineWebAuthPinRequest::reason} is
-           \l{WebEngineWebAuthUxRequest.PinEntryReason.Challenge}.
+           \c{WebEngineWebAuthUxRequest.PinEntryReason.Challenge}.
 */
 
 /*!
diff --git a/src/core/doc/src/qwebenginepage_lgpl.qdoc b/src/core/doc/src/qwebenginepage_lgpl.qdoc
index 630ea507e26..e464a2472b3 100644
--- a/src/core/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/core/doc/src/qwebenginepage_lgpl.qdoc
@@ -461,7 +461,7 @@
     The action is owned by the QWebEnginePage but you can customize the look by
     changing its properties.
 
-    \l{QWebEnginePage::action(WebAction action)} does not have a default styled icon.
+    The returned action does not have a default styled icon.
     Use \l{QWebEngineView::pageAction()} to have an action with a default styled icon.
 
     QWebEnginePage also takes care of implementing the action, so that upon
diff --git a/src/core/doc/src/qwebenginesettings_lgpl.qdoc b/src/core/doc/src/qwebenginesettings_lgpl.qdoc
index dbe9c1d349f..7bd6d292436 100644
--- a/src/core/doc/src/qwebenginesettings_lgpl.qdoc
+++ b/src/core/doc/src/qwebenginesettings_lgpl.qdoc
@@ -105,7 +105,6 @@
             Enables displaying the built-in error pages of Chromium. Enabled by default.
     \value  PluginsEnabled
             Enables support for Pepper plugins, such as the Flash player. Disabled by default.
-            See also \l{Pepper Plugin API}. (Added in Qt 5.6)
     \value  FullScreenSupportEnabled
             Enables fullscreen support in an application. Disabled by default. (Added in Qt 5.6)
     \value  ScreenCaptureEnabled
diff --git a/src/webenginequick/api/qquickwebengineprofile.cpp b/src/webenginequick/api/qquickwebengineprofile.cpp
index 1979d18a0cd..d4adbb45864 100644
--- a/src/webenginequick/api/qquickwebengineprofile.cpp
+++ b/src/webenginequick/api/qquickwebengineprofile.cpp
@@ -487,7 +487,7 @@ void QQuickWebEngineProfile::setStorageName(const QString &name)
     Changing a profile from \e off-the-record to disk-based behavior also requires setting a
     proper storageName.
 
-    \sa storageName()
+    \sa storageName
 */
 
 
diff --git a/src/webenginequick/api/qquickwebenginescriptcollection.cpp b/src/webenginequick/api/qquickwebenginescriptcollection.cpp
index 00ddb78e5db..f5328a134e4 100644
--- a/src/webenginequick/api/qquickwebenginescriptcollection.cpp
+++ b/src/webenginequick/api/qquickwebenginescriptcollection.cpp
@@ -119,7 +119,8 @@ QQuickWebEngineScriptCollection::~QQuickWebEngineScriptCollection() { }
 /*!
     \qmlmethod bool WebEngineScriptCollection::contains(WebEngineScript script)
     \since QtWebEngine 6.2
-    Checks if the specified \a script is in the collection.
+    Returns \c true if the specified \a script is in the collection, \c false
+    otherwise.
     \sa find()
 */
 
diff --git a/src/webenginequick/api/qquickwebenginesettings.cpp b/src/webenginequick/api/qquickwebenginesettings.cpp
index 50fb5c3b0f8..04fd8b61767 100644
--- a/src/webenginequick/api/qquickwebenginesettings.cpp
+++ b/src/webenginequick/api/qquickwebenginesettings.cpp
@@ -184,8 +184,6 @@ bool QQuickWebEngineSettings::errorPageEnabled() const
     Enables support for Pepper plugins, such as the Flash player.
 
     Disabled by default.
-
-   \sa {Pepper Plugin API}
 */
 bool QQuickWebEngineSettings::pluginsEnabled() const
 {
diff --git a/src/webenginequick/doc/src/webengineview_lgpl.qdoc b/src/webenginequick/doc/src/webengineview_lgpl.qdoc
index ac90bb0183c..45b8ec6393b 100644
--- a/src/webenginequick/doc/src/webengineview_lgpl.qdoc
+++ b/src/webenginequick/doc/src/webengineview_lgpl.qdoc
@@ -875,9 +875,9 @@
     \value  WebEngineView.Notifications
             Web notifications for the end-user.
     \value  WebEngineView.ClipboardReadWrite
-            Read and write access for the clipboard. If both \l{WebEngineSettings::JavascriptCanPaste}
-            {JavascriptCanPaste} and \l{WebEngineSettings::JavascriptCanAccessClipboard}
-            {JavascriptCanAccessClipboard} settings are enabled, this permission will always be granted
+            Read and write access for the clipboard. If both \l{WebEngineSettings::}
+            {javascriptCanPaste} and \l{WebEngineSettings::}
+            {javascriptCanAccessClipboard} settings are enabled, this permission will always be granted
             automatically and no feature requests will be made.
             (Added in Qt 6.8)
     \value  WebEngineView.LocalFontsAccess

From 291c9168e152c8b8214ac57b94911980cbd91426 Mon Sep 17 00:00:00 2001
From: Topi Reinio <topi.reinio@qt.io>
Date: Mon, 29 Jul 2024 10:18:27 +0000
Subject: [PATCH 106/356] Doc: Document value types with \qmlvaluetype

As these types are value types, document them as such. Separate
object and value types on the QML module page, and fix the
incorrect \instantiates argument for webEngineFrame.

Change-Id: Ieb654efef0ede0eea7c10537d51cc040dc4e9935
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Moss Heim <moss.heim@qt.io>
(cherry picked from commit 3b830b75df1dbc3eb51fe5b5f910e38e65e47a32)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/doc/qtwebengine.qdocconf                     | 2 +-
 src/webenginequick/doc/src/qtwebengine-qmlmodule.qdoc | 7 +++++++
 src/webenginequick/doc/src/webengine_permission.qdoc  | 3 ++-
 src/webenginequick/doc/src/webengineframe.qdoc        | 4 ++--
 4 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/src/core/doc/qtwebengine.qdocconf b/src/core/doc/qtwebengine.qdocconf
index 4a869b96e15..25f55f154cf 100644
--- a/src/core/doc/qtwebengine.qdocconf
+++ b/src/core/doc/qtwebengine.qdocconf
@@ -22,7 +22,7 @@ qhp.QtWebEngine.subprojects.classes.sortPages = true
 
 qhp.QtWebEngine.subprojects.qmltypes.title = QML Types
 qhp.QtWebEngine.subprojects.qmltypes.indexTitle = Qt WebEngine QML Types
-qhp.QtWebEngine.subprojects.qmltypes.selectors = qmltype
+qhp.QtWebEngine.subprojects.qmltypes.selectors = qmltype qmlvaluetype
 qhp.QtWebEngine.subprojects.qmltypes.sortPages = true
 
 qhp.QtWebEngine.subprojects.examples.title = Examples (Quick)
diff --git a/src/webenginequick/doc/src/qtwebengine-qmlmodule.qdoc b/src/webenginequick/doc/src/qtwebengine-qmlmodule.qdoc
index ecf3a4a6edc..5966fef4741 100644
--- a/src/webenginequick/doc/src/qtwebengine-qmlmodule.qdoc
+++ b/src/webenginequick/doc/src/qtwebengine-qmlmodule.qdoc
@@ -7,6 +7,7 @@
     \brief Provides QML types for rendering web content within a QML application.
     \ingroup qtwebengine-modules
     \ingroup qmlmodules
+    \noautolist
 
     To link against the module using build with qmake,
     add the following QT variable to your qmake .pro file:
@@ -26,4 +27,10 @@
     Where the content of main.qml is simply:
 
     \snippet minimal/main.qml Minimal Example
+
+    \section1 QML object types
+    \generatelist qmltypesbymodule QtWebEngine
+
+    \section1 QML value types
+    \generatelist qmlvaluetypesbymodule QtWebEngine
 */
diff --git a/src/webenginequick/doc/src/webengine_permission.qdoc b/src/webenginequick/doc/src/webengine_permission.qdoc
index e36264240dd..6912ef4fa2c 100644
--- a/src/webenginequick/doc/src/webengine_permission.qdoc
+++ b/src/webenginequick/doc/src/webengine_permission.qdoc
@@ -2,9 +2,10 @@
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
 
 /*!
-    \qmltype webEnginePermission
+    \qmlvaluetype webEnginePermission
     \instantiates QWebEnginePermission
     \inqmlmodule QtWebEngine
+    \since 6.8
     \brief An object used to access and modify the state of a single permission that's been
     granted or denied to a specific origin URL.
 
diff --git a/src/webenginequick/doc/src/webengineframe.qdoc b/src/webenginequick/doc/src/webengineframe.qdoc
index 8f852501ef8..3bcbd30b850 100644
--- a/src/webenginequick/doc/src/webengineframe.qdoc
+++ b/src/webenginequick/doc/src/webengineframe.qdoc
@@ -2,8 +2,8 @@
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
 
 /*!
-    \qmltype webEngineFrame
-    \instantiates QQuickWebEngineFrame
+    \qmlvaluetype webEngineFrame
+    \instantiates QWebEngineFrame
     \brief webEngineFrame provides information about and control over a page frame.
     \since 6.8
     \ingroup qmlvaluetypes

From 635144c58b127cd60434c9a235882413005ab89b Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Mon, 12 Aug 2024 10:16:52 +0200
Subject: [PATCH 107/356] Fix -no-opengl build

Change-Id: I12e88207e1c0c0ece99cf7afd00c555af96bd31f
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 11ae74a9d56a06dee0caf7ffeb881e59d059c846)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/ozone/gl_surface_egl_qt.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/core/ozone/gl_surface_egl_qt.cpp b/src/core/ozone/gl_surface_egl_qt.cpp
index cc588453d16..0ac02681dd3 100644
--- a/src/core/ozone/gl_surface_egl_qt.cpp
+++ b/src/core/ozone/gl_surface_egl_qt.cpp
@@ -53,6 +53,7 @@ gl::GLDisplay *GLSurfaceEGLQt::InitializeOneOff(gl::GpuPreference preference)
                 GLContextHelper::isCreateContextRobustnessSupported();
     }
 
+#if QT_CONFIG(opengl)
     if (egl_display->ext->b_EGL_EXT_image_dma_buf_import
         || egl_display->ext->b_EGL_EXT_image_dma_buf_import_modifiers
         || egl_display->ext->b_EGL_MESA_image_dma_buf_export) {
@@ -61,6 +62,7 @@ gl::GLDisplay *GLSurfaceEGLQt::InitializeOneOff(gl::GpuPreference preference)
         egl_display->ext->b_EGL_EXT_image_dma_buf_import_modifiers = dmaBufSupported;
         egl_display->ext->b_EGL_MESA_image_dma_buf_export = dmaBufSupported;
     }
+#endif
 
     g_config = GLContextHelper::getEGLConfig();
     if (!g_config) {

From 7e8eebaa65386d042c5034e077f31e95540542fa Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Mon, 12 Aug 2024 10:59:21 +0200
Subject: [PATCH 108/356] Do not set Vulkan rendering if RHI is disabled

If Qt is built without OpenGL support, the default graphics API is
Vulkan on Linux. In this case we initialize Chromium with Vulkan
rendering. This doesn't make too much sense if the user requests
software rendering what also disables RHI.

Try to avoid this configuration even if it doesn't cause any known issue.

Change-Id: Ia70366a4edfd7204940fd17dea8763a9aa8e4747
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit cb829408b5f178444d99400b44c37ea7624285cf)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/web_engine_context.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index ccbd333d1f2..a9e0e292a01 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -982,7 +982,7 @@ WebEngineContext::WebEngineContext()
         }
     }
 
-    if (QQuickWindow::graphicsApi() == QSGRendererInterface::Vulkan) {
+    if (QQuickWindow::graphicsApi() == QSGRendererInterface::Vulkan && usingSupportedSGBackend()) {
         enableFeatures.push_back(features::kVulkan.name);
         parsedCommandLine->AppendSwitchASCII(switches::kUseVulkan,
                                              switches::kVulkanImplementationNameNative);

From 37cff5478eed9d4cd7d3063204c0132e2c8d4cbf Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 8 Aug 2024 14:35:59 +0200
Subject: [PATCH 109/356] Exclude ozone sources from non-Linux builds

Keep some of them for WGL on Windows.

Change-Id: Ib10c0fac2fca4f548efc12e573b79838749f62fa
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit fdc2ab963483dbda411c03e621d59d6fe7def308)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/CMakeLists.txt                | 32 ++++++---
 src/core/chromium_overrides.cpp        |  3 +
 src/core/content_main_delegate_qt.cpp  |  2 +
 src/core/content_main_delegate_qt.h    |  9 ++-
 src/core/ozone/gl_share_context_qt.cpp |  3 -
 src/core/ozone/gl_surface_qt.cpp       | 91 --------------------------
 src/core/ozone/gl_surface_wgl_qt.cpp   | 82 ++++++++++++++++++++++-
 src/core/ozone/gl_surface_wgl_qt.h     |  6 +-
 src/core/web_engine_context.cpp        | 14 +++-
 9 files changed, 127 insertions(+), 115 deletions(-)

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 24ccdacbbf4..487ac15fb49 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -98,7 +98,6 @@ foreach(arch ${archs})
                 color_chooser_qt.cpp color_chooser_qt.h
                 common/qt_messages.cpp common/qt_messages.h
                 compositor/compositor.cpp compositor/compositor.h
-                compositor/content_gpu_client_qt.cpp compositor/content_gpu_client_qt.h
                 compositor/display_overrides.cpp
                 compositor/display_software_output_surface.cpp compositor/display_software_output_surface.h
                 compositor/native_skia_output_device.cpp compositor/native_skia_output_device.h
@@ -148,15 +147,6 @@ foreach(arch ${archs})
                 net/url_request_custom_job_proxy.cpp net/url_request_custom_job_proxy.h
                 net/version_ui_qt.cpp net/version_ui_qt.h
                 net/webui_controller_factory_qt.cpp net/webui_controller_factory_qt.h
-                ozone/gl_context_qt.cpp ozone/gl_context_qt.h
-                ozone/gl_ozone_angle_qt.cpp ozone/gl_ozone_angle_qt.h
-                ozone/gl_ozone_egl_qt.cpp ozone/gl_ozone_egl_qt.h
-                ozone/gl_share_context_qt.cpp ozone/gl_share_context_qt.h
-                ozone/gl_surface_egl_qt.cpp ozone/gl_surface_egl_qt.h
-                ozone/gl_surface_qt.cpp ozone/gl_surface_qt.h
-                ozone/gl_surface_wgl_qt.cpp ozone/gl_surface_wgl_qt.h
-                ozone/platform_window_qt.cpp ozone/platform_window_qt.h
-                ozone/surface_factory_qt.cpp ozone/surface_factory_qt.h
                 permission_manager_qt.cpp permission_manager_qt.h
                 pdf_util_qt.cpp pdf_util_qt.h
                 platform_notification_service_qt.cpp platform_notification_service_qt.h
@@ -210,6 +200,28 @@ foreach(arch ${archs})
                 accessibility_activation_observer.cpp accessibility_activation_observer.h
         )
 
+        extend_gn_target(${buildGn} CONDITION LINUX OR WIN32
+            SOURCES
+                compositor/content_gpu_client_qt.cpp compositor/content_gpu_client_qt.h
+                ozone/gl_context_qt.cpp ozone/gl_context_qt.h
+                ozone/gl_share_context_qt.cpp ozone/gl_share_context_qt.h
+                ozone/gl_surface_qt.cpp ozone/gl_surface_qt.h
+        )
+
+        extend_gn_target(${buildGn} CONDITION WIN32
+            SOURCES
+                ozone/gl_surface_wgl_qt.cpp ozone/gl_surface_wgl_qt.h
+        )
+
+        extend_gn_target(${buildGn} CONDITION LINUX
+            SOURCES
+                ozone/gl_ozone_angle_qt.cpp ozone/gl_ozone_angle_qt.h
+                ozone/gl_ozone_egl_qt.cpp ozone/gl_ozone_egl_qt.h
+                ozone/gl_surface_egl_qt.cpp ozone/gl_surface_egl_qt.h
+                ozone/platform_window_qt.cpp ozone/platform_window_qt.h
+                ozone/surface_factory_qt.cpp ozone/surface_factory_qt.h
+        )
+
         extend_gn_target(${buildGn} CONDITION QT_FEATURE_webengine_ozone_x11
             SOURCES
                 ozone/gl_ozone_glx_qt.cpp ozone/gl_ozone_glx_qt.h
diff --git a/src/core/chromium_overrides.cpp b/src/core/chromium_overrides.cpp
index 28917e6c5c2..dd273d3b79b 100644
--- a/src/core/chromium_overrides.cpp
+++ b/src/core/chromium_overrides.cpp
@@ -17,6 +17,7 @@
 #include "gpu/vulkan/buildflags.h"
 #include "ui/base/dragdrop/os_exchange_data.h"
 #include "ui/base/dragdrop/os_exchange_data_provider_factory.h"
+#include "ui/base/ozone_buildflags.h"
 
 #include <QGuiApplication>
 #include <QFontDatabase>
@@ -37,10 +38,12 @@
 #endif // defined(USE_OZONE)
 #endif // defined(ENABLE_VULKAN)
 
+#if BUILDFLAG(IS_OZONE_X11)
 void *GetQtXDisplay()
 {
     return GLContextHelper::getXDisplay();
 }
+#endif
 
 namespace content {
 class RenderViewHostDelegateView;
diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp
index f949d93a5ad..148be4f1c9d 100644
--- a/src/core/content_main_delegate_qt.cpp
+++ b/src/core/content_main_delegate_qt.cpp
@@ -201,11 +201,13 @@ content::ContentBrowserClient *ContentMainDelegateQt::CreateContentBrowserClient
     return m_browserClient.get();
 }
 
+#if defined(USE_OZONE) || BUILDFLAG(IS_WIN)
 content::ContentGpuClient *ContentMainDelegateQt::CreateContentGpuClient()
 {
     m_gpuClient.reset(new ContentGpuClientQt);
     return m_gpuClient.get();
 }
+#endif
 
 content::ContentRendererClient *ContentMainDelegateQt::CreateContentRendererClient()
 {
diff --git a/src/core/content_main_delegate_qt.h b/src/core/content_main_delegate_qt.h
index a177bd6df84..534d9e4dd63 100644
--- a/src/core/content_main_delegate_qt.h
+++ b/src/core/content_main_delegate_qt.h
@@ -6,11 +6,14 @@
 
 #include "content/public/app/content_main_delegate.h"
 
-#include "compositor/content_gpu_client_qt.h"
 #include "content_browser_client_qt.h"
 #include "content_client_qt.h"
 #include "content_utility_client_qt.h"
 
+#if defined(USE_OZONE) || BUILDFLAG(IS_WIN)
+#include "compositor/content_gpu_client_qt.h"
+#endif
+
 namespace QtWebEngineCore {
 
 class ContentMainDelegateQt : public content::ContentMainDelegate
@@ -23,7 +26,9 @@ class ContentMainDelegateQt : public content::ContentMainDelegate
 
     content::ContentClient *CreateContentClient() override;
     content::ContentBrowserClient* CreateContentBrowserClient() override;
+#if defined(USE_OZONE) || BUILDFLAG(IS_WIN)
     content::ContentGpuClient* CreateContentGpuClient() override;
+#endif
     content::ContentRendererClient* CreateContentRendererClient() override;
     content::ContentUtilityClient* CreateContentUtilityClient() override;
     absl::optional<int> BasicStartupComplete() override;
@@ -31,7 +36,9 @@ class ContentMainDelegateQt : public content::ContentMainDelegate
 private:
     ContentClientQt m_contentClient;
     std::unique_ptr<ContentBrowserClientQt> m_browserClient;
+#if defined(USE_OZONE) || BUILDFLAG(IS_WIN)
     std::unique_ptr<ContentGpuClientQt> m_gpuClient;
+#endif
     std::unique_ptr<ContentUtilityClientQt> m_utilityClient;
 };
 
diff --git a/src/core/ozone/gl_share_context_qt.cpp b/src/core/ozone/gl_share_context_qt.cpp
index f2078b59785..56b50084aa5 100644
--- a/src/core/ozone/gl_share_context_qt.cpp
+++ b/src/core/ozone/gl_share_context_qt.cpp
@@ -20,9 +20,6 @@ QtShareGLContext::QtShareGLContext(QOpenGLContext *context)
     : gl::GLContext(nullptr), m_handle(nullptr)
 {
 #if QT_CONFIG(opengl)
-#if defined(Q_OS_MACOS)
-    qFatal("macOS only support using ANGLE.");
-#endif
 #if defined(Q_OS_WIN)
     auto *win_ctx = context->nativeInterface<QNativeInterface::QWGLContext>();
     if (win_ctx && !m_handle)
diff --git a/src/core/ozone/gl_surface_qt.cpp b/src/core/ozone/gl_surface_qt.cpp
index b6f3fa7f6d6..68aa35df3e7 100644
--- a/src/core/ozone/gl_surface_qt.cpp
+++ b/src/core/ozone/gl_surface_qt.cpp
@@ -7,28 +7,10 @@
 
 #include "qtwebenginecoreglobal_p.h"
 
-#if !defined(Q_OS_MACOS)
-
 #include "gl_surface_qt.h"
 
 #include "base/logging.h"
 
-#if BUILDFLAG(IS_WIN)
-#include "web_engine_context.h"
-#include "ozone/gl_surface_wgl_qt.h"
-
-#include "gpu/ipc/service/image_transport_surface.h"
-#include "ui/gl/init/gl_display_initializer.h"
-#include "ui/gl/direct_composition_support.h"
-#include "ui/gl/gl_angle_util_win.h"
-#include "ui/gl/gl_display.h"
-#include "ui/gl/gl_implementation.h"
-#include "ui/gl/gl_surface_egl.h"
-#include "ui/gl/gl_utils.h"
-#include "ui/gl/vsync_provider_win.h"
-#endif
-
-
 namespace gl {
 
 GLDisplay *GLSurfaceQt::g_display = nullptr;
@@ -89,77 +71,4 @@ void* GLSurfaceQt::GetConfig()
     return g_config;
 }
 
-#if BUILDFLAG(IS_WIN)
-namespace init {
-
-gl::GLDisplay *InitializeGLOneOffPlatform(gl::GpuPreference gpu_preference)
-{
-    VSyncProviderWin::InitializeOneOff();
-
-    if (GetGLImplementation() == kGLImplementationDesktopGL || GetGLImplementation() == kGLImplementationDesktopGLCoreProfile)
-        return GLSurfaceWGLQt::InitializeOneOff(gpu_preference);
-
-    GLDisplayEGL *display = GetDisplayEGL(gpu_preference);
-    switch (GetGLImplementation()) {
-    case kGLImplementationEGLANGLE:
-        if (!InitializeDisplay(display, EGLDisplayPlatform(GetDC(nullptr)))) {
-            LOG(ERROR) << "GLDisplayEGL::Initialize failed.";
-            return nullptr;
-        }
-        if (auto d3d11_device = QueryD3D11DeviceObjectFromANGLE())
-            InitializeDirectComposition(std::move(d3d11_device));
-        break;
-    case kGLImplementationMockGL:
-    case kGLImplementationStubGL:
-        break;
-    default:
-        NOTREACHED();
-    }
-    return display;
-}
-
-bool usingSoftwareDynamicGL()
-{
-#if QT_CONFIG(opengl)
-    return QtWebEngineCore::usingSoftwareDynamicGL();
-#else
-    return false;
-#endif // QT_CONFIG(opengl)
-}
-
-scoped_refptr<GLSurface> CreateOffscreenGLSurface(GLDisplay *display, const gfx::Size &size)
-{
-    scoped_refptr<GLSurface> surface;
-    switch (GetGLImplementation()) {
-    case kGLImplementationDesktopGLCoreProfile:
-    case kGLImplementationDesktopGL: {
-        surface = new GLSurfaceWGLQt(size);
-        if (surface->Initialize(GLSurfaceFormat()))
-            return surface;
-        break;
-    }
-    case kGLImplementationEGLANGLE: {
-        GLDisplayEGL *display_egl = display->GetAs<gl::GLDisplayEGL>();
-        if (display_egl->IsEGLSurfacelessContextSupported() && size.width() == 0 && size.height() == 0)
-            return InitializeGLSurface(new SurfacelessEGL(display_egl, size));
-        return InitializeGLSurface(new PbufferGLSurfaceEGL(display_egl, size));
-    }
-    default:
-        break;
-    }
-    LOG(ERROR) << "Requested OpenGL implementation is not supported. Implementation: " << GetGLImplementation();
-    Q_UNREACHABLE();
-    return nullptr;
-}
-
-scoped_refptr<GLSurface>
-CreateViewGLSurface(GLDisplay *display, gfx::AcceleratedWidget window)
-{
-    return nullptr;
-}
-
-} // namespace init
-#endif  // BUILDFLAG(IS_WIN)
 } // namespace gl
-
-#endif // !defined(Q_OS_MACOS)
diff --git a/src/core/ozone/gl_surface_wgl_qt.cpp b/src/core/ozone/gl_surface_wgl_qt.cpp
index db4aed88461..afd68e5a263 100644
--- a/src/core/ozone/gl_surface_wgl_qt.cpp
+++ b/src/core/ozone/gl_surface_wgl_qt.cpp
@@ -2,10 +2,18 @@
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
 
 #include "gl_surface_wgl_qt.h"
+#include "web_engine_context.h"
 
-#if BUILDFLAG(IS_WIN)
+#include "ui/gl/init/gl_display_initializer.h"
+#include "ui/gl/direct_composition_support.h"
+#include "ui/gl/gl_angle_util_win.h"
+#include "ui/gl/gl_display.h"
 #include "ui/gl/gl_display_manager.h"
+#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_surface_egl.h"
 #include "ui/gl/gl_surface_wgl.h"
+#include "ui/gl/gl_utils.h"
+#include "ui/gl/vsync_provider_win.h"
 
 namespace gl {
 
@@ -55,6 +63,74 @@ void *GLSurfaceWGLQt::GetConfig()
     return m_surfaceBuffer->GetConfig();
 }
 
-} //namespace gl
+// Overrides for WGL:
+namespace init {
 
-#endif // BUILDFLAG(IS_WIN)
+gl::GLDisplay *InitializeGLOneOffPlatform(gl::GpuPreference gpu_preference)
+{
+    VSyncProviderWin::InitializeOneOff();
+
+    if (GetGLImplementation() == kGLImplementationDesktopGL || GetGLImplementation() == kGLImplementationDesktopGLCoreProfile)
+        return GLSurfaceWGLQt::InitializeOneOff(gpu_preference);
+
+    GLDisplayEGL *display = GetDisplayEGL(gpu_preference);
+    switch (GetGLImplementation()) {
+    case kGLImplementationEGLANGLE:
+        if (!InitializeDisplay(display, EGLDisplayPlatform(GetDC(nullptr)))) {
+            LOG(ERROR) << "GLDisplayEGL::Initialize failed.";
+            return nullptr;
+        }
+        if (auto d3d11_device = QueryD3D11DeviceObjectFromANGLE())
+            InitializeDirectComposition(std::move(d3d11_device));
+        break;
+    case kGLImplementationMockGL:
+    case kGLImplementationStubGL:
+        break;
+    default:
+        NOTREACHED();
+    }
+    return display;
+}
+
+bool usingSoftwareDynamicGL()
+{
+#if QT_CONFIG(opengl)
+    return QtWebEngineCore::usingSoftwareDynamicGL();
+#else
+    return false;
+#endif // QT_CONFIG(opengl)
+}
+
+scoped_refptr<GLSurface> CreateOffscreenGLSurface(GLDisplay *display, const gfx::Size &size)
+{
+    scoped_refptr<GLSurface> surface;
+    switch (GetGLImplementation()) {
+    case kGLImplementationDesktopGLCoreProfile:
+    case kGLImplementationDesktopGL: {
+        surface = new GLSurfaceWGLQt(size);
+        if (surface->Initialize(GLSurfaceFormat()))
+            return surface;
+        break;
+    }
+    case kGLImplementationEGLANGLE: {
+        GLDisplayEGL *display_egl = display->GetAs<gl::GLDisplayEGL>();
+        if (display_egl->IsEGLSurfacelessContextSupported() && size.width() == 0 && size.height() == 0)
+            return InitializeGLSurface(new SurfacelessEGL(display_egl, size));
+        return InitializeGLSurface(new PbufferGLSurfaceEGL(display_egl, size));
+    }
+    default:
+        break;
+    }
+    LOG(ERROR) << "Requested OpenGL implementation is not supported. Implementation: " << GetGLImplementation();
+    Q_UNREACHABLE();
+    return nullptr;
+}
+
+scoped_refptr<GLSurface>
+CreateViewGLSurface(GLDisplay *display, gfx::AcceleratedWidget window)
+{
+    return nullptr;
+}
+
+} // namespace init
+} // namespace gl
diff --git a/src/core/ozone/gl_surface_wgl_qt.h b/src/core/ozone/gl_surface_wgl_qt.h
index 6c590e46c6d..014b77d766e 100644
--- a/src/core/ozone/gl_surface_wgl_qt.h
+++ b/src/core/ozone/gl_surface_wgl_qt.h
@@ -6,8 +6,6 @@
 
 #include "gl_surface_qt.h"
 
-#if BUILDFLAG(IS_WIN)
-
 namespace gl {
 
 class PbufferGLSurfaceWGL;
@@ -31,7 +29,7 @@ class GLSurfaceWGLQt: public GLSurfaceQt {
     scoped_refptr<PbufferGLSurfaceWGL> m_surfaceBuffer;
 };
 
-}
-#endif // BUILDFLAG(IS_WIN)
+} // namespace gl
+
 #endif // GL_SURFACE_WGL_QT_H
 
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index a9e0e292a01..bc55de20db0 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -95,7 +95,6 @@
 #include "devtools_manager_delegate_qt.h"
 #include "media_capture_devices_dispatcher.h"
 #include "net/webui_controller_factory_qt.h"
-#include "ozone/gl_context_qt.h"
 #include "profile_adapter.h"
 #include "type_conversion.h"
 #include "web_engine_library_info.h"
@@ -114,7 +113,9 @@
 #include <QtQuick/private/qsgrhisupport_p.h>
 #include <QLoggingCategory>
 
-#if QT_CONFIG(opengl)
+#if QT_CONFIG(opengl) && (defined(USE_OZONE) || defined(Q_OS_WIN))
+#include "ozone/gl_context_qt.h"
+
 #include <QOpenGLContext>
 #include <qopenglcontext_platform.h>
 
@@ -527,6 +528,7 @@ static void logContext(const std::string &glType, base::CommandLine *cmd)
             << QLatin1StringView(GLContextHelper::getEglPlatformInterface() ? "yes" : "no")
             << QLatin1StringView("\n");
 #endif
+#if defined(USE_OZONE) || defined(Q_OS_WIN)
         log << QLatin1StringView("Using Shared GL:")
             << QLatin1StringView(qt_gl_global_share_context() ? "yes" : "no")
             << QLatin1StringView("\n");
@@ -552,6 +554,7 @@ static void logContext(const std::string &glType, base::CommandLine *cmd)
                             .arg(sharedFormat.minorVersion());
         }
         log << QLatin1StringView("\n");
+#endif // defined(USE_OZONE) || defined(Q_OS_WIN)
 #endif // QT_CONFIG(opengl)
 
         log << QLatin1StringView("Init Parameters:\n");
@@ -732,8 +735,11 @@ void WebEngineContext::destroy()
 
     // Destroy the main runner, this stops main message loop
     m_browserRunner.reset();
-    // gpu thread is no longer around, so no more cotnext is used, remove the helper
+
+#if QT_CONFIG(opengl) && (defined(USE_OZONE) || defined(Q_OS_WIN))
+    // gpu thread is no longer around, so no more context is used, remove the helper
     GLContextHelper::destroy();
+#endif
 
     // These would normally be in the content-runner, but we allocated them separately:
     m_mojoIpcSupport.reset();
@@ -1026,7 +1032,9 @@ WebEngineContext::WebEngineContext()
 
     initializeFeatureList(parsedCommandLine, enableFeatures, disableFeatures);
 
+#if QT_CONFIG(opengl) && (defined(USE_OZONE) || defined(Q_OS_WIN))
     GLContextHelper::initialize();
+#endif
 
     // If user requested GL support instead of using Skia rendering to
     // bitmaps, use software rendering via software OpenGL. This might be less

From 87b999b0fee11a1a2c4177c82760e9ce7ae00484 Mon Sep 17 00:00:00 2001
From: Anu Aliyas <anu.aliyas@qt.io>
Date: Tue, 18 Jun 2024 15:25:37 +0200
Subject: [PATCH 110/356] Prevent OTR to non-OTR profile switching when the
 storage name is empty

When switching from profile from OTR to non-OTR requires valid storage
name. If it not there, then display a warning message and and don't
switch to disk based behavior.

Fixes: QTBUG-126312
Pick-to: 6.7 6.2
Change-Id: Id689c8b280b4070b9ecbf11c6001685ac4ffd2f3
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 5cf87f1919ec88d5830c1a635da8c70a9cad9d42)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 .../quicknanobrowser/ApplicationRoot.qml              |  4 ++--
 src/webenginequick/api/qquickwebengineprofile.cpp     |  7 +++++++
 tests/auto/quick/qmltests/data/tst_basicProfiles.qml  | 11 ++---------
 tests/auto/quick/qmltests/data/tst_favicon.qml        |  3 ++-
 .../auto/quick/qmltests/data/tst_faviconDatabase.qml  |  9 ++++++---
 5 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/examples/webenginequick/quicknanobrowser/ApplicationRoot.qml b/examples/webenginequick/quicknanobrowser/ApplicationRoot.qml
index 5a27d46df95..bd93cd9aa06 100644
--- a/examples/webenginequick/quicknanobrowser/ApplicationRoot.qml
+++ b/examples/webenginequick/quicknanobrowser/ApplicationRoot.qml
@@ -8,14 +8,14 @@ QtObject {
     id: root
 
     property QtObject defaultProfile: WebEngineProfile {
-        storageName: "Profile"
         offTheRecord: false
-
+        storageName: "Profile"
         Component.onCompleted: {
             let fullVersionList = defaultProfile.clientHints.fullVersionList;
             fullVersionList["QuickNanoBrowser"] = "1.0";
             defaultProfile.clientHints.fullVersionList = fullVersionList;
         }
+
     }
 
     property QtObject otrProfile: WebEngineProfile {
diff --git a/src/webenginequick/api/qquickwebengineprofile.cpp b/src/webenginequick/api/qquickwebengineprofile.cpp
index d4adbb45864..719c3380284 100644
--- a/src/webenginequick/api/qquickwebengineprofile.cpp
+++ b/src/webenginequick/api/qquickwebengineprofile.cpp
@@ -515,6 +515,13 @@ void QQuickWebEngineProfile::setOffTheRecord(bool offTheRecord)
     Q_D(QQuickWebEngineProfile);
     if (d->profileAdapter()->isOffTheRecord() == offTheRecord)
         return;
+
+    if (!offTheRecord && d->profileAdapter()->storageName().isEmpty()) {
+        qWarning("Storage name is empty. Cannot change profile from off-the-record "
+                 "to disk-based behavior as it requires a proper storage name");
+        return;
+    }
+
     ProfileAdapter::HttpCacheType oldCacheType = d->profileAdapter()->httpCacheType();
     ProfileAdapter::PersistentCookiesPolicy oldCookiePolicy = d->profileAdapter()->persistentCookiesPolicy();
     ProfileAdapter::PersistentPermissionsPolicy oldPermissionsPolicy = d->profileAdapter()->persistentPermissionsPolicy();
diff --git a/tests/auto/quick/qmltests/data/tst_basicProfiles.qml b/tests/auto/quick/qmltests/data/tst_basicProfiles.qml
index 11d631344b9..6fcbb08ff8f 100644
--- a/tests/auto/quick/qmltests/data/tst_basicProfiles.qml
+++ b/tests/auto/quick/qmltests/data/tst_basicProfiles.qml
@@ -8,7 +8,7 @@ import Qt.labs.platform
 
 Item {
     WebEngineProfile { id: otrProfile; /* MEMO implicit offTheRecord: true */ }
-    WebEngineProfile { id: nonOtrProfile; offTheRecord: false }
+    WebEngineProfile { id: nonOtrProfile; offTheRecord: false; storageName: 'Test' }
 
     function getPath(path, offset = 1) { return path.substr(path.indexOf(':') + offset, path.length) }
     property string appDataLocation: getPath(getPath(StandardPaths.writableLocation(StandardPaths.AppDataLocation).toString(), 3))
@@ -60,15 +60,9 @@ Item {
 
         function test_nonOtrProfile() {
             let p = nonOtrProfile
+            compare(p.storageName, 'Test')
             verify(!p.offTheRecord)
 
-            compare(p.storageName, '')
-            compare(p.cachePath, '')
-            compare(getPath(p.persistentStoragePath), appDataLocation + '/QtWebEngine/UnknownProfile')
-            compare(p.httpCacheType, WebEngineProfile.MemoryHttpCache)
-            compare(p.httpCacheMaximumSize, 0)
-            compare(p.persistentCookiesPolicy, WebEngineProfile.NoPersistentCookies)
-
             compare(getPath(p.downloadPath), downloadLocation)
             compare(p.httpAcceptLanguage, '')
             verify(p.httpUserAgent !== '')
@@ -77,7 +71,6 @@ Item {
 
             compare(p.userScripts.collection, [])
 
-            p.storageName = 'Test'
             compare(p.storageName, 'Test')
             compare(getPath(p.cachePath), cacheLocation + '/QtWebEngine/' + p.storageName)
             compare(getPath(p.persistentStoragePath), appDataLocation + '/QtWebEngine/' + p.storageName)
diff --git a/tests/auto/quick/qmltests/data/tst_favicon.qml b/tests/auto/quick/qmltests/data/tst_favicon.qml
index d4b5c805366..ce2995424d6 100644
--- a/tests/auto/quick/qmltests/data/tst_favicon.qml
+++ b/tests/auto/quick/qmltests/data/tst_favicon.qml
@@ -19,8 +19,9 @@ TestWebEngineView {
     }
 
     property QtObject nonOTRProfile: WebEngineProfile {
-        persistentStoragePath: tempDir.path() + '/WebEngineFavicon'
         offTheRecord: false
+        storageName: 'WebEngineFavicon'
+        persistentStoragePath: tempDir.path() + '/WebEngineFavicon'
     }
 
     function removeFaviconProviderPrefix(url) {
diff --git a/tests/auto/quick/qmltests/data/tst_faviconDatabase.qml b/tests/auto/quick/qmltests/data/tst_faviconDatabase.qml
index 22250852048..d0292851194 100644
--- a/tests/auto/quick/qmltests/data/tst_faviconDatabase.qml
+++ b/tests/auto/quick/qmltests/data/tst_faviconDatabase.qml
@@ -19,8 +19,9 @@ TestWebEngineView {
     }
 
     property QtObject nonOTRProfile: WebEngineProfile {
-        persistentStoragePath: tempDir.path() + '/WebEngineFavicon'
         offTheRecord: false
+        storageName: 'WebEngineFavicon'
+        persistentStoragePath: tempDir.path() + '/WebEngineFavicon'
     }
 
     function getFaviconPixel(faviconImage) {
@@ -147,8 +148,9 @@ TestWebEngineView {
                     TestWebEngineView {\n
                         TempDir { id: tempDir }
                         profile: WebEngineProfile {\n
-                            persistentStoragePath: tempDir.path() + '/WebEngineFavicon1'\n
                             offTheRecord: false\n
+                            storageName: 'WebEngineFavicon1'\n
+                            persistentStoragePath: tempDir.path() + '/WebEngineFavicon1'\n
                         }\n
                     }", testCase);
 
@@ -159,8 +161,9 @@ TestWebEngineView {
                     TestWebEngineView {\n
                         TempDir { id: tempDir }
                         profile: WebEngineProfile {\n
-                            persistentStoragePath: tempDir.path() + '/WebEngineFavicon2'\n
                             offTheRecord: false\n
+                            storageName: 'WebEngineFavicon2'\n
+                            persistentStoragePath: tempDir.path() + '/WebEngineFavicon2'\n
                         }\n
                     }", testCase);
 

From adf1e4736f3c4f2490c108abeaaa546213cd3878 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Wed, 14 Aug 2024 17:08:34 +0000
Subject: [PATCH 111/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I07d6c79d270da1e469b0306ee66346f48dfdf0ff
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 7282ef2ccc0..6a42ca64446 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 10d00aca5e9da3973bca4b8d083ea11d5b0f1775
+    ref: 2f25a48950aa879049029abe5a0450e2d4441d08
     required: true
   ../qtpositioning:
-    ref: 9891aed7411ddb70a3f07d92fca43e59149dc1d4
+    ref: 3b2af9765053f1d07cb9af4736462ca406be27e7
     required: false
   ../qttools:
-    ref: b7ca1c6048043a3e0de84729067db18f78b5f92f
+    ref: b86f119560588634519a6c49846a6109d88ba20d
     required: false
   ../qtwebchannel:
-    ref: 56ad85728e9396cfd917e59011d6e1d72fc25392
+    ref: 6fe7d5b306da9588f17c1a436f717ada7a3ce6c2
     required: false

From 5fff4a3a9507c741e2dc5918e08a3be54bf6a0d4 Mon Sep 17 00:00:00 2001
From: Tian Shilin <tianshilin@uniontech.com>
Date: Wed, 14 Aug 2024 13:20:00 +0800
Subject: [PATCH 112/356] fix conditional redundancy for totalBytes

m_progressBar->setValue(qRound(100 * receivedBytes / totalBytes));
There is a potential risk of de-zeroing here, since
receivedBytes / totalBytes will trigger a runtime
error if totalBytes is zero. In addition, if totalBytes
is always greater than or equal to 0, then checking for
totalBytes >= 0 is actually redundant, since the concern
should be that totalBytes is not zero. To ensure the robustness
of the code, a check that totalBytes is zero should be added
to prevent divide-by-zero errors. By ensuring that totalBytes
is greater than zero, this improvement not only avoids the
risk of de-zeroing, but also ensures that the percentage
calculation of the progress bar is meaningful. At the same
time, for cases where totalBytes is 0 or unknown, the progress
bar is displayed as 0% and the format is "unknown size".
This is a safer way to handle the situation and is more
in line with the needs of the actual application.

Pick-to: 6.7
Change-Id: I7537243e375f336f5c68ef1cc6ec8ade8fa16e5c
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 16aa88039199e6ffbed95818fb9366db8f47aecf)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 examples/webenginewidgets/simplebrowser/downloadwidget.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/examples/webenginewidgets/simplebrowser/downloadwidget.cpp b/examples/webenginewidgets/simplebrowser/downloadwidget.cpp
index 2fb65e1a8fc..c6d3b0921ee 100644
--- a/examples/webenginewidgets/simplebrowser/downloadwidget.cpp
+++ b/examples/webenginewidgets/simplebrowser/downloadwidget.cpp
@@ -59,7 +59,7 @@ void DownloadWidget::updateWidget()
         Q_UNREACHABLE();
         break;
     case QWebEngineDownloadRequest::DownloadInProgress:
-        if (totalBytes >= 0) {
+        if (totalBytes > 0) {
             m_progressBar->setValue(qRound(100 * receivedBytes / totalBytes));
             m_progressBar->setDisabled(false);
             m_progressBar->setFormat(

From ff364fcb12049afcfe58159ed137203f7b6773fc Mon Sep 17 00:00:00 2001
From: Alexandru Croitor <alexandru.croitor@qt.io>
Date: Tue, 23 Jul 2024 12:24:44 +0200
Subject: [PATCH 113/356] CMake: Skip Intel CET hardening on MSVC

The WebEngineCore library should be built without hardening, to avoid
runtime crashes.

Fixes: QTBUG-127464
Change-Id: I670178acc1dfe67a2e5523e113bba4ca0cbdefbb
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 19a977443c628ad819923b308266699bfb019219)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/CMakeLists.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/core/api/CMakeLists.txt b/src/core/api/CMakeLists.txt
index 916c219d0a3..9ca610d3299 100644
--- a/src/core/api/CMakeLists.txt
+++ b/src/core/api/CMakeLists.txt
@@ -67,6 +67,10 @@ qt_internal_add_module(WebEngineCore
     SBOM_INCOMPLETE_3RD_PARTY_DEPENDENCIES
 )
 
+if(MSVC)
+    qt_internal_skip_intel_cet_hardening(WebEngineCore)
+endif()
+
 set_target_properties(WebEngineCore PROPERTIES QTWEBENGINEPROCESS_NAME ${qtWebEngineProcessName})
 set_target_properties(WebEngineCore PROPERTIES CXX_STANDARD 20)
 # Chromium included headers are not clean

From 3933bf51e4858380f5bea854e912acb57de76cb7 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Mon, 19 Aug 2024 16:37:45 +0200
Subject: [PATCH 114/356] Update Chromium
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Submodule src/3rdparty 23009a64..c091eb3f:
* Add missing check for use_cups
* FIXUP: "Shut GL down on process exit to silence Direct3D11 warnings"
* Shut GL down on process exit to silence Direct3D11 warnings
* [Backport] Enable the PriorityHeader feature by default
* [Backport]Ship Zstd Content-Encoding

Change-Id: I1e28a35a90e37ae1f2c652ff94160e37ded21c55
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
---
 src/3rdparty | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/3rdparty b/src/3rdparty
index 23009a64b01..c091eb3fa68 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit 23009a64b01fa6ee40e04d60ee35bb835dcd1951
+Subproject commit c091eb3fa68e1e9c03147623071fa2015a9e3692

From 0cd5541a1062efb46a0a890ea58b8e031c998dd1 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Wed, 14 Aug 2024 11:56:13 +0200
Subject: [PATCH 115/356] Do not use cups

We do not use print dialog and it seems 'use_cups' is
anyway overridden on linux in config setup to 'false'.

Therefore make sure it stays 'false' also for 'qtpdf'.

In case cups is needed at some point we should switch
from 'cups-config' (wrapped by cups_config_helper.py)
to 'pkg-config' during gn run as the
use of former one is deprecated.

Task-number: QTBUG-120248
Fixes: QTBUG-122407
Change-Id: I150a0b30f4f57fe0f4fe92fe8760eaebe4136bd8
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 09c09126e10f0e7428eab7ede5da6498a560e688)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/CMakeLists.txt      | 6 +-----
 src/core/api/configure.cmake | 5 +----
 src/pdf/CMakeLists.txt       | 1 +
 3 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 487ac15fb49..a05842be2b8 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -356,6 +356,7 @@ foreach(arch ${archs})
             optimize_webui=false
             strip_absolute_paths_from_debug_symbols=false
             pdf_use_skia=true
+            use_cups=false
             use_dawn=false
             skia_use_dawn=false
             devtools_fast_bundle=false
@@ -373,10 +374,6 @@ foreach(arch ${archs})
             ARGS enable_printing enable_basic_printing enable_print_preview enable_pdf
             CONDITION QT_FEATURE_webengine_printing_and_pdf
         )
-        extend_gn_list(gnArgArg
-            ARGS use_cups
-            CONDITION QT_FEATURE_webengine_printing_and_pdf AND NOT WIN32
-        )
         extend_gn_list(gnArgArg
             ARGS enable_plugins
             CONDITION QT_FEATURE_webengine_printing_and_pdf OR
@@ -443,7 +440,6 @@ foreach(arch ${archs})
                 angle_enable_gl=true
                 use_gtk=false # GTK toolkit bindings
                 use_qt=false # Qt5 toolkit bindings
-                use_cups=false
                 use_gio=false
                 use_bundled_fontconfig=false
                 use_glib=false
diff --git a/src/core/api/configure.cmake b/src/core/api/configure.cmake
index f8488c05718..47d72767180 100644
--- a/src/core/api/configure.cmake
+++ b/src/core/api/configure.cmake
@@ -18,8 +18,6 @@ if(NOT QT_CONFIGURE_RUNNING)
             pkg_check_modules(GIO gio-2.0)
         endif()
     endif()
-    find_package(Cups)
-
     find_package(Qt6 ${PROJECT_VERSION} CONFIG QUIET
         OPTIONAL_COMPONENTS Positioning WebChannel PrintSupport)
 endif()
@@ -87,8 +85,7 @@ qt_feature("webengine-printing-and-pdf" PRIVATE
     LABEL "Printing and PDF"
     PURPOSE "Provides printing and output to PDF."
     AUTODETECT NOT QT_FEATURE_webengine_embedded_build
-    CONDITION TARGET Qt::PrintSupport AND QT_FEATURE_printer AND
-    (CUPS_FOUND OR WIN32)
+    CONDITION TARGET Qt::PrintSupport AND QT_FEATURE_printer
 )
 qt_feature("webengine-pepper-plugins" PRIVATE
     LABEL "Pepper Plugins"
diff --git a/src/pdf/CMakeLists.txt b/src/pdf/CMakeLists.txt
index eeb84a8e1c7..fcb5f1186cc 100644
--- a/src/pdf/CMakeLists.txt
+++ b/src/pdf/CMakeLists.txt
@@ -124,6 +124,7 @@ foreach(arch ${archs})
           enable_swiftshader_vulkan=false
           angle_enable_swiftshader=false
           dawn_use_swiftshader=false
+          use_cups=false
           use_dawn=false
           build_dawn_tests=false
           enable_ipc_fuzzer=false

From 3b59323898ae990e8f3ae9983c6dea6c3f714a38 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Mon, 19 Aug 2024 10:36:50 +0200
Subject: [PATCH 116/356] QQuickWebEngineProfile: Add missing REVISION to new
 property
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Found during API review.

Change-Id: I2e84f4d9fd5f95f8f4726ed130d67fc715d57d18
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
(cherry picked from commit a2d039da3af62246867c2c6c072893da2f324c39)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/webenginequick/api/qquickwebengineprofile.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/webenginequick/api/qquickwebengineprofile.h b/src/webenginequick/api/qquickwebengineprofile.h
index 27ce9d9fcec..90425c5ca76 100644
--- a/src/webenginequick/api/qquickwebengineprofile.h
+++ b/src/webenginequick/api/qquickwebengineprofile.h
@@ -34,7 +34,7 @@ class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineProfile : public QObject {
     Q_PROPERTY(HttpCacheType httpCacheType READ httpCacheType WRITE setHttpCacheType NOTIFY httpCacheTypeChanged FINAL)
     Q_PROPERTY(QString httpAcceptLanguage READ httpAcceptLanguage WRITE setHttpAcceptLanguage NOTIFY httpAcceptLanguageChanged FINAL REVISION(1,1))
     Q_PROPERTY(PersistentCookiesPolicy persistentCookiesPolicy READ persistentCookiesPolicy WRITE setPersistentCookiesPolicy NOTIFY persistentCookiesPolicyChanged FINAL)
-    Q_PROPERTY(PersistentPermissionsPolicy persistentPermissionsPolicy READ persistentPermissionsPolicy WRITE setPersistentPermissionsPolicy NOTIFY persistentPermissionsPolicyChanged FINAL)
+    Q_PROPERTY(PersistentPermissionsPolicy persistentPermissionsPolicy READ persistentPermissionsPolicy WRITE setPersistentPermissionsPolicy NOTIFY persistentPermissionsPolicyChanged FINAL REVISION(6,8))
     Q_PROPERTY(int httpCacheMaximumSize READ httpCacheMaximumSize WRITE setHttpCacheMaximumSize NOTIFY httpCacheMaximumSizeChanged FINAL)
     Q_PROPERTY(QStringList spellCheckLanguages READ spellCheckLanguages WRITE setSpellCheckLanguages NOTIFY spellCheckLanguagesChanged FINAL REVISION(1,3))
     Q_PROPERTY(bool spellCheckEnabled READ isSpellCheckEnabled WRITE setSpellCheckEnabled NOTIFY spellCheckEnabledChanged FINAL REVISION(1,3))

From 41e27f4e4377b9f567532c29c4cec664061f84ea Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Mon, 19 Aug 2024 16:49:36 +0000
Subject: [PATCH 117/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I32aef9d82dce53c6112483367671b885daab4059
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 6a42ca64446..da7c80c4d53 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 2f25a48950aa879049029abe5a0450e2d4441d08
+    ref: b3a855155422b6183148ad0a8b0a861cb0d84e1b
     required: true
   ../qtpositioning:
-    ref: 3b2af9765053f1d07cb9af4736462ca406be27e7
+    ref: e926e1d7a86a65b3dd6132c43e6866d3eceb6114
     required: false
   ../qttools:
-    ref: b86f119560588634519a6c49846a6109d88ba20d
+    ref: 751d170ff4b4b56f251875b8e0ffd1fc4e96f7e7
     required: false
   ../qtwebchannel:
-    ref: 6fe7d5b306da9588f17c1a436f717ada7a3ce6c2
+    ref: 21ba04c7bd7880e23482eec9b464e48609e589b5
     required: false

From d230f880f6c736776c4f1354aa06d20700161156 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Wed, 17 Jul 2024 12:01:49 +0200
Subject: [PATCH 118/356] QWebEnginePermission: Simplify copy constructor and
 assignment

Found during API review

Change-Id: I958fd3d1b719eedb72970c2718ab9d35a2d887e8
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 69d2e050434c17483b94f0f9be9ba6cdd6883333)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebenginepermission.cpp | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/src/core/api/qwebenginepermission.cpp b/src/core/api/qwebenginepermission.cpp
index 0cee6506b8a..7a5a2ab414e 100644
--- a/src/core/api/qwebenginepermission.cpp
+++ b/src/core/api/qwebenginepermission.cpp
@@ -89,7 +89,7 @@ QWebEnginePermission::QWebEnginePermission(QWebEnginePermissionPrivate *pvt)
 }
 
 QWebEnginePermission::QWebEnginePermission(const QWebEnginePermission &other)
-    : d_ptr(new QWebEnginePermissionPrivate(*other.d_ptr))
+    : d_ptr(other.d_ptr)
 {
 }
 
@@ -102,10 +102,7 @@ QWebEnginePermission::~QWebEnginePermission() = default;
 
 QWebEnginePermission &QWebEnginePermission::operator=(const QWebEnginePermission &other)
 {
-    if (this == &other)
-        return *this;
-
-    d_ptr.reset(new QWebEnginePermissionPrivate(*other.d_ptr));
+    d_ptr = other.d_ptr;
     return *this;
 }
 

From 1dba5a2a42f75db182081f1e48ea35759bb7d62a Mon Sep 17 00:00:00 2001
From: Tian Shilin <tianshilin@uniontech.com>
Date: Wed, 14 Aug 2024 14:38:55 +0800
Subject: [PATCH 119/356] fix: Avoid empty engine

The engine variable is obtained by calling
qmlEngine(m_view). If m_view is not associated
with a valid QML engine, then the engine may be
null,so advancing the null check on the engine
to immediately after the engine is fetched ensures
that an invalid engine is not accidentally used in
subsequent code, especially if(m_importDirs.isEmpty()
&& !initializeImportDirs(m_importDirs, engine)),which
I verified with a static scan tool to verify the
above statement,and found that it does indeed
result in a nullpointer error of type

Pick-to: 6.7
Change-Id: I8cc427d2b94f93e8c9fc24a202d41abd8e00143d
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit b13a99a01e950bfd471f5ade8455dade2504fe6b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/webenginequick/ui_delegates_manager.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/webenginequick/ui_delegates_manager.cpp b/src/webenginequick/ui_delegates_manager.cpp
index a4a22fedd7d..3b14c2821f4 100644
--- a/src/webenginequick/ui_delegates_manager.cpp
+++ b/src/webenginequick/ui_delegates_manager.cpp
@@ -111,6 +111,10 @@ UIDelegatesManager::~UIDelegatesManager()
 bool UIDelegatesManager::ensureComponentLoaded(ComponentType type)
 {
     QQmlEngine* engine = qmlEngine(m_view);
+
+    if (!engine)
+        return false;
+
     if (m_importDirs.isEmpty() && !initializeImportDirs(m_importDirs, engine))
         return false;
 
@@ -128,8 +132,6 @@ bool UIDelegatesManager::ensureComponentLoaded(ComponentType type)
 #else // Unconditionally reload the components each time.
     fprintf(stderr, "%s: %s\n", Q_FUNC_INFO, qPrintable(fileName));
 #endif
-    if (!engine)
-        return false;
 
     for (const QString &importDir : std::as_const(m_importDirs)) {
         const QString componentFilePath = importDir % QLatin1Char('/') % fileName;

From c407b198b7f8a42ad639d04be5d11cef3e7e6c7b Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Mon, 4 Mar 2024 13:38:47 +0100
Subject: [PATCH 120/356] Hook up quicknanobrowser to screen capturing API

A Qt Quick API was implemented alongside the Widgets one, but it
seems the quicknanobrowser example was never updated to make use of it.

Pick-to: 6.7
Change-Id: I8ac996f2237a2673bdbbab85a8174fa166fdd5b1
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 0d9e429b4de070eaac5d5508832f22efdcdf633f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 examples/webenginequick/quicknanobrowser/BrowserWindow.qml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/examples/webenginequick/quicknanobrowser/BrowserWindow.qml b/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
index 02f5564aca2..1c31ea94409 100644
--- a/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
+++ b/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
@@ -561,6 +561,7 @@ ApplicationWindow {
                 settings.webRTCPublicInterfacesOnly: appSettings.webRTCPublicInterfacesOnly
                 settings.pdfViewerEnabled: appSettings.pdfViewerEnabled
                 settings.imageAnimationPolicy: appSettings.imageAnimationPolicy
+                settings.screenCaptureEnabled: true
 
                 onCertificateError: function(error) {
                     if (!error.isMainFrame) {
@@ -610,6 +611,11 @@ ApplicationWindow {
                     request.accept();
                 }
 
+                onDesktopMediaRequested: function(request) {
+                    // select the primary screen
+                    request.selectScreen(request.screensModel.index(0, 0));
+                }
+
                 onRenderProcessTerminated: function(terminationStatus, exitCode) {
                     var status = "";
                     switch (terminationStatus) {

From b12082cec301d108074fb468471e5d1f6e86bb2e Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Mon, 19 Aug 2024 16:11:20 +0200
Subject: [PATCH 121/356] Make ResourceTypeJson documented as 6.8 value in enum
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Adaptations 122-based return this resource type
so make it already documented in 6.8.

Change-Id: I2e03eb387c60dca6ef4b7326b5ce786ea122f55b
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
(cherry picked from commit 78bcc5b2f1348f328a22c45d642e0eb7251e4265)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebengineurlrequestinfo.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp
index b323b5ec3b3..e3335f559c0 100644
--- a/src/core/api/qwebengineurlrequestinfo.cpp
+++ b/src/core/api/qwebengineurlrequestinfo.cpp
@@ -161,7 +161,7 @@ QWebEngineUrlRequestInfo::QWebEngineUrlRequestInfo(QWebEngineUrlRequestInfoPriva
     \value ResourceTypeNavigationPreloadSubFrame  A sub-frame service worker navigation preload request. (Added in Qt 5.14)
     \value ResourceTypeWebSocket  A WebSocket request. (Added in Qt 6.4)
     \value ResourceTypeUnknown  Unknown request type.
-    \value ResourceTypeJson A JSON module. (Added in Qt 6.9)
+    \value ResourceTypeJson A JSON module. (Added in Qt 6.8)
 
     \note For forward compatibility all values not matched should be treated as unknown,
     not just \c ResourceTypeUnknown.

From 707e2ef267f5798245b5d0d646aaa121137fdd43 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Thu, 22 Aug 2024 09:54:45 +0200
Subject: [PATCH 122/356] Fix cross comile error for apalis-imx8

Deals with:

"error: operands to '?:' have different types 'intptr_t' {aka 'long
int'} and 'EGLNativeDisplayType' {aka 'wl_display*'}"

Task-number: QTBUG-126655
Change-Id: I62b2369b2dff2b7a2929a91d59cde4d24b8c2398
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 639d9f5b547486281bb1c218dc87f968c69a2642)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/ozone/gl_ozone_egl_qt.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/core/ozone/gl_ozone_egl_qt.cpp b/src/core/ozone/gl_ozone_egl_qt.cpp
index 26d11df3157..8cc79384151 100644
--- a/src/core/ozone/gl_ozone_egl_qt.cpp
+++ b/src/core/ozone/gl_ozone_egl_qt.cpp
@@ -75,7 +75,8 @@ scoped_refptr<gl::GLSurface> GLOzoneEGLQt::CreateOffscreenGLSurface(gl::GLDispla
 gl::EGLDisplayPlatform GLOzoneEGLQt::GetNativeDisplay()
 {
     static void *display = GLContextHelper::getNativeDisplay();
-    static gl::EGLDisplayPlatform platform(display ? reinterpret_cast<intptr_t>(display) : EGL_DEFAULT_DISPLAY);
+    static gl::EGLDisplayPlatform platform(display ? reinterpret_cast<EGLNativeDisplayType>(display)
+                                                   : EGL_DEFAULT_DISPLAY);
     return platform;
 }
 

From 8e25079b80ae53d2192e33f8162cd1f9afa9f92c Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Thu, 22 Aug 2024 22:26:45 +0000
Subject: [PATCH 123/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I46e6cbb8bf5e00178fd4a11cebaa214170202027
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index da7c80c4d53..86f8978b78f 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: b3a855155422b6183148ad0a8b0a861cb0d84e1b
+    ref: 68a468980fe9831ad81fb382cf9d17a03236d4bb
     required: true
   ../qtpositioning:
-    ref: e926e1d7a86a65b3dd6132c43e6866d3eceb6114
+    ref: 2977c2489d6a8434cfac6b055564eaf19cd4faf5
     required: false
   ../qttools:
-    ref: 751d170ff4b4b56f251875b8e0ffd1fc4e96f7e7
+    ref: 5a3155df8ca8fc9ff491ebf0b28f5c4a4ec5a30d
     required: false
   ../qtwebchannel:
-    ref: 21ba04c7bd7880e23482eec9b464e48609e589b5
+    ref: 518ce9061cad91d3780c559412c2657ee38bd527
     required: false

From 9f4c1bc7c7baac93995e764b1a177e5772c29b93 Mon Sep 17 00:00:00 2001
From: Allan Sandfeld Jensen <allan.jensen@qt.io>
Date: Fri, 2 Feb 2024 13:49:16 +0100
Subject: [PATCH 124/356] Make QQuickWebEngineDownloadRequest public

We only really need the QWebEngineDownloadRequest, but the fact
it was just that was in the private header.

Fixes: QTBUG-120370
Change-Id: I9bcd79e068e67ec0ed07ae31cfb2a0d4e011e22b
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit 712607ff9ce24779393fa44163705916ebf9b3a7)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/webenginequick/CMakeLists.txt             |  2 +-
 .../api/qquickwebenginedownloadrequest.cpp    |  5 ++--
 ...t_p.h => qquickwebenginedownloadrequest.h} | 23 +++++--------------
 .../api/qquickwebengineprofile.cpp            |  2 +-
 tests/auto/quick/publicapi/tst_publicapi.cpp  |  4 ++--
 .../tst_qquickwebengineview.cpp               |  2 +-
 6 files changed, 14 insertions(+), 24 deletions(-)
 rename src/webenginequick/api/{qquickwebenginedownloadrequest_p.h => qquickwebenginedownloadrequest.h} (63%)

diff --git a/src/webenginequick/CMakeLists.txt b/src/webenginequick/CMakeLists.txt
index b7de1c2af35..50d038cc9fa 100644
--- a/src/webenginequick/CMakeLists.txt
+++ b/src/webenginequick/CMakeLists.txt
@@ -18,7 +18,7 @@ qt_internal_add_qml_module(WebEngineQuick
         api/qquickwebengineaction_p_p.h
         api/qquickwebengineclientcertificateselection.cpp api/qquickwebengineclientcertificateselection_p.h
         api/qquickwebenginedialogrequests.cpp api/qquickwebenginedialogrequests_p.h
-        api/qquickwebenginedownloadrequest.cpp api/qquickwebenginedownloadrequest_p.h
+        api/qquickwebenginedownloadrequest.cpp api/qquickwebenginedownloadrequest.h
         api/qquickwebenginefaviconprovider.cpp
         api/qquickwebenginefaviconprovider_p_p.h
         api/qquickwebenginenewwindowrequest.cpp api/qquickwebenginenewwindowrequest_p.h
diff --git a/src/webenginequick/api/qquickwebenginedownloadrequest.cpp b/src/webenginequick/api/qquickwebenginedownloadrequest.cpp
index f745ba3b309..e4892977163 100644
--- a/src/webenginequick/api/qquickwebenginedownloadrequest.cpp
+++ b/src/webenginequick/api/qquickwebenginedownloadrequest.cpp
@@ -1,7 +1,8 @@
 // Copyright (C) 2021 The Qt Company Ltd.
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
 
-#include "qquickwebenginedownloadrequest_p.h"
+#include "qquickwebenginedownloadrequest.h"
+#include "qquickwebengineview_p.h"
 #include "QtWebEngineCore/private/qwebenginedownloadrequest_p.h"
 
 #include "web_contents_adapter_client.h"
@@ -29,4 +30,4 @@ QQuickWebEngineView *QQuickWebEngineDownloadRequest::view() const
 
 QT_END_NAMESPACE
 
-#include "moc_qquickwebenginedownloadrequest_p.cpp"
+#include "moc_qquickwebenginedownloadrequest.cpp"
diff --git a/src/webenginequick/api/qquickwebenginedownloadrequest_p.h b/src/webenginequick/api/qquickwebenginedownloadrequest.h
similarity index 63%
rename from src/webenginequick/api/qquickwebenginedownloadrequest_p.h
rename to src/webenginequick/api/qquickwebenginedownloadrequest.h
index 42a0d88bade..291b59e08ba 100644
--- a/src/webenginequick/api/qquickwebenginedownloadrequest_p.h
+++ b/src/webenginequick/api/qquickwebenginedownloadrequest.h
@@ -1,27 +1,16 @@
 // Copyright (C) 2021 The Qt Company Ltd.
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
 
-#ifndef QQUICKWEBENGINEDOWNLOADREQUEST_P_H
-#define QQUICKWEBENGINEDOWNLOADREQUEST_P_H
-
-//
-//  W A R N I N G
-//  -------------
-//
-// This file is not part of the Qt API.  It exists purely as an
-// implementation detail.  This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtWebEngineQuick/private/qtwebenginequickglobal_p.h>
-#include <QtWebEngineQuick/private/qquickwebengineview_p.h>
+#ifndef QQUICKWEBENGINEDOWNLOADREQUEST_H
+#define QQUICKWEBENGINEDOWNLOADREQUEST_H
+
 #include <QtWebEngineCore/qwebenginedownloadrequest.h>
+#include <QtWebEngineQuick/qtwebenginequickglobal.h>
 #include <QtQml/qqmlregistration.h>
 
 QT_BEGIN_NAMESPACE
 
+class QQuickWebEngineView;
 class QQuickWebEngineProfilePrivate;
 
 class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineDownloadRequest : public QWebEngineDownloadRequest
@@ -43,4 +32,4 @@ class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineDownloadRequest : public QWebEngine
 
 QT_END_NAMESPACE
 
-#endif // QQUICKWEBENGINEDOWNLOADREQUEST_P_H
+#endif // QQUICKWEBENGINEDOWNLOADREQUEST_H
diff --git a/src/webenginequick/api/qquickwebengineprofile.cpp b/src/webenginequick/api/qquickwebengineprofile.cpp
index 719c3380284..4dcdb1af465 100644
--- a/src/webenginequick/api/qquickwebengineprofile.cpp
+++ b/src/webenginequick/api/qquickwebengineprofile.cpp
@@ -3,7 +3,7 @@
 
 #include "qquickwebengineprofile.h"
 #include "qquickwebengineprofile_p.h"
-#include "qquickwebenginedownloadrequest_p.h"
+#include "qquickwebenginedownloadrequest.h"
 #include "qquickwebenginesettings_p.h"
 #include "qquickwebenginescriptcollection_p.h"
 #include "qquickwebenginescriptcollection_p_p.h"
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index 6abaac31567..499acbfc51e 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -8,7 +8,6 @@
 #include <QMetaType>
 #include <QQmlListProperty>
 #include <QtTest/QtTest>
-#include <QtWebEngineQuick/QQuickWebEngineProfile>
 #include <QtWebEngineCore/QWebEngineCertificateError>
 #include <QtWebEngineCore/QWebEngineDesktopMediaRequest>
 #include <QtWebEngineCore/QWebEngineFileSystemAccessRequest>
@@ -28,11 +27,12 @@
 #include <QtWebEngineCore/QWebEngineWebAuthUxRequest>
 #include <QtWebEngineCore/QWebEngineFrame>
 #include <QtWebEngineCore/QWebEnginePermission>
+#include <QtWebEngineQuick/QQuickWebEngineDownloadRequest>
+#include <QtWebEngineQuick/QQuickWebEngineProfile>
 #include <private/qquickwebengineview_p.h>
 #include <private/qquickwebengineaction_p.h>
 #include <private/qquickwebengineclientcertificateselection_p.h>
 #include <private/qquickwebenginedialogrequests_p.h>
-#include <private/qquickwebenginedownloadrequest_p.h>
 #include <private/qquickwebenginenewwindowrequest_p.h>
 #include <private/qquickwebenginesettings_p.h>
 #include <private/qquickwebenginesingleton_p.h>
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index 7e90b58b8ec..c2e4ef210eb 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -15,11 +15,11 @@
 #include <QtGui/qpa/qwindowsysteminterface.h>
 #include <QtQml/QQmlEngine>
 #include <QtTest/QtTest>
+#include <QtWebEngineQuick/QQuickWebEngineDownloadRequest>
 #include <QtWebEngineQuick/QQuickWebEngineProfile>
 #include <QtGui/private/qinputmethod_p.h>
 #include <QtWebEngineQuick/private/qquickwebenginescriptcollection_p.h>
 #include <QtWebEngineQuick/private/qquickwebenginesettings_p.h>
-#include <QtWebEngineQuick/private/qquickwebenginedownloadrequest_p.h>
 #include <QtWebEngineQuick/private/qquickwebengineview_p.h>
 #include <QtWebEngineCore/private/qtwebenginecore-config_p.h>
 #include <qpa/qplatforminputcontext.h>

From 926ed58d2fa9e4cbea9a0fea30637f6627150820 Mon Sep 17 00:00:00 2001
From: Allan Sandfeld Jensen <allan.jensen@qt.io>
Date: Fri, 26 Jul 2024 14:29:10 +0200
Subject: [PATCH 125/356] Mark the persistentPermissionPolicy API as new in 6.8

Was missing.

Change-Id: Ie6bd9659c60bab240431329f469f91dac6b3b176
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
Reviewed-by: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
(cherry picked from commit 86a208192e11563708d262f3415c5b6a4f1c9781)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebengineprofile.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/core/api/qwebengineprofile.cpp b/src/core/api/qwebengineprofile.cpp
index b238d32a5d9..1d78a804af1 100644
--- a/src/core/api/qwebengineprofile.cpp
+++ b/src/core/api/qwebengineprofile.cpp
@@ -599,6 +599,7 @@ void QWebEngineProfile::setPersistentCookiesPolicy(QWebEngineProfile::Persistent
     Off-the-record profiles are not allowed to save data to the disk, so they can only return
     \c StoreInMemory or \c AskEveryTime.
 
+    \since 6.8
     \sa QWebEngineProfile::PersistentPermissionsPolicy, setPersistentPermissionsPolicy()
 */
 QWebEngineProfile::PersistentPermissionsPolicy QWebEngineProfile::persistentPermissionsPolicy() const
@@ -610,6 +611,7 @@ QWebEngineProfile::PersistentPermissionsPolicy QWebEngineProfile::persistentPerm
 /*!
     Sets the policy for persistent permissions to \a newPersistentPermissionsPolicy.
 
+    \since 6.8
     \sa QWebEngineProfile::PersistentPermissionsPolicy, persistentPermissionsPolicy()
 */
 void QWebEngineProfile::setPersistentPermissionsPolicy(QWebEngineProfile::PersistentPermissionsPolicy newPersistentPermissionsPolicy)

From 52455440635a2cc9beb6a5e667fe78f21963030e Mon Sep 17 00:00:00 2001
From: Anu Aliyas <anu.aliyas@qt.io>
Date: Wed, 21 Aug 2024 11:41:07 +0200
Subject: [PATCH 126/356] Document sourceUrl() and setSourceUrl() in
 QWebEngineScript

Added missing documentation for sourceUrl and setSourceUrl in
QWebEngineScript.

Fixes: QTBUG-128140
Pick-to: 6.7
Change-Id: Iff77961060a8b3efea42d074ac66c4800afc0fb3
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit e013c508e99b74866a480a52d6a23aeda0473b4b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebenginescript.cpp | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/src/core/api/qwebenginescript.cpp b/src/core/api/qwebenginescript.cpp
index 29b92a39652..846b011967c 100644
--- a/src/core/api/qwebenginescript.cpp
+++ b/src/core/api/qwebenginescript.cpp
@@ -131,12 +131,26 @@ void QWebEngineScript::setName(const QString &scriptName)
     d->setName(scriptName);
 }
 
-
+/*!
+ * Returns the remote source location of the user script (if any).
+ */
 QUrl QWebEngineScript::sourceUrl() const
 {
     return d->sourceUrl();
 }
 
+/*!
+ * Sets the remote source location of the user script to \a url.
+ *
+ * Unlike \l setSourceCode(), this function allows referring to user scripts that
+ * are not already loaded in memory, for instance, when stored on disk.
+ *
+ * Setting this value will change the \l sourceCode of the script.
+ *
+ * \note At present, only file-based sources are supported.
+ *
+ * \sa setSourceCode()
+ */
 void QWebEngineScript::setSourceUrl(const QUrl &url)
 {
     if (url == sourceUrl())

From f1980f9d7da50d49e4f7bf3ac01d70affc5a9bde Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Sat, 24 Aug 2024 14:06:00 +0000
Subject: [PATCH 127/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I465136e9041aa6136938812b057d1af0c687e42d
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 86f8978b78f..71c937db2b2 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 68a468980fe9831ad81fb382cf9d17a03236d4bb
+    ref: 752bce98f903052d7b9bd30610c326592784576f
     required: true
   ../qtpositioning:
-    ref: 2977c2489d6a8434cfac6b055564eaf19cd4faf5
+    ref: 4b0791714b45c68e9afff61c4bef661ece88235d
     required: false
   ../qttools:
-    ref: 5a3155df8ca8fc9ff491ebf0b28f5c4a4ec5a30d
+    ref: 10dbff6001deea0339f38c5f84edf332c65c665a
     required: false
   ../qtwebchannel:
-    ref: 518ce9061cad91d3780c559412c2657ee38bd527
+    ref: 67d7422d9814f7a9b58ca095ad83791210f85d60
     required: false

From 7107fee8627dd7743f511bc887ad752524711b4a Mon Sep 17 00:00:00 2001
From: Allan Sandfeld Jensen <allan.jensen@qt.io>
Date: Tue, 20 Aug 2024 10:58:08 +0200
Subject: [PATCH 128/356] Set content_enable_legacy_ipc to true

Otherwise it is only indirectly enabled by enable_ppapi,
and we still use legacy ipc.

Change-Id: I0d7c754b746463d43acc5ffc2342280101939ee6
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit bc5cec1a57afd85f0030a04af1ec26af8857c284)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/CMakeLists.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index a05842be2b8..de52226456a 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -363,6 +363,7 @@ foreach(arch ${archs})
             devtools_skip_typecheck=false
             use_static_angle=true
             use_perfetto_client_library=false
+            content_enable_legacy_ipc=true
             enable_extensions_legacy_ipc=true
             enable_bound_session_credentials=false
         )

From c6958702d75e2942fe708427a0bf7d44278c0033 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Thu, 15 Aug 2024 16:27:44 +0200
Subject: [PATCH 129/356] Permission manager: separate tracking of transient
 permissions

Following the rewrite of the permissions API, transient
(a.k.a non-persistent) permissions still passed through
the persistent store sometimes, but were filtered out when
using user-facing APIs. Unfortunately, thisstill presented some
edge cases in the AskEveryTime permission policy mode.

This change modifies the PermissionManagerQt class to store
a second set of permissions, and associate them with a
RenderFrameHost the way the Chromium API is designed to do
anyway. This way, a permission will be kept around for the
lifetime of a web page, and calling JavaScript APIs that
trigger checks for permission state will work properly
(e.g. navigator.mediaDevices.enumerateDevices).
The new store is regularly cleaned up to make sure expired
permissions are purged before they impact performance.

As a side effect, this change also introduces pre-granting
of non-persistent permissions, which was the biggest
omission in the permissions rewrite. In those cases,
the permissions will be temporarily stored inside the
persistent store, and moved to the transient one the next
time they're queried (and can thus be associated with
a RenderFrameHost).

This also fixes some extremely broken test cases that
relied on invalid web API.

Fixes: QTBUG-127951
Change-Id: Ic084af7673ea0b255d98d94382e77323bb5e7ab0
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 8001d8e149b2d109718f6a671c93e3489c4ecd54)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 .../simplebrowser/browser.cpp                 |   1 +
 src/core/api/qwebenginepermission.cpp         |  21 +-
 src/core/api/qwebengineprofile.cpp            |  11 +-
 src/core/permission_manager_qt.cpp            | 224 +++++++++++++++---
 src/core/permission_manager_qt.h              |  30 ++-
 src/core/profile_adapter.cpp                  |  13 +-
 src/core/profile_adapter.h                    |  10 +-
 src/core/web_contents_adapter.cpp             |  23 +-
 src/core/web_contents_delegate_qt.cpp         |  17 +-
 .../doc/src/webengine_permission.qdoc         |   9 +-
 tests/auto/httpserver/data/notification.html  |   4 +-
 .../quick/qmltests/data/tst_geopermission.qml |   5 +
 .../quick/qmltests/data/tst_notification.qml  |   4 +-
 .../qwebenginepage/tst_qwebenginepage.cpp     |   2 -
 .../tst_qwebengineprofile.cpp                 |   8 +-
 15 files changed, 292 insertions(+), 90 deletions(-)

diff --git a/examples/webenginewidgets/simplebrowser/browser.cpp b/examples/webenginewidgets/simplebrowser/browser.cpp
index fd68246d0ce..30c7fc98eab 100644
--- a/examples/webenginewidgets/simplebrowser/browser.cpp
+++ b/examples/webenginewidgets/simplebrowser/browser.cpp
@@ -33,6 +33,7 @@ BrowserWindow *Browser::createHiddenWindow(bool offTheRecord)
     }
     auto profile = !offTheRecord ? m_profile.get() : QWebEngineProfile::defaultProfile();
     auto mainWindow = new BrowserWindow(this, profile, false);
+    profile->setPersistentPermissionsPolicy(QWebEngineProfile::PersistentPermissionsPolicy::AskEveryTime);
     m_windows.append(mainWindow);
     QObject::connect(mainWindow, &QObject::destroyed, [this, mainWindow]() {
         m_windows.removeOne(mainWindow);
diff --git a/src/core/api/qwebenginepermission.cpp b/src/core/api/qwebenginepermission.cpp
index 7a5a2ab414e..d6f5ed98fcc 100644
--- a/src/core/api/qwebenginepermission.cpp
+++ b/src/core/api/qwebenginepermission.cpp
@@ -54,7 +54,7 @@ QWebEnginePermissionPrivate::QWebEnginePermissionPrivate(const QUrl &origin_, QW
 
     \l QWebEnginePermission::PermissionType describes all the permission types Qt WebEngine supports. Only some permission types
     are remembered between browsing sessions; they are \e persistent. Non-persistent permissions query the user every time a
-    website requests them, and cannot be granted in advance. You can check whether a permission type is persistent at runtime
+    website requests them. You can check whether a permission type is persistent at runtime
     using the static method QWebEnginePermission::isPersistent().
 
     Persistent permissions are stored inside the active QWebEngineProfile, and their lifetime depends on the value of
@@ -166,8 +166,7 @@ QUrl QWebEnginePermission::origin() const
     \value Unsupported An unsupported permission type.
 
     \note Non-persistent permission types are ones that will never be remembered by the underlying storage, and will trigger
-    a permission request every time a website tries to use them. They can only be denied/granted as they're needed;
-    any attempts to pre-grant a non-persistent permission will fail.
+    a permission request every time a website tries to use them.
 */
 
 /*!
@@ -196,7 +195,7 @@ QWebEnginePermission::PermissionType QWebEnginePermission::permissionType() cons
 
     If a permission for the specified \l permissionType() and \l origin() has already been granted or denied,
     the return value is QWebEnginePermission::Granted, or QWebEnginePermission::Denied, respectively.
-    When this is the first time the permission is requested, or if the \l permissionType() is non-persistent,
+    When this is the first time the permission is requested,
     the return value is QWebEnginePermission::Ask. If the object is in an invalid state, the returned
     value is QWebEnginePermission::Invalid.
 
@@ -210,8 +209,7 @@ QWebEnginePermission::State QWebEnginePermission::state() const
         return d_ptr->webContentsAdapter.toStrongRef()->getPermissionState(origin(), permissionType());
     if (d_ptr->profileAdapter)
         return d_ptr->profileAdapter->getPermissionState(origin(), permissionType());
-    Q_UNREACHABLE();
-    return State::Ask;
+    Q_UNREACHABLE_RETURN(State::Ask);
 }
 
 /*!
@@ -221,9 +219,8 @@ QWebEnginePermission::State QWebEnginePermission::state() const
     An invalid QWebEnginePermission is either:
     \list
         \li One whose \l permissionType() is unsupported;
-        \li One whose \l permissionType() is non-persistent, and the user has navigated away from the web page that triggered the request;
-        \li One whose \l permissionType() is persistent, but the associated profile has been destroyed;
-        \li One whose \l origin() is invalid.
+        \li One whose \l origin() is invalid;
+        \li One whose associated profile has been destroyed
     \endlist
 
     \sa isPersistent()
@@ -234,9 +231,7 @@ bool QWebEnginePermission::isValid() const
         return false;
     if (permissionType() == PermissionType::Unsupported)
         return false;
-    if (!isPersistent(permissionType()) && !d_ptr->webContentsAdapter)
-        return false;
-    if (!d_ptr->profileAdapter)
+    if (!d_ptr->profileAdapter && !d_ptr->webContentsAdapter)
         return false;
     if (!d_ptr->origin.isValid())
         return false;
@@ -277,7 +272,7 @@ void QWebEnginePermission::deny() const
     Removes the permission from the profile's underlying storage. By default, permissions are stored on disk (except for
     off-the-record profiles, where permissions are stored in memory and are destroyed with the profile).
     This means that an already granted/denied permission will not be requested twice, but will get automatically
-    granted/denied every subsequent time a website requests it. Calling reset() allows the query to be asked
+    granted/denied every subsequent time a website requests it. Calling reset() allows the query to be displayed
     again the next time the website requests it.
 
     Does nothing when \l isValid() evaluates to false.
diff --git a/src/core/api/qwebengineprofile.cpp b/src/core/api/qwebengineprofile.cpp
index 1d78a804af1..b0824af3503 100644
--- a/src/core/api/qwebengineprofile.cpp
+++ b/src/core/api/qwebengineprofile.cpp
@@ -985,7 +985,11 @@ void QWebEngineProfile::requestIconForIconURL(const QUrl &url, int desiredSizeIn
  * for a permission to already exist; the returned object may also be used to pre-grant a permission if a website is
  * known to use it.
  *
- * \note This may only be used for persistent permission types. Calling it with a non-persistent type will return an invalid object.
+ * You may use this to pre-grant a permission of a non-persistent type. Doing so will keep the permission in
+ * the granted (or denied) state until the next time a website with the associated origin requests it. At that point,
+ * the permission's lifetime will be tied to that specific web page's lifetime, and navigating away will invalidate
+ * the permission.
+ *
  * \since 6.8
  * \sa listAllPermissions(), listPermissionsForOrigin(), listPermissionsForPermissionType(), QWebEnginePermission::PermissionType
  */
@@ -998,11 +1002,6 @@ QWebEnginePermission QWebEngineProfile::queryPermission(const QUrl &securityOrig
         return QWebEnginePermission(new QWebEnginePermissionPrivate());
     }
 
-    if (!QWebEnginePermission::isPersistent(permissionType)) {
-        qWarning() << "Attempting to get permission for permission type" << permissionType << ". Returned object will be in an invalid state.";
-        return QWebEnginePermission(new QWebEnginePermissionPrivate());
-    }
-
     auto *pvt = new QWebEnginePermissionPrivate(securityOrigin, permissionType, nullptr, d->profileAdapter());
     return QWebEnginePermission(pvt);
 }
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index 2792a07edf1..2ecac308a8c 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -28,6 +28,11 @@
 
 namespace QtWebEngineCore {
 
+// Extra permission types that don't exist on the Chromium side.
+enum class ExtraPermissionType {
+    POINTER_LOCK = 39, // TODO this exists in Chromium 126, remove after we merge
+};
+
 static QWebEnginePermission::PermissionType toQt(blink::PermissionType type)
 {
     switch (type) {
@@ -48,6 +53,8 @@ static QWebEnginePermission::PermissionType toQt(blink::PermissionType type)
         return QWebEnginePermission::PermissionType::Notifications;
     case blink::PermissionType::LOCAL_FONTS:
         return QWebEnginePermission::PermissionType::LocalFontsAccess;
+    case (blink::PermissionType)ExtraPermissionType::POINTER_LOCK:
+        return QWebEnginePermission::PermissionType::MouseLock;
     case blink::PermissionType::ACCESSIBILITY_EVENTS:
     case blink::PermissionType::CAMERA_PAN_TILT_ZOOM:
     case blink::PermissionType::WINDOW_MANAGEMENT:
@@ -97,8 +104,9 @@ static blink::PermissionType toBlink(QWebEnginePermission::PermissionType permis
         return blink::PermissionType::CLIPBOARD_READ_WRITE;
     case QWebEnginePermission::PermissionType::LocalFontsAccess:
         return blink::PermissionType::LOCAL_FONTS;
-    case QWebEnginePermission::PermissionType::MediaAudioVideoCapture:
     case QWebEnginePermission::PermissionType::MouseLock:
+        return (blink::PermissionType)ExtraPermissionType::POINTER_LOCK;
+    case QWebEnginePermission::PermissionType::MediaAudioVideoCapture:
     case QWebEnginePermission::PermissionType::Unsupported:
         LOG(INFO) << "Unexpected unsupported WebEngine permission type: " << static_cast<int>(permissionType);
         return blink::PermissionType::NUM;
@@ -138,6 +146,14 @@ std::string permissionTypeString(QWebEnginePermission::PermissionType permission
     // e.g. in case we add extra Features that do not correspond to a PermissionType, and
     // we need to store them.
     switch (permissionType) {
+    case QWebEnginePermission::PermissionType::MediaAudioCapture:
+        return "MediaAudioCapture";
+    case QWebEnginePermission::PermissionType::MediaVideoCapture:
+        return "MediaVideoCapture";
+    case QWebEnginePermission::PermissionType::DesktopAudioVideoCapture:
+        return "DesktopAudioVideoCapture";
+    case QWebEnginePermission::PermissionType::MouseLock:
+        return "MouseLock";
     case QWebEnginePermission::PermissionType::Notifications:
         return "Notifications";
     case QWebEnginePermission::PermissionType::Geolocation:
@@ -146,12 +162,6 @@ std::string permissionTypeString(QWebEnginePermission::PermissionType permission
         return "ClipboardReadWrite";
     case QWebEnginePermission::PermissionType::LocalFontsAccess:
         return "LocalFontsAccess";
-    case QWebEnginePermission::PermissionType::MediaAudioCapture:
-        return "MediaAudioCapture";
-    case QWebEnginePermission::PermissionType::MediaVideoCapture:
-        return "MediaVideoCapture";
-    case QWebEnginePermission::PermissionType::DesktopAudioVideoCapture:
-        return "DesktopAudioVideoCapture";
     default:
         Q_UNREACHABLE();
         return nullptr;
@@ -174,6 +184,7 @@ static blink::mojom::PermissionStatus getStatusFromSettings(blink::PermissionTyp
 
 PermissionManagerQt::PermissionManagerQt(ProfileAdapter *profileAdapter)
     : m_requestIdCount(0)
+    , m_transientWriteCount(0)
     , m_profileAdapter(profileAdapter)
     , m_persistence(true)
 {
@@ -195,15 +206,14 @@ PermissionManagerQt::PermissionManagerQt(ProfileAdapter *profileAdapter)
         factory.set_user_prefs(new InMemoryPrefStore);
     }
 
+    m_permissionTypes.push_back(QWebEnginePermission::PermissionType::MediaAudioCapture);
+    m_permissionTypes.push_back(QWebEnginePermission::PermissionType::MediaVideoCapture);
+    m_permissionTypes.push_back(QWebEnginePermission::PermissionType::MouseLock);
     m_permissionTypes.push_back(QWebEnginePermission::PermissionType::Notifications);
     m_permissionTypes.push_back(QWebEnginePermission::PermissionType::Geolocation);
     m_permissionTypes.push_back(QWebEnginePermission::PermissionType::ClipboardReadWrite);
     m_permissionTypes.push_back(QWebEnginePermission::PermissionType::LocalFontsAccess);
 
-    // Transient, but the implementation relies on them being written to storage
-    m_permissionTypes.push_back(QWebEnginePermission::PermissionType::MediaAudioCapture);
-    m_permissionTypes.push_back(QWebEnginePermission::PermissionType::MediaVideoCapture);
-
     // Register all preference types as keys prior to doing anything else
     for (auto &type : m_permissionTypes) {
         prefRegistry->RegisterDictionaryPref(permissionTypeString(type));
@@ -224,23 +234,39 @@ PermissionManagerQt::~PermissionManagerQt()
     commit();
 }
 
-void PermissionManagerQt::setPermission(const QUrl &url, QWebEnginePermission::PermissionType permissionType, QWebEnginePermission::State state)
+void PermissionManagerQt::setPermission(
+    const QUrl &url,
+    QWebEnginePermission::PermissionType permissionType,
+    QWebEnginePermission::State state,
+    content::RenderFrameHost *rfh)
 {
     // Normalize the QUrl to Chromium origin form.
     const GURL gorigin = toGurl(url).DeprecatedGetOriginAsURL();
     const QUrl origin = gorigin.is_empty() ? url : toQt(gorigin);
     if (origin.isEmpty())
         return;
-    if (state == QWebEnginePermission::State::Ask)
-        ResetPermission(toBlink(permissionType), gorigin, gorigin);
-    else
-        setPermission(toBlink(permissionType), gorigin, state == QWebEnginePermission::State::Granted);
-    blink::mojom::PermissionStatus status = toBlink(state);
-    if (state != QWebEnginePermission::State::Ask) {
+
+    // Send eligible permissions with an associated rfh to the transient store. When pre-granting
+    // a non-persistent permission (or pre-granting any permission in AskEveryTime mode), it is allowed
+    // to pass through the persistent store. It will be moved to the transient store and associated
+    // with a rfh the next time its status is requested.
+    bool inTransientStore = rfh && (!QWebEnginePermission::isPersistent(permissionType) || !m_persistence);
+
+    blink::mojom::PermissionStatus blinkStatus = toBlink(state);
+    if (state == QWebEnginePermission::State::Ask) {
+        if (inTransientStore)
+            resetTransientPermission(toBlink(permissionType), gorigin, rfh->GetGlobalFrameToken());
+        else
+            ResetPermission(toBlink(permissionType), gorigin, gorigin);
+    } else {
+        if (inTransientStore)
+            setTransientPermission(toBlink(permissionType), gorigin, state == QWebEnginePermission::State::Granted, rfh->GetGlobalFrameToken());
+        else
+            setPersistentPermission(toBlink(permissionType), gorigin, state == QWebEnginePermission::State::Granted);
         auto it = m_requests.begin();
         while (it != m_requests.end()) {
             if (it->origin == origin && it->type == permissionType) {
-                std::move(it->callback).Run(status);
+                std::move(it->callback).Run(blinkStatus);
                 it = m_requests.erase(it);
             } else
                 ++it;
@@ -249,7 +275,7 @@ void PermissionManagerQt::setPermission(const QUrl &url, QWebEnginePermission::P
 
     for (const auto &it : m_subscribers) {
         if (it.second.origin == origin && it.second.type == permissionType)
-            it.second.callback.Run(status);
+            it.second.callback.Run(blinkStatus);
     }
 
     if (state == QWebEnginePermission::State::Ask)
@@ -267,7 +293,12 @@ void PermissionManagerQt::setPermission(const QUrl &url, QWebEnginePermission::P
                     continue;
                 }
 
-                blink::mojom::PermissionStatus permissionStatus = GetPermissionStatus(permission, gorigin, GURL());
+                blink::mojom::PermissionStatus permissionStatus;
+                if (inTransientStore)
+                    permissionStatus = toBlink(getPermissionState(url, permissionType, rfh));
+                else
+                    permissionStatus = GetPermissionStatus(permission, gorigin, GURL());
+
                 if (permissionStatus == toBlink(state)) {
                     if (permissionStatus == blink::mojom::PermissionStatus::ASK) {
                         answerable = false;
@@ -290,8 +321,14 @@ void PermissionManagerQt::setPermission(const QUrl &url, QWebEnginePermission::P
     }
 }
 
-QWebEnginePermission::State PermissionManagerQt::getPermissionState(const QUrl &origin, QWebEnginePermission::PermissionType permissionType)
+QWebEnginePermission::State PermissionManagerQt::getPermissionState(const QUrl &origin, QWebEnginePermission::PermissionType permissionType,
+    content::RenderFrameHost *rfh)
 {
+    if (rfh) {
+        // Ignore the origin parameter
+        return toQt(GetPermissionStatusForCurrentDocument(toBlink(permissionType), rfh));
+    }
+
     return toQt(GetPermissionStatus(toBlink(permissionType), toGurl(origin), GURL()));
 }
 
@@ -368,8 +405,35 @@ void PermissionManagerQt::RequestPermissions(content::RenderFrameHost *frameHost
 
         blink::mojom::PermissionStatus permissionStatus = getStatusFromSettings(permission, contentsDelegate->webEngineSettings());
         if (permissionStatus == blink::mojom::PermissionStatus::ASK) {
-            permissionStatus = GetPermissionStatus(permission, requestDescription.requesting_origin, GURL());
-            if (m_persistence && permissionStatus != blink::mojom::PermissionStatus::ASK) {
+            const GURL &rorigin = requestDescription.requesting_origin;
+
+            if (!m_persistence) {
+                answerable = false;
+                break;
+            }
+
+            bool inTransientStore = !QWebEnginePermission::isPersistent(toQt(permission));
+            if (inTransientStore) {
+                permissionStatus = getTransientPermissionStatus(permission, rorigin, frameHost->GetGlobalFrameToken());
+
+                if (permissionStatus != blink::mojom::PermissionStatus::ASK) {
+                    result.push_back(permissionStatus);
+                    continue;
+                }
+
+                // Fall through to check if permission was pre-granted (and thus landed in the permanent store)
+            }
+
+            permissionStatus = GetPermissionStatus(permission, rorigin, rorigin);
+
+            if (inTransientStore && permissionStatus != blink::mojom::PermissionStatus::ASK) {
+                // Move the pre-granted permission to the transient store and associate it with the rfh
+                ResetPermission(permission, rorigin, rorigin);
+                setTransientPermission(permission, rorigin, permissionStatus == blink::mojom::PermissionStatus::GRANTED,
+                    frameHost->GetGlobalFrameToken());
+            }
+
+            if (permissionStatus != blink::mojom::PermissionStatus::ASK) {
                 // Automatically grant/deny without prompt if already asked once
                 result.push_back(permissionStatus);
             } else {
@@ -428,8 +492,7 @@ blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatus(
     // Workaround: local fonts are entirely managed by Chromium, which only calls RequestPermission() _after_
     // it's checked whether the permission has been granted. By always returning ASK, we force the request to
     // come through every time.
-    if (permission == blink::PermissionType::LOCAL_FONTS
-        && m_profileAdapter->persistentPermissionsPolicy() == ProfileAdapter::PersistentPermissionsPolicy::AskEveryTime)
+    if (permission == blink::PermissionType::LOCAL_FONTS && !m_persistence)
         return blink::mojom::PermissionStatus::ASK;
 
     if (requestedPermission.value())
@@ -441,6 +504,8 @@ blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatusForCurren
         blink::PermissionType permission,
         content::RenderFrameHost *render_frame_host)
 {
+    Q_ASSERT(render_frame_host);
+
     if (permission == blink::PermissionType::CLIPBOARD_READ_WRITE ||
             permission == blink::PermissionType::CLIPBOARD_SANITIZED_WRITE) {
         WebContentsDelegateQt *delegate = static_cast<WebContentsDelegateQt *>(
@@ -451,10 +516,34 @@ blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatusForCurren
             return status;
     }
 
-    return GetPermissionStatus(
-                permission,
-                render_frame_host->GetLastCommittedOrigin().GetURL(),
-                render_frame_host->GetLastCommittedOrigin().GetURL());
+    permission = toBlink(toQt(permission)); // Filter out merged/unsupported permissions (e.g. clipboard)
+    if (toQt(permission) == QWebEnginePermission::PermissionType::Unsupported)
+        return blink::mojom::PermissionStatus::DENIED;
+
+    GURL origin = render_frame_host->GetLastCommittedOrigin().GetURL();
+    auto status = blink::mojom::PermissionStatus::ASK;
+
+    bool inTransientStore = !QWebEnginePermission::isPersistent(toQt(permission)) || !m_persistence;
+    if (inTransientStore) {
+        status = getTransientPermissionStatus(permission, origin, render_frame_host->GetGlobalFrameToken());
+
+        if (status != blink::mojom::PermissionStatus::ASK) {
+            return status;
+        }
+
+        // Fall through to check if permission was pre-granted (and thus landed in the permanent store)
+    }
+
+    status = GetPermissionStatus(permission, origin, origin);
+
+    if (inTransientStore && status != blink::mojom::PermissionStatus::ASK) {
+        // Move the pre-granted permission to the transient store and associate it with the rfh
+        ResetPermission(permission, origin, origin);
+        setTransientPermission(permission, origin, status == blink::mojom::PermissionStatus::GRANTED,
+            render_frame_host->GetGlobalFrameToken());
+    }
+
+    return status;
 }
 
 blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatusForWorker(
@@ -462,6 +551,7 @@ blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatusForWorker
         content::RenderProcessHost *render_process_host,
         const GURL &url)
 {
+    Q_UNUSED(render_process_host);
     return GetPermissionStatus(permission, url, url);
 }
 
@@ -517,7 +607,28 @@ void PermissionManagerQt::UnsubscribeFromPermissionStatusChange(
         LOG(WARNING) << "PermissionManagerQt::UnsubscribePermissionStatusChange called on unknown subscription id" << subscription_id;
 }
 
-void PermissionManagerQt::setPermission(
+blink::mojom::PermissionStatus PermissionManagerQt::getTransientPermissionStatus(blink::PermissionType permission,
+        const GURL& requesting_origin,
+        content::GlobalRenderFrameHostToken token)
+{
+    const QWebEnginePermission::PermissionType permissionType = toQt(permission);
+    if (permissionType == QWebEnginePermission::PermissionType::Unsupported)
+        return blink::mojom::PermissionStatus::DENIED;
+
+    if (!m_transientPermissions.contains(token))
+        return blink::mojom::PermissionStatus::ASK;
+
+    auto &permissionsForToken = m_transientPermissions[token];
+    for (auto p = permissionsForToken.begin(); p != permissionsForToken.end(); ++p) {
+        if (get<0>(*p) == requesting_origin && get<1>(*p) == permission) {
+            return get<2>(*p) ? blink::mojom::PermissionStatus::GRANTED : blink::mojom::PermissionStatus::DENIED;
+        }
+    }
+
+    return blink::mojom::PermissionStatus::ASK;
+}
+
+void PermissionManagerQt::setPersistentPermission(
     blink::PermissionType permission,
     const GURL& requesting_origin,
     bool granted)
@@ -535,4 +646,55 @@ void PermissionManagerQt::setPermission(
     m_prefService->SchedulePendingLossyWrites();
 }
 
+void PermissionManagerQt::setTransientPermission(blink::PermissionType permission,
+        const GURL& requesting_origin,
+        bool granted,
+        content::GlobalRenderFrameHostToken token)
+{
+    const QWebEnginePermission::PermissionType permissionType = toQt(permission);
+    if (permissionType == QWebEnginePermission::PermissionType::Unsupported)
+        return;
+
+    auto &permissionsForToken = m_transientPermissions[token];
+    for (auto &p : permissionsForToken) {
+        if (get<0>(p) == requesting_origin && get<1>(p) == permission) {
+            get<2>(p) = granted;
+            return;
+        }
+    }
+
+    permissionsForToken.push_back({requesting_origin, permission, granted});
+
+    // Render frame hosts get discarded often, so the map will eventualy fill up with junk unless
+    // periodically cleaned. The number 25 was chosen arbitrarily.
+    if (++m_transientWriteCount > 25) {
+        content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
+            base::BindOnce([](PermissionManagerQt *p){
+                for (auto i = p->m_transientPermissions.begin(); i != p->m_transientPermissions.end(); ++i) {
+                    if (content::RenderFrameHost::FromFrameToken(i->first) == nullptr) {
+                        i = p->m_transientPermissions.erase(i);
+                    }
+                }
+            }, this));
+        m_transientWriteCount = 0;
+    }
+}
+
+void PermissionManagerQt::resetTransientPermission(blink::PermissionType permission,
+        const GURL& requesting_origin,
+        content::GlobalRenderFrameHostToken token)
+{
+    const QWebEnginePermission::PermissionType permissionType = toQt(permission);
+    if (permissionType == QWebEnginePermission::PermissionType::Unsupported)
+        return;
+
+    auto &permissionsForToken = m_transientPermissions[token];
+    for (auto i = permissionsForToken.begin(); i != permissionsForToken.end(); ++i) {
+        if (get<0>(*i) == requesting_origin && get<1>(*i) == permission) {
+            permissionsForToken.erase(i);
+            return;
+        }
+    }
+}
+
 } // namespace QtWebEngineCore
diff --git a/src/core/permission_manager_qt.h b/src/core/permission_manager_qt.h
index ea69243b5f1..88b777c7faa 100644
--- a/src/core/permission_manager_qt.h
+++ b/src/core/permission_manager_qt.h
@@ -5,12 +5,15 @@
 #define PERMISSION_MANAGER_QT_H
 
 #include "base/functional/callback.h"
+#include "content/public/browser/global_routing_id.h"
 #include "content/public/browser/permission_controller_delegate.h"
+#include "content/public/browser/render_frame_host.h"
 
 #include <QtWebEngineCore/qwebenginepermission.h>
 #include "profile_adapter.h"
 
 #include <map>
+#include <tuple>
 
 class PrefService;
 
@@ -22,8 +25,13 @@ class PermissionManagerQt : public content::PermissionControllerDelegate
     PermissionManagerQt(ProfileAdapter *adapter);
     ~PermissionManagerQt();
 
-    void setPermission(const QUrl &origin, QWebEnginePermission::PermissionType permissionType, QWebEnginePermission::State state);
-    QWebEnginePermission::State getPermissionState(const QUrl &origin, QWebEnginePermission::PermissionType permissionType);
+    void setPermission(
+        const QUrl &origin,
+        QWebEnginePermission::PermissionType permissionType,
+        QWebEnginePermission::State state,
+        content::RenderFrameHost *rfh = nullptr);
+    QWebEnginePermission::State getPermissionState(const QUrl &origin, QWebEnginePermission::PermissionType permissionType,
+        content::RenderFrameHost *rfh = nullptr);
     QList<QWebEnginePermission> listPermissions(const QUrl &origin, QWebEnginePermission::PermissionType permissionType);
 
     void commit();
@@ -84,16 +92,32 @@ class PermissionManagerQt : public content::PermissionControllerDelegate
         base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback;
     };
 
-    void setPermission(blink::PermissionType permission,
+    blink::mojom::PermissionStatus getTransientPermissionStatus(blink::PermissionType permission,
+        const GURL& requesting_origin,
+        content::GlobalRenderFrameHostToken token);
+
+    void setPersistentPermission(blink::PermissionType permission,
         const GURL& requesting_origin,
         bool granted);
 
+    void setTransientPermission(blink::PermissionType permission,
+        const GURL& requesting_origin,
+        bool granted,
+        content::GlobalRenderFrameHostToken token);
+
+    void resetTransientPermission(blink::PermissionType permission,
+        const GURL& requesting_origin,
+        content::GlobalRenderFrameHostToken token);
+
     std::vector<Request> m_requests;
     std::vector<MultiRequest> m_multiRequests;
     std::vector<QWebEnginePermission::PermissionType> m_permissionTypes;
+    std::map<content::GlobalRenderFrameHostToken,
+        QList<std::tuple<GURL, blink::PermissionType, bool>>> m_transientPermissions;
     std::map<content::PermissionControllerDelegate::SubscriptionId, Subscription> m_subscribers;
     content::PermissionControllerDelegate::SubscriptionId::Generator subscription_id_generator_;
     int m_requestIdCount;
+    int m_transientWriteCount;
     std::unique_ptr<PrefService> m_prefService;
     QPointer<QtWebEngineCore::ProfileAdapter> m_profileAdapter;
     bool m_persistence;
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index 031ee6dec87..952e5031e0c 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -568,17 +568,16 @@ UserResourceControllerHost *ProfileAdapter::userResourceController()
     return m_userResourceController.data();
 }
 
-void ProfileAdapter::setPermission(const QUrl &origin, QWebEnginePermission::PermissionType permissionType, QWebEnginePermission::State state)
+void ProfileAdapter::setPermission(const QUrl &origin, QWebEnginePermission::PermissionType permissionType,
+    QWebEnginePermission::State state, content::RenderFrameHost *rfh)
 {
-    static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->setPermission(origin, permissionType, state);
+    static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->setPermission(origin, permissionType, state, rfh);
 }
 
-QWebEnginePermission::State ProfileAdapter::getPermissionState(const QUrl &origin, QWebEnginePermission::PermissionType permissionType)
+QWebEnginePermission::State ProfileAdapter::getPermissionState(const QUrl &origin, QWebEnginePermission::PermissionType permissionType,
+    content::RenderFrameHost *rfh)
 {
-    if (persistentPermissionsPolicy() == ProfileAdapter::PersistentPermissionsPolicy::AskEveryTime)
-        return QWebEnginePermission::State::Ask;
-
-    return static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->getPermissionState(origin, permissionType);
+    return static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->getPermissionState(origin, permissionType, rfh);
 }
 
 QList<QWebEnginePermission> ProfileAdapter::listPermissions(const QUrl &origin, QWebEnginePermission::PermissionType permissionType)
diff --git a/src/core/profile_adapter.h b/src/core/profile_adapter.h
index d0194df99c7..06628632193 100644
--- a/src/core/profile_adapter.h
+++ b/src/core/profile_adapter.h
@@ -37,6 +37,10 @@ namespace base {
 class CancelableTaskTracker;
 }
 
+namespace content {
+class RenderFrameHost;
+}
+
 namespace QtWebEngineCore {
 
 class UserNotificationController;
@@ -172,8 +176,10 @@ class Q_WEBENGINECORE_EXPORT ProfileAdapter : public QObject
     const QList<QByteArray> customUrlSchemes() const;
     UserResourceControllerHost *userResourceController();
 
-    void setPermission(const QUrl &origin, QWebEnginePermission::PermissionType permissionType, QWebEnginePermission::State state);
-    QWebEnginePermission::State getPermissionState(const QUrl &origin, QWebEnginePermission::PermissionType permissionType);
+    void setPermission(const QUrl &origin, QWebEnginePermission::PermissionType permissionType,
+        QWebEnginePermission::State state, content::RenderFrameHost *rfh = nullptr);
+    QWebEnginePermission::State getPermissionState(const QUrl &origin, QWebEnginePermission::PermissionType permissionType,
+        content::RenderFrameHost *rfh = nullptr);
     QList<QWebEnginePermission> listPermissions(const QUrl &origin = QUrl(),
         QWebEnginePermission::PermissionType permissionType = QWebEnginePermission::PermissionType::Unsupported);
 
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index c49331f1e76..807b733e001 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -1416,7 +1416,12 @@ void WebContentsAdapter::setPermission(const QUrl &origin, QWebEnginePermission:
     if (QWebEnginePermission::isPersistent(permissionType)) {
         // Do not check for initialization in this path so permissions can be set before first navigation
         Q_ASSERT(m_profileAdapter);
-        m_profileAdapter->setPermission(origin, permissionType, state);
+        if (!isInitialized()) {
+            m_profileAdapter->setPermission(origin, permissionType, state);
+        } else {
+            m_profileAdapter->setPermission(origin, permissionType, state, m_webContents.get()->GetPrimaryMainFrame());
+        }
+
         return;
     }
 
@@ -1484,11 +1489,7 @@ void WebContentsAdapter::setPermission(const QUrl &origin, QWebEnginePermission:
 
 QWebEnginePermission::State WebContentsAdapter::getPermissionState(const QUrl &origin, QWebEnginePermission::PermissionType permissionType)
 {
-    // For now, we just return Ask for transient (a.k.a non-persistent) PermissionTypes
-    if (!QWebEnginePermission::isPersistent(permissionType))
-        return QWebEnginePermission::State::Ask;
-
-    return m_profileAdapter->getPermissionState(origin, permissionType);
+    return m_profileAdapter->getPermissionState(origin, permissionType, m_webContents.get()->GetPrimaryMainFrame());
 }
 
 void WebContentsAdapter::grantMediaAccessPermission(const QUrl &origin, WebContentsAdapterClient::MediaRequestFlags flags)
@@ -1496,9 +1497,15 @@ void WebContentsAdapter::grantMediaAccessPermission(const QUrl &origin, WebConte
     CHECK_INITIALIZED();
     // Let the permission manager remember the reply.
     if (flags & WebContentsAdapterClient::MediaAudioCapture)
-        m_profileAdapter->setPermission(origin, QWebEnginePermission::PermissionType::MediaAudioCapture, QWebEnginePermission::State::Granted);
+        m_profileAdapter->setPermission(origin,
+            QWebEnginePermission::PermissionType::MediaAudioCapture,
+            QWebEnginePermission::State::Granted,
+            m_webContents.get()->GetPrimaryMainFrame());
     if (flags & WebContentsAdapterClient::MediaVideoCapture)
-        m_profileAdapter->setPermission(origin, QWebEnginePermission::PermissionType::MediaVideoCapture, QWebEnginePermission::State::Granted);
+        m_profileAdapter->setPermission(origin,
+            QWebEnginePermission::PermissionType::MediaVideoCapture,
+            QWebEnginePermission::State::Granted,
+            m_webContents.get()->GetPrimaryMainFrame());
     MediaCaptureDevicesDispatcher::GetInstance()->handleMediaAccessPermissionResponse(m_webContents.get(), origin, flags);
 }
 
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 2eada9d3c86..d0bbb98564d 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -794,17 +794,24 @@ void WebContentsDelegateQt::BeforeUnloadFired(content::WebContents *tab, bool pr
         m_viewClient->windowCloseRejected();
 }
 
-bool WebContentsDelegateQt::CheckMediaAccessPermission(content::RenderFrameHost *,
+bool WebContentsDelegateQt::CheckMediaAccessPermission(content::RenderFrameHost *rfh,
                                                        const url::Origin &security_origin,
                                                        blink::mojom::MediaStreamType type)
 {
+    Q_ASSERT(rfh);
     switch (type) {
     case blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE:
-        return m_viewClient->profileAdapter()->getPermissionState(toQt(security_origin), QWebEnginePermission::PermissionType::MediaAudioCapture)
-            == QWebEnginePermission::State::Granted;
+        return m_viewClient->profileAdapter()->getPermissionState(
+            toQt(security_origin),
+            QWebEnginePermission::PermissionType::MediaAudioCapture,
+            rfh)
+                == QWebEnginePermission::State::Granted;
     case blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE:
-        return m_viewClient->profileAdapter()->getPermissionState(toQt(security_origin), QWebEnginePermission::PermissionType::MediaVideoCapture)
-            == QWebEnginePermission::State::Granted;
+        return m_viewClient->profileAdapter()->getPermissionState(
+            toQt(security_origin),
+            QWebEnginePermission::PermissionType::MediaVideoCapture,
+            rfh)
+                == QWebEnginePermission::State::Granted;
     default:
         LOG(INFO) << "WebContentsDelegateQt::CheckMediaAccessPermission: "
                   << "Unsupported media stream type checked " << type;
diff --git a/src/webenginequick/doc/src/webengine_permission.qdoc b/src/webenginequick/doc/src/webengine_permission.qdoc
index 6912ef4fa2c..efe434dde60 100644
--- a/src/webenginequick/doc/src/webengine_permission.qdoc
+++ b/src/webenginequick/doc/src/webengine_permission.qdoc
@@ -27,7 +27,7 @@
 
     The \l permissionType enumeration describes all the permission types Qt WebEngine supports. Only some permission types
     are remembered between browsing sessions; they are \e persistent. Non-persistent permissions query the user every time a
-    website requests them, and cannot be granted in advance. You can check whether a permission type is persistent at runtime
+    website requests them. You can check whether a permission type is persistent at runtime
     using the static method WebEnginePermission::isPersistent().
 
     Persistent permissions are stored inside the active WebEngineProfile, and their lifetime depends on the value of
@@ -72,8 +72,7 @@
     \omitvalue WebEnginePermission.MouseLock
 
     \note Non-persistent permission types are ones that will never be remembered by the underlying storage, and will trigger
-    a permission request every time a website tries to use them. They can only be denied/granted as they're needed;
-    any attempts to pre-grant a non-persistent permission will fail.
+    a permission request every time a website tries to use them.
 */
 
 /*!
@@ -87,7 +86,7 @@
 
     If a permission for the specified \l permissionType and \l origin has already been granted or denied,
     the return value is WebEnginePermission.Granted, or WebEnginePermission.Denied, respectively.
-    When this is the first time the permission is requested, or if the \l permissionType is non-persistent,
+    When this is the first time the permission is requested,
     the return value is WebEnginePermission.Ask. If the object is in an invalid state, the returned
     value is WebEnginePermission.Invalid.
 
@@ -131,7 +130,7 @@
     Removes the permission from the profile's underlying storage. By default, permissions are stored on disk (except for
     off-the-record profiles, where permissions are stored in memory and are destroyed with the profile).
     This means that an already granted/denied permission will not be requested twice, but will get automatically
-    granted/denied every subsequent time a website requests it. Calling reset() allows the query to be asked
+    granted/denied every subsequent time a website requests it. Calling reset() allows the query to be displayed
     again the next time the website requests it.
 
     Does nothing when \l isValid evaluates to false.
diff --git a/tests/auto/httpserver/data/notification.html b/tests/auto/httpserver/data/notification.html
index 1d1e9c4119d..11ebf534e58 100644
--- a/tests/auto/httpserver/data/notification.html
+++ b/tests/auto/httpserver/data/notification.html
@@ -3,9 +3,7 @@
 <head>
 <title>Desktop Notifications Demo</title>
 <script>
-    function resetPermission() { document.Notification = 'default' }
-
-    function getPermission() { return document.Notification }
+    function getPermission() { return Notification.permission }
 
     function sendNotification(title, body) {
         let notification = new Notification(title, { body: body, dir: 'rtl', lang: 'de', tag: 'tst' })
diff --git a/tests/auto/quick/qmltests/data/tst_geopermission.qml b/tests/auto/quick/qmltests/data/tst_geopermission.qml
index 2957367edb1..774b2fdc7ad 100644
--- a/tests/auto/quick/qmltests/data/tst_geopermission.qml
+++ b/tests/auto/quick/qmltests/data/tst_geopermission.qml
@@ -12,6 +12,7 @@ TestWebEngineView {
 
     property bool deniedGeolocation: false
     property bool geoPermissionRequested: false
+    property var permissionObject: undefined
 
     profile.persistentPermissionsPolicy: WebEngineProfile.PersistentPermissionsPolicy.AskEveryTime
 
@@ -24,6 +25,7 @@ TestWebEngineView {
     onPermissionRequested: function(perm) {
         if (perm.permissionType === WebEnginePermission.PermissionType.Geolocation) {
             geoPermissionRequested = true
+            permissionObject = perm
             if (deniedGeolocation) {
                 perm.deny()
             }
@@ -56,6 +58,9 @@ TestWebEngineView {
         }
 
         function init() {
+            if (permissionObject != undefined) {
+                permissionObject.reset()
+            }
             deniedGeolocation = false
             permissionSpy.clear()
         }
diff --git a/tests/auto/quick/qmltests/data/tst_notification.qml b/tests/auto/quick/qmltests/data/tst_notification.qml
index 4795ac31d68..df2bfa94ef7 100644
--- a/tests/auto/quick/qmltests/data/tst_notification.qml
+++ b/tests/auto/quick/qmltests/data/tst_notification.qml
@@ -46,6 +46,9 @@ TestWebEngineView {
         }
 
         function init() {
+            if (permissionObject != undefined) {
+                permissionObject.reset()
+            }
             permissionRequested = false
             spyRequest.clear()
         }
@@ -63,7 +66,6 @@ TestWebEngineView {
             view.url = resolverUrl('notification.html')
             verify(view.waitForLoadSucceeded())
 
-            view.runJavaScript('resetPermission()')
             let result = {}
 
             view.runJavaScript('getPermission()', function (permission) { result.permission = permission })
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 24a2e348be8..a5e96bc7954 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -3854,7 +3854,6 @@ struct NotificationPage : ConsolePage {
 
     QString getPermission() { return evaluateJavaScriptSync(this, "getPermission()").toString(); }
     void requestPermission() { runJavaScript("requestPermission()"); }
-    void resetPermission() { runJavaScript("resetPermission()"); }
     void sendNotification(const QString &title, const QString &body) {
         runJavaScript("sendNotification('" + title + "', '" + body + "')");
     }
@@ -3935,7 +3934,6 @@ void tst_QWebEnginePage::sendNotification()
     NotificationPage page(QWebEnginePermission::State::Granted);
     QVERIFY(page.spyLoad.waitForResult());
 
-    page.resetPermission();
     page.requestPermission();
     auto origin = page.spyRequest.waitForResult();
     QVERIFY(page.spyRequest.wasCalled());
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index 6c9af17271a..d9997d50c36 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -1109,13 +1109,13 @@ void tst_QWebEngineProfile::queryPermission_data()
     QTest::addColumn<bool>("expectedValid");
 
     QTest::newRow("badUrl")
-        << QWebEnginePermission::PermissionType::Notifications << QUrl(QStringLiteral("//:bad-url"))                   << false;
+        << QWebEnginePermission::PermissionType::Notifications << QUrl(QStringLiteral("//:bad-url"))                     << false;
     QTest::newRow("badFeature")
-        << QWebEnginePermission::PermissionType::Unsupported   << QUrl(QStringLiteral("qrc:/resources/hedgehog.html")) << false;
+        << QWebEnginePermission::PermissionType::Unsupported   << QUrl(QStringLiteral("qrc:/resources/permission.html")) << false;
     QTest::newRow("transientFeature")
-        << QWebEnginePermission::PermissionType::MouseLock     << QUrl(QStringLiteral("qrc:/resources/hedgehog.html")) << false;
+        << QWebEnginePermission::PermissionType::MouseLock     << QUrl(QStringLiteral("qrc:/resources/permission.html")) << true;
     QTest::newRow("good")
-        << QWebEnginePermission::PermissionType::Notifications << QUrl(QStringLiteral("qrc:/resources/hedgehog.html")) << true;
+        << QWebEnginePermission::PermissionType::Notifications << QUrl(QStringLiteral("qrc:/resources/permission.html")) << true;
 }
 
 void tst_QWebEngineProfile::queryPermission()

From 6d62d33316bbf92b3bfd5cec75f7c2a04e06a23c Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Mon, 26 Aug 2024 12:51:32 +0000
Subject: [PATCH 130/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Ied9a014fc8d3731e17d57706e7abebf703cc54b9
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 71c937db2b2..ac6b71da8a1 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 752bce98f903052d7b9bd30610c326592784576f
+    ref: d5171b14251cf4abd7d8ad16288690af53248856
     required: true
   ../qtpositioning:
-    ref: 4b0791714b45c68e9afff61c4bef661ece88235d
+    ref: 9e17051c777b460aa92632664d42eeb82158fbba
     required: false
   ../qttools:
-    ref: 10dbff6001deea0339f38c5f84edf332c65c665a
+    ref: 5034a5008302f830f0966162665a1249f288d2bb
     required: false
   ../qtwebchannel:
-    ref: 67d7422d9814f7a9b58ca095ad83791210f85d60
+    ref: c6dafd8d5220d797c64b229a7378817369d0bc5b
     required: false

From d3a8b30d48f3a072f2402de3ff7010f9af516112 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Mon, 3 Jun 2024 14:59:13 +0200
Subject: [PATCH 131/356] Fix drag-and-drop after 120 adaptations

Following the 120 adaptations, WebContentsAdapter would repeatedly
freeze for three seconds when attempting to drag anything. This change
fixes the issue, and makes proper use of the new parameter inside
WebContentsViewQt::UpdateDragOperation.

Fixes: QTBUG-128361
Change-Id: I0c2992610ed2a130efcef0aefce51149d2a350cc
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
---
 src/core/web_contents_adapter.cpp | 4 +++-
 src/core/web_contents_adapter.h   | 3 ++-
 src/core/web_contents_view_qt.cpp | 5 ++---
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 807b733e001..f98c6a9300d 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -1853,11 +1853,12 @@ void WebContentsAdapter::waitForUpdateDragActionCalled()
     }
 }
 
-void WebContentsAdapter::updateDragAction(int action)
+void WebContentsAdapter::updateDragAction(int action, bool documentIsHandlingDrag)
 {
     CHECK_INITIALIZED();
     m_updateDragActionCalled = true;
     m_currentDropAction = action;
+    m_documentIsHandlingDrag = documentIsHandlingDrag;
 }
 
 void WebContentsAdapter::endDragging(QDropEvent *e, const QPointF &screenPos)
@@ -1867,6 +1868,7 @@ void WebContentsAdapter::endDragging(QDropEvent *e, const QPointF &screenPos)
     rvh->GetWidget()->FilterDropData(m_currentDropData.get());
     m_lastDragClientPos = e->position();
     m_lastDragScreenPos = screenPos;
+    m_currentDropData->document_is_handling_drag = m_documentIsHandlingDrag;
     rvh->GetWidget()->DragTargetDrop(*m_currentDropData, toGfx(m_lastDragClientPos), toGfx(m_lastDragScreenPos),
                                      toWeb(e->buttons()) | toWeb(e->modifiers()), base::DoNothing());
 
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 44ee7823dde..3a2db1c1e06 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -205,7 +205,7 @@ class Q_WEBENGINECORE_EXPORT WebContentsAdapter : public QEnableSharedFromThis<W
                        Qt::DropActions allowedActions, const QPixmap &pixmap, const QPoint &offset);
     void enterDrag(QDragEnterEvent *e, const QPointF &screenPos);
     Qt::DropAction updateDragPosition(QDragMoveEvent *e, const QPointF &screenPos);
-    void updateDragAction(int action);
+    void updateDragAction(int action, bool documentIsHandlingDrag);
     void endDragging(QDropEvent *e, const QPointF &screenPos);
     void leaveDrag();
 #endif // QT_CONFIG(draganddrop)
@@ -285,6 +285,7 @@ class Q_WEBENGINECORE_EXPORT WebContentsAdapter : public QEnableSharedFromThis<W
     LifecycleState m_lifecycleState = LifecycleState::Active;
     LifecycleState m_recommendedState = LifecycleState::Active;
     bool m_inspector = false;
+    bool m_documentIsHandlingDrag = false;
     QPointer<QWebEngineUrlRequestInterceptor> m_requestInterceptor;
 };
 
diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp
index 50d964de7fc..028cca6f831 100644
--- a/src/core/web_contents_view_qt.cpp
+++ b/src/core/web_contents_view_qt.cpp
@@ -257,11 +257,10 @@ void WebContentsViewQt::StartDragging(const content::DropData &drop_data,
 #endif // QT_CONFIG(draganddrop)
 }
 
-void WebContentsViewQt::UpdateDragOperation(ui::mojom::DragOperation dragOperation, bool isDrag)
+void WebContentsViewQt::UpdateDragOperation(ui::mojom::DragOperation dragOperation, bool document_is_handling_drag)
 {
 #if QT_CONFIG(draganddrop)
-    if (isDrag)
-        m_client->webContentsAdapter()->updateDragAction(int(dragOperation));
+    m_client->webContentsAdapter()->updateDragAction(int(dragOperation), document_is_handling_drag);
 #endif // QT_CONFIG(draganddrop)
 }
 

From f2cc6aa0ef438aa8b7ab5ae8eaeb38d99e6bb852 Mon Sep 17 00:00:00 2001
From: Tian Shilin <tianshilin@uniontech.com>
Date: Thu, 15 Aug 2024 16:26:45 +0800
Subject: [PATCH 132/356] fix conditional redundancy for receivedBytes

In updateWidget,receivedBytes / m_timeAdded.elapsed() * 1000 may divide
by zero,if m_timeAdded.elapsed() returns 0, it will cause the denominator
in the division to be zero, which will trigger a warning or error, to fix this,
check the m_timeAdded.elapsed() is zero, if it is, you can set a default
value () or just set bytesPerSecond to 0 to avoid dividing by zero.

Pick-to: 6.7
Change-Id: Id73b287d44241f97271308f85c64d4830b944948
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit f57db4b9a4c71133b781773c2e6e6d5121de4fe7)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 examples/webenginewidgets/simplebrowser/downloadwidget.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/examples/webenginewidgets/simplebrowser/downloadwidget.cpp b/examples/webenginewidgets/simplebrowser/downloadwidget.cpp
index c6d3b0921ee..ed12bc6607e 100644
--- a/examples/webenginewidgets/simplebrowser/downloadwidget.cpp
+++ b/examples/webenginewidgets/simplebrowser/downloadwidget.cpp
@@ -51,7 +51,11 @@ void DownloadWidget::updateWidget()
 {
     qreal totalBytes = m_download->totalBytes();
     qreal receivedBytes = m_download->receivedBytes();
-    qreal bytesPerSecond = receivedBytes / m_timeAdded.elapsed() * 1000;
+    qreal bytesPerSecond = 0;  // Initialized to 0 for a reasonable default value
+
+    // Check for division by zero
+    if (m_timeAdded.elapsed() != 0)
+        bytesPerSecond = receivedBytes / m_timeAdded.elapsed() * 1000;
 
     auto state = m_download->state();
     switch (state) {

From 02425e90d7d7bd9c805deebb65115cf678847bd0 Mon Sep 17 00:00:00 2001
From: Paul Wicking <paul.wicking@qt.io>
Date: Tue, 20 Aug 2024 09:38:02 +0200
Subject: [PATCH 133/356] Doc: Replace \instantiates with \nativetype

Since the implementation of the `\nativetype`-command in QDoc,
the `\instantiates`-command is deprecated. Replace the use of the
deprecated command in favor of its replacement.

Task-number: QTBUG-128216
Change-Id: I10cad9942e34301ded99c7014c1c70375e0698e1
Reviewed-by: Venugopal Shivashankar <Venugopal.Shivashankar@qt.io>
(cherry picked from commit a3d01750172e60ab6411748731b02c602ac113f8)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebenginenavigationrequest.cpp           |  2 +-
 src/core/api/qwebenginenewwindowrequest.cpp            |  2 +-
 src/core/api/qwebenginenotification.cpp                |  2 +-
 src/core/api/qwebenginewebauthuxrequest.cpp            |  2 +-
 src/pdfquick/qquickpdfbookmarkmodel.cpp                |  2 +-
 src/pdfquick/qquickpdfdocument.cpp                     |  2 +-
 src/pdfquick/qquickpdflinkmodel.cpp                    |  2 +-
 src/pdfquick/qquickpdfpageimage.cpp                    |  2 +-
 src/pdfquick/qquickpdfpagenavigator.cpp                |  2 +-
 src/pdfquick/qquickpdfsearchmodel.cpp                  |  2 +-
 src/pdfquick/qquickpdfselection.cpp                    |  2 +-
 src/webenginequick/api/qquickwebengineaction.cpp       |  2 +-
 .../api/qquickwebengineclientcertificateselection.cpp  |  4 ++--
 .../api/qquickwebenginedialogrequests.cpp              | 10 +++++-----
 src/webenginequick/api/qquickwebengineprofile.cpp      |  2 +-
 src/webenginequick/api/qquickwebenginesettings.cpp     |  2 +-
 src/webenginequick/api/qquickwebenginesingleton.cpp    |  4 ++--
 src/webenginequick/doc/src/context_menu_request.qdoc   |  2 +-
 src/webenginequick/doc/src/fullscreen_request.qdoc     |  2 +-
 src/webenginequick/doc/src/loading_info.qdoc           |  2 +-
 src/webenginequick/doc/src/navigation_history.qdoc     |  4 ++--
 src/webenginequick/doc/src/quota_request.qdoc          |  2 +-
 .../doc/src/register_protocol_handler_request.qdoc     |  2 +-
 .../doc/src/touch_selection_menu_request.qdoc          |  2 +-
 .../doc/src/webengine_certificate_error.qdoc           |  2 +-
 .../doc/src/webengine_download_request.qdoc            |  2 +-
 src/webenginequick/doc/src/webengine_permission.qdoc   |  2 +-
 src/webenginequick/doc/src/webengineframe.qdoc         |  2 +-
 src/webenginequick/doc/src/webenginescript.qdoc        |  2 +-
 src/webenginequick/doc/src/webengineview_lgpl.qdoc     |  4 ++--
 30 files changed, 38 insertions(+), 38 deletions(-)

diff --git a/src/core/api/qwebenginenavigationrequest.cpp b/src/core/api/qwebenginenavigationrequest.cpp
index dc7447b882e..a83a9289de5 100644
--- a/src/core/api/qwebenginenavigationrequest.cpp
+++ b/src/core/api/qwebenginenavigationrequest.cpp
@@ -41,7 +41,7 @@ class QWebEngineNavigationRequestPrivate {
 
 /*!
     \qmltype WebEngineNavigationRequest
-    \instantiates QWebEngineNavigationRequest
+    \nativetype QWebEngineNavigationRequest
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.0
 
diff --git a/src/core/api/qwebenginenewwindowrequest.cpp b/src/core/api/qwebenginenewwindowrequest.cpp
index 895033fd126..1f0be9aa03c 100644
--- a/src/core/api/qwebenginenewwindowrequest.cpp
+++ b/src/core/api/qwebenginenewwindowrequest.cpp
@@ -24,7 +24,7 @@ QT_BEGIN_NAMESPACE
 
 /*!
     \qmltype WebEngineNewWindowRequest
-    \instantiates QWebEngineNewWindowRequest
+    \nativetype QWebEngineNewWindowRequest
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.12
 
diff --git a/src/core/api/qwebenginenotification.cpp b/src/core/api/qwebenginenotification.cpp
index 136047042fb..0c72848c6aa 100644
--- a/src/core/api/qwebenginenotification.cpp
+++ b/src/core/api/qwebenginenotification.cpp
@@ -13,7 +13,7 @@ using QtWebEngineCore::UserNotificationController;
 
 /*!
     \qmltype WebEngineNotification
-    \instantiates QWebEngineNotification
+    \nativetype QWebEngineNotification
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.9
     \brief Encapsulates the data of an HTML5 web notification.
diff --git a/src/core/api/qwebenginewebauthuxrequest.cpp b/src/core/api/qwebenginewebauthuxrequest.cpp
index 8ae856af559..cc951a2e0a7 100644
--- a/src/core/api/qwebenginewebauthuxrequest.cpp
+++ b/src/core/api/qwebenginewebauthuxrequest.cpp
@@ -7,7 +7,7 @@
 
 /*!
     \qmltype WebEngineWebAuthUxRequest
-    \instantiates QWebEngineWebAuthUxRequest
+    \nativetype QWebEngineWebAuthUxRequest
     \inqmlmodule QtWebEngine
     \since QtWebEngine 6.7
     \brief Encapsulates the data of a WebAuth UX request.
diff --git a/src/pdfquick/qquickpdfbookmarkmodel.cpp b/src/pdfquick/qquickpdfbookmarkmodel.cpp
index 81f8547ae73..b32af20c909 100644
--- a/src/pdfquick/qquickpdfbookmarkmodel.cpp
+++ b/src/pdfquick/qquickpdfbookmarkmodel.cpp
@@ -8,7 +8,7 @@ QT_BEGIN_NAMESPACE
 
 /*!
     \qmltype PdfBookmarkModel
-//!    \instantiates QQuickPdfBookmarkModel
+//!    \nativetype QQuickPdfBookmarkModel
     \inqmlmodule QtQuick.Pdf
     \ingroup pdf
     \brief A tree of links (anchors) within a PDF document, such as the table of contents.
diff --git a/src/pdfquick/qquickpdfdocument.cpp b/src/pdfquick/qquickpdfdocument.cpp
index 9770900db57..268036d39fe 100644
--- a/src/pdfquick/qquickpdfdocument.cpp
+++ b/src/pdfquick/qquickpdfdocument.cpp
@@ -14,7 +14,7 @@ QT_BEGIN_NAMESPACE
 
 /*!
     \qmltype PdfDocument
-//!    \instantiates QQuickPdfDocument
+//!    \nativetype QQuickPdfDocument
     \inqmlmodule QtQuick.Pdf
     \ingroup pdf
     \brief A representation of a PDF document.
diff --git a/src/pdfquick/qquickpdflinkmodel.cpp b/src/pdfquick/qquickpdflinkmodel.cpp
index 469d13faff8..10d76630b25 100644
--- a/src/pdfquick/qquickpdflinkmodel.cpp
+++ b/src/pdfquick/qquickpdflinkmodel.cpp
@@ -10,7 +10,7 @@ QT_BEGIN_NAMESPACE
 
 /*!
     \qmltype PdfLinkModel
-//!    \instantiates QQuickPdfLinkModel
+//!    \nativetype QQuickPdfLinkModel
     \inqmlmodule QtQuick.Pdf
     \ingroup pdf
     \brief A representation of links within a PDF document.
diff --git a/src/pdfquick/qquickpdfpageimage.cpp b/src/pdfquick/qquickpdfpageimage.cpp
index 9ff0337a5d1..fe6dced8eca 100644
--- a/src/pdfquick/qquickpdfpageimage.cpp
+++ b/src/pdfquick/qquickpdfpageimage.cpp
@@ -12,7 +12,7 @@ Q_LOGGING_CATEGORY(qLcImg, "qt.pdf.image")
 
 /*!
     \qmltype PdfPageImage
-//!    \instantiates QQuickPdfPageImage
+//!    \nativetype QQuickPdfPageImage
     \inqmlmodule QtQuick.Pdf
     \ingroup pdf
     \inherits Image
diff --git a/src/pdfquick/qquickpdfpagenavigator.cpp b/src/pdfquick/qquickpdfpagenavigator.cpp
index 939d928e918..f5b423d4a18 100644
--- a/src/pdfquick/qquickpdfpagenavigator.cpp
+++ b/src/pdfquick/qquickpdfpagenavigator.cpp
@@ -8,7 +8,7 @@ QT_BEGIN_NAMESPACE
 
 /*!
     \qmltype PdfPageNavigator
-//!    \instantiates QQuickPdfPageNavigator
+//!    \nativetype QQuickPdfPageNavigator
     \inqmlmodule QtQuick.Pdf
     \ingroup pdf
     \brief History of the destinations visited within a PDF Document.
diff --git a/src/pdfquick/qquickpdfsearchmodel.cpp b/src/pdfquick/qquickpdfsearchmodel.cpp
index 896584ad756..87acf46aef8 100644
--- a/src/pdfquick/qquickpdfsearchmodel.cpp
+++ b/src/pdfquick/qquickpdfsearchmodel.cpp
@@ -10,7 +10,7 @@ Q_LOGGING_CATEGORY(qLcSearch, "qt.pdf.search")
 
 /*!
     \qmltype PdfSearchModel
-//!    \instantiates QQuickPdfSearchModel
+//!    \nativetype QQuickPdfSearchModel
     \inqmlmodule QtQuick.Pdf
     \ingroup pdf
     \brief A representation of text search results within a PDF Document.
diff --git a/src/pdfquick/qquickpdfselection.cpp b/src/pdfquick/qquickpdfselection.cpp
index 5a9aa0025e6..f93cb43940a 100644
--- a/src/pdfquick/qquickpdfselection.cpp
+++ b/src/pdfquick/qquickpdfselection.cpp
@@ -20,7 +20,7 @@ static const QRegularExpression WordDelimiter(QStringLiteral("\\s"));
 
 /*!
     \qmltype PdfSelection
-//!    \instantiates QQuickPdfSelection
+//!    \nativetype QQuickPdfSelection
     \inqmlmodule QtQuick.Pdf
     \ingroup pdf
     \inherits Item
diff --git a/src/webenginequick/api/qquickwebengineaction.cpp b/src/webenginequick/api/qquickwebengineaction.cpp
index 006715c701f..c918f647ee2 100644
--- a/src/webenginequick/api/qquickwebengineaction.cpp
+++ b/src/webenginequick/api/qquickwebengineaction.cpp
@@ -10,7 +10,7 @@ QT_BEGIN_NAMESPACE
 
 /*!
     \qmltype WebEngineAction
-    \instantiates QQuickWebEngineAction
+    \nativetype QQuickWebEngineAction
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.8
 
diff --git a/src/webenginequick/api/qquickwebengineclientcertificateselection.cpp b/src/webenginequick/api/qquickwebengineclientcertificateselection.cpp
index 46e531716c4..8c2ca3840ed 100644
--- a/src/webenginequick/api/qquickwebengineclientcertificateselection.cpp
+++ b/src/webenginequick/api/qquickwebengineclientcertificateselection.cpp
@@ -9,7 +9,7 @@ QT_BEGIN_NAMESPACE
 
 /*!
     \qmltype WebEngineClientCertificateOption
-    //! \instantiates QQuickWebEngineClientCertificateOption
+    //! \nativetype QQuickWebEngineClientCertificateOption
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.9
     \brief Represents a client certificate option.
@@ -79,7 +79,7 @@ void QQuickWebEngineClientCertificateOption::select()
 
 /*!
     \qmltype WebEngineClientCertificateSelection
-    //! \instantiates QQuickWebEngineClientCertificateSelection
+    //! \nativetype QQuickWebEngineClientCertificateSelection
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.9
     \brief Provides a selection of client certificates.
diff --git a/src/webenginequick/api/qquickwebenginedialogrequests.cpp b/src/webenginequick/api/qquickwebenginedialogrequests.cpp
index d49f173976c..34ce580735c 100644
--- a/src/webenginequick/api/qquickwebenginedialogrequests.cpp
+++ b/src/webenginequick/api/qquickwebenginedialogrequests.cpp
@@ -35,7 +35,7 @@ ASSERT_ENUMS_MATCH(FilePickerController::Save,
 
 /*!
     \qmltype AuthenticationDialogRequest
-    //! \instantiates QQuickWebEngineAuthenticationDialogRequest
+    //! \nativetype QQuickWebEngineAuthenticationDialogRequest
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.4
 
@@ -210,7 +210,7 @@ void QQuickWebEngineAuthenticationDialogRequest::dialogReject()
 
 /*!
     \qmltype JavaScriptDialogRequest
-    //! \instantiates QQuickWebEngineJavaScriptDialogRequest
+    //! \nativetype QQuickWebEngineJavaScriptDialogRequest
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.4
 
@@ -405,7 +405,7 @@ void QQuickWebEngineJavaScriptDialogRequest::dialogReject()
 
 /*!
     \qmltype ColorDialogRequest
-    //! \instantiates QQuickWebEngineColorDialogRequest
+    //! \nativetype QQuickWebEngineColorDialogRequest
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.4
 
@@ -524,7 +524,7 @@ void QQuickWebEngineColorDialogRequest::dialogReject()
 
 /*!
     \qmltype FileDialogRequest
-    //! \instantiates QQuickWebEngineFileDialogRequest
+    //! \nativetype QQuickWebEngineFileDialogRequest
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.4
 
@@ -680,7 +680,7 @@ void QQuickWebEngineFileDialogRequest::dialogReject()
 
 /*!
     \qmltype TooltipRequest
-    //! \instantiates QQuickWebEngineTooltipRequest
+    //! \nativetype QQuickWebEngineTooltipRequest
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.10
 
diff --git a/src/webenginequick/api/qquickwebengineprofile.cpp b/src/webenginequick/api/qquickwebengineprofile.cpp
index 4dcdb1af465..4654fdb84e6 100644
--- a/src/webenginequick/api/qquickwebengineprofile.cpp
+++ b/src/webenginequick/api/qquickwebengineprofile.cpp
@@ -340,7 +340,7 @@ QQuickWebEngineScriptCollection *QQuickWebEngineProfilePrivate::getUserScripts()
 }
 /*!
     \qmltype WebEngineProfile
-    \instantiates QQuickWebEngineProfile
+    \nativetype QQuickWebEngineProfile
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.1
     \brief Contains settings, scripts, and visited links common to multiple web engine views.
diff --git a/src/webenginequick/api/qquickwebenginesettings.cpp b/src/webenginequick/api/qquickwebenginesettings.cpp
index 04fd8b61767..9a15e02f27c 100644
--- a/src/webenginequick/api/qquickwebenginesettings.cpp
+++ b/src/webenginequick/api/qquickwebenginesettings.cpp
@@ -14,7 +14,7 @@ QQuickWebEngineSettings::QQuickWebEngineSettings(QQuickWebEngineSettings *parent
 
 /*!
     \qmltype WebEngineSettings
-    //! \instantiates QQuickWebEngineSettings
+    //! \nativetype QQuickWebEngineSettings
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.1
     \brief Allows configuration of browser properties and attributes.
diff --git a/src/webenginequick/api/qquickwebenginesingleton.cpp b/src/webenginequick/api/qquickwebenginesingleton.cpp
index a51d2aca468..215d4689698 100644
--- a/src/webenginequick/api/qquickwebenginesingleton.cpp
+++ b/src/webenginequick/api/qquickwebenginesingleton.cpp
@@ -12,7 +12,7 @@ QT_BEGIN_NAMESPACE
 
 /*!
     \qmltype WebEngine
-    //! \instantiates QQuickWebEngineSingleton
+    //! \nativetype QQuickWebEngineSingleton
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.1
     \brief Provides access to the default settings and profiles shared by all web engine views.
@@ -65,7 +65,7 @@ QQuickWebEngineProfile *QQuickWebEngineSingleton::defaultProfile() const
 
 /*!
     \qmlmethod WebEngineScript WebEngine::script
-    //! \instantiates QWebEngineScript
+    //! \nativetype QWebEngineScript
     \since QtWebEngine 6.2
 
     Constructs WebEngineScript, which can be set up and inserted into user scripts' collection
diff --git a/src/webenginequick/doc/src/context_menu_request.qdoc b/src/webenginequick/doc/src/context_menu_request.qdoc
index e7d732d5e28..e253ffb05e0 100644
--- a/src/webenginequick/doc/src/context_menu_request.qdoc
+++ b/src/webenginequick/doc/src/context_menu_request.qdoc
@@ -3,7 +3,7 @@
 
 /*!
     \qmltype ContextMenuRequest
-    //! \instantiates QQuickWebEngineContextMenuRequest
+    //! \nativetype QQuickWebEngineContextMenuRequest
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.4
 
diff --git a/src/webenginequick/doc/src/fullscreen_request.qdoc b/src/webenginequick/doc/src/fullscreen_request.qdoc
index 60da2748c2a..204c5d623c4 100644
--- a/src/webenginequick/doc/src/fullscreen_request.qdoc
+++ b/src/webenginequick/doc/src/fullscreen_request.qdoc
@@ -3,7 +3,7 @@
 
 /*!
     \qmltype FullScreenRequest
-    \instantiates QWebEngineFullScreenRequest
+    \nativetype QWebEngineFullScreenRequest
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.1
 
diff --git a/src/webenginequick/doc/src/loading_info.qdoc b/src/webenginequick/doc/src/loading_info.qdoc
index c97799e2485..4ed745166d6 100644
--- a/src/webenginequick/doc/src/loading_info.qdoc
+++ b/src/webenginequick/doc/src/loading_info.qdoc
@@ -3,7 +3,7 @@
 
 /*!
     \qmltype WebEngineLoadingInfo
-    \instantiates QWebEngineLoadingInfo
+    \nativetype QWebEngineLoadingInfo
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.0
 
diff --git a/src/webenginequick/doc/src/navigation_history.qdoc b/src/webenginequick/doc/src/navigation_history.qdoc
index 94876799da1..42afc070ebb 100644
--- a/src/webenginequick/doc/src/navigation_history.qdoc
+++ b/src/webenginequick/doc/src/navigation_history.qdoc
@@ -3,7 +3,7 @@
 
 /*!
     \qmltype WebEngineHistoryModel
-    \instantiates QWebEngineHistoryModel
+    \nativetype QWebEngineHistoryModel
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.1
 
@@ -24,7 +24,7 @@
 
 /*!
     \qmltype WebEngineHistory
-    \instantiates QWebEngineHistory
+    \nativetype QWebEngineHistory
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.1
 
diff --git a/src/webenginequick/doc/src/quota_request.qdoc b/src/webenginequick/doc/src/quota_request.qdoc
index 01f4ec28606..e96f7a21486 100644
--- a/src/webenginequick/doc/src/quota_request.qdoc
+++ b/src/webenginequick/doc/src/quota_request.qdoc
@@ -3,7 +3,7 @@
 
 /*!
     \qmltype QuotaRequest
-    \instantiates QWebEngineQuotaRequest
+    \nativetype QWebEngineQuotaRequest
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.7
     \deprecated [6.5] Requesting host quota is no longer supported by Chromium.
diff --git a/src/webenginequick/doc/src/register_protocol_handler_request.qdoc b/src/webenginequick/doc/src/register_protocol_handler_request.qdoc
index d69f4d264e6..412a7e656d5 100644
--- a/src/webenginequick/doc/src/register_protocol_handler_request.qdoc
+++ b/src/webenginequick/doc/src/register_protocol_handler_request.qdoc
@@ -3,7 +3,7 @@
 
 /*!
     \qmltype RegisterProtocolHandlerRequest
-    \instantiates QWebEngineRegisterProtocolHandlerRequest
+    \nativetype QWebEngineRegisterProtocolHandlerRequest
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.7
     \brief The RegisterProtocolHandlerRequest type enables accepting
diff --git a/src/webenginequick/doc/src/touch_selection_menu_request.qdoc b/src/webenginequick/doc/src/touch_selection_menu_request.qdoc
index 9ca6ed36bfb..83743502781 100644
--- a/src/webenginequick/doc/src/touch_selection_menu_request.qdoc
+++ b/src/webenginequick/doc/src/touch_selection_menu_request.qdoc
@@ -3,7 +3,7 @@
 
 /*!
     \qmltype TouchSelectionMenuRequest
-    //! \instantiates QQuickWebEngineTouchSelectionMenuRequest
+    //! \nativetype QQuickWebEngineTouchSelectionMenuRequest
     \inqmlmodule QtWebEngine
     \since QtWebEngine 6.3
 
diff --git a/src/webenginequick/doc/src/webengine_certificate_error.qdoc b/src/webenginequick/doc/src/webengine_certificate_error.qdoc
index 93bad9fb113..6253a41facd 100644
--- a/src/webenginequick/doc/src/webengine_certificate_error.qdoc
+++ b/src/webenginequick/doc/src/webengine_certificate_error.qdoc
@@ -3,7 +3,7 @@
 
 /*!
     \qmltype WebEngineCertificateError
-    \instantiates QWebEngineCertificateError
+    \nativetype QWebEngineCertificateError
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.1
 
diff --git a/src/webenginequick/doc/src/webengine_download_request.qdoc b/src/webenginequick/doc/src/webengine_download_request.qdoc
index 96d84e0a3c2..bc93edb62cf 100644
--- a/src/webenginequick/doc/src/webengine_download_request.qdoc
+++ b/src/webenginequick/doc/src/webengine_download_request.qdoc
@@ -3,7 +3,7 @@
 
 /*!
     \qmltype WebEngineDownloadRequest
-    \instantiates QWebEngineDownloadRequest
+    \nativetype QWebEngineDownloadRequest
     \inqmlmodule QtWebEngine
     \brief Provides information about a download.
 
diff --git a/src/webenginequick/doc/src/webengine_permission.qdoc b/src/webenginequick/doc/src/webengine_permission.qdoc
index efe434dde60..ff278470f4e 100644
--- a/src/webenginequick/doc/src/webengine_permission.qdoc
+++ b/src/webenginequick/doc/src/webengine_permission.qdoc
@@ -3,7 +3,7 @@
 
 /*!
     \qmlvaluetype webEnginePermission
-    \instantiates QWebEnginePermission
+    \nativetype QWebEnginePermission
     \inqmlmodule QtWebEngine
     \since 6.8
     \brief An object used to access and modify the state of a single permission that's been
diff --git a/src/webenginequick/doc/src/webengineframe.qdoc b/src/webenginequick/doc/src/webengineframe.qdoc
index 3bcbd30b850..5d6a5599a92 100644
--- a/src/webenginequick/doc/src/webengineframe.qdoc
+++ b/src/webenginequick/doc/src/webengineframe.qdoc
@@ -3,7 +3,7 @@
 
 /*!
     \qmlvaluetype webEngineFrame
-    \instantiates QWebEngineFrame
+    \nativetype QWebEngineFrame
     \brief webEngineFrame provides information about and control over a page frame.
     \since 6.8
     \ingroup qmlvaluetypes
diff --git a/src/webenginequick/doc/src/webenginescript.qdoc b/src/webenginequick/doc/src/webenginescript.qdoc
index 493873f891e..f669ceaaed8 100644
--- a/src/webenginequick/doc/src/webenginescript.qdoc
+++ b/src/webenginequick/doc/src/webenginescript.qdoc
@@ -3,7 +3,7 @@
 
 /*!
     \qmltype WebEngineScript
-    \instantiates QWebEngineScript
+    \nativetype QWebEngineScript
     \brief Enables the programmatic injection of scripts in the JavaScript engine.
     \since QtWebEngine 1.1
     \ingroup qmlvaluetypes
diff --git a/src/webenginequick/doc/src/webengineview_lgpl.qdoc b/src/webenginequick/doc/src/webengineview_lgpl.qdoc
index 45b8ec6393b..04981acfa33 100644
--- a/src/webenginequick/doc/src/webengineview_lgpl.qdoc
+++ b/src/webenginequick/doc/src/webengineview_lgpl.qdoc
@@ -8,7 +8,7 @@
 
 /*!
     \qmltype WebEngineView
-    \instantiates QQuickWebEngineView
+    \nativetype QQuickWebEngineView
     \inherits Item
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.0
@@ -1460,7 +1460,7 @@
 
 /*!
     \qmltype FindTextResult
-    \instantiates QWebEngineFindTextResult
+    \nativetype QWebEngineFindTextResult
     \inqmlmodule QtWebEngine
     \since QtWebEngine 1.10
 

From 408c7588fd343332cd7bf4c4676ea1359aba72e2 Mon Sep 17 00:00:00 2001
From: Anu Aliyas <anu.aliyas@qt.io>
Date: Wed, 12 Jun 2024 12:43:56 +0200
Subject: [PATCH 134/356] Disable blink WebOTP feature

Qt webengine doesn't support WebOTP and the feature is disabled by
webengine. runtime feature enable option  is marked as kSetOnlyIfOverridden
for WebOTP, due to which blink feature is not affected by base::Feature
and explicit disabling of blink feature is need in such cases.

Fixes: QTBUG-126256
Pick-to: 6.7
Change-Id: Ifedbc8d20aa6930cd5dcb3ea750d01cabfc99481
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 9839a94ca77992077272a1988b387a26a6e3f637)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/web_engine_context.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index bc55de20db0..bfc9aee28da 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -950,6 +950,7 @@ WebEngineContext::WebEngineContext()
 
     // Explicitly tell Chromium about default-on features we do not support
     disableFeatures.push_back(features::kBackgroundFetch.name);
+    parsedCommandLine->AppendSwitchASCII(switches::kDisableBlinkFeatures, "WebOTP");
     disableFeatures.push_back(features::kWebOTP.name);
     disableFeatures.push_back(features::kWebPayments.name);
     disableFeatures.push_back(features::kWebUsb.name);

From 6eb9568410c16f687cb20c2b5d890f26c6c3666f Mon Sep 17 00:00:00 2001
From: Anu Aliyas <anu.aliyas@qt.io>
Date: Thu, 20 Jun 2024 15:55:19 +0200
Subject: [PATCH 135/356] Update WebEngineWebAuthPinRequest documentation

WebEngineWebAuthPinRequest is a QML value type and it's name should
begin with lowercase letter. Modified documentation and type name
accordingly.

Change-Id: Id238479799cb3538f2ea329cfa18d2d2f4c44c8f
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit eda6f4577f4b86c1f4512db16aa05f4fa30455d7)
---
 src/core/api/qwebenginewebauthuxrequest.cpp        | 14 +++++++-------
 .../api/qquickwebengineforeigntypes_p.h            |  2 +-
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/core/api/qwebenginewebauthuxrequest.cpp b/src/core/api/qwebenginewebauthuxrequest.cpp
index cc951a2e0a7..18ebbb70ea9 100644
--- a/src/core/api/qwebenginewebauthuxrequest.cpp
+++ b/src/core/api/qwebenginewebauthuxrequest.cpp
@@ -94,8 +94,8 @@
 */
 
 /*!
-    \qmltype WebEngineWebAuthPinRequest
-    \instantiates QWebEngineWebAuthPinRequest
+    \qmlvaluetype webEngineWebAuthPinRequest
+    \ingroup qmlvaluetypes
     \inqmlmodule QtWebEngine
     \since QtWebEngine 6.8
     \brief Encapsulates the data of a PIN WebAuth UX request.
@@ -105,7 +105,7 @@
     \li The reason for the PIN prompt.
     \li The error details for the PIN prompt.
     \li The number of attempts remaining before a hard lock. Should be ignored unless
-        \l{WebEngineWebAuthPinRequest::reason} is
+        \l{webEngineWebAuthPinRequest::reason} is
         \c{WebEngineWebAuthUxRequest.PinEntryReason.Challenge}.
     \li The minimum PIN length that the authenticator will accept for the PIN.
     \endlist
@@ -114,7 +114,7 @@
 */
 
 /*!
-    \qmlproperty enumeration WebEngineWebAuthPinRequest::reason
+    \qmlproperty enumeration QtWebEngine::webEngineWebAuthPinRequest::reason
     \brief The reason for the PIN prompt.
 
     \value WebEngineWebAuthUxRequest.PinEntryReason.Set A new PIN is being set.
@@ -123,7 +123,7 @@
 */
 
 /*!
-    \qmlproperty enumeration WebEngineWebAuthPinRequest::error
+    \qmlproperty enumeration QtWebEngine::webEngineWebAuthPinRequest::error
     \brief The error details for the PIN prompt.
 
     \value WebEngineWebAuthUxRequest.PinEntryError.NoError No error has occurred.
@@ -135,14 +135,14 @@
 */
 
 /*!
-    \qmlproperty int WebEngineWebAuthPinRequest::remainingAttempts
+    \qmlproperty int QtWebEngine::webEngineWebAuthPinRequest::remainingAttempts
     \brief The number of attempts remaining before a hard lock. Should be ignored unless
            \l{WebEngineWebAuthPinRequest::reason} is
            \c{WebEngineWebAuthUxRequest.PinEntryReason.Challenge}.
 */
 
 /*!
-    \qmlproperty int WebEngineWebAuthPinRequest::minPinLength
+    \qmlproperty int QtWebEngine::webEngineWebAuthPinRequest::minPinLength
     \brief The minimum PIN length that the authenticator will accept for the PIN.
 */
 
diff --git a/src/webenginequick/api/qquickwebengineforeigntypes_p.h b/src/webenginequick/api/qquickwebengineforeigntypes_p.h
index 58dee066ffb..58e9a556139 100644
--- a/src/webenginequick/api/qquickwebengineforeigntypes_p.h
+++ b/src/webenginequick/api/qquickwebengineforeigntypes_p.h
@@ -236,7 +236,7 @@ struct ForeginWebEngineWebAuthPinRequest
 {
     Q_GADGET
     QML_FOREIGN(QWebEngineWebAuthPinRequest)
-    QML_NAMED_ELEMENT(WebEngineWebAuthPinRequest)
+    QML_VALUE_TYPE(webEngineWebAuthPinRequest)
     QML_ADDED_IN_VERSION(6, 8)
     QML_UNCREATABLE("")
 };

From 4980afa461a8cf5f5bdb703269bd236b5966c55f Mon Sep 17 00:00:00 2001
From: Anu Aliyas <anu.aliyas@qt.io>
Date: Fri, 23 Aug 2024 17:40:21 +0200
Subject: [PATCH 136/356] Add use_sck to GN argument list

GN argument use_sck is set based on macOS SDK version to ensure
the support of screen capture using macOS's ScreenCaptureKit.

Fixes: QTBUG-127797
Pick-to: 6.7
Change-Id: I02a005d6dc026cec47448a31d3d641461d027987
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 87f58bae3265abf671360f727ef4343fcbffd698)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 cmake/Functions.cmake           | 6 ++++++
 src/core/web_engine_context.cpp | 4 ++++
 2 files changed, 10 insertions(+)

diff --git a/cmake/Functions.cmake b/cmake/Functions.cmake
index f87fd5de316..b9a48821e6f 100644
--- a/cmake/Functions.cmake
+++ b/cmake/Functions.cmake
@@ -922,6 +922,12 @@ macro(append_compiler_linker_sdk_setup)
                 mac_sdk_min="${macSdkVersion}"
                 use_libcxx=true
             )
+            _qt_internal_get_apple_sdk_version(apple_sdk_version)
+            if (apple_sdk_version LESS 13.2)
+                list(APPEND gnArgArg
+                    use_sck=false
+                )
+            endif()
         endif()
         if(IOS)
             list(APPEND gnArgArg
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index bfc9aee28da..a9bfed5a12f 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -939,6 +939,10 @@ WebEngineContext::WebEngineContext()
 
     enableFeatures.push_back(features::kNetworkServiceInProcess.name);
     enableFeatures.push_back(features::kTracingServiceInProcess.name);
+#if defined(Q_OS_MACOS) && BUILDFLAG(USE_SCK)
+    // The feature name should match the definition of kScreenCaptureKitMacScreen.
+    enableFeatures.push_back("ScreenCaptureKitMacScreen");
+#endif // defined(Q_OS_MACOS)
 
     // Avoid crashing when websites tries using this feature (since 83)
     disableFeatures.push_back(features::kInstalledApp.name);

From 6f8668ade2a03a49e95ea173602cdae51fb20aeb Mon Sep 17 00:00:00 2001
From: Anu Aliyas <anu.aliyas@qt.io>
Date: Mon, 26 Aug 2024 18:04:21 +0200
Subject: [PATCH 137/356] Update Chromium

Submodule src/3rdparty c091eb3f..fc4dffda:
* Use ScreenCaptureKit for macOS 13.2 and later
* Avoid crashes related to accessing a null WebRtcLogUploader
* Make gn fat

Change-Id: I22cc74f2d9913f7e4f4e3fc8b07bf5673593e796
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit fa6e6c36752cb52c3a2d0a8b233ad00ab161aba0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/3rdparty | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/3rdparty b/src/3rdparty
index c091eb3fa68..fc4dffdada4 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit c091eb3fa68e1e9c03147623071fa2015a9e3692
+Subproject commit fc4dffdada44bac3e17c209854f58c1d5f448155

From c3a8bb64eab796ae997d7447c596c54f83264265 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Mon, 26 Aug 2024 11:33:36 +0200
Subject: [PATCH 138/356] Quick Nano Browser: Remove usage of
 QCommandLineParser

This change partially reverts 98bae072c090ee19e2a5a1e85eed712a060d12fc
to remove usage of QCommandLineParser. The class does not support
WebEngine's way of passing arguments to Chromium using --webEngineArgs,
and attempting to do so simply closes the app at startup.

Pick-to: 6.7 6.5
Change-Id: I7a26637da8771aaa1851bc988118acd074e00997
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
---
 .../webenginequick/quicknanobrowser/main.cpp  | 24 +++++++++----------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/examples/webenginequick/quicknanobrowser/main.cpp b/examples/webenginequick/quicknanobrowser/main.cpp
index 1e693cbcd26..7a64eb8f3a9 100644
--- a/examples/webenginequick/quicknanobrowser/main.cpp
+++ b/examples/webenginequick/quicknanobrowser/main.cpp
@@ -14,12 +14,17 @@
 #include <QtCore/QCommandLineOption>
 #include <QtCore/QLoggingCategory>
 
-static QUrl startupUrl(const QCommandLineParser &parser)
+static QUrl startupUrl()
 {
-    if (!parser.positionalArguments().isEmpty()) {
-        const QUrl url = Utils::fromUserInput(parser.positionalArguments().constFirst());
-        if (url.isValid())
-            return url;
+    QUrl ret;
+    QStringList args(qApp->arguments());
+    args.takeFirst();
+    for (const QString &arg : qAsConst(args)) {
+        if (arg.startsWith(QLatin1Char('-')))
+             continue;
+        ret = Utils::fromUserInput(arg);
+        if (ret.isValid())
+            return ret;
     }
     return QUrl(QStringLiteral("chrome://qt"));
 }
@@ -34,20 +39,13 @@ int main(int argc, char **argv)
     QGuiApplication app(argc, argv);
     QLoggingCategory::setFilterRules(QStringLiteral("qt.webenginecontext.debug=true"));
 
-    QCommandLineParser parser;
-    parser.addHelpOption();
-    parser.addVersionOption();
-    parser.addPositionalArgument("url", "The URL to open.");
-    parser.process(app);
-
     QQmlApplicationEngine appEngine;
     appEngine.load(QUrl("qrc:/ApplicationRoot.qml"));
     if (appEngine.rootObjects().isEmpty())
         qFatal("Failed to load sources");
 
-    const QUrl url = startupUrl(parser);
     QMetaObject::invokeMethod(appEngine.rootObjects().constFirst(),
-                              "load", Q_ARG(QVariant, url));
+                              "load", Q_ARG(QVariant, startupUrl()));
 
     return app.exec();
 }

From a3e1c902a7700daea22f5706393b19440241fdbf Mon Sep 17 00:00:00 2001
From: Marc Mutz <marc.mutz@qt.io>
Date: Mon, 26 Aug 2024 18:02:42 +0200
Subject: [PATCH 139/356] QWebEnginePermission: fix move ctor and QESDP macro
 use

Unless you =default also ~Public(), the _WITH_EXPORT version of
QT_DECLARE_QESDP_SPECIALIZATION_DTOR is not needed, and could cause
problems with linker scripts that try to keep private API out of the
ABI. For an inline move ctor, the export isn't needed, because the
compiler never calls the d_ptr dtor (even though it must be present
during compilation).

Also fix the move ctor to be inline, noexcept and =default'ed. That's
the whole point of using the QESDP macros, after all.

Found in API-review.

Change-Id: Id4092e98931cbbd7334a7cfe763696b8b9b4948a
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
(cherry picked from commit 46d1e664f2d100355dfcf2438d775189c4d8c0f7)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebenginepermission.cpp | 5 -----
 src/core/api/qwebenginepermission.h   | 5 ++---
 2 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/src/core/api/qwebenginepermission.cpp b/src/core/api/qwebenginepermission.cpp
index d6f5ed98fcc..5fa1ed4842e 100644
--- a/src/core/api/qwebenginepermission.cpp
+++ b/src/core/api/qwebenginepermission.cpp
@@ -93,11 +93,6 @@ QWebEnginePermission::QWebEnginePermission(const QWebEnginePermission &other)
 {
 }
 
-QWebEnginePermission::QWebEnginePermission(QWebEnginePermission &&other)
-    : d_ptr(std::move(other.d_ptr))
-{
-}
-
 QWebEnginePermission::~QWebEnginePermission() = default;
 
 QWebEnginePermission &QWebEnginePermission::operator=(const QWebEnginePermission &other)
diff --git a/src/core/api/qwebenginepermission.h b/src/core/api/qwebenginepermission.h
index bb74e6a2052..476c8bdd40b 100644
--- a/src/core/api/qwebenginepermission.h
+++ b/src/core/api/qwebenginepermission.h
@@ -21,8 +21,7 @@ class QQuickWebEngineViewPrivate;
 class QQuickWebEngineProfile;
 
 struct QWebEnginePermissionPrivate;
-QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QWebEnginePermissionPrivate,
-                                                 Q_WEBENGINECORE_EXPORT)
+QT_DECLARE_QESDP_SPECIALIZATION_DTOR(QWebEnginePermissionPrivate)
 
 class QWebEnginePermission
 {
@@ -37,7 +36,7 @@ class QWebEnginePermission
     Q_WEBENGINECORE_EXPORT QWebEnginePermission();
 
     Q_WEBENGINECORE_EXPORT QWebEnginePermission(const QWebEnginePermission &other);
-    Q_WEBENGINECORE_EXPORT QWebEnginePermission(QWebEnginePermission &&other);
+    QWebEnginePermission(QWebEnginePermission &&other) noexcept = default;
     Q_WEBENGINECORE_EXPORT ~QWebEnginePermission();
 
     Q_WEBENGINECORE_EXPORT QWebEnginePermission &operator=(const QWebEnginePermission &other);

From 6d65c33cd660e5b92df15c7785fe0f9bf54c0547 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Mon, 29 Jul 2024 13:47:55 +0200
Subject: [PATCH 140/356] Fix not working popup with qquick on eglfs

After refactoring in 5d1ef38 we lost popups with qquick.
Unfortunately we do not have tests for it as we do
not run eglfs on ci.

Pick-to: 6.7
Fixes: QTBUG-119908
Change-Id: Iea6cadf96dcac488898bb31132938fe8020d4d79
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 746cdfc088eaf4171d8dc1dc0ae489cdd846c68a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/webenginequick/api/qquickwebengineview.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/webenginequick/api/qquickwebengineview.cpp b/src/webenginequick/api/qquickwebengineview.cpp
index 56985780859..0fa9db0f060 100644
--- a/src/webenginequick/api/qquickwebengineview.cpp
+++ b/src/webenginequick/api/qquickwebengineview.cpp
@@ -261,8 +261,9 @@ class WebEngineQuickWidgetDelegate : public QtWebEngineCore::WidgetDelegate
 
     void InitAsPopup(const QRect &screenRect) override
     {
-        Q_UNUSED(screenRect);
-        Q_UNREACHABLE();
+        // note this is called when there is no windowing system
+        // otherwsie see RenderWidgetHostViewQtDelegateQuickWindow
+        m_contentItem->setPosition(screenRect.topLeft());
     }
 
     void Bind(WebContentsAdapterClient *client) override

From 67dcf8ced943a1e234d206224e5c7c483ac998d7 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Tue, 4 Jun 2024 13:30:36 +0200
Subject: [PATCH 141/356] Fix crash on Windows when storing blobs on disk

As a security feature, files that may get accessed by multiple threads
on Windows get marked with a deny execute ACE when written to disk,
which prevents them from being opened for execution later on.
Unfortunately, the directories allowed to have files marked like this
are limited, and need explicit opt-in. This triggers a debug crash
whenever a blob is to be written to disk, since the target directory is
not in that list.

This change ensures that profile storage directories (including custom
ones set by the user) get added to that list. We do so by keeping our
own static list of all storage paths needed by non-OTR profiles, and
making sure that said list is passed to Chromium whenever a new storage
path is to be used.

However, the code in this commit only ensures that the last
registered profile path will work correctly, since Chromium does not
expect an embedder to allow multiple non-OTR profiles alive at the same
time, each with its own arbitrary storage path. To make this use case
work, the underlying code in the path service is also changed in a
separate Chromium change.

Pick-to: 6.7
Change-Id: Ic0f12f8e444fc0c6325cc2f1ee06a0b73634e398
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit d06d875cdee7cff699b0c3163e2f1a36f3158670)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/profile_adapter.cpp |  1 +
 src/core/profile_qt.cpp      | 41 ++++++++++++++++++++++++++++++++++++
 src/core/profile_qt.h        |  1 +
 3 files changed, 43 insertions(+)

diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index 952e5031e0c..a74ecc8cf38 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -266,6 +266,7 @@ void ProfileAdapter::setDataPath(const QString &path)
     m_dataPath = path;
     m_profile->setupPrefService();
     m_profile->setupPermissionsManager();
+    m_profile->setupStoragePath();
     if (!m_profile->m_profileIOData->isClearHttpCacheInProgress())
         m_profile->m_profileIOData->resetNetworkContext();
     if (!m_offTheRecord && m_visitedLinksManager)
diff --git a/src/core/profile_qt.cpp b/src/core/profile_qt.cpp
index ffb1297a5cf..5bb9599bc79 100644
--- a/src/core/profile_qt.cpp
+++ b/src/core/profile_qt.cpp
@@ -17,7 +17,9 @@
 #include "web_engine_library_info.h"
 
 #include "base/base_paths.h"
+#include "base/path_service.h"
 #include "base/files/file_util.h"
+#include "base/task/thread_pool.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/prefs/pref_service.h"
 #include "components/user_prefs/user_prefs.h"
@@ -40,6 +42,11 @@
 
 namespace QtWebEngineCore {
 
+enum {
+    PATH_QT_START = 1000, // Same as PATH_START in chrome_paths.h; no chance of collision
+    PATH_QT_END = 1999
+};
+
 ProfileQt::ProfileQt(ProfileAdapter *profileAdapter)
     : m_profileIOData(new ProfileIODataQt(this))
     , m_profileAdapter(profileAdapter)
@@ -53,6 +60,7 @@ ProfileQt::ProfileQt(ProfileAdapter *profileAdapter)
         : profile_metrics::BrowserProfileType::kRegular);
 
     setupPrefService();
+    setupStoragePath();
 
     // Mark the context as live. This prevents the use-after-free DCHECK in
     // AssertBrowserContextWasntDestroyed from being triggered when a new
@@ -254,6 +262,39 @@ void ProfileQt::setupPrefService()
 #endif
 }
 
+void ProfileQt::setupStoragePath()
+{
+#if defined(Q_OS_WIN)
+    if (IsOffTheRecord())
+        return;
+
+    // Mark the storage path as a "safe" path, allowing the path service on Windows to
+    // block file execution and prevent assertions when saving blobs to disk.
+    // We keep a static list of all profile paths
+
+    base::FilePath thisStoragePath = GetPath();
+
+    static std::vector<base::FilePath> storagePaths;
+    auto it = std::find(storagePaths.begin(), storagePaths.end(), thisStoragePath);
+    if (it == storagePaths.end()) {
+        if (storagePaths.size() >= (PATH_QT_END - PATH_QT_START)) {
+            qWarning() << "Number of profile paths exceeded " << PATH_QT_END - PATH_QT_START << ", storage may break";
+            return;
+        }
+
+        storagePaths.push_back(thisStoragePath);
+        it = storagePaths.end() - 1;
+    }
+
+    int pathID = PATH_QT_START + (it - storagePaths.begin());
+    base::ThreadPool::PostTaskAndReplyWithResult(FROM_HERE, { base::MayBlock() },
+        base::BindOnce(base::PathService::Override, PATH_QT_START + (it - storagePaths.begin()), thisStoragePath),
+        base::BindOnce([](int pathID_, bool succeeded) {
+            if (succeeded) base::SetExtraNoExecuteAllowedPath(pathID_);
+        }, pathID));
+#endif // defined(Q_OS_WIN)
+}
+
 void ProfileQt::setupPermissionsManager()
 {
     m_permissionManager.reset(new PermissionManagerQt(profileAdapter()));
diff --git a/src/core/profile_qt.h b/src/core/profile_qt.h
index 5394182e4e1..f5ca0375915 100644
--- a/src/core/profile_qt.h
+++ b/src/core/profile_qt.h
@@ -72,6 +72,7 @@ class ProfileQt : public Profile
     // Build/Re-build the preference service. Call when updating the storage
     // data path.
     void setupPrefService();
+    void setupStoragePath();
     void setupPermissionsManager();
 
     PrefServiceAdapter &prefServiceAdapter();

From 0e5c781964fab8fa725a6aafb06b6441e3ccf5c2 Mon Sep 17 00:00:00 2001
From: David Faure <david.faure@kdab.com>
Date: Sun, 1 Sep 2024 13:42:50 +0200
Subject: [PATCH 142/356] QPDFIoHandler: add error handling for seek() call

Don't process garbage data if the device has less than 6 bytes.

Change-Id: I2c44d869b109ea6e004b038f45dfc305da5aba10
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
(cherry picked from commit 9777abeb7e4b114501ec4386bcff61773936b585)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp b/src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp
index bb3e7c92930..a7fd9fa9e76 100644
--- a/src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp
+++ b/src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp
@@ -36,7 +36,8 @@ bool QPdfIOHandler::canRead() const
 bool QPdfIOHandler::canRead(QIODevice *device)
 {
     char buf[6];
-    device->peek(buf, 6);
+    if (device->peek(buf, 6) != 6)
+        return false;
     return (!qstrncmp(buf, "%PDF-", 5) || Q_UNLIKELY(!qstrncmp(buf, "\012%PDF-", 6)));
 }
 

From fdc60518c5c41efdac80a45d8385a0d235204941 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Mon, 15 Jul 2024 14:51:38 +0200
Subject: [PATCH 143/356] Stop location provider when location is disabled
 globally
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Qt Core still doesn't have a permission backend on Windows, which
results in the permission check for location always returning true,
regardless of the actual Windows setting. In that case, the WebEngine
location provider would just pass along the info that access was denied,
but keep updates on, resulting in the location request just timing out.

This change makes sure that the location provider is stopped immediately
when access is denied, removing the timeout and signalling
to the we application that permission has been denied. This isn't the
exact behavior of other browsers, since they fall back on consentless
(low accuracy) location info and we don't, but that's a limitation of
the QtPositioning module.

Pick-to: 6.7
Change-Id: I097bade1ec6b31352321139195b630124657c23a
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
(cherry picked from commit ba1d8dc18f6b2406f39968ec1070ea5becfb6a8e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/location_provider_qt.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/core/location_provider_qt.cpp b/src/core/location_provider_qt.cpp
index dc0d80aa79d..479228dc498 100644
--- a/src/core/location_provider_qt.cpp
+++ b/src/core/location_provider_qt.cpp
@@ -214,8 +214,12 @@ void QtPositioningHelper::error(QGeoPositionInfoSource::Error positioningError)
         break;
     }
     auto newResult = device::mojom::GeopositionResult::NewError(std::move(newError));
-    if (m_locationProvider)
+    if (m_locationProvider) {
         postToLocationProvider(base::BindOnce(&LocationProviderQt::updatePosition, m_locationProviderFactory.GetWeakPtr(), std::move(newResult)));
+        if (positioningError == QGeoPositionInfoSource::AccessError) {
+            postToLocationProvider(base::BindOnce(&LocationProviderQt::StopProvider, m_locationProviderFactory.GetWeakPtr()));
+        }
+    }
 }
 
 inline void QtPositioningHelper::postToLocationProvider(base::OnceClosure task)

From a7331ca3ee2948de2f16787b62a22a74868cf00a Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Wed, 17 Jul 2024 17:12:59 +0200
Subject: [PATCH 144/356] Handle null desktop media capturer
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

With wayland+no pipewire, webrtc will return a null capturer. We need
to handle this to avoid a crash.

Pick-to: 6.7
Fixes: QTBUG-127726
Change-Id: I0ce730a1156305a6d869630c43f0f1f23cb1df0c
Reviewed-by: Martin Negyokru <negyokru@inf.u-szeged.hu>
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
(cherry picked from commit e0ffa1ec136fb1e6c8a4b46df6c4282ab9f29137)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 .../api/qwebenginedesktopmediarequest.cpp     |  3 +-
 src/core/desktop_media_controller.cpp         | 70 ++++++++------
 src/core/desktop_media_controller.h           |  1 -
 src/core/desktop_media_controller_p.h         |  1 +
 .../quick/qmltests/data/tst_getUserMedia.qml  | 39 ++++++--
 .../qwebenginepage/tst_qwebenginepage.cpp     | 94 ++++++++++++-------
 6 files changed, 133 insertions(+), 75 deletions(-)

diff --git a/src/core/api/qwebenginedesktopmediarequest.cpp b/src/core/api/qwebenginedesktopmediarequest.cpp
index dae69a68c57..1d93edc99ba 100644
--- a/src/core/api/qwebenginedesktopmediarequest.cpp
+++ b/src/core/api/qwebenginedesktopmediarequest.cpp
@@ -108,7 +108,8 @@ QWebEngineDesktopMediaRequestPrivate::~QWebEngineDesktopMediaRequestPrivate()
 {
     // Keep old behavior, if there were no user action select the primary screen.
     if (!didSelectOrCancel)
-        controller->selectScreen(0);
+        controller->screens()->getSourceCount() > 0 ? controller->selectScreen(0)
+                                                    : controller->cancel();
 }
 
 void QWebEngineDesktopMediaRequestPrivate::selectWindow(const QModelIndex &index)
diff --git a/src/core/desktop_media_controller.cpp b/src/core/desktop_media_controller.cpp
index 50ac0a40c45..09c1aea1914 100644
--- a/src/core/desktop_media_controller.cpp
+++ b/src/core/desktop_media_controller.cpp
@@ -15,6 +15,8 @@
 #include "content/public/browser/desktop_capture.h"
 #endif // QT_CONFIG(webengine_webrtc)
 
+#include <QtCore/QTimer>
+
 namespace QtWebEngineCore {
 namespace {
 DesktopMediaList::Type toMediaListType(DesktopMediaType type)
@@ -39,15 +41,21 @@ std::unique_ptr<DesktopMediaList> createMediaList(DesktopMediaType type)
     case DesktopMediaList::Type::kScreen: {
         std::unique_ptr<webrtc::DesktopCapturer> screenCapturer =
                 webrtc::DesktopCapturer::CreateScreenCapturer(options);
-        std::unique_ptr<DesktopCapturerWrapper> capturer =
-                std::make_unique<DesktopCapturerWrapper>(std::move(screenCapturer));
+        if (!screenCapturer) {
+            qWarning() << "Screen capturing is not available. Media list will be empty.";
+            return nullptr;
+        }
+        auto capturer = std::make_unique<DesktopCapturerWrapper>(std::move(screenCapturer));
         return std::make_unique<NativeDesktopMediaList>(listType, std::move(capturer));
     }
     case DesktopMediaList::Type::kWindow: {
         std::unique_ptr<webrtc::DesktopCapturer> windowCapturer =
                 webrtc::DesktopCapturer::CreateWindowCapturer(options);
-        std::unique_ptr<DesktopCapturerWrapper> capturer =
-                std::make_unique<DesktopCapturerWrapper>(std::move(windowCapturer));
+        if (!windowCapturer) {
+            qWarning() << "Window capturing is not available. Media list will be empty.";
+            return nullptr;
+        }
+        auto capturer = std::make_unique<DesktopCapturerWrapper>(std::move(windowCapturer));
         return std::make_unique<NativeDesktopMediaList>(
                 listType, std::move(capturer),
                 !content::desktop_capture::ShouldEnumerateCurrentProcessWindows());
@@ -69,6 +77,7 @@ class DesktopMediaListQtPrivate : public DesktopMediaListObserver
 
     void init();
     void startUpdating();
+    int getSourceCount() const;
     const DesktopMediaList::Source& getSource(int index) const;
 
     void OnSourceAdded(int index) override;
@@ -80,21 +89,19 @@ class DesktopMediaListQtPrivate : public DesktopMediaListObserver
     void OnDelegatedSourceListSelection() override { }
     void OnDelegatedSourceListDismissed() override { }
 
-    bool isInitialized;
     std::unique_ptr<DesktopMediaList> mediaList;
     DesktopMediaListQt *q_ptr;
     Q_DECLARE_PUBLIC(DesktopMediaListQt)
 };
 
 DesktopMediaListQtPrivate::DesktopMediaListQtPrivate(DesktopMediaType type, DesktopMediaListQt *qq)
-    : isInitialized(false)
-    , mediaList(createMediaList(type))
-    , q_ptr(qq)
+    : mediaList(createMediaList(type)), q_ptr(qq)
 {
 }
 
 const DesktopMediaList::Source& DesktopMediaListQtPrivate::getSource(int index) const
 {
+    Q_ASSERT(mediaList);
     return mediaList->GetSource(index);
 }
 
@@ -105,21 +112,30 @@ void DesktopMediaListQtPrivate::init()
     // This makes direct 'selectScreen/Window' calls possible from the frontend.
     // Note: StartUpdating should be called after Update is completed as it can overwrite the
     // internal cb.
-    base::OnceCallback<void()> onComplete = base::BindOnce(
-            [](DesktopMediaListQtPrivate *observer) {
-                observer->isInitialized = true;
-                Q_EMIT observer->q_ptr->initialized();
-                observer->startUpdating();
-            },
-            this);
-    mediaList->Update(std::move(onComplete));
+    if (mediaList) {
+        base::OnceCallback<void()> onComplete = base::BindOnce(
+                [](DesktopMediaListQtPrivate *observer) {
+                    Q_EMIT observer->q_ptr->initialized();
+                    observer->startUpdating();
+                },
+                this);
+        mediaList->Update(std::move(onComplete));
+    } else {
+        QTimer::singleShot(0, q_ptr, [this]() { Q_EMIT q_ptr->initialized(); });
+    }
 }
 
 void DesktopMediaListQtPrivate::startUpdating()
 {
+    Q_ASSERT(mediaList);
     mediaList->StartUpdating(this);
 }
 
+int DesktopMediaListQtPrivate::getSourceCount() const
+{
+    return mediaList ? mediaList->GetSourceCount() : 0;
+}
+
 void DesktopMediaListQtPrivate::OnSourceAdded(int index)
 {
     Q_Q(DesktopMediaListQt);
@@ -159,12 +175,7 @@ QString DesktopMediaListQt::getSourceName(int index) const
 
 int DesktopMediaListQt::getSourceCount() const
 {
-    return d->mediaList->GetSourceCount();
-}
-
-bool DesktopMediaListQt::isInitialized() const
-{
-    return d->isInitialized;
+    return d->getSourceCount();
 }
 
 DesktopMediaControllerPrivate::DesktopMediaControllerPrivate(
@@ -172,6 +183,7 @@ DesktopMediaControllerPrivate::DesktopMediaControllerPrivate(
     : doneCallback(std::move(doneCallback))
     , screens(new DesktopMediaListQt(DesktopMediaType::Screen))
     , windows(new DesktopMediaListQt(DesktopMediaType::Window))
+    , numInitialized(0)
 {
 }
 
@@ -198,16 +210,14 @@ DesktopMediaController::DesktopMediaController(DesktopMediaControllerPrivate *dd
     // Make sure both lists are populated before sending the request.
     DesktopMediaListQt *screens = DesktopMediaController::screens();
     DesktopMediaListQt *windows = DesktopMediaController::windows();
-    QObject::connect(screens, &DesktopMediaListQt::initialized, [windows, this]() {
-        if (windows->isInitialized())
-            Q_EMIT mediaListsInitialized();
-    });
-
-    QObject::connect(windows, &DesktopMediaListQt::initialized, [screens, this]() {
-        if (screens->isInitialized())
+    auto initCb = [this] {
+        ++d->numInitialized;
+        if (d->numInitialized == 2)
             Q_EMIT mediaListsInitialized();
-    });
+    };
 
+    QObject::connect(screens, &DesktopMediaListQt::initialized, initCb);
+    QObject::connect(windows, &DesktopMediaListQt::initialized, initCb);
     screens->d->init();
     windows->d->init();
 }
diff --git a/src/core/desktop_media_controller.h b/src/core/desktop_media_controller.h
index 0cb7412250a..fee3f34c9fd 100644
--- a/src/core/desktop_media_controller.h
+++ b/src/core/desktop_media_controller.h
@@ -35,7 +35,6 @@ class Q_WEBENGINECORE_EXPORT DesktopMediaListQt : public QObject
 private:
     friend class DesktopMediaController;
     friend class DesktopMediaControllerPrivate;
-    bool isInitialized() const;
     explicit DesktopMediaListQt(DesktopMediaType type);
     std::unique_ptr<DesktopMediaListQtPrivate> d;
 };
diff --git a/src/core/desktop_media_controller_p.h b/src/core/desktop_media_controller_p.h
index 4bb3a6312f7..95d4fd585c5 100644
--- a/src/core/desktop_media_controller_p.h
+++ b/src/core/desktop_media_controller_p.h
@@ -21,6 +21,7 @@ class Q_WEBENGINECORE_EXPORT DesktopMediaControllerPrivate
     base::OnceCallback<void(content::DesktopMediaID)> doneCallback;
     QScopedPointer<DesktopMediaListQt> screens;
     QScopedPointer<DesktopMediaListQt> windows;
+    int numInitialized;
 };
 
 } // namespace QtWebEngineCore
diff --git a/tests/auto/quick/qmltests/data/tst_getUserMedia.qml b/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
index 371977ac737..c6fcee43e77 100644
--- a/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
+++ b/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
@@ -69,7 +69,7 @@ TestWebEngineView {
 
             // 1. Rejecting request on QML side should reject promise on JS side.
             jsGetUserMedia(row.constraints)
-            tryVerify(function(){ return gotFeatureRequest(row.feature) })
+            tryVerify(function(){ return gotExpectedRequests(row.feature) })
             rejectPendingRequest()
             tryVerify(function(){ return !jsPromiseFulfilled() && jsPromiseRejected() })
 
@@ -79,13 +79,13 @@ TestWebEngineView {
             // always be fulfilled, however in this case an error should be returned to
             // JS instead of leaving the Promise in limbo.
             jsGetUserMedia(row.constraints)
-            tryVerify(function(){ return gotFeatureRequest(row.feature) })
+            tryVerify(function(){ return gotExpectedRequests(row.feature) })
             acceptPendingRequest()
             tryVerify(function(){ return jsPromiseFulfilled() || jsPromiseRejected() });
 
             // 3. Media feature permissions are not remembered.
             jsGetUserMedia(row.constraints);
-            tryVerify(function(){ return gotFeatureRequest(row.feature) })
+            tryVerify(function(){ return gotExpectedRequests(row.feature) })
             acceptPendingRequest()
             tryVerify(function(){ return jsPromiseFulfilled() || jsPromiseRejected() });
         }
@@ -117,23 +117,48 @@ TestWebEngineView {
     // synchronous permission requests
 
     property variant permissionObject
+    property bool gotDesktopMediaRequest: false
+    property bool gotEmptyDesktopMediaRequest: false
 
     onPermissionRequested: function(perm) {
         permissionObject = perm
     }
 
-    function gotFeatureRequest(expectedFeature) {
+    onDesktopMediaRequested: function(request) {
+        gotDesktopMediaRequest = true
+        gotEmptyDesktopMediaRequest = request.screensModel.rowCount() == 0
+        if (gotEmptyDesktopMediaRequest)
+            request.cancel()
+        else
+            request.selectScreen(request.screensModel.index(0, 0))
+    }
+
+    function gotExpectedRequests(expectedFeature) {
+        var isDesktopPermission = expectedFeature == WebEnginePermission.PermissionType.DesktopAudioVideoCapture ||
+            expectedFeature == WebEnginePermission.PermissionType.DesktopVideoCapture;
+        if (isDesktopPermission != gotDesktopMediaRequest)
+            return false
+        if (isDesktopPermission && gotEmptyDesktopMediaRequest)
+            return permissionObject == undefined
         return permissionObject && permissionObject.permissionType == expectedFeature
     }
 
     function acceptPendingRequest() {
-        permissionObject.grant()
+        if (permissionObject)
+            permissionObject.grant()
+        resetRequestState()
+    }
+
+    function resetRequestState() {
         permissionObject = undefined
+        gotDesktopMediaRequest = false
+        gotEmptyDesktopMediaRequest = false
     }
 
     function rejectPendingRequest() {
-        permissionObject.deny()
-        permissionObject = undefined
+        if (permissionObject)
+            permissionObject.deny()
+        resetRequestState()
     }
 
     ////
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index a5e96bc7954..e6b7f615ea8 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -1672,11 +1672,14 @@ Q_OBJECT
 
 public:
     GetUserMediaTestPage()
-        : m_gotRequest(false)
+        : m_gotDesktopMediaRequest(false)
+        , m_gotEmptyDesktopMediaRequest(false)
         , m_loadSucceeded(false)
         , m_permission(nullptr)
     {
         connect(this, &QWebEnginePage::permissionRequested, this, &GetUserMediaTestPage::onPermissionRequested);
+        connect(this, &QWebEnginePage::desktopMediaRequested, this,
+                &GetUserMediaTestPage::onDesktopMediaRequested);
         connect(this, &QWebEnginePage::loadFinished, [this](bool success){
             m_loadSucceeded = success;
         });
@@ -1714,25 +1717,26 @@ Q_OBJECT
 
     void rejectPendingRequest()
     {
-        QVERIFY(m_permission);
-        m_permission->deny();
-        m_gotRequest = false;
-    }
-    void acceptPendingRequest()
-    {
-        QVERIFY(m_permission);
-        m_permission->grant();
-        m_gotRequest = false;
+        if (m_permission)
+            m_permission->deny();
+        resetRequestState();
     }
 
-    bool gotFeatureRequest(QWebEnginePermission::PermissionType permissionType)
+    void acceptPendingRequest()
     {
-        return m_gotRequest && m_permission && m_permission->permissionType() == permissionType;
+        if (m_permission)
+            m_permission->grant();
+        resetRequestState();
     }
 
-    bool gotFeatureRequest() const
+    bool gotExpectedRequests(bool isDesktopPermission,
+                             QWebEnginePermission::PermissionType permissionType) const
     {
-        return m_gotRequest;
+        if (isDesktopPermission != m_gotDesktopMediaRequest)
+            return false;
+        if (isDesktopPermission && m_gotEmptyDesktopMediaRequest)
+            return !m_permission;
+        return m_permission && m_permission->permissionType() == permissionType;
     }
 
     bool loadSucceeded() const
@@ -1744,11 +1748,26 @@ private Q_SLOTS:
     void onPermissionRequested(QWebEnginePermission permission)
     {
         m_permission.reset(new QWebEnginePermission(permission));
-        m_gotRequest = true;
+    }
+
+    void onDesktopMediaRequested(QWebEngineDesktopMediaRequest request)
+    {
+        m_gotDesktopMediaRequest = true;
+        m_gotEmptyDesktopMediaRequest = request.screensModel()->rowCount() == 0;
+        // On destruction, the request will automatically select screen 0, or cancel
+        // if no screens are available.
     }
 
 private:
-    bool m_gotRequest;
+    void resetRequestState()
+    {
+        m_gotDesktopMediaRequest = false;
+        m_gotEmptyDesktopMediaRequest = false;
+        m_permission.reset();
+    }
+
+    bool m_gotDesktopMediaRequest;
+    bool m_gotEmptyDesktopMediaRequest;
     bool m_loadSucceeded;
     std::unique_ptr<QWebEnginePermission> m_permission;
 };
@@ -1757,21 +1776,20 @@ void tst_QWebEnginePage::getUserMediaRequest_data()
 {
     QTest::addColumn<QString>("call");
     QTest::addColumn<QWebEnginePermission::PermissionType>("permissionType");
+    using PT = QWebEnginePermission::PermissionType;
 
-    QTest::addRow("device audio")
-        << "getUserMedia({audio: true})" << QWebEnginePermission::PermissionType::MediaAudioCapture;
-    QTest::addRow("device video")
-        << "getUserMedia({video: true})" << QWebEnginePermission::PermissionType::MediaVideoCapture;
+    QTest::addRow("device audio") << "getUserMedia({audio: true})" << PT::MediaAudioCapture;
+    QTest::addRow("device video") << "getUserMedia({video: true})" << PT::MediaVideoCapture;
     QTest::addRow("device audio+video")
-        << "getUserMedia({audio: true, video: true})" << QWebEnginePermission::PermissionType::MediaAudioVideoCapture;
+            << "getUserMedia({audio: true, video: true})" << PT::MediaAudioVideoCapture;
     QTest::addRow("desktop video")
-        << "getUserMedia({video: { mandatory: { chromeMediaSource: 'desktop' }}})"
-        << QWebEnginePermission::PermissionType::DesktopVideoCapture;
+            << "getUserMedia({video: { mandatory: { chromeMediaSource: 'desktop' }}})"
+            << PT::DesktopVideoCapture;
     QTest::addRow("desktop audio+video")
-        << "getUserMedia({audio: { mandatory: { chromeMediaSource: 'desktop' }}, video: { mandatory: { chromeMediaSource: 'desktop' }}})"
-        << QWebEnginePermission::PermissionType::DesktopAudioVideoCapture;
-    QTest::addRow("display video")
-        << "getDisplayMedia()" << QWebEnginePermission::PermissionType::DesktopVideoCapture;
+            << "getUserMedia({audio: { mandatory: { chromeMediaSource: 'desktop' }}, video: { "
+               "mandatory: { chromeMediaSource: 'desktop' }}})"
+            << PT::DesktopAudioVideoCapture;
+    QTest::addRow("display video") << "getDisplayMedia()" << PT::DesktopVideoCapture;
 }
 
 void tst_QWebEnginePage::getUserMediaRequest()
@@ -1779,10 +1797,12 @@ void tst_QWebEnginePage::getUserMediaRequest()
     QFETCH(QString, call);
     QFETCH(QWebEnginePermission::PermissionType, permissionType);
 
+    bool isDesktopPermission =
+            permissionType == QWebEnginePermission::PermissionType::DesktopVideoCapture
+            || permissionType == QWebEnginePermission::PermissionType::DesktopAudioVideoCapture;
     GetUserMediaTestPage page;
     QWebEngineView view;
-    if (permissionType == QWebEnginePermission::PermissionType::DesktopVideoCapture
-            || permissionType == QWebEnginePermission::PermissionType::DesktopAudioVideoCapture) {
+    if (isDesktopPermission) {
         // Desktop capture needs to be on a desktop.
         view.setPage(&page);
         view.resize(640, 480);
@@ -1795,7 +1815,7 @@ void tst_QWebEnginePage::getUserMediaRequest()
 
     // 1. Rejecting request on C++ side should reject promise on JS side.
     page.jsGetMedia(call);
-    QTRY_VERIFY(page.gotFeatureRequest(permissionType));
+    QTRY_VERIFY(page.gotExpectedRequests(isDesktopPermission, permissionType));
     page.rejectPendingRequest();
     QTRY_VERIFY(!page.jsPromiseFulfilled() && page.jsPromiseRejected());
 
@@ -1805,13 +1825,13 @@ void tst_QWebEnginePage::getUserMediaRequest()
     // always be fulfilled, however in this case an error should be returned to
     // JS instead of leaving the Promise in limbo.
     page.jsGetMedia(call);
-    QTRY_VERIFY(page.gotFeatureRequest(permissionType));
+    QTRY_VERIFY(page.gotExpectedRequests(isDesktopPermission, permissionType));
     page.acceptPendingRequest();
     QTRY_VERIFY(page.jsPromiseFulfilled() || page.jsPromiseRejected());
 
     // 3. Media permissions are not remembered.
     page.jsGetMedia(call);
-    QTRY_VERIFY(page.gotFeatureRequest(permissionType));
+    QTRY_VERIFY(page.gotExpectedRequests(isDesktopPermission, permissionType));
     page.acceptPendingRequest();
     QTRY_VERIFY(page.jsPromiseFulfilled() || page.jsPromiseRejected());
 }
@@ -1873,7 +1893,7 @@ void tst_QWebEnginePage::getUserMediaRequestDesktopVideoManyPages()
     for (GetUserMediaTestPage &page : pages)
         page.jsGetUserMedia(constraints);
     for (GetUserMediaTestPage &page : pages)
-        QTRY_VERIFY(page.gotFeatureRequest(permissionType));
+        QTRY_VERIFY(page.gotExpectedRequests(/*isDesktopPermission*/ true, permissionType));
     for (GetUserMediaTestPage &page : pages)
         page.acceptPendingRequest();
     for (GetUserMediaTestPage &page : pages)
@@ -1899,7 +1919,7 @@ void tst_QWebEnginePage::getUserMediaRequestDesktopVideoManyRequests()
     page.settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true);
     for (int i = 0; i != 100; ++i) {
         page.jsGetUserMedia(constraints);
-        QTRY_VERIFY(page.gotFeatureRequest(permissionType));
+        QTRY_VERIFY(page.gotExpectedRequests(/*isDesktopPermission*/ true, permissionType));
         page.acceptPendingRequest();
         QTRY_VERIFY(page.jsPromiseFulfilled() || page.jsPromiseRejected());
     }
@@ -5800,11 +5820,13 @@ void tst_QWebEnginePage::chooseDesktopMedia()
     page.profile()->setPersistentPermissionsPolicy(QWebEngineProfile::PersistentPermissionsPolicy::AskEveryTime);
 
     bool desktopMediaRequested = false;
+    bool emptyDesktopMediaRequested = false;
     bool permissionRequested = false;
 
     connect(&page, &QWebEnginePage::desktopMediaRequested,
-            [&](const QWebEngineDesktopMediaRequest &) {
+            [&](const QWebEngineDesktopMediaRequest &request) {
                 desktopMediaRequested = true;
+                emptyDesktopMediaRequested = request.screensModel()->rowCount() == 0;
             });
 
     connect(&page, &QWebEnginePage::permissionRequested,
@@ -5824,7 +5846,7 @@ void tst_QWebEnginePage::chooseDesktopMedia()
                                "})()").arg(extensionId));
 
     QTRY_VERIFY(desktopMediaRequested);
-    QTRY_VERIFY(permissionRequested);
+    QTRY_VERIFY(permissionRequested || emptyDesktopMediaRequested);
 #endif // QT_CONFIG(webengine_extensions) && QT_CONFIG(webengine_webrtc)
 }
 

From 5738369469c58301a131b5752e95d71351da0d8f Mon Sep 17 00:00:00 2001
From: Allan Sandfeld Jensen <allan.jensen@qt.io>
Date: Tue, 3 Sep 2024 13:31:33 +0200
Subject: [PATCH 145/356] Fix arm64 detection

aarch64 is arm64 and so is ARM64.

Change-Id: I97cdedf4e24009e197c7bdc0f0705bcb55fa4e26
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 5395235844b0f83277e08411524148f0669a0444)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 cmake/Functions.cmake | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/cmake/Functions.cmake b/cmake/Functions.cmake
index b9a48821e6f..f41a0082c34 100644
--- a/cmake/Functions.cmake
+++ b/cmake/Functions.cmake
@@ -618,16 +618,17 @@ endfunction()
 # Function maps TEST_architecture_arch or CMAKE_SYSTEM_PROCESSOR into gn architecture
 function(get_gn_arch result arch)
     set(armList arm armv7-a)
+    set(arm64List arm64 ARM64 aarch64)
     set(mips64List mips64 mipsel64)
     set(x86List i386 i686)
-    set(x64List x86_64 AMD64 x86_64h aarch64)
+    set(x64List x86_64 AMD64 x86_64h)
     if(arch IN_LIST x86List)
         set(${result} "x86" PARENT_SCOPE)
     elseif(arch IN_LIST x64List)
         set(${result} "x64" PARENT_SCOPE)
     elseif(arch IN_LIST armList)
         set(${result} "arm" PARENT_SCOPE)
-    elseif(arch STREQUAL "arm64")
+    elseif(arch IN_LIST arm64List)
         set(${result} "arm64" PARENT_SCOPE)
     elseif(arch STREQUAL "mipsel")
         set(${result} "mipsel" PARENT_SCOPE)

From e5c6113f78f72454568abbeae310491ba866247c Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Wed, 4 Sep 2024 16:24:29 +0000
Subject: [PATCH 146/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I6797c478639b4c85823c1ef619ae3803e601e214
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index ac6b71da8a1..2ebf0ab2574 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: d5171b14251cf4abd7d8ad16288690af53248856
+    ref: a30b06d522edb56b8fded1ba91306f1564cef5fc
     required: true
   ../qtpositioning:
-    ref: 9e17051c777b460aa92632664d42eeb82158fbba
+    ref: 6a5145c4e246d976075fbce0f0af949185194e9c
     required: false
   ../qttools:
-    ref: 5034a5008302f830f0966162665a1249f288d2bb
+    ref: 829288c6ac0678e9ecc6320fb2fdbcccbf4b7689
     required: false
   ../qtwebchannel:
-    ref: c6dafd8d5220d797c64b229a7378817369d0bc5b
+    ref: 01403a3d77ae7bce252c6a67e22adf6dd35f0e64
     required: false

From 9d9216f42861802fdb1b16c436924203031da2c9 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Thu, 5 Sep 2024 18:51:56 +0000
Subject: [PATCH 147/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I7a68868c056ac11cd0ec1ff83a7c4dabc161260a
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 2ebf0ab2574..53327e0a95c 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: a30b06d522edb56b8fded1ba91306f1564cef5fc
+    ref: 31ca527744533b5895ae6547d21a90efc94737e3
     required: true
   ../qtpositioning:
-    ref: 6a5145c4e246d976075fbce0f0af949185194e9c
+    ref: bdae173e970b00c22bb6538cc2a0b1cb6ea79943
     required: false
   ../qttools:
-    ref: 829288c6ac0678e9ecc6320fb2fdbcccbf4b7689
+    ref: f8bcc983a9baa7ea7000c7e7d1299e16a6b6650c
     required: false
   ../qtwebchannel:
-    ref: 01403a3d77ae7bce252c6a67e22adf6dd35f0e64
+    ref: 6f1e669290f0958055a728d5ec0d7327bc3caada
     required: false

From b75ae0661e7cd894adc89d6d6955f0dcb2dcefe1 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Tue, 10 Sep 2024 00:24:55 +0000
Subject: [PATCH 148/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Iebeb9f292716e889f378e7c91ddfe817be443b05
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 53327e0a95c..cc880bb681c 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 31ca527744533b5895ae6547d21a90efc94737e3
+    ref: a6e32c939e8d34839a74f97a4265aeb45266e52d
     required: true
   ../qtpositioning:
-    ref: bdae173e970b00c22bb6538cc2a0b1cb6ea79943
+    ref: 3f33d28148ac21d9241e384f4cf2f8e0ebd6667f
     required: false
   ../qttools:
-    ref: f8bcc983a9baa7ea7000c7e7d1299e16a6b6650c
+    ref: 547410a5b511ec4584953136b9c066525c14732e
     required: false
   ../qtwebchannel:
-    ref: 6f1e669290f0958055a728d5ec0d7327bc3caada
+    ref: d64d78c373fc7329a2e6c7810e4fc39305ade313
     required: false

From 65843741c9ff777c1e43f43466ec6b3c6bd55469 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Fri, 6 Sep 2024 12:53:30 +0200
Subject: [PATCH 149/356] Fix compilation without egl

Add missing egl guards, keep linker happy.

Pick-to: dev
Change-Id: I02eb162103645b917688e29c43aa29d20b44e251
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
---
 src/core/ozone/gl_context_qt.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/core/ozone/gl_context_qt.cpp b/src/core/ozone/gl_context_qt.cpp
index b65f5c75694..f87df50cb8e 100644
--- a/src/core/ozone/gl_context_qt.cpp
+++ b/src/core/ozone/gl_context_qt.cpp
@@ -158,7 +158,7 @@ bool GLContextHelper::isCreateContextRobustnessSupported()
     return contextHelper->m_robustness;
 }
 
-#if QT_CONFIG(opengl) && defined(USE_OZONE)
+#if QT_CONFIG(opengl) && QT_CONFIG(egl) && defined(USE_OZONE)
 class ScopedGLContext
 {
 public:
@@ -244,7 +244,9 @@ class ScopedGLContext
     EGLDisplay m_previousEGLDisplay = nullptr;
     std::vector<uint> m_textures;
 };
+#endif // QT_CONFIG(opengl) && QT_COFNIG(egl) && defined(USE_OZONE)
 
+#if QT_CONFIG(opengl) && defined(USE_OZONE)
 EGLHelper::EGLFunctions::EGLFunctions()
 {
     const static auto getProcAddress =
@@ -329,6 +331,7 @@ EGLHelper::EGLHelper()
 void EGLHelper::queryDmaBuf(const int width, const int height, int *fd, int *stride, int *offset,
                             uint64_t *modifiers)
 {
+#if QT_CONFIG(egl)
     if (!m_isDmaBufSupported)
         return;
 
@@ -364,6 +367,7 @@ void EGLHelper::queryDmaBuf(const int width, const int height, int *fd, int *str
                    << ui::GetEGLErrorString(m_functions->eglGetError());
 
     m_functions->eglDestroyImage(eglDisplay, eglImage);
+#endif // QT_CONFIG(egl)
 }
 
 bool EGLHelper::isDmaBufSupported()

From cd6dc906fd95de2ca8c00d7ffe03e933ebb27e94 Mon Sep 17 00:00:00 2001
From: Vladimir Belyavsky <belyavskyv@gmail.com>
Date: Thu, 5 Sep 2024 18:54:49 +0300
Subject: [PATCH 150/356] EGL: Do not create GL context with no compatible
 surface

Otherwise it crashes on gl::GLContextEGL::Initialize() with
nullptr access. It is not yet clear under what conditions we
cannot create a compatible surface, but it may somehow happen
on some older AMD GPUs.

Task-number: QTBUG-128308
Pick-to: 6.7
Change-Id: I24845c4a6785872f1b3ff56adacaa2a6cef0e5f7
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
(cherry picked from commit 5bd9d6183dcbad1e7fb9ac83a79217a9ee16b865)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/ozone/gl_context_qt.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/core/ozone/gl_context_qt.cpp b/src/core/ozone/gl_context_qt.cpp
index f87df50cb8e..ce099a4a3d6 100644
--- a/src/core/ozone/gl_context_qt.cpp
+++ b/src/core/ozone/gl_context_qt.cpp
@@ -395,6 +395,10 @@ scoped_refptr<GLContext> CreateGLContext(GLShareGroup *share_group,
         return context;
     }
     case kGLImplementationEGLANGLE:
+        if (Q_UNLIKELY(!compatible_surface)) {
+            qWarning("EGL: no compatible surface.");
+            return nullptr;
+        }
         return InitializeGLContext(new GLContextEGL(share_group),
                                    compatible_surface, attribs);
     case kGLImplementationDisabled:

From 8360fb98d823125d66309fce3857ab52c3df8abe Mon Sep 17 00:00:00 2001
From: Liang Qi <liang.qi@qt.io>
Date: Wed, 11 Sep 2024 14:23:52 +0200
Subject: [PATCH 151/356] tests: blacklist
 tst_QQuickWebEngineView::htmlSelectPopup() on offscreen

Pick-to: 6.8.0
Task-number: QTBUG-128653
Change-Id: Id466b1ed4a63271a15c0b80e78eebda8b693bd42
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Liang Qi <liang.qi@qt.io>
(cherry picked from commit 861a8032b6da463181751fbd2d63e4e3184adf3c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 tests/auto/quick/qquickwebengineview/BLACKLIST | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tests/auto/quick/qquickwebengineview/BLACKLIST b/tests/auto/quick/qquickwebengineview/BLACKLIST
index d4a35a76a57..5293f7259d9 100644
--- a/tests/auto/quick/qquickwebengineview/BLACKLIST
+++ b/tests/auto/quick/qquickwebengineview/BLACKLIST
@@ -1,2 +1,5 @@
 [javascriptClipboard]
 ubuntu-20.04
+
+[htmlSelectPopup]
+ubuntu-24.04 offscreen # QTBUG-128653

From 67d2d353fce4543493cd17cf3f884549088a8ab2 Mon Sep 17 00:00:00 2001
From: Liang Qi <liang.qi@qt.io>
Date: Wed, 11 Sep 2024 14:47:24 +0200
Subject: [PATCH 152/356] tests: skip one test in tst_qmltests on linux arm64

Pick-to: 6.8.0
Task-number: QTBUG-128652
Change-Id: I9ac46da046c8270c43871d24fc830579e21ca500
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Liang Qi <liang.qi@qt.io>
(cherry picked from commit 60befab9bee138f69869ae9510ea9fd336a52f80)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 tests/auto/quick/qmltests/CMakeLists.txt | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/tests/auto/quick/qmltests/CMakeLists.txt b/tests/auto/quick/qmltests/CMakeLists.txt
index daae6d60dcd..a62734a2c4e 100644
--- a/tests/auto/quick/qmltests/CMakeLists.txt
+++ b/tests/auto/quick/qmltests/CMakeLists.txt
@@ -63,6 +63,11 @@ set(testList
     tst_save.qml
 )
 
+# QTBUG-128652
+if(CMAKE_SYSTEM_PROCESSOR MATCHES "(arm|aarch).*64" AND LINUX)
+    list(REMOVE_ITEM testList tst_faviconDatabase.qml)
+endif()
+
 if(QT_FEATURE_webengine_webchannel)
     list(APPEND testList tst_webchannel.qml)
 endif()

From 3d8b9b4860e3d5ea44cb97ae82cc32283a9cd1df Mon Sep 17 00:00:00 2001
From: Vladimir Belyavsky <belyavskyv@gmail.com>
Date: Thu, 5 Sep 2024 13:25:28 +0300
Subject: [PATCH 153/356] Do not create shared OpenGL context when D3D11 RHI is
 used

We don't need shared OpenGL context when D3D11 RHI is used on Windows.
So we shouldn't even try to create it, otherwise we might encounter
unexpected side effects like warnings or even crashes when creating
OpenGL context on some older GPUs/drivers.

Fixes: QTBUG-128784
Pick-to: 6.7
Change-Id: I8f7a6dd7c5dd56c361a085c45fffb8dcfcfb722f
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
(cherry picked from commit 7eeabd5a0103f7dde66814d6e49806a2f2a1cc20)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qtwebenginecoreglobal.cpp | 71 ++++++++++++++------------
 1 file changed, 39 insertions(+), 32 deletions(-)

diff --git a/src/core/api/qtwebenginecoreglobal.cpp b/src/core/api/qtwebenginecoreglobal.cpp
index d5112ccb342..1d02dac9174 100644
--- a/src/core/api/qtwebenginecoreglobal.cpp
+++ b/src/core/api/qtwebenginecoreglobal.cpp
@@ -36,6 +36,42 @@ static void deleteShareContext()
     shareContext = 0;
 }
 
+static void ensureShareContext()
+{
+    // No need to override the shared context if QApplication already set one (e.g with Qt::AA_ShareOpenGLContexts).
+    if (qt_gl_global_share_context())
+        return;
+
+    QCoreApplication *app = QCoreApplication::instance();
+    if (!app) {
+        qFatal("QtWebEngineQuick::initialize() but no core application instance.");
+        return;
+    }
+
+    // Bail out silently if the user did not construct a QGuiApplication.
+    if (!qobject_cast<QGuiApplication *>(app))
+        return;
+
+    if (app->thread() != QThread::currentThread()) {
+        qFatal("QtWebEngineQuick::initialize() must be called from the Qt gui thread.");
+        return;
+    }
+
+    if (shareContext)
+        return;
+
+    shareContext = new QOpenGLContext;
+    QSurfaceFormat format = QSurfaceFormat::defaultFormat();
+
+    shareContext->setFormat(format);
+    shareContext->create();
+    qAddPostRoutine(deleteShareContext);
+    qt_gl_set_global_share_context(shareContext);
+
+    // Classes like QOpenGLWidget check for the attribute
+    app->setAttribute(Qt::AA_ShareOpenGLContexts);
+}
+
 #endif
 // ### Qt 6: unify this logic and Qt::AA_ShareOpenGLContexts.
 // QtWebEngineQuick::initialize was introduced first and meant to be called
@@ -56,39 +92,10 @@ Q_WEBENGINECORE_EXPORT void initialize()
 #endif
     )
         QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL);
-    // No need to override the shared context if QApplication already set one (e.g with Qt::AA_ShareOpenGLContexts).
-    if (!qt_gl_global_share_context()) {
-
-        QCoreApplication *app = QCoreApplication::instance();
-        if (!app) {
-            qFatal("QtWebEngineQuick::initialize() but no core application instance.");
-            return;
-        }
-
-        // Bail out silently if the user did not construct a QGuiApplication.
-        if (!qobject_cast<QGuiApplication *>(app))
-            return;
-
-        if (app->thread() != QThread::currentThread()) {
-            qFatal("QtWebEngineQuick::initialize() must be called from the Qt gui thread.");
-            return;
-        }
-
-        if (shareContext)
-            return;
-
-        shareContext = new QOpenGLContext;
-        QSurfaceFormat format = QSurfaceFormat::defaultFormat();
-
-        shareContext->setFormat(format);
-        shareContext->create();
-        qAddPostRoutine(deleteShareContext);
-        qt_gl_set_global_share_context(shareContext);
-
-        // Classes like QOpenGLWidget check for the attribute
-        app->setAttribute(Qt::AA_ShareOpenGLContexts);
-    }
 
+    // ensure we have shared OpenGL context
+    if (QQuickWindow::graphicsApi() != QSGRendererInterface::Direct3D11)
+        ensureShareContext();
 #endif // QT_CONFIG(opengl) && !defined(Q_OS_MACOS)
 }
 

From 2de0ca74cdeb98718a5cafbb76357ced0d107dd1 Mon Sep 17 00:00:00 2001
From: Anu Aliyas <anu.aliyas@qt.io>
Date: Thu, 12 Sep 2024 13:35:53 +0200
Subject: [PATCH 154/356] Fixup pinch gesture event handling

The current gesture pinch event handling requires the needs_wheel_event
to be set. When the gesture event is created, it is set to true, so that
the input router knows to offer the event to the renderer as a wheel
event. Once the wheel event is acknowledged, needs_wheel_event is set
to false and the event is resent. When the input router receives it the
second time, it knows to send the real gesture event to the renderer.
Qt webengine creates pinch begin and end events with needs_wheel_event
set to true, but the same is missing for update event. The event resent
logic is also missing. This can be done from
RenderWidgetHostViewQt::GestureEventAck() by calling
ForwardTouchpadZoomEventIfNecessary().

Pick-to: 6.7
Change-Id: I52da137c69da494f497bcd112fcdd466eb08281b
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 0dcf9312f9a5cfa87d0392a5c4ddc2d0ebec775e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/render_widget_host_view_qt.cpp | 2 ++
 src/core/web_event_factory.cpp          | 1 +
 2 files changed, 3 insertions(+)

diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 4405de46c56..2393fa5e338 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -925,6 +925,8 @@ void RenderWidgetHostViewQt::WheelEventAck(const blink::WebMouseWheelEvent &even
 void RenderWidgetHostViewQt::GestureEventAck(const blink::WebGestureEvent &event,
                                              blink::mojom::InputEventResultState ack_result)
 {
+    ForwardTouchpadZoomEventIfNecessary(event, ack_result);
+
     // Forward unhandled scroll events back as wheel events
     if (event.GetType() != blink::WebInputEvent::Type::kGestureScrollUpdate)
         return;
diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp
index 617eea2d0be..fcf14b45f57 100644
--- a/src/core/web_event_factory.cpp
+++ b/src/core/web_event_factory.cpp
@@ -1505,6 +1505,7 @@ WebGestureEvent WebEventFactory::toWebGestureEvent(QNativeGestureEvent *ev)
     case Qt::ZoomNativeGesture:
         webKitEvent.SetType(WebInputEvent::Type::kGesturePinchUpdate);
         webKitEvent.data.pinch_update.scale = static_cast<float>(ev->value() + 1.0);
+        webKitEvent.SetNeedsWheelEvent(true);
         break;
     case Qt::SmartZoomNativeGesture:
         webKitEvent.SetType(WebInputEvent::Type::kGestureDoubleTap);

From 7a403cb664da3fba5b9c00429ff36843eb07c592 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Thu, 12 Sep 2024 20:52:36 +0200
Subject: [PATCH 155/356] Update Chromium

Submodule src/3rdparty fc4dffda..42f7d89f:
  * Build fix for change in internal::SetCurrentThreadType on Windows
  * [Backport] Security bug 349641090
  * [Backport] Security bug 348473836
  * [Backport] CVE-2024-8636: Heap buffer overflow in Skia
  * [Backport] Security bug 345261068 (2/2)
  * [Backport] Security bug 345261068 (1/2)
  * [Backport] Security bug 349517592
  * [Backport] Security bug 352424865
  * [Backport] CVE-2024-8362: Use after free in WebAudio
  * [Backport] CVE-2024-8198: Heap buffer overflow in Skia
  * [Backport] CVE-2024-8193: Heap buffer overflow in Skia
  * [Backport] CVE-2024-7969: Type Confusion in V8
  * [Backport] CVE-2024-7972: Inappropriate implementation in V8
  * Fix DCHECK failure in text fragment selector generator
  * [Backport] Security bug 349248170
  * [Backport] Security bug 343000522
  * [Backport] Security bug 346686148
  * [Backport] Security bug 346799730
  * [Backport] Security bug 351876778
  * [Backport] CVE-2024-7978: Insufficient policy enforcement in Data Transfer
  * [Backport] CVE-2024-7974: Insufficient data validation in V8 API
  * [Backport] CVE-2024-7975: Inappropriate implementation in Permissions (2/2)
  * [Backport] CVE-2024-7975: Inappropriate implementation in Permissions (1/2)
  * [Backport] CVE-2024-7966: Out of bounds memory access in Skia (2/2)
  * [Backport] CVE-2024-7966: Out of bounds memory access in Skia (1/2)
  * [Backport] CVE-2024-7973: Heap buffer overflow in PDFium
  * [Backport] CVE-2024-7967: Heap buffer overflow in Fonts (3/3)
  * [Backport] CVE-2024-7967: Heap buffer overflow in Fonts (2/3)
  * [Backport] CVE-2024-7967: Heap buffer overflow in Fonts (1/3)
  * [Backport] CVE-2024-7971: Type confusion in V8
  * [Backport] CVE-2024-7965: Inappropriate implementation in V8
  * Do not change priority of main thread
  * Support win-arm64 in gn
  * Fix compilation with the latest MSVC 2022
  * [Backport] Fix instances of new clang warning -Wmissing-template-arg-list-after-template-kw.
  * [Backport] Fix QuicIntervalDeque::Iterator::operator+=
  * [Backport] Fix instances of -Wmissing-template-arg-list-after-template-kw.
  * [Backport] Fix base::IDMap::Iterator::operator=
  * [Backport] Fix NoDestructor::PlacementStorage::get() const
  * Allow multiple extra "no-execute" storage paths

Fixes: QTBUG-128786
Fixes: QTBUG-128787
Fixes: QTBUG-128788
Fixes: QTBUG-128877
Change-Id: I1d728b4bdefb2003d470e3b1bd7a0b177b447ee0
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 9907cb41e90a80fb7b5f40d9f77fb0948e98b272)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit d4b615628962707f4ed2a266433f51836a6fbff3)
---
 CHROMIUM_VERSION                | 2 +-
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index ffb8180d5dd..ce7d0197005 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
 Based on Chromium version:                                      122.0.6261.171
-Patched with security patches up to Chromium version:           127.0.6533.99
+Patched with security patches up to Chromium version:           128.0.6613.137
diff --git a/src/3rdparty b/src/3rdparty
index fc4dffdada4..42f7d89fa5c 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit fc4dffdada44bac3e17c209854f58c1d5f448155
+Subproject commit 42f7d89fa5c4adf3cd7c4882cf1364d214fd6f10
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index a9bfed5a12f..23b047e4813 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1272,7 +1272,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "127.0.6533.99"; // FIXME: Remember to update
+    return "128.0.6613.137"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From 68224efb4eb835b5715c09f9fc18417623aa0a97 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Wed, 14 Aug 2024 15:01:00 +0200
Subject: [PATCH 156/356] Pass osx architectures to gn project
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

To support universal builds we need to pass
osx architectures from core project to
gn external one.

Task-number: QTBUG-126317
Change-Id: I1ecbd4db403bf1aa369407c49ab8490f9548b701
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
(cherry picked from commit 045dea582074c6419202cb83b72f88a150bb87f3)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 cmake/Functions.cmake | 4 ++++
 src/gn/CMakeLists.txt | 3 +++
 2 files changed, 7 insertions(+)

diff --git a/cmake/Functions.cmake b/cmake/Functions.cmake
index f41a0082c34..93be1725e9a 100644
--- a/cmake/Functions.cmake
+++ b/cmake/Functions.cmake
@@ -1433,15 +1433,19 @@ macro(qt_webengine_build_and_install_gn)
 endmacro()
 
 macro(qt_webengine_externalproject_add)
+    list(JOIN CMAKE_OSX_ARCHITECTURES "," OSX_ARCH_STR)
     externalproject_add(${ARGN}
         PREFIX      gn
         USES_TERMINAL_BUILD TRUE
+        LIST_SEPARATOR ","
         CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release
                    -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
                    -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
                    -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
                    -DCMAKE_PREFIX_PATH:PATH=<INSTALL_DIR>
+                   -DCMAKE_OSX_ARCHITECTURES=${OSX_ARCH_STR}
                    -DWEBENGINE_ROOT_BUILD_DIR=${PROJECT_BINARY_DIR}
                    -DQT_ALLOW_SYMLINK_IN_PATHS=${QT_ALLOW_SYMLINK_IN_PATHS}
     )
+    unset(OSX_ARCH_STR)
 endmacro()
diff --git a/src/gn/CMakeLists.txt b/src/gn/CMakeLists.txt
index 0fe3e4e05b8..70bfec070d0 100644
--- a/src/gn/CMakeLists.txt
+++ b/src/gn/CMakeLists.txt
@@ -55,6 +55,7 @@ else()
     message(FATAL_ERROR "Unsupported gn platform !")
 endif()
 
+list(JOIN CMAKE_OSX_ARCHITECTURES "$<COMMA>" OSX_ARCH)
 add_custom_command(
     OUTPUT ${GN_EXECUTABLE}
     WORKING_DIRECTORY ${GN_BINARY_DIR}
@@ -69,6 +70,8 @@ add_custom_command(
         --qt-version "${QT_REPO_MODULE_VERSION}.qtwebengine.qt.io"
         $<$<PLATFORM_ID:Darwin>:--isysroot>
         $<$<PLATFORM_ID:Darwin>:${CMAKE_OSX_SYSROOT}>
+        $<$<AND:$<PLATFORM_ID:Darwin>,$<BOOL:${OSX_ARCH}>>:--osx-architectures>
+        $<$<AND:$<PLATFORM_ID:Darwin>,$<BOOL:${OSX_ARCH}>>:${OSX_ARCH}>
     COMMAND Ninja::ninja -C ${GN_BINARY_DIR}/$<CONFIG> ${GN_EXECUTABLE}
     VERBATIM
     USES_TERMINAL

From 6385173bbd4010d8146859d2ad2c984ad2175695 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Wed, 18 Sep 2024 11:07:05 +0200
Subject: [PATCH 157/356] Update Chromium

Submodule src/3rdparty 42f7d89f..af1adfbb:
  * [Backport] Security bug 356649155
  * [Backport] CVE-2024-8905: Inappropriate implementation in V8
  * [Backport] Security bug 340822365 (3/3)
  * [Backport] Security bug 340822365 (2/3)
  * [Backport] Security bug 340822365 (1/3)
  * [Backport] CVE-2024-5160: Heap buffer overflow in Dawn
  * [Backport] CVE-2024-5159: Heap buffer overflow in ANGLE
  * [Backport] CVE-2024-5158: Type Confusion in V8
  * [Backport] CVE-2024-5157: Use after free in Scheduling
  * [Backport] CVE-2024-4761: Out of bounds write in V8

Fixes: QTBUG-129060
Fixes: QTBUG-129069
Change-Id: I80916feac5e6993203c9cefad590812d248093cc
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 9927b415297a732eef9b21433030abf2cda1ee92)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 85213433da4793b69edd3cd8ff8f7cf5db87c524)
---
 CHROMIUM_VERSION                | 2 +-
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index ce7d0197005..7f98334efb0 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
 Based on Chromium version:                                      122.0.6261.171
-Patched with security patches up to Chromium version:           128.0.6613.137
+Patched with security patches up to Chromium version:           129.0.6668.58
diff --git a/src/3rdparty b/src/3rdparty
index 42f7d89fa5c..af1adfbb967 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit 42f7d89fa5c4adf3cd7c4882cf1364d214fd6f10
+Subproject commit af1adfbb96731305a9f7ccd969d92906adacfd09
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 23b047e4813..e868372689e 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1272,7 +1272,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "128.0.6613.137"; // FIXME: Remember to update
+    return "129.0.6668.58"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From 7a47e4017eca87f6ecbf4dfa766703f8746eaa3d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Mon, 25 Sep 2023 16:38:25 +0200
Subject: [PATCH 158/356] Correct documentation for
 QWebEngineUrlReuqestInfo::redirect

It was incorrectly stating the redirect did not work for requests with
payload.

Pick-to: 6.7
Fixes: QTBUG-108763
Change-Id: If9bbbad9ac514fae811356c28aac586d8f24cd2f
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit bf159b2312640bb43d9ef180405baa7fb67d0bc7)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebengineurlrequestinfo.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp
index e3335f559c0..5c0fa178863 100644
--- a/src/core/api/qwebengineurlrequestinfo.cpp
+++ b/src/core/api/qwebengineurlrequestinfo.cpp
@@ -275,7 +275,6 @@ void QWebEngineUrlRequestInfo::resetChanged()
 
 /*!
     Redirects this request to \a url.
-    It is only possible to redirect requests that do not have payload data, such as GET requests.
 */
 
 void QWebEngineUrlRequestInfo::redirect(const QUrl &url)

From 72adc4b55bcbb4a1596cd46225ea9bf8e66a016a Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Mon, 2 Sep 2024 16:05:23 +0200
Subject: [PATCH 159/356] Remove assert in
 RenderWidgetHostViewQt::WheelEventAck

When inspecting with devtools and using the screen cast option,
attempting to scroll in the secondary view will cause the assertion
to fail. This is because the WheelEventAck function gets called twice;
once for the devtools view, and once for the full-size view. This
change removes the assertion, and simply bails out of the function if
no scroll event is pending.

Pick-to: 6.7
Change-Id: If4518c8be15ca0736756bb1e27a6de6c3d43d198
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 23b8ff08a2b7ac753f8fc4829cf75f03bc87bb88)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/render_widget_host_view_qt.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 2393fa5e338..92b6074e772 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -911,7 +911,8 @@ void RenderWidgetHostViewQt::WheelEventAck(const blink::WebMouseWheelEvent &even
 {
     if (event.phase == blink::WebMouseWheelEvent::kPhaseEnded)
         return;
-    Q_ASSERT(m_wheelAckPending);
+    if (!m_wheelAckPending)
+        return;
     m_wheelAckPending = false;
     while (!m_pendingWheelEvents.isEmpty() && !m_wheelAckPending) {
         blink::WebMouseWheelEvent webEvent = m_pendingWheelEvents.takeFirst();

From a4b08429b47f086d65316ab07aabfd78fe3cff86 Mon Sep 17 00:00:00 2001
From: Jani Heikkinen <jani.heikkinen@qt.io>
Date: Thu, 12 Sep 2024 11:38:29 +0100
Subject: [PATCH 160/356] Bump version to 6.8.1

Change-Id: I2768d9927f4c4cd3af792d8d5608cc183b48c8c1
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 .cmake.conf | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.cmake.conf b/.cmake.conf
index 7bf893be9ee..dcfb220c1bc 100644
--- a/.cmake.conf
+++ b/.cmake.conf
@@ -1,4 +1,4 @@
-set(QT_REPO_MODULE_VERSION "6.8.0")
+set(QT_REPO_MODULE_VERSION "6.8.1")
 set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1")
 set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_WEBENGINE "3.19")
 set(QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_NO_AS_CONST=1")

From 6b73ec1d73d91911982542315e43740aec523da1 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Sat, 21 Sep 2024 09:19:02 +0000
Subject: [PATCH 161/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I4aef983862a59d363aa148316b3d6f38f863ae2d
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index cc880bb681c..ee1421ffafc 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: a6e32c939e8d34839a74f97a4265aeb45266e52d
+    ref: 355e8782f4d31f483c42d719120b50af8d9406f6
     required: true
   ../qtpositioning:
-    ref: 3f33d28148ac21d9241e384f4cf2f8e0ebd6667f
+    ref: 330e42e219a002003556c1d599061257414c423f
     required: false
   ../qttools:
-    ref: 547410a5b511ec4584953136b9c066525c14732e
+    ref: 5322b41d3060cbbda5b2add2ba9ed42714acdc7b
     required: false
   ../qtwebchannel:
-    ref: d64d78c373fc7329a2e6c7810e4fc39305ade313
+    ref: 92fd3df656dcec5e5c2a84981ec99cddf83c2160
     required: false

From 12c02121d802b1314558afbf111153b55f121bca Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Tue, 10 Sep 2024 17:23:09 +0200
Subject: [PATCH 162/356] Fix crash with popups over transparent backgrounds

An earlier color update fix (dcc464b14c) caused color updates to
be applied to views without owner delegates, in the case of combo box
popups for example. We now guard this pointer dereference.

Fixes: QTBUG-128241
Pick-to: 6.7 6.7.3
Change-Id: Ib086c7d544b29bf41101ff423160de2310890174
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 9dae13cca7e06ea16db015aa35e61cc77e16951a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/render_widget_host_view_qt.cpp       |  2 +-
 .../widgets/qwebenginepage/CMakeLists.txt     |  1 +
 .../qwebenginepage/tst_qwebenginepage.cpp     | 24 +++++++++++++++++++
 3 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 92b6074e772..707afca92bd 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -388,7 +388,7 @@ void RenderWidgetHostViewQt::UpdateBackgroundColor()
     m_rootLayer->SetColor(color);
     m_uiCompositor->SetBackgroundColor(color);
 
-    if (color == SK_ColorTRANSPARENT)
+    if (color == SK_ColorTRANSPARENT && host()->owner_delegate())
         host()->owner_delegate()->SetBackgroundOpaque(false);
 }
 
diff --git a/tests/auto/widgets/qwebenginepage/CMakeLists.txt b/tests/auto/widgets/qwebenginepage/CMakeLists.txt
index f63d6211c08..55c35af8810 100644
--- a/tests/auto/widgets/qwebenginepage/CMakeLists.txt
+++ b/tests/auto/widgets/qwebenginepage/CMakeLists.txt
@@ -9,6 +9,7 @@ qt_internal_add_test(tst_qwebenginepage
         tst_qwebenginepage.cpp
     LIBRARIES
         Qt::CorePrivate
+        Qt::GuiPrivate
         Qt::NetworkPrivate
         Qt::WebEngineCorePrivate
         Qt::WebEngineWidgets
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index e6b7f615ea8..f0b1e5bf6f8 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -41,6 +41,8 @@
 #    include <QStateMachine>
 #endif
 #include <QtGui/QClipboard>
+#include <QtGui/qpa/qplatformintegration.h>
+#include <QtGui/private/qguiapplication_p.h>
 #include <QtTest/QtTest>
 #include <QTextCharFormat>
 #if QT_CONFIG(webengine_webchannel)
@@ -268,6 +270,7 @@ private Q_SLOTS:
     void renderProcessCrashed();
     void renderProcessPid();
     void backgroundColor();
+    void popupOnTransparentBackground();
     void audioMuted();
     void closeContents();
     void isSafeRedirect_data();
@@ -5336,6 +5339,27 @@ void tst_QWebEnginePage::backgroundColor()
     QTRY_COMPARE(view.grab().toImage().pixelColor(center), Qt::green);
 }
 
+void tst_QWebEnginePage::popupOnTransparentBackground()
+{
+    if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(
+                QPlatformIntegration::WindowActivation))
+        QSKIP("Cannot test on platforms without window activation capability");
+
+    QWebEngineView view;
+    view.resize(640, 480);
+    view.page()->setBackgroundColor(Qt::transparent);
+    view.show();
+    QVERIFY(QTest::qWaitForWindowExposed(&view));
+    QSignalSpy spyLoadFinished(&view, SIGNAL(loadFinished(bool)));
+    view.setHtml(QLatin1String("<html><head></head><body><select id='foo' name='meow'>"
+                               "<option>fran</option><option>troz</option>"
+                               "</select></body></html>"));
+    QTRY_COMPARE(spyLoadFinished.size(), 1);
+    makeClick(view.windowHandle(), false, elementCenter(view.page(), "foo"));
+    QPointer<QWidget> popup;
+    QTRY_VERIFY((popup = QApplication::activePopupWidget()));
+}
+
 void tst_QWebEnginePage::audioMuted()
 {
     QWebEngineProfile profile;

From 90cbd1c0cbf835518c29bfbfed1c69bfae1d8d84 Mon Sep 17 00:00:00 2001
From: Vladimir Belyavsky <belyavskyv@gmail.com>
Date: Mon, 16 Sep 2024 14:44:31 +0300
Subject: [PATCH 163/356] Compositor: do not call unbind() from the base
 destructor

We must call unbind() from the destructor of the final class, not from
the base one. Otherwise, we may encounter various problems when
destroying the compositor or observer due to a race condition since
they are destroyed from different threads.

For example, we might crash on pure virtual function call in Present()
method of NativeSkiaOutputDevice (aka "Compositor") when it's called
from Chrome_InProcGpuThread thread during destruction of a
RenderWidgetHostViewQtDelegateItem (aka "Observer") in the main
thread. There is a call to observer(), which may return a pointer to a
partially destroyed object in such a case.

This is partial revert of 16b2976e2c983cabe6011cd732e3ec46e3402d22.

Fixes: QTBUG-128897
Change-Id: Ide0bb8c3d86de7942ae22f2c56382c87199849c7
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 6781151fc822a91bf460c0cf0d67d022a8107108)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/compositor/compositor.cpp            | 32 +++++++++++++------
 src/core/compositor/compositor.h              |  4 +--
 .../compositor/display_skia_output_device.cpp |  1 +
 .../display_software_output_surface.cpp       |  6 ++++
 .../compositor/native_skia_output_device.cpp  |  1 +
 ...nder_widget_host_view_qt_delegate_item.cpp |  3 +-
 6 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/src/core/compositor/compositor.cpp b/src/core/compositor/compositor.cpp
index 4c0bd4c0d80..35b30234f14 100644
--- a/src/core/compositor/compositor.cpp
+++ b/src/core/compositor/compositor.cpp
@@ -82,12 +82,13 @@ void Compositor::Observer::bind(Id id)
 
 void Compositor::Observer::unbind()
 {
-    DCHECK(m_binding);
     g_bindings.lock();
-    m_binding->observer = nullptr;
-    if (m_binding->compositor == nullptr)
-        delete m_binding;
-    m_binding = nullptr;
+    if (m_binding) {
+        m_binding->observer = nullptr;
+        if (m_binding->compositor == nullptr)
+            delete m_binding;
+        m_binding = nullptr;
+    }
     g_bindings.unlock();
 }
 
@@ -100,6 +101,11 @@ Compositor::Handle<Compositor> Compositor::Observer::compositor()
     return nullptr;
 }
 
+Compositor::Observer::~Observer()
+{
+    DCHECK(!m_binding); // check that unbind() was called by derived final class
+}
+
 // Compositor
 
 void Compositor::bind(Id id)
@@ -114,12 +120,13 @@ void Compositor::bind(Id id)
 
 void Compositor::unbind()
 {
-    DCHECK(m_binding);
     g_bindings.lock();
-    m_binding->compositor = nullptr;
-    if (m_binding->observer == nullptr)
-        delete m_binding;
-    m_binding = nullptr;
+    if (m_binding) {
+        m_binding->compositor = nullptr;
+        if (m_binding->observer == nullptr)
+            delete m_binding;
+        m_binding = nullptr;
+    }
     g_bindings.unlock();
 }
 
@@ -154,6 +161,11 @@ bool Compositor::textureIsFlipped()
 
 void Compositor::releaseResources() { }
 
+Compositor::~Compositor()
+{
+    DCHECK(!m_binding); // check that unbind() was called by derived final class
+}
+
 // static
 void Compositor::unlockBindings()
 {
diff --git a/src/core/compositor/compositor.h b/src/core/compositor/compositor.h
index 501559060d4..5d3033f8ef4 100644
--- a/src/core/compositor/compositor.h
+++ b/src/core/compositor/compositor.h
@@ -90,7 +90,7 @@ class Q_WEBENGINECORE_EXPORT Compositor
 
     protected:
         Observer() = default;
-        ~Observer() { if (m_binding) unbind(); }
+        ~Observer();
 
     private:
         Binding *m_binding = nullptr;
@@ -137,7 +137,7 @@ class Q_WEBENGINECORE_EXPORT Compositor
 
 protected:
     Compositor(Type type) : m_type(type) { }
-    virtual ~Compositor() { if (m_binding) unbind(); }
+    virtual ~Compositor();
 
 private:
     template<typename T>
diff --git a/src/core/compositor/display_skia_output_device.cpp b/src/core/compositor/display_skia_output_device.cpp
index ab891f81400..800e2cc1b24 100644
--- a/src/core/compositor/display_skia_output_device.cpp
+++ b/src/core/compositor/display_skia_output_device.cpp
@@ -113,6 +113,7 @@ DisplaySkiaOutputDevice::DisplaySkiaOutputDevice(
 
 DisplaySkiaOutputDevice::~DisplaySkiaOutputDevice()
 {
+    unbind();
 }
 
 void DisplaySkiaOutputDevice::SetFrameSinkId(const viz::FrameSinkId &id)
diff --git a/src/core/compositor/display_software_output_surface.cpp b/src/core/compositor/display_software_output_surface.cpp
index 2c208ca5736..62f23edb50a 100644
--- a/src/core/compositor/display_software_output_surface.cpp
+++ b/src/core/compositor/display_software_output_surface.cpp
@@ -21,6 +21,7 @@ class DisplaySoftwareOutputSurface::Device final : public viz::SoftwareOutputDev
 {
 public:
     Device(bool requiresAlpha);
+    ~Device() override;
 
     // Overridden from viz::SoftwareOutputDevice.
     void Resize(const gfx::Size &sizeInPixels, float devicePixelRatio) override;
@@ -50,6 +51,11 @@ DisplaySoftwareOutputSurface::Device::Device(bool requiresAlpha)
 {
 }
 
+DisplaySoftwareOutputSurface::Device::~Device()
+{
+    unbind();
+}
+
 void DisplaySoftwareOutputSurface::Device::Resize(const gfx::Size &sizeInPixels, float devicePixelRatio)
 {
     if (viewport_pixel_size_ == sizeInPixels && m_devicePixelRatio == devicePixelRatio)
diff --git a/src/core/compositor/native_skia_output_device.cpp b/src/core/compositor/native_skia_output_device.cpp
index 3c916d114ff..2f0115353f9 100644
--- a/src/core/compositor/native_skia_output_device.cpp
+++ b/src/core/compositor/native_skia_output_device.cpp
@@ -65,6 +65,7 @@ NativeSkiaOutputDevice::NativeSkiaOutputDevice(
 
 NativeSkiaOutputDevice::~NativeSkiaOutputDevice()
 {
+    unbind();
 }
 
 void NativeSkiaOutputDevice::SetFrameSinkId(const viz::FrameSinkId &id)
diff --git a/src/core/render_widget_host_view_qt_delegate_item.cpp b/src/core/render_widget_host_view_qt_delegate_item.cpp
index aafa7556aa8..17a5c657518 100644
--- a/src/core/render_widget_host_view_qt_delegate_item.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_item.cpp
@@ -30,11 +30,12 @@ RenderWidgetHostViewQtDelegateItem::RenderWidgetHostViewQtDelegateItem(RenderWid
         setFocus(true);
         setActiveFocusOnTab(true);
     }
-    bind(client->compositorId());
+    bind(client->compositorId()); // Compositor::Observer
 }
 
 RenderWidgetHostViewQtDelegateItem::~RenderWidgetHostViewQtDelegateItem()
 {
+    unbind(); // Compositor::Observer
     releaseTextureResources();
     if (m_widgetDelegate) {
         m_widgetDelegate->Unbind();

From bfeea6231dfacb37de3ca5ee2e0167c71b540b90 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Thu, 22 Aug 2024 13:20:42 -0700
Subject: [PATCH 164/356] Pass no-static-libstdc++ to gen.py

GN requires libstdc++.a to be installed on host systems by default,
which is often not very common, for no particular reason.

Disable warnings as errors, this helps building on some older
distributions e.g. debian-12 with gcc 12.x as default compiler

Change-Id: Ie654f50f9e7e75154477e6efa4aece2dd1a90da3
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 8581bed9003f43bd2aa6c41ebeab1877be910625)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/gn/CMakeLists.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/gn/CMakeLists.txt b/src/gn/CMakeLists.txt
index 70bfec070d0..9782f17abc8 100644
--- a/src/gn/CMakeLists.txt
+++ b/src/gn/CMakeLists.txt
@@ -61,10 +61,12 @@ add_custom_command(
     WORKING_DIRECTORY ${GN_BINARY_DIR}
     COMMAND ${Python3_EXECUTABLE} ${GN_SOURCE_DIR}/build/gen.py
         --no-last-commit-position
+        --no-static-libstdc++
         --out-path ${GN_BINARY_DIR}/$<CONFIG>
         --cc ${CMAKE_C_COMPILER}
         --cxx ${CMAKE_CXX_COMPILER}
         --ld ${GN_LINKER}
+        --allow-warnings
         --platform ${platform}
         --ar ${CMAKE_AR}
         --qt-version "${QT_REPO_MODULE_VERSION}.qtwebengine.qt.io"

From 345bdd6bbed76130c16d7be0291309e68c5d064f Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Tue, 17 Sep 2024 14:48:45 +0200
Subject: [PATCH 165/356] Increase wait time in
 tst_Printing::printFromPdfViewer

It seems the ubuntu 24.04 dev build takes longer than 10s to run this test, so bump it up to 15s.

Task-Id: QTBUG-128514
Change-Id: I1c3fd1f651d8b0939cbc36cc05c94084bc461f78
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 455201ae6e6ee2d28384ed332e47f7b3cb322bb0)
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
---
 tests/auto/widgets/printing/tst_printing.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/auto/widgets/printing/tst_printing.cpp b/tests/auto/widgets/printing/tst_printing.cpp
index c9f6e8cfa92..69c957fc9ac 100644
--- a/tests/auto/widgets/printing/tst_printing.cpp
+++ b/tests/auto/widgets/printing/tst_printing.cpp
@@ -159,7 +159,7 @@ void tst_Printing::printFromPdfViewer()
         rectf rect;
         return pdfPage->search(ustring::from_latin1("Hello Paper World"), rect, page::search_from_top,
                             case_sensitive);
-    }, 10000);
+    }, 15000);
     QVERIFY(ok);
 }
 #endif

From 05875c43456c03ccadb3e28090b1b04f1dff6ed3 Mon Sep 17 00:00:00 2001
From: Vladimir Belyavsky <belyavskyv@gmail.com>
Date: Thu, 19 Sep 2024 17:12:50 +0300
Subject: [PATCH 166/356] WebEngineContext: actualize and cleanup GL type
 detection

Align logic in getGLType() when built with or without OpenGL support:
- check for RHI backend first and switch to SW rendering if unsupported
- use ANGLE unconditionally on macOS and Windows

Do not check for software GL implementation if ANGLE is used,
keep it only for platforms that still use direct GL rendering.

Fixes: QTBUG-128784
Change-Id: I6c1a5a7617ea59f562b446a1eacffddcfb99b629
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
(cherry picked from commit f23959b6ad41b96bae2d4732961928922b457a4a)
---
 src/core/web_engine_context.cpp | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index e868372689e..2d9fa7a2778 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -393,17 +393,9 @@ bool usingSoftwareDynamicGL()
 #endif
 }
 
-static bool openGLPlatformSupport()
-{
-    return QGuiApplicationPrivate::platformIntegration()->hasCapability(
-            QPlatformIntegration::OpenGL);
-}
-
 static std::string getGLType(bool enableGLSoftwareRendering, bool disableGpu)
 {
-    const bool tryGL =
-            usingSupportedSGBackend() && !usingSoftwareDynamicGL() && openGLPlatformSupport();
-    if (disableGpu || (!tryGL && !enableGLSoftwareRendering))
+    if (disableGpu || !usingSupportedSGBackend())
         return gl::kGLImplementationDisabledName;
 
 #if defined(Q_OS_MACOS)
@@ -416,6 +408,9 @@ static std::string getGLType(bool enableGLSoftwareRendering, bool disableGpu)
     }
 #endif
 
+    if (usingSoftwareDynamicGL() && !enableGLSoftwareRendering)
+        return gl::kGLImplementationDisabledName;
+
     if (!qt_gl_global_share_context() || !qt_gl_global_share_context()->isValid()) {
         qWarning("WebEngineContext is used before QtWebEngineQuick::initialize() or OpenGL context "
                  "creation failed.");
@@ -448,8 +443,9 @@ static std::string getGLType(bool enableGLSoftwareRendering, bool disableGpu)
 #else
 static std::string getGLType(bool /*enableGLSoftwareRendering*/, bool disableGpu)
 {
-    if (disableGpu)
+    if (disableGpu || !usingSupportedSGBackend())
         return gl::kGLImplementationDisabledName;
+
 #if defined(Q_OS_MACOS)
     return gl::kGLImplementationANGLEName;
 #elif defined(Q_OS_WIN)

From 85b14b5455c6f75d048c6163f7317a4b477a4c2b Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Thu, 26 Sep 2024 19:59:03 +0000
Subject: [PATCH 167/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Id3c60a1f5749fee8032de0776ea5a53c6cbb92b1
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index ee1421ffafc..9a3411f8914 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 355e8782f4d31f483c42d719120b50af8d9406f6
+    ref: 06e9fa1b24314872dce61fec10de6d186f63c1e3
     required: true
   ../qtpositioning:
-    ref: 330e42e219a002003556c1d599061257414c423f
+    ref: db580cf8f1367a5842e4a44cc02218711b240b1a
     required: false
   ../qttools:
-    ref: 5322b41d3060cbbda5b2add2ba9ed42714acdc7b
+    ref: 0001c6903562e170f623ca7f504883052e3ad7db
     required: false
   ../qtwebchannel:
-    ref: 92fd3df656dcec5e5c2a84981ec99cddf83c2160
+    ref: cde92e22072fd4a6e14ab0f7371cf491ef657015
     required: false

From b349f38f134f263df809ec033dcfa52c6a28a20d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Thu, 26 Sep 2024 15:56:41 +0200
Subject: [PATCH 168/356] Update Chromium

Submodule src/3rdparty af1adfbb..f8edd3c2:
  * [Backport] CVE-2024-45492 / Security bug 364778067 (3/3)
  * [Backport] CVE-2024-45491 / Security bug 364778067 (2/3)
  * [Backport] CVE-2024-45490 / Security bug 364778067 (1/3)
  * [Backport] CVE-2024-9123: Integer overflow in Skia
  * [Backport] CVE-2024-9122: Type Confusion in V8
  * [Backport] CVE-2024-9120: Use after free in Dawn

Fixes: QTBUG-129309
Change-Id: Ieb824d18673a5f0f05b58d8a04415aed1eee8d5e
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit e2775ec726cc2ce8073701aa382c269f30d003df)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 CHROMIUM_VERSION                | 2 +-
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index 7f98334efb0..6b076862729 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
 Based on Chromium version:                                      122.0.6261.171
-Patched with security patches up to Chromium version:           129.0.6668.58
+Patched with security patches up to Chromium version:           129.0.6668.70
diff --git a/src/3rdparty b/src/3rdparty
index af1adfbb967..f8edd3c2c43 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit af1adfbb96731305a9f7ccd969d92906adacfd09
+Subproject commit f8edd3c2c43a48bb66c8667a20864df6677eb706
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 2d9fa7a2778..e1964347022 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1268,7 +1268,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "129.0.6668.58"; // FIXME: Remember to update
+    return "129.0.6668.70"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From ff816247421245e17b800c11877f1f2bccac85d2 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Mon, 30 Sep 2024 08:55:36 +0000
Subject: [PATCH 169/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Ie8a913e9cdfcde19e895e24ed447f3138cbbdef4
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 9a3411f8914..c05f16d1c97 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 06e9fa1b24314872dce61fec10de6d186f63c1e3
+    ref: 14a16b1ed7f3b59dae49a0881707d26a6010a5fa
     required: true
   ../qtpositioning:
-    ref: db580cf8f1367a5842e4a44cc02218711b240b1a
+    ref: c0eef32881615afde2428e5d2a1009277ce93a08
     required: false
   ../qttools:
-    ref: 0001c6903562e170f623ca7f504883052e3ad7db
+    ref: f156198c114560d540dac9bccb731471f65b9184
     required: false
   ../qtwebchannel:
-    ref: cde92e22072fd4a6e14ab0f7371cf491ef657015
+    ref: 9859a11e8acf8917ff832ebf8c3870496d048be3
     required: false

From ca2884c902726cc6a17bdd29cea931da42ebd0e1 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Tue, 1 Oct 2024 11:09:15 +0000
Subject: [PATCH 170/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I12f646340d1c9aceb6bdf7e6c217325c864b8de8
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index c05f16d1c97..68d4313763c 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 14a16b1ed7f3b59dae49a0881707d26a6010a5fa
+    ref: 280e7c78ec56d72585a46becf05b4b72352968ce
     required: true
   ../qtpositioning:
-    ref: c0eef32881615afde2428e5d2a1009277ce93a08
+    ref: 46e9b29ed941213c5337da2cd000d1a3186cbb40
     required: false
   ../qttools:
-    ref: f156198c114560d540dac9bccb731471f65b9184
+    ref: b09d142d52183e8b9f257d24d029f5c88ffef295
     required: false
   ../qtwebchannel:
-    ref: 9859a11e8acf8917ff832ebf8c3870496d048be3
+    ref: 255b6588f352972ca73007685ada66a67092c24d
     required: false

From a8b975a213dabdfa557b4fbe0204256be1cfe8c7 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Wed, 14 Aug 2024 10:29:18 +0200
Subject: [PATCH 171/356] Fix xkbcommon and xkbfile dependencies check
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Gn runs pkg-config check for those two as we build ozone-x11
backend.

Note required libs are added to generated documentation.

Fixes: QTBUG-120248
Change-Id: Ib5f581f62fe793765a279cdc1b7617fb294f7a18
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
(cherry picked from commit 0083a883b0ce2c7ea1717a1578d185ac31f257e2)
---
 configure.cmake | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/configure.cmake b/configure.cmake
index 81b1c95bbe5..213ea4223e9 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -60,6 +60,8 @@ if(PkgConfig_FOUND)
     pkg_check_modules(VPX vpx>=1.10.0 IMPORTED_TARGET)
     pkg_check_modules(LIBPCI libpci)
     pkg_check_modules(LIBOPENJP2 libopenjp2)
+    pkg_check_modules(XKBCOMMON xkbcommon)
+    pkg_check_modules(XKBFILE xkbfile)
 endif()
 
 if(Python3_EXECUTABLE)
@@ -431,7 +433,7 @@ qt_feature("webengine-system-libpci" PRIVATE
 )
 
 qt_feature("webengine-ozone-x11" PRIVATE
-    LABEL "Support GLX on qpa-xcb"
+    LABEL "Support X11 on qpa-xcb"
     CONDITION LINUX
         AND TARGET Qt::Gui
         AND QT_FEATURE_xcb
@@ -444,6 +446,8 @@ qt_feature("webengine-ozone-x11" PRIVATE
         AND XRANDR_FOUND
         AND XTST_FOUND
         AND XSHMFENCE_FOUND
+        AND XKBCOMMON_FOUND
+        AND XKBFILE_FOUND
 )
 
 #### Support Checks
@@ -691,7 +695,7 @@ qt_configure_add_report_entry(
 )
 
 if(LINUX AND QT_FEATURE_xcb AND TARGET Qt::Gui)
-    set(ozone_x11_support X11 LIBDRM XCOMPOSITE XCURSOR XRANDR XI XPROTO XSHMFENCE XTST)
+    set(ozone_x11_support X11 LIBDRM XCOMPOSITE XCURSOR XRANDR XI XPROTO XSHMFENCE XTST XKBCOMMON XKBFILE)
     set(ozone_x11_error OFF)
     foreach(xs ${ozone_x11_support})
         if(NOT ${xs}_FOUND)

From 207d1a4dc5e99b03a21ead58f128077de4ec2f27 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Thu, 3 Oct 2024 07:32:51 +0000
Subject: [PATCH 172/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I465072e52dc58b8e51856913e703bd0010fb1ab4
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 68d4313763c..337e5bcf721 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 280e7c78ec56d72585a46becf05b4b72352968ce
+    ref: 0b4feaf97a83f1f4a4b0f2898e2c2ffd34e0928d
     required: true
   ../qtpositioning:
-    ref: 46e9b29ed941213c5337da2cd000d1a3186cbb40
+    ref: cfc1210ad29b2a006d7cbe13157f4f8f838fcffe
     required: false
   ../qttools:
-    ref: b09d142d52183e8b9f257d24d029f5c88ffef295
+    ref: a3791a834593ee4279d0a5f688b149c0db97b831
     required: false
   ../qtwebchannel:
-    ref: 255b6588f352972ca73007685ada66a67092c24d
+    ref: 78db08846c7efd9aae6eac707f6eca127b83c180
     required: false

From 944eff45a286074261434bf494b518e49fe1977f Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Tue, 1 Oct 2024 10:27:30 +0200
Subject: [PATCH 173/356] Fix gl_bindings header inclusion for
 native_skia_output_device_opengl
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

If there is no ozone-x11 we still might want to compile vulkan part
which requires opengl defines. Moreover ozone-x11 check has
nothing to do with opengl and should just guard x11 headers.

Pick-to: dev
Change-Id: I199032076907ce3804c4ae2f61df021a0d5cbc61
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
---
 .../native_skia_output_device_opengl.cpp      | 22 +++++++++----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/src/core/compositor/native_skia_output_device_opengl.cpp b/src/core/compositor/native_skia_output_device_opengl.cpp
index 017d1714d75..493050f7f4a 100644
--- a/src/core/compositor/native_skia_output_device_opengl.cpp
+++ b/src/core/compositor/native_skia_output_device_opengl.cpp
@@ -16,6 +16,16 @@
 #include "ui/gl/gl_implementation.h"
 
 #if defined(USE_OZONE)
+#include "ui/gl/gl_bindings.h"
+#undef glBindTexture
+#undef glCreateMemoryObjectsEXT
+#undef glDeleteMemoryObjectsEXT
+#undef glDeleteTextures
+#undef glGenTextures
+#undef glGetError
+#undef glImportMemoryFdEXT
+#undef glTextureStorageMem2DEXT
+
 #include "base/posix/eintr_wrapper.h"
 #include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h"
 #include "ui/gfx/linux/drm_util_linux.h"
@@ -27,16 +37,6 @@
 #include "ui/gfx/x/future.h"
 #include "ui/gfx/x/glx.h"
 #include "ui/gfx/x/xproto.h"
-
-#include "ui/gl/gl_bindings.h"
-#undef glBindTexture
-#undef glCreateMemoryObjectsEXT
-#undef glDeleteMemoryObjectsEXT
-#undef glDeleteTextures
-#undef glGenTextures
-#undef glGetError
-#undef glImportMemoryFdEXT
-#undef glTextureStorageMem2DEXT
 #endif // BUILDFLAG(IS_OZONE_X11)
 
 #if BUILDFLAG(ENABLE_VULKAN)
@@ -388,7 +388,7 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
         auto glFun = glContext->functions();
         glFun->glDeleteTextures(1, &glTexture);
     };
-#endif
+#endif // defined(USE_OZONE)
 
     return texture;
 }

From fab70d72793bd13b8092e025541d3ca7d0612a0e Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Wed, 25 Sep 2024 11:43:18 +0200
Subject: [PATCH 174/356] [pdf] Don't trigger MOC for non-MOC header

Silence "note: No relevant classes found. No output generated."

Change-Id: I27891753f3bb744d7aa7e4262683b3a20a3f9cdd
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 7a033371255398f30529c0abb8caacef8f1f8156)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/pdf/qpdflinkmodel.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pdf/qpdflinkmodel.cpp b/src/pdf/qpdflinkmodel.cpp
index 0a8b1e812f5..1652189176f 100644
--- a/src/pdf/qpdflinkmodel.cpp
+++ b/src/pdf/qpdflinkmodel.cpp
@@ -335,4 +335,4 @@ void QPdfLinkModel::onStatusChanged(QPdfDocument::Status status)
 
 QT_END_NAMESPACE
 
-#include "moc_qpdflinkmodel_p.cpp"
+#include "moc_qpdflinkmodel.cpp"

From 34bdce39879b8595e0d2dd41bf2f0ec50ba046a8 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Mon, 7 Oct 2024 07:36:51 +0000
Subject: [PATCH 175/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I2018bcce62f60e0b66c85b538d5874aa498cbcf4
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 337e5bcf721..3e66dcc59ef 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 0b4feaf97a83f1f4a4b0f2898e2c2ffd34e0928d
+    ref: b95062be66a3bfcfbd83bfafe56e754dd6ecda86
     required: true
   ../qtpositioning:
-    ref: cfc1210ad29b2a006d7cbe13157f4f8f838fcffe
+    ref: 6d1ac78af34e024da0caaa031b655944721a3492
     required: false
   ../qttools:
-    ref: a3791a834593ee4279d0a5f688b149c0db97b831
+    ref: 2ad3a85beb8abfb2d8a7c8c2ab6df7b76ea3f212
     required: false
   ../qtwebchannel:
-    ref: 78db08846c7efd9aae6eac707f6eca127b83c180
+    ref: f5124192eaeb20711243872ce8fe000bbc2b6a07
     required: false

From ddddbe178dfc7bf2d6116a15c6e0c72f35c7ab87 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Tue, 8 Oct 2024 07:49:21 +0000
Subject: [PATCH 176/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I9c9bc5003a072cb0c71a0564f9c73d2c633325ff
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 3e66dcc59ef..89a0062c85c 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: b95062be66a3bfcfbd83bfafe56e754dd6ecda86
+    ref: 1700e54cbcf28fe1c2913e6501e11672ae92fe72
     required: true
   ../qtpositioning:
-    ref: 6d1ac78af34e024da0caaa031b655944721a3492
+    ref: 98cfee404afaf8fb012c0cb8bb2ed671160fbe5b
     required: false
   ../qttools:
-    ref: 2ad3a85beb8abfb2d8a7c8c2ab6df7b76ea3f212
+    ref: 32fc47a677821a34a9bafc9014a3496ff4b57113
     required: false
   ../qtwebchannel:
-    ref: f5124192eaeb20711243872ce8fe000bbc2b6a07
+    ref: a97bc6ce13f89b2796b61365334306dce9ca0d3f
     required: false

From f5b6a7414bbb1f685e262a90455b66ebf4fa37dc Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Wed, 9 Oct 2024 09:05:33 +0000
Subject: [PATCH 177/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Iba03e572ec0c7d42a0c46ed0d3f038cb721e33ba
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 89a0062c85c..a04ffc8d02e 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 1700e54cbcf28fe1c2913e6501e11672ae92fe72
+    ref: c367deb846f8996f59b4657d43800dc4bf3e9338
     required: true
   ../qtpositioning:
-    ref: 98cfee404afaf8fb012c0cb8bb2ed671160fbe5b
+    ref: 1a3a33941aeb8f1e84bbddc812a9307e0365e66c
     required: false
   ../qttools:
-    ref: 32fc47a677821a34a9bafc9014a3496ff4b57113
+    ref: b0ed42f2cc6e6a6dfe8df964da0e3738c114a7bf
     required: false
   ../qtwebchannel:
-    ref: a97bc6ce13f89b2796b61365334306dce9ca0d3f
+    ref: 25baff547827ff8a8ccbe2faaf927cc9dab28235
     required: false

From 9690c10a95375517c9904d170e452684219126dc Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Thu, 10 Oct 2024 13:36:39 +0000
Subject: [PATCH 178/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I5ca90c2b5b95ee03ffc3cb3d30afa1891669f7f4
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index a04ffc8d02e..e5061cdb3a7 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: c367deb846f8996f59b4657d43800dc4bf3e9338
+    ref: 8971dc7ab9713d8f36b414881b411b431aec2112
     required: true
   ../qtpositioning:
-    ref: 1a3a33941aeb8f1e84bbddc812a9307e0365e66c
+    ref: f241c64a3f751bbea268d8ddede5105c2463395c
     required: false
   ../qttools:
-    ref: b0ed42f2cc6e6a6dfe8df964da0e3738c114a7bf
+    ref: 62da0f7eae2e9fcabc2481bed5082162d9b0e9ce
     required: false
   ../qtwebchannel:
-    ref: 25baff547827ff8a8ccbe2faaf927cc9dab28235
+    ref: 327d5988d8a704ea8905a802119ca457fe5ddd6d
     required: false

From d890b1c40560a27f15aa483fdfe075aeb380b203 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Fri, 4 Oct 2024 16:10:28 +0200
Subject: [PATCH 179/356] Update Chromium

Submodule src/3rdparty f8edd3c2..4ebc0a64:
  * Revert "Disable accelerated_2d_canvas for Intel drivers on Windows"
  * [Backport] CVE-2024-9369: Insufficient data validation in Mojo

Task-number: QTBUG-128857
Task-number: QTBUG-104065
Fixes: QTBUG-129610
Change-Id: I179c57e668075b1aff5caab338f514264d1070de
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
---
 CHROMIUM_VERSION                | 2 +-
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index 6b076862729..17a1d677c93 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
 Based on Chromium version:                                      122.0.6261.171
-Patched with security patches up to Chromium version:           129.0.6668.70
+Patched with security patches up to Chromium version:           129.0.6668.90
diff --git a/src/3rdparty b/src/3rdparty
index f8edd3c2c43..4ebc0a64f11 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit f8edd3c2c43a48bb66c8667a20864df6677eb706
+Subproject commit 4ebc0a64f1100ed22467d50037a05338daf5df29
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index e1964347022..7683201199c 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1268,7 +1268,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "129.0.6668.70"; // FIXME: Remember to update
+    return "129.0.6668.90"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From 0ca5fbaefaef3ac52d2aced7acead3e03c637b50 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Thu, 17 Oct 2024 01:10:28 +0000
Subject: [PATCH 180/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I0285df3f61a494b4d3557c861c6c47aeb9307512
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index e5061cdb3a7..7b3fe079c7b 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 8971dc7ab9713d8f36b414881b411b431aec2112
+    ref: 76fe874d3f15ee25df29d3d855b1f33785e5a3f9
     required: true
   ../qtpositioning:
-    ref: f241c64a3f751bbea268d8ddede5105c2463395c
+    ref: d11badc34816223130be35a7e830a6be82810a70
     required: false
   ../qttools:
-    ref: 62da0f7eae2e9fcabc2481bed5082162d9b0e9ce
+    ref: 027054ec343a83ad2e8dc77c89122c1b4c5b3451
     required: false
   ../qtwebchannel:
-    ref: 327d5988d8a704ea8905a802119ca457fe5ddd6d
+    ref: 760a514f7625aa7121bd5a44f9775ca85afbad90
     required: false

From 955c8cb21c3037b0c741c8a4919ac28a19775c70 Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Wed, 18 Sep 2024 17:24:51 +0200
Subject: [PATCH 181/356] Handle missing webrtc in getUserMedia tests
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When the webengine_webrtc feature is disabled, desktop media requests
will be delivered as non-desktop media requests instead, which means we
cannot rely on those signals in tests. This shouldn't affect the
previous change to protect against a null desktop media capturer,
because that requires webengine_webrtc=on and
webengine_webrtc_pipewire=off.

Change-Id: Id49e41596efd8e0574607a4eb2e0e7b66f5951c9
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
(cherry picked from commit 8f0265788a3a4a83af2d8b66a9cbe4d2e2ce98b2)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 tests/auto/quick/qmltests/CMakeLists.txt            |  1 +
 tests/auto/quick/qmltests/data/tst_getUserMedia.qml |  6 ++++--
 tests/auto/quick/qmltests/tst_qmltests.cpp          | 13 +++++++++++++
 .../widgets/qwebenginepage/tst_qwebenginepage.cpp   |  4 ++++
 4 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/tests/auto/quick/qmltests/CMakeLists.txt b/tests/auto/quick/qmltests/CMakeLists.txt
index a62734a2c4e..fa927fbc313 100644
--- a/tests/auto/quick/qmltests/CMakeLists.txt
+++ b/tests/auto/quick/qmltests/CMakeLists.txt
@@ -12,6 +12,7 @@ qt_internal_add_test(tst_qmltests
         Qt::QuickTest
         Qt::TestPrivate
         Qt::WebEngineQuick
+        Qt::WebEngineCorePrivate
         Test::HttpServer
         Test::Util
 )
diff --git a/tests/auto/quick/qmltests/data/tst_getUserMedia.qml b/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
index c6fcee43e77..06f1d01b2c0 100644
--- a/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
+++ b/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
@@ -4,6 +4,7 @@
 import QtQuick
 import QtTest
 import QtWebEngine
+import Test.Shared as Shared
 
 TestWebEngineView {
     id: webEngineView
@@ -134,8 +135,9 @@ TestWebEngineView {
     }
 
     function gotExpectedRequests(expectedFeature) {
-        var isDesktopPermission = expectedFeature == WebEnginePermission.PermissionType.DesktopAudioVideoCapture ||
-            expectedFeature == WebEnginePermission.PermissionType.DesktopVideoCapture;
+        // When webrtc is disabled, desktop media requests come through as non-desktop.
+        var isDesktopPermission = Shared.TestEnvironment.hasWebRTC() && (expectedFeature == WebEnginePermission.PermissionType.DesktopAudioVideoCapture ||
+            expectedFeature == WebEnginePermission.PermissionType.DesktopVideoCapture);
         if (isDesktopPermission != gotDesktopMediaRequest)
             return false
         if (isDesktopPermission && gotEmptyDesktopMediaRequest)
diff --git a/tests/auto/quick/qmltests/tst_qmltests.cpp b/tests/auto/quick/qmltests/tst_qmltests.cpp
index 79c9965a25d..a603c61bcda 100644
--- a/tests/auto/quick/qmltests/tst_qmltests.cpp
+++ b/tests/auto/quick/qmltests/tst_qmltests.cpp
@@ -17,6 +17,8 @@
 #include <QtTest/qtest.h>
 #include <QtWebEngineQuick/qquickwebengineprofile.h>
 #include <QtWebEngineQuick/qtwebenginequickglobal.h>
+#include <QtWebEngineCore/qtwebenginecore-config.h>
+#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
 #include <qt_webengine_quicktest.h>
 
 #include <cstdio>
@@ -98,6 +100,14 @@ static void sigSegvHandler(int signum)
 }
 #endif
 
+class TestEnvironment : public QObject
+{
+    Q_OBJECT
+
+public:
+    Q_INVOKABLE bool hasWebRTC() const { return QT_CONFIG(webengine_webrtc); }
+};
+
 class TempDir : public QObject {
     Q_OBJECT
 
@@ -254,6 +264,9 @@ int main(int argc, char **argv)
     qmlRegisterType<TestInputEvent>("Test.util", 1, 0, "TestInputEvent");
 
     QTEST_SET_MAIN_SOURCE_PATH
+    qmlRegisterSingletonType<TestEnvironment>(
+            "Test.Shared", 1, 0, "TestEnvironment",
+            [&](QQmlEngine *, QJSEngine *) { return new TestEnvironment; });
     qmlRegisterSingletonType<HttpServer>("Test.Shared", 1, 0, "HttpServer", [&] (QQmlEngine *, QJSEngine *) {
         auto server = new HttpServer;
         server->setResourceDirs(
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index f0b1e5bf6f8..37d066531b6 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -1735,6 +1735,10 @@ Q_OBJECT
     bool gotExpectedRequests(bool isDesktopPermission,
                              QWebEnginePermission::PermissionType permissionType) const
     {
+#if !QT_CONFIG(webengine_webrtc)
+        // When webrtc is disabled, these come through as media requests and not desktop requests.
+        isDesktopPermission = false;
+#endif
         if (isDesktopPermission != m_gotDesktopMediaRequest)
             return false;
         if (isDesktopPermission && m_gotEmptyDesktopMediaRequest)

From 7f50d4d8a55282392e48a43c54c71f179fc7a4c9 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Wed, 16 Oct 2024 10:15:16 +0200
Subject: [PATCH 182/356] Stabilize flaky getUserMedia auto tests

Reduce the number of runJavaScript() calls.

runJavaScript() is expensive and calling it multiple times in a single
QTRY_VERIFY or tryVerify check may lead to a timeout.

Moreover, reading a JS variable by runJavaScript() while setting the
variable from a promise callback may cause deadlock. As a workaround,
intercept promise results by using the javaScriptConsoleMessage API
instead of calling runJavaScript().

Task-number: QTBUG-127726
Fixes: QTBUG-129884
Fixes: QTBUG-130034
Fixes: QTBUG-130035
Change-Id: I130fc98675d54dba4b8f5bbcd8c1d43e56601bc6
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Moss Heim <moss.heim@qt.io>
(cherry picked from commit 5cc56d692e07d8c75ca92000f469d758aed12b26)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 .../quick/qmltests/data/tst_getUserMedia.qml  | 91 +++++++++++--------
 .../qwebenginepage/tst_qwebenginepage.cpp     | 50 +++++-----
 2 files changed, 79 insertions(+), 62 deletions(-)

diff --git a/tests/auto/quick/qmltests/data/tst_getUserMedia.qml b/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
index 06f1d01b2c0..ebb49f9df3d 100644
--- a/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
+++ b/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
@@ -15,6 +15,7 @@ TestWebEngineView {
     profile.persistentPermissionsPolicy: WebEngineProfile.PersistentPermissionsPolicy.AskEveryTime
 
     TestCase {
+        id: testCase
         name: "GetUserMedia"
         when: windowShown
 
@@ -70,9 +71,9 @@ TestWebEngineView {
 
             // 1. Rejecting request on QML side should reject promise on JS side.
             jsGetUserMedia(row.constraints)
-            tryVerify(function(){ return gotExpectedRequests(row.feature) })
+            verifyPermissionType(row.feature)
             rejectPendingRequest()
-            tryVerify(function(){ return !jsPromiseFulfilled() && jsPromiseRejected() })
+            tryVerify(jsPromiseRejected)
 
             // 2. Accepting request on QML side should either fulfill or reject the
             // Promise on JS side. Due to the potential lack of physical media devices
@@ -80,15 +81,15 @@ TestWebEngineView {
             // always be fulfilled, however in this case an error should be returned to
             // JS instead of leaving the Promise in limbo.
             jsGetUserMedia(row.constraints)
-            tryVerify(function(){ return gotExpectedRequests(row.feature) })
+            verifyPermissionType(row.feature)
             acceptPendingRequest()
-            tryVerify(function(){ return jsPromiseFulfilled() || jsPromiseRejected() });
+            tryVerify(jsPromiseSettled)
 
             // 3. Media feature permissions are not remembered.
             jsGetUserMedia(row.constraints);
-            tryVerify(function(){ return gotExpectedRequests(row.feature) })
+            verifyPermissionType(row.feature)
             acceptPendingRequest()
-            tryVerify(function(){ return jsPromiseFulfilled() || jsPromiseRejected() });
+            tryVerify(jsPromiseSettled)
         }
     }
 
@@ -118,7 +119,7 @@ TestWebEngineView {
     // synchronous permission requests
 
     property variant permissionObject
-    property bool gotDesktopMediaRequest: false
+    property bool isDesktopMediaRequestHandled: false
     property bool gotEmptyDesktopMediaRequest: false
 
     onPermissionRequested: function(perm) {
@@ -126,23 +127,32 @@ TestWebEngineView {
     }
 
     onDesktopMediaRequested: function(request) {
-        gotDesktopMediaRequest = true
         gotEmptyDesktopMediaRequest = request.screensModel.rowCount() == 0
         if (gotEmptyDesktopMediaRequest)
             request.cancel()
         else
             request.selectScreen(request.screensModel.index(0, 0))
+        isDesktopMediaRequestHandled = true
     }
 
-    function gotExpectedRequests(expectedFeature) {
+    function verifyPermissionType(expectedFeature) {
         // When webrtc is disabled, desktop media requests come through as non-desktop.
-        var isDesktopPermission = Shared.TestEnvironment.hasWebRTC() && (expectedFeature == WebEnginePermission.PermissionType.DesktopAudioVideoCapture ||
-            expectedFeature == WebEnginePermission.PermissionType.DesktopVideoCapture);
-        if (isDesktopPermission != gotDesktopMediaRequest)
-            return false
-        if (isDesktopPermission && gotEmptyDesktopMediaRequest)
-            return permissionObject == undefined
-        return permissionObject && permissionObject.permissionType == expectedFeature
+        var isDesktopPermission = Shared.TestEnvironment.hasWebRTC() &&
+                (expectedFeature == WebEnginePermission.PermissionType.DesktopAudioVideoCapture ||
+                 expectedFeature == WebEnginePermission.PermissionType.DesktopVideoCapture)
+
+        if (isDesktopPermission) {
+            testCase.tryVerify(function() { return isDesktopMediaRequestHandled })
+
+            // Request has been cancelled
+            if (gotEmptyDesktopMediaRequest) {
+                testCase.compare(permissionObject, undefined)
+                return
+            }
+        }
+
+        testCase.tryVerify(function() { return permissionObject != undefined })
+        testCase.compare(permissionObject.permissionType, expectedFeature)
     }
 
     function acceptPendingRequest() {
@@ -153,7 +163,7 @@ TestWebEngineView {
 
     function resetRequestState() {
         permissionObject = undefined
-        gotDesktopMediaRequest = false
+        isDesktopMediaRequestHandled = false
         gotEmptyDesktopMediaRequest = false
     }
 
@@ -164,40 +174,43 @@ TestWebEngineView {
     }
 
     ////
-    // synchronous JavaScript evaluation
-
-    signal runJavaScriptFinished(variant result)
+    // Intercept promise callback results
 
     SignalSpy {
-        id: spyOnRunJavaScriptFinished
+        id: promiseMessageSpy
         target: webEngineView
-        signalName: "runJavaScriptFinished"
+        signalName: "javaScriptConsoleMessage"
     }
 
-    function runJavaScriptSync(code) {
-        spyOnRunJavaScriptFinished.clear()
-        runJavaScript(code, runJavaScriptFinished)
-        spyOnRunJavaScriptFinished.wait()
-        return spyOnRunJavaScriptFinished.signalArguments[0][0]
+    function jsPromiseSettled()
+    {
+        return promiseMessageSpy.count > 0;
+    }
+
+    function jsPromiseFulfilled()
+    {
+        if (!jsPromiseSettled())
+            return false;
+
+        return promiseMessageSpy.signalArguments[0][1] === "fulfilled"
+    }
+
+    function jsPromiseRejected()
+    {
+        if (!jsPromiseSettled())
+            return false;
+
+        return promiseMessageSpy.signalArguments[0][1] === "rejected"
     }
 
     ////
     // JavaScript snippets
 
     function jsGetUserMedia(constraints) {
+        promiseMessageSpy.clear();
         runJavaScript(
-            "var promiseFulfilled = false;" +
-            "var promiseRejected = false;" +
             "navigator.mediaDevices.getUserMedia(" + JSON.stringify(constraints) + ")" +
-            ".then(stream => { promiseFulfilled = true})" +
-            ".catch(err => { promiseRejected = true})")
-    }
-
-    function jsPromiseFulfilled() {
-        return runJavaScriptSync("promiseFulfilled")
-    }
-
-    function jsPromiseRejected() {
-        return runJavaScriptSync("promiseRejected")
+            ".then(stream => { console.info('fulfilled') })" +
+            ".catch(err => { console.info('rejected') })")
     }
 }
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 37d066531b6..eae3761606b 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -1693,14 +1693,13 @@ Q_OBJECT
 
     void jsGetMedia(const QString &call)
     {
+        m_jsPromiseFulfilled = false;
+        m_jsPromiseRejected = false;
         evaluateJavaScriptSync(this,
-            QStringLiteral(
-                "var promiseFulfilled = false;"
-                "var promiseRejected = false;"
-                "navigator.mediaDevices.%1"
-                ".then(stream => { promiseFulfilled = true})"
-                ".catch(err => { promiseRejected = true})")
-            .arg(call));
+                               QStringLiteral("navigator.mediaDevices.%1"
+                                              ".then(stream => { console.info('fulfilled') })"
+                                              ".catch(err => { console.info('rejected') })")
+                                       .arg(call));
     }
 
     void jsGetUserMedia(const QString &constraints)
@@ -1708,15 +1707,11 @@ Q_OBJECT
         jsGetMedia(QStringLiteral("getUserMedia(%1)").arg(constraints));
     }
 
-    bool jsPromiseFulfilled()
-    {
-        return evaluateJavaScriptSync(this, QStringLiteral("promiseFulfilled")).toBool();
-    }
+    bool jsPromiseSettled() { return m_jsPromiseFulfilled || m_jsPromiseRejected; }
 
-    bool jsPromiseRejected()
-    {
-        return evaluateJavaScriptSync(this, QStringLiteral("promiseRejected")).toBool();
-    }
+    bool jsPromiseFulfilled() { return m_jsPromiseFulfilled; }
+
+    bool jsPromiseRejected() { return m_jsPromiseRejected; }
 
     void rejectPendingRequest()
     {
@@ -1773,6 +1768,15 @@ private Q_SLOTS:
         m_permission.reset();
     }
 
+    void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel, const QString &message, int,
+                                  const QString &) override
+    {
+        m_jsPromiseFulfilled = (message == "fulfilled");
+        m_jsPromiseRejected = (message == "rejected");
+    }
+
+    bool m_jsPromiseFulfilled;
+    bool m_jsPromiseRejected;
     bool m_gotDesktopMediaRequest;
     bool m_gotEmptyDesktopMediaRequest;
     bool m_loadSucceeded;
@@ -1824,7 +1828,7 @@ void tst_QWebEnginePage::getUserMediaRequest()
     page.jsGetMedia(call);
     QTRY_VERIFY(page.gotExpectedRequests(isDesktopPermission, permissionType));
     page.rejectPendingRequest();
-    QTRY_VERIFY(!page.jsPromiseFulfilled() && page.jsPromiseRejected());
+    QTRY_VERIFY(page.jsPromiseRejected());
 
     // 2. Accepting request on C++ side should either fulfill or reject the
     // Promise on JS side. Due to the potential lack of physical media devices
@@ -1834,13 +1838,13 @@ void tst_QWebEnginePage::getUserMediaRequest()
     page.jsGetMedia(call);
     QTRY_VERIFY(page.gotExpectedRequests(isDesktopPermission, permissionType));
     page.acceptPendingRequest();
-    QTRY_VERIFY(page.jsPromiseFulfilled() || page.jsPromiseRejected());
+    QTRY_VERIFY(page.jsPromiseSettled());
 
     // 3. Media permissions are not remembered.
     page.jsGetMedia(call);
     QTRY_VERIFY(page.gotExpectedRequests(isDesktopPermission, permissionType));
     page.acceptPendingRequest();
-    QTRY_VERIFY(page.jsPromiseFulfilled() || page.jsPromiseRejected());
+    QTRY_VERIFY(page.jsPromiseSettled());
 }
 
 void tst_QWebEnginePage::getUserMediaRequestDesktopAudio()
@@ -1854,11 +1858,11 @@ void tst_QWebEnginePage::getUserMediaRequestDesktopAudio()
 
     page.jsGetUserMedia(
         QStringLiteral("{audio: { mandatory: { chromeMediaSource: 'desktop' }}}"));
-    QTRY_VERIFY(!page.jsPromiseFulfilled() && page.jsPromiseRejected());
+    QTRY_VERIFY(page.jsPromiseRejected());
 
     page.jsGetUserMedia(
         QStringLiteral("{audio: { mandatory: { chromeMediaSource: 'desktop' }}, video: true}"));
-    QTRY_VERIFY(!page.jsPromiseFulfilled() && page.jsPromiseRejected());
+    QTRY_VERIFY(page.jsPromiseRejected());
 }
 
 void tst_QWebEnginePage::getUserMediaRequestSettingDisabled()
@@ -1871,7 +1875,7 @@ void tst_QWebEnginePage::getUserMediaRequestSettingDisabled()
     // asking for permission first.
 
     page.jsGetUserMedia(QStringLiteral("{video: { mandatory: { chromeMediaSource: 'desktop' }}}"));
-    QTRY_VERIFY(!page.jsPromiseFulfilled() && page.jsPromiseRejected());
+    QTRY_VERIFY(page.jsPromiseRejected());
 }
 
 // Try to trigger any possible race condition between the UI thread (permission
@@ -1904,7 +1908,7 @@ void tst_QWebEnginePage::getUserMediaRequestDesktopVideoManyPages()
     for (GetUserMediaTestPage &page : pages)
         page.acceptPendingRequest();
     for (GetUserMediaTestPage &page : pages)
-        QTRY_VERIFY(page.jsPromiseFulfilled() || page.jsPromiseRejected());
+        QTRY_VERIFY(page.jsPromiseSettled());
 }
 
 // Try to trigger any possible race condition between the UI or audio/device
@@ -1928,7 +1932,7 @@ void tst_QWebEnginePage::getUserMediaRequestDesktopVideoManyRequests()
         page.jsGetUserMedia(constraints);
         QTRY_VERIFY(page.gotExpectedRequests(/*isDesktopPermission*/ true, permissionType));
         page.acceptPendingRequest();
-        QTRY_VERIFY(page.jsPromiseFulfilled() || page.jsPromiseRejected());
+        QTRY_VERIFY(page.jsPromiseSettled());
     }
 }
 

From b2223c3902a56e9e392e8a4728a5fbec594dd5eb Mon Sep 17 00:00:00 2001
From: Paul Wicking <paul.wicking@qt.io>
Date: Mon, 21 Oct 2024 08:17:51 +0200
Subject: [PATCH 183/356] Doc: Drop unbalanced and unneeded curly brace from
 code snippet

The QWebEngineUrlSchemeHandler class documentation contains a code
snippet that demonstrates its usage. In a nested conditional, an if
expression opens a scope with a curly brace. This scope is never closed.
Thus, the code is malformed, and copy/pasting the snippet leads to
errors.

As the following statement is a one-liner, there's no need for braces.
Adding braces would be intrusive as Qt's code style mandates that all
branches are braced if any of them are. Therefore, drop the opening
curly brace that follows the if expression.

Fixes: QTBUG-130327
Change-Id: I2bb8e8fdde5c554df97e4bcda8b617ef00803de4
Reviewed-by: Jerome Pasion <jerome.pasion@qt.io>
(cherry picked from commit d48f8489882fc4106e514b6b267669c25980c78c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebengineurlschemehandler.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/api/qwebengineurlschemehandler.cpp b/src/core/api/qwebengineurlschemehandler.cpp
index e01ecef4942..cc77bcac88f 100644
--- a/src/core/api/qwebengineurlschemehandler.cpp
+++ b/src/core/api/qwebengineurlschemehandler.cpp
@@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
             const QUrl url = job->requestUrl();
 
             if (isValidUrl(url)) {
-                if (method == QByteArrayLiteral("GET")) {
+                if (method == QByteArrayLiteral("GET"))
                     job->reply(QByteArrayLiteral("text/html"), makeReply(url));
                 else // Unsupported method
                     job->fail(QWebEngineUrlRequestJob::RequestDenied);

From f6b43df635ce6af9abe4475b47114717d71501ed Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Wed, 23 Oct 2024 06:15:49 +0000
Subject: [PATCH 184/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Ie308ab6257bf1cbc8df45c9a7e40b273199854f8
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 7b3fe079c7b..22c5860a304 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 76fe874d3f15ee25df29d3d855b1f33785e5a3f9
+    ref: d3b09adbd5d8d3bd388bc7d4d3b7e282dff7a775
     required: true
   ../qtpositioning:
-    ref: d11badc34816223130be35a7e830a6be82810a70
+    ref: d9391bd7b9f9bd47d095c10c71bbcb0db26195df
     required: false
   ../qttools:
-    ref: 027054ec343a83ad2e8dc77c89122c1b4c5b3451
+    ref: 1148ae94db3efa883c2f309683461ab59535f43d
     required: false
   ../qtwebchannel:
-    ref: 760a514f7625aa7121bd5a44f9775ca85afbad90
+    ref: c4805b3845dfd400d7ff2aac222d5d89a83b472e
     required: false

From 2d20cd01063f8313ccddbecef7b1af6236c39b3f Mon Sep 17 00:00:00 2001
From: Anu Aliyas <anu.aliyas@qt.io>
Date: Thu, 24 Oct 2024 15:25:20 +0200
Subject: [PATCH 185/356] Fix the crash when accessing a blocked site from
 Google search

When swapping the contents, chromium expects a different SiteInstance
than the current one. When a blocked site is loaded from Google, the new
and current instances were the same, causing the crash. This is because
the error code for the blocked request was set to
net::ERR_BLOCKED_BY_CLIENT. If the request is not browser initiated, it
will use the current process and leading to the crash. Changed the
error code to net::ERR_ACCESS_DENIED to resolve the issue.

Fixes: QTBUG-129796
Change-Id: Id082ddf871357dabcad75d8c8f0d4471c6a77497
Reviewed-by: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 474132e4d311377c4c1d94c67c14d3c42a4ed30b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/net/proxying_url_loader_factory_qt.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/core/net/proxying_url_loader_factory_qt.cpp b/src/core/net/proxying_url_loader_factory_qt.cpp
index 220f44023f6..ea5e1ebd656 100644
--- a/src/core/net/proxying_url_loader_factory_qt.cpp
+++ b/src/core/net/proxying_url_loader_factory_qt.cpp
@@ -374,8 +374,9 @@ void InterceptedRequest::ContinueAfterIntercept()
         }
 
         if (info.changed) {
+            // Used the same error code as AwProxyingURLLoaderFactory's blocked request.
             if (info.shouldBlockRequest)
-                return SendErrorAndCompleteImmediately(net::ERR_BLOCKED_BY_CLIENT);
+                return SendErrorAndCompleteImmediately(net::ERR_ACCESS_DENIED);
 
             if (info.shouldRedirectRequest) {
                 net::RedirectInfo::FirstPartyURLPolicy first_party_url_policy =

From c0f3bfdb86406a9b4210948e618e9eee73d9779c Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Thu, 24 Oct 2024 21:07:47 +0000
Subject: [PATCH 186/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Idd1f6c953c9c1ab79d38c5c3401be23260ef6241
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 22c5860a304..53030348c4e 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: d3b09adbd5d8d3bd388bc7d4d3b7e282dff7a775
+    ref: 4ed387feddf0e3683252af2fe1ba38789ad71c0e
     required: true
   ../qtpositioning:
-    ref: d9391bd7b9f9bd47d095c10c71bbcb0db26195df
+    ref: 3d75fffb83671bac854daa4231720c602c03136f
     required: false
   ../qttools:
-    ref: 1148ae94db3efa883c2f309683461ab59535f43d
+    ref: d15a1b25827c9c7d3c903904607d972f125db6f1
     required: false
   ../qtwebchannel:
-    ref: c4805b3845dfd400d7ff2aac222d5d89a83b472e
+    ref: 4ef0f73fc3a3c15a10d42ad44c78efa9efa59af9
     required: false

From eecc0ad041bb7bec9cc262900fd6fd82aff76dc9 Mon Sep 17 00:00:00 2001
From: Timur Pocheptsov <timur.pocheptsov@qt.io>
Date: Fri, 25 Oct 2024 12:23:25 +0200
Subject: [PATCH 187/356] clientAuthentication: do not block in keychain access

if testing with SecureTransport backend build with SDK < 15
on a system >= macOS 15.

Fixes: QTBUG-130500
Change-Id: Ica758b45c8d8c0c30ea31a85e5dc18268207c005
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 2a3610d77418a2841a13e041e9e136e3abb395a1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 .../tst_qwebengineclientcertificatestore.cpp        | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp b/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp
index d203ab130b3..27ef7383a3b 100644
--- a/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp
+++ b/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp
@@ -10,6 +10,9 @@
 #include <QtWebEngineCore/qwebenginecertificateerror.h>
 #include <QtWebEngineCore/qwebenginesettings.h>
 
+#include <QtCore/qoperatingsystemversion.h>
+#include <QtCore/qsystemdetection.h>
+
 class tst_QWebEngineClientCertificateStore : public QObject
 {
     Q_OBJECT
@@ -115,6 +118,16 @@ void tst_QWebEngineClientCertificateStore::clientAuthentication()
     QFETCH(bool, in_memory);
     QFETCH(bool, add_more_in_memory_certificates);
 
+#ifdef Q_OS_MACOS
+#if !QT_MACOS_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(150000, 180000)
+    if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSSequoia
+        && QSslSocket::activeBackend() == QLatin1String("securetransport")) {
+        // Built with SDK < 15, with file-based keychains that no longer work on macOS >= 15.
+        QSKIP("SecureTransport will block the test server while accessing the login keychain");
+    }
+#endif
+#endif // Q_OS_MACOS
+
     HttpsServer server(":/resources/server.pem", ":/resources/server.key", ":resources/ca.pem");
     server.setExpectError(false);
     QVERIFY(server.start());

From e8e41ee84d79b179ed39a14747eac34419d825ad Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Mon, 23 Sep 2024 11:45:52 +0200
Subject: [PATCH 188/356] Use raw string literal in gn_find_mocables

Python 3.12 throws a syntax warning when encountering something
that looks like an invalid escape sequence. This messes with the
regex in gn_find_mocables, so this change makes the offending string
a raw string literal instead.

Pick-to: 6.7
Change-Id: I36872e02464ee4bfa3091accd8d780eb3103e2a4
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 3273cd52bfbf6b4b568b8d52ce91329b4c048438)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 tools/scripts/gn_find_mocables.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/scripts/gn_find_mocables.py b/tools/scripts/gn_find_mocables.py
index 68f648889c2..31383e6ada9 100644
--- a/tools/scripts/gn_find_mocables.py
+++ b/tools/scripts/gn_find_mocables.py
@@ -28,7 +28,7 @@
             line = line.partition("//")[0]
         if re.match(".*Q_OBJECT", line):
             mocables.add(f)
-        im = re.search('#include "(moc_\w+.cpp)"', line)
+        im = re.search(r'#include "(moc_\w+.cpp)"', line)
         if im:
             includedMocs.add(im.group(1))
 

From d1eb5d209cdbedc85ea0f6d42f82348ea80cbc43 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Tue, 29 Oct 2024 11:42:38 +0100
Subject: [PATCH 189/356] Docs: Fix formatting errors in PermissionBrowser
 example docs

Fixes a couple of broken links, a broken list, and a missing \c tag.

Change-Id: I57bd37aea88a3780b1897ab0223d7964e6399755
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 963f197eb105d15cb3c7e295eafe9efe94cdbfba)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 .../permissionbrowser/doc/src/permissionbrowser.qdoc   | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/examples/webenginewidgets/permissionbrowser/doc/src/permissionbrowser.qdoc b/examples/webenginewidgets/permissionbrowser/doc/src/permissionbrowser.qdoc
index 3715d63cd94..995d0046afe 100644
--- a/examples/webenginewidgets/permissionbrowser/doc/src/permissionbrowser.qdoc
+++ b/examples/webenginewidgets/permissionbrowser/doc/src/permissionbrowser.qdoc
@@ -97,9 +97,9 @@
     \section1 Modifying a permission and displaying it to the user
 
     The QWebEnginePermission interface provides the \l {QWebEnginePermission::grant}{grant}()
-    and {QWebEnginePermission::deny}{deny}() functions, which are all that's needed to
+    and \l {QWebEnginePermission::deny}{deny}() functions, which are all that's needed to
     change the status of a permission. If the application needs to forget about a permission,
-    we use the {QWebEnginePermission::reset}{reset}() function.
+    we use the \l {QWebEnginePermission::reset}{reset}() function.
 
     Inside the \c PermissionWidget constructor, we hook those function up to the buttons'
     \c clicked signal, so that we can execute the relevant functionality on the
@@ -127,7 +127,7 @@
 
     When a pending permission is granted or denied, we want to move the associated
     widget to the list above, which contains all currently existing permissions.
-    We do this in the MainWindow::handlePermissionModified slot.
+    We do this in the \c MainWindow::handlePermissionModified slot.
 
     \quotefromfile webenginewidgets/permissionbrowser/mainwindow.cpp
     \skipto void MainWindow::handlePermissionModified
@@ -196,10 +196,10 @@
         loaded back up at next startup. A permission onlycneeds to be granted once, and
         subsequent uses of the API that triggered the request will automatically be granted,
         until the application calls QWebEnginePermission::reset().
-        li \l QWebEngineProfile::StoreInMemory Has the same behavior as above,
+        \li \l QWebEngineProfile::StoreInMemory Has the same behavior as above,
         except that permissions will be destroyed at application exit, and not committed
         to disk.
-        li \l QWebEngineProfile::AskEveryTime makes sure permissions are never
+        \li \l QWebEngineProfile::AskEveryTime makes sure permissions are never
         remembered, and all act as if they're non-persistent. Thus, every time a web API needs
         a permission, a new prompt will be shown to the user. This option is intended for
         backwards compatibility and applications which implement their own permission storage.

From 9685f5e408cfb29c9b758bcde6b3507b29409365 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Thu, 31 Oct 2024 01:33:58 +0000
Subject: [PATCH 190/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I2a5e9e20fdc51c5b38903d3d97bf8d7c1e3943a4
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 53030348c4e..eef523a86cf 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 4ed387feddf0e3683252af2fe1ba38789ad71c0e
+    ref: 556e46460661f1f16baed4151289ef7c3ba7ba5c
     required: true
   ../qtpositioning:
-    ref: 3d75fffb83671bac854daa4231720c602c03136f
+    ref: 7127083cd623a8fc4ddd5958b20a3ab066642b8e
     required: false
   ../qttools:
-    ref: d15a1b25827c9c7d3c903904607d972f125db6f1
+    ref: 342a6332e320f32ac5cc26afd208467a456c0ed7
     required: false
   ../qtwebchannel:
-    ref: 4ef0f73fc3a3c15a10d42ad44c78efa9efa59af9
+    ref: 615bc04acdfa1cf56fb25468c4fd19fff884928b
     required: false

From 3c33a08154c725c21bf6315ec88bd43a3e36a44b Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Tue, 15 Oct 2024 09:05:49 +0200
Subject: [PATCH 191/356] Update required python version to 3.8

To build chromium 118 pyton 3.8 is offcially required.
https://chromium-review.googlesource.com/c/chromium/src/+/4824013

Note the change is reflected also in generated docs.

Fixes: QTBUG-129826
Change-Id: Ib6676b5da32155353c3e36f5b488d5a6a2629310
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 4c47caee99ef7ae619fd26d9484fa4592b88bfee)
---
 cmake/Gn.cmake      | 2 +-
 cmake/License.cmake | 2 +-
 configure.cmake     | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/cmake/Gn.cmake b/cmake/Gn.cmake
index 15b349e0898..2617f92dc1a 100644
--- a/cmake/Gn.cmake
+++ b/cmake/Gn.cmake
@@ -24,7 +24,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
 
 find_package(Gn ${QT_REPO_MODULE_VERSION} EXACT)
 if(NOT Python3_EXECUTABLE)
-    find_package(Python3 3.6 REQUIRED)
+    find_package(Python3 3.8 REQUIRED)
 endif()
 set(gnCmd ${Gn_EXECUTABLE})
 set(buildDir ${BUILD_DIR})
diff --git a/cmake/License.cmake b/cmake/License.cmake
index 2427ad67976..4884c8229f6 100644
--- a/cmake/License.cmake
+++ b/cmake/License.cmake
@@ -16,7 +16,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
 
 find_package(Gn ${QT_REPO_MODULE_VERSION} EXACT)
 if(NOT Python3_EXECUTABLE)
-    find_package(Python3 3.6 REQUIRED)
+    find_package(Python3 3.8 REQUIRED)
 endif()
 
 set(extraThirdPartyDirs "")
diff --git a/configure.cmake b/configure.cmake
index 213ea4223e9..5bc97afdc95 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -13,7 +13,7 @@ else()
     find_package(Gn ${QT_REPO_MODULE_VERSION} EXACT)
     find_program(Python3_EXECUTABLE NAMES python3 python HINTS $ENV{PYTHON3_PATH})
     if(NOT Python3_EXECUTABLE)
-        find_package(Python3 3.6)
+        find_package(Python3 3.8)
     endif()
     find_package(GPerf)
     find_package(BISON)
@@ -511,7 +511,7 @@ add_check_for_support(
 add_check_for_support(
    MODULES QtWebEngine QtPdf
    CONDITION Python3_EXECUTABLE
-   MESSAGE "Python version 3.6 or later is required."
+   MESSAGE "Python version 3.8 or later is required."
 )
 add_check_for_support(
    MODULES QtWebEngine QtPdf

From aaae449f21ccf899f845bd18acf0bd6d8755aefe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Mon, 21 Oct 2024 10:42:07 +0200
Subject: [PATCH 192/356] Update Chromium

Submodule src/3rdparty 4ebc0a64..6040f729:
  * [Backport] CVE-2024-10487: Out of bounds write in Dawn
  * FIXUP: Do not initialize default locale in local isolate
  * Fixup: Fix building with system ffmpeg
  * [Backport] CVE-2024-10230: Type Confusion in V8
  * Avoid SSE4/AVX instructions on Windows
  * [Backport] CVE-2024-10231: Type Confusion in V8
  * [Backport] CVE-2024-10229: Inappropriate implementation in Extensions
  * [Backport] Remove CrashOnInProcessANGLEContextLoss feature
  * [Backport] Security bug 369630648
  * [Backport] CVE-2024-9965: Insufficient data validation in DevTools
  * [Backport] CVE-2024-9966: Inappropriate implementation in Navigations
  * [Backport] Security bug 366635354
  * [Backport] CVE-2024-9959: Use after free in DevTools
  * [Backport] CVE-2024-9955: Use after free in Web Authentication
  * [Backport] CVE-2024-9602: Type Confusion in V8
  * [Backport] CVE-2024-9603: Type Confusion in V8

Fixes: QTBUG-129073
Fixes: QTBUG-130246
Fixes: QTBUG-130262
Fixes: QTBUG-130484
Fixes: QTBUG-130693
Change-Id: Ibc94885d789b637a8dfe498321d310577634101a
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
---
 CHROMIUM_VERSION                | 2 +-
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index 17a1d677c93..9b8609cca24 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
 Based on Chromium version:                                      122.0.6261.171
-Patched with security patches up to Chromium version:           129.0.6668.90
+Patched with security patches up to Chromium version:           130.0.6723.92
diff --git a/src/3rdparty b/src/3rdparty
index 4ebc0a64f11..6040f729684 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit 4ebc0a64f1100ed22467d50037a05338daf5df29
+Subproject commit 6040f7296848acf59a45825edd7c2a8806f5ade8
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 7683201199c..1adcd1bb3c2 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1268,7 +1268,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "129.0.6668.90"; // FIXME: Remember to update
+    return "130.0.6723.92"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From e412bc7964d632bf196654a36870d31928eecfdc Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Thu, 4 Jul 2024 09:22:12 +0200
Subject: [PATCH 193/356] Do not override signals in qml delegates
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Since 36478e25 in qtdeclarative overriding signals
is reported as warning and will be dropped in the
future as it is not supported.

Drop 'accepted' and 'rejected' signals and use signals from
base component, which is the "correct" way of handling it.
Remove some logic coming from qqc1.

Change-Id: I3eeeca4b25fb866d0c6e3da01c1513afd85904f0
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
(cherry picked from commit f600a8ee31ccd01739517b146f010173768e9252)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/qwebenginepage.cpp               |  3 +-
 src/core/authentication_dialog_controller.cpp | 12 ++++++--
 src/core/authentication_dialog_controller.h   |  3 +-
 src/core/authentication_dialog_controller_p.h |  4 ++-
 .../api/qquickwebenginedialogrequests.cpp     |  6 ++--
 src/webenginequick/ui/AlertDialog.qml         | 20 +------------
 .../ui/AuthenticationDialog.qml               | 26 +++--------------
 src/webenginequick/ui/ConfirmDialog.qml       | 28 ++-----------------
 src/webenginequick/ui/PromptDialog.qml        | 23 ++-------------
 src/webenginequick/ui_delegates_manager.cpp   |  7 ++++-
 10 files changed, 35 insertions(+), 97 deletions(-)

diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp
index c125b3aca47..f256daf4e63 100644
--- a/src/core/api/qwebenginepage.cpp
+++ b/src/core/api/qwebenginepage.cpp
@@ -571,7 +571,8 @@ void QWebEnginePagePrivate::authenticationRequired(QSharedPointer<Authentication
         return;
     }
 
-    controller->accept(networkAuth.user(), networkAuth.password());
+    controller->credentials(networkAuth.user(), networkAuth.password());
+    controller->accept();
 }
 
 void QWebEnginePagePrivate::releaseProfile()
diff --git a/src/core/authentication_dialog_controller.cpp b/src/core/authentication_dialog_controller.cpp
index 4efd5dad3a7..87536b9e45c 100644
--- a/src/core/authentication_dialog_controller.cpp
+++ b/src/core/authentication_dialog_controller.cpp
@@ -14,7 +14,7 @@ AuthenticationDialogControllerPrivate::AuthenticationDialogControllerPrivate(bas
 {
 }
 
-void AuthenticationDialogControllerPrivate::dialogFinished(bool accepted, const QString &user, const QString &password)
+void AuthenticationDialogControllerPrivate::dialogFinished(bool accepted)
 {
     content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
                    base::BindOnce(&LoginDelegateQt::sendAuthToRequester,
@@ -51,9 +51,15 @@ bool AuthenticationDialogController::isProxy() const
     return d->isProxy;
 }
 
-void AuthenticationDialogController::accept(const QString &user, const QString &password)
+void AuthenticationDialogController::credentials(const QString &user, const QString &password)
 {
-    d->dialogFinished(true, user, password);
+    d->user = user;
+    d->password = password;
+}
+
+void AuthenticationDialogController::accept()
+{
+    d->dialogFinished(true);
 }
 
 void AuthenticationDialogController::reject()
diff --git a/src/core/authentication_dialog_controller.h b/src/core/authentication_dialog_controller.h
index 944ec4d159a..beb61f2c154 100644
--- a/src/core/authentication_dialog_controller.h
+++ b/src/core/authentication_dialog_controller.h
@@ -33,7 +33,8 @@ class Q_WEBENGINECORE_EXPORT AuthenticationDialogController : public QObject {
     bool isProxy() const;
 
 public Q_SLOTS:
-    void accept(const QString &user, const QString &password);
+    void credentials(const QString &user, const QString &password);
+    void accept();
     void reject();
 
 private:
diff --git a/src/core/authentication_dialog_controller_p.h b/src/core/authentication_dialog_controller_p.h
index 6c35a60dc66..3cea053fa02 100644
--- a/src/core/authentication_dialog_controller_p.h
+++ b/src/core/authentication_dialog_controller_p.h
@@ -14,13 +14,15 @@ class AuthenticationDialogControllerPrivate {
 
 public:
     AuthenticationDialogControllerPrivate(base::WeakPtr<LoginDelegateQt> loginDelegate);
-    void dialogFinished(bool accepted, const QString &user = QString(), const QString &password = QString());
+    void dialogFinished(bool accepted);
 
     base::WeakPtr<LoginDelegateQt> loginDelegate;
     QUrl url;
     QString host;
     QString realm;
     bool isProxy;
+    QString user;
+    QString password;
 };
 
 } // namespace QtWebEngineCore
diff --git a/src/webenginequick/api/qquickwebenginedialogrequests.cpp b/src/webenginequick/api/qquickwebenginedialogrequests.cpp
index 34ce580735c..9d6b5ed7000 100644
--- a/src/webenginequick/api/qquickwebenginedialogrequests.cpp
+++ b/src/webenginequick/api/qquickwebenginedialogrequests.cpp
@@ -186,8 +186,10 @@ void QQuickWebEngineAuthenticationDialogRequest::dialogAccept(const QString &use
     m_accepted = true;
     QSharedPointer<AuthenticationDialogController> controller
             = m_controller.toStrongRef();
-    if (controller)
-        controller->accept(user,password);
+    if (controller) {
+        controller->credentials(user, password);
+        controller->accept();
+    }
 }
 
 /*!
diff --git a/src/webenginequick/ui/AlertDialog.qml b/src/webenginequick/ui/AlertDialog.qml
index e4c17b05621..f149c0e6fc7 100644
--- a/src/webenginequick/ui/AlertDialog.qml
+++ b/src/webenginequick/ui/AlertDialog.qml
@@ -8,29 +8,11 @@ import QtQuick.Layouts
 Dialog {
     property alias text: message.text
     property bool handled: false
-    signal accepted()
-    signal rejected()
     title: qsTr("Alert Dialog")
     modal: false
     anchors.centerIn: parent
     objectName: "alertDialog"
 
-    //handle the case where users simply closes the dialog
-    onVisibleChanged: {
-        if (visible == false && handled == false) {
-            handled = true;
-            rejected();
-        } else {
-            handled = false;
-        }
-    }
-
-    function acceptDialog() {
-        accepted();
-        handled = true;
-        close();
-    }
-
     ColumnLayout {
         id: rootLayout
         anchors.fill: parent
@@ -58,7 +40,7 @@ Dialog {
         Button {
             Layout.alignment: Qt.AlignHCenter
             text: qsTr("OK")
-            onClicked: acceptDialog()
+            onClicked: accept()
         }
     }
 }
diff --git a/src/webenginequick/ui/AuthenticationDialog.qml b/src/webenginequick/ui/AuthenticationDialog.qml
index d0611b84f51..925102f94e0 100644
--- a/src/webenginequick/ui/AuthenticationDialog.qml
+++ b/src/webenginequick/ui/AuthenticationDialog.qml
@@ -8,33 +8,15 @@ import QtQuick.Layouts
 Dialog {
     property alias text: message.text
     property bool handled: false
-    signal accepted(string user, string password)
-    signal rejected()
+    signal credentials(string user, string password)
     title: qsTr("Authentication Required")
     modal: false
     anchors.centerIn: parent
     objectName: "authenticationDialog"
 
-    //handle the case where users simply closes the dialog
-    onVisibleChanged: {
-        if (visible == false && handled == false) {
-            handled = true;
-            rejected();
-        } else {
-            handled = false;
-        }
-    }
-
     function acceptDialog() {
-        accepted(userField.text, passwordField.text);
-        handled = true;
-        close();
-    }
-
-    function rejectDialog() {
-        rejected();
-        handled = true;
-        close();
+        credentials(userField.text, passwordField.text);
+        accept()
     }
 
     ColumnLayout {
@@ -90,7 +72,7 @@ Dialog {
             Button {
                 id: cancelButton
                 text: qsTr("Cancel")
-                onClicked: rejectDialog()
+                onClicked: reject()
             }
             Button {
                 text: qsTr("Log In")
diff --git a/src/webenginequick/ui/ConfirmDialog.qml b/src/webenginequick/ui/ConfirmDialog.qml
index cfffe7c4d54..db7bcfbf1f4 100644
--- a/src/webenginequick/ui/ConfirmDialog.qml
+++ b/src/webenginequick/ui/ConfirmDialog.qml
@@ -8,35 +8,11 @@ import QtQuick.Layouts
 Dialog {
     property alias text: message.text
     property bool handled: false
-    signal accepted()
-    signal rejected()
     title: qsTr("Confirm Dialog")
     modal: false
     anchors.centerIn: parent
     objectName: "confirmDialog"
 
-    //handle the case where users simply closes the dialog
-    onVisibleChanged: {
-        if (visible == false && handled == false) {
-            handled = true;
-            rejected();
-        } else {
-            handled = false;
-        }
-    }
-
-    function acceptDialog() {
-        accepted();
-        handled = true;
-        close();
-    }
-
-    function rejectDialog() {
-        rejected();
-        handled = true;
-        close();
-    }
-
     ColumnLayout {
         id: rootLayout
         anchors.fill: parent
@@ -66,11 +42,11 @@ Dialog {
             spacing: 8
             Button {
                 text: qsTr("OK")
-                onClicked: acceptDialog()
+                onClicked: accept()
             }
             Button {
                 text: qsTr("Cancel")
-                onClicked: rejectDialog()
+                onClicked: reject()
             }
         }
     }
diff --git a/src/webenginequick/ui/PromptDialog.qml b/src/webenginequick/ui/PromptDialog.qml
index 275deace862..027dd5ece32 100644
--- a/src/webenginequick/ui/PromptDialog.qml
+++ b/src/webenginequick/ui/PromptDialog.qml
@@ -10,34 +10,15 @@ Dialog {
     property alias prompt: field.text
     property bool handled: false
     signal input(string text)
-    signal accepted()
-    signal rejected()
     title: qsTr("Prompt Dialog")
     modal: false
     anchors.centerIn: parent
     objectName: "promptDialog"
 
-    //handle the case where users simply closes the dialog
-    onVisibleChanged: {
-        if (visible == false && handled == false) {
-            handled = true;
-            rejected();
-        } else {
-            handled = false;
-        }
-    }
 
     function acceptDialog() {
         input(field.text);
-        accepted();
-        handled = true;
-        close();
-    }
-
-    function rejectDialog() {
-        rejected();
-        handled = true;
-        close();
+        accept();
     }
 
     ColumnLayout {
@@ -72,7 +53,7 @@ Dialog {
             }
             Button {
                 text: qsTr("Cancel")
-                onClicked: rejectDialog()
+                onClicked: reject()
             }
         }
     }
diff --git a/src/webenginequick/ui_delegates_manager.cpp b/src/webenginequick/ui_delegates_manager.cpp
index 3b14c2821f4..f4036059d6a 100644
--- a/src/webenginequick/ui_delegates_manager.cpp
+++ b/src/webenginequick/ui_delegates_manager.cpp
@@ -336,12 +336,17 @@ void UIDelegatesManager::showDialog(QSharedPointer<AuthenticationDialogControlle
 
     QQmlProperty acceptSignal(authenticationDialog, QStringLiteral("onAccepted"));
     QQmlProperty rejectSignal(authenticationDialog, QStringLiteral("onRejected"));
+    QQmlProperty credentialsSignal(authenticationDialog, QStringLiteral("onCredentials"));
     CHECK_QML_SIGNAL_PROPERTY(acceptSignal, authenticationDialogComponent->url());
     CHECK_QML_SIGNAL_PROPERTY(rejectSignal, authenticationDialogComponent->url());
 
-    static int acceptIndex = dialogController->metaObject()->indexOfSlot("accept(QString,QString)");
+    static int acceptIndex = dialogController->metaObject()->indexOfSlot("accept()");
+    static int credentialsIndex =
+            dialogController->metaObject()->indexOfSlot("credentials(QString,QString)");
     static int deleteLaterIndex = authenticationDialog->metaObject()->indexOfSlot("deleteLater()");
     QObject::connect(authenticationDialog, acceptSignal.method(), dialogController.data(), dialogController->metaObject()->method(acceptIndex));
+    QObject::connect(authenticationDialog, credentialsSignal.method(), dialogController.data(),
+                     dialogController->metaObject()->method(credentialsIndex));
     QObject::connect(authenticationDialog, acceptSignal.method(), authenticationDialog, authenticationDialog->metaObject()->method(deleteLaterIndex));
     static int rejectIndex = dialogController->metaObject()->indexOfSlot("reject()");
     QObject::connect(authenticationDialog, rejectSignal.method(), dialogController.data(), dialogController->metaObject()->method(rejectIndex));

From 9f129a83ca7d0168ab232abd3ca71df09a9b1410 Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Tue, 29 Oct 2024 11:59:08 +0100
Subject: [PATCH 194/356] Correct behavior of JavscriptCanAccessClipboard

Previously, sanitized clipboard writes were only enabled with
JavascriptCanPaste AND JavascriptCanAccessClipboard enabled. This broke
backward compatibility with code that expected it to only be enabled by
JavascriptCanAccessClipboard.

This compatibility is now restored. In the permission manager, all
writes and reads are still controlled by ClipboardReadWrite.

Fixes: QTBUG-130599
Change-Id: I03dc2ea739782e475faacc0900804708c37763cc
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit f9165faf225166acdc5316c76b427609190e6242)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/doc/src/qwebenginesettings_lgpl.qdoc | 25 ++++++++++++-------
 src/core/permission_manager_qt.cpp            |  5 +++-
 .../api/qquickwebenginesettings.cpp           | 20 ++++++++++-----
 .../tst_qquickwebengineview.cpp               |  4 +--
 .../qwebenginepage/tst_qwebenginepage.cpp     | 20 +++++++++------
 5 files changed, 48 insertions(+), 26 deletions(-)

diff --git a/src/core/doc/src/qwebenginesettings_lgpl.qdoc b/src/core/doc/src/qwebenginesettings_lgpl.qdoc
index 7bd6d292436..89fc0c8ddac 100644
--- a/src/core/doc/src/qwebenginesettings_lgpl.qdoc
+++ b/src/core/doc/src/qwebenginesettings_lgpl.qdoc
@@ -70,10 +70,13 @@
             Allows JavaScript programs to open popup windows without user
             interaction. Enabled by default.
     \value  JavascriptCanAccessClipboard
-            Allows JavaScript programs to read from and write to the clipboard.
-            Writing to the clipboard is always allowed if it is specifically requested by the user.
-            See JavascriptCanPaste to also allow pasting the content of the clipboard content from
-            JavaScript. Since unrestricted clipboard access is a potential security concern, it is
+            Allows JavaScript programs to write (copy) sanitized content to the clipboard. A
+            sanitized write is done with the \c{write} and \c{writeText} JavaScript Clipboard API
+            calls and must be accompanied by user action.
+            Unsanitized writes, and reading from the clipboard, are
+            enabled by \l{JavascriptCanPaste}.
+            Prior to Chromium version 81, this setting enabled all clipboard writes.
+            Since unrestricted clipboard access is a potential security concern, it is
             recommended that applications leave this disabled and instead respond to
             \l{QWebEnginePage::ClipboardReadWrite}{ClipboardReadWrite} feature permission requests.
             Disabled by default.
@@ -152,11 +155,15 @@
             similar to Chrome on desktops. To overwrite the default behavior,
             disable this setting. (Added in Qt 5.11)
     \value  JavascriptCanPaste
-            Enables JavaScript \c{execCommand("paste")}. This also requires enabling
-            JavascriptCanAccessClipboard. Since unrestricted clipboard access is a potential
-            security concern, it is recommended that applications leave this disabled
-            and instead respond to \l{QWebEnginePage::ClipboardReadWrite}{ClipboardReadWrite}
-            feature permission requests.
+            Allows JavaScript programs to read (paste) from the clipboard and to write unsanitized
+            content. A sanitized write is done with the \c{write} and \c{writeText} JavaScript
+            Clipboard API calls and must be accompanied by user action; unsanitized writes are any
+            writes which do not meet these criteria.
+            For this setting to have any effect, \l{JavascriptCanAccessClipboard} must also be
+            enabled.
+            Since unrestricted clipboard access is a potential security concern, it is
+            recommended that applications leave this disabled and instead respond to
+            \l{QWebEnginePage::ClipboardReadWrite}{ClipboardReadWrite} feature permission requests.
             Disabled by default. (Added in Qt 5.11)
     \value  WebRTCPublicInterfacesOnly
             Limits WebRTC to public IP addresses only. When disabled WebRTC may also use
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index 2ecac308a8c..33be3e8d789 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -172,11 +172,14 @@ static blink::mojom::PermissionStatus getStatusFromSettings(blink::PermissionTyp
 {
     switch (type) {
     case blink::PermissionType::CLIPBOARD_READ_WRITE:
-    case blink::PermissionType::CLIPBOARD_SANITIZED_WRITE:
         if (settings->testAttribute(QWebEngineSettings::JavascriptCanPaste)
             && settings->testAttribute(QWebEngineSettings::JavascriptCanAccessClipboard))
             return blink::mojom::PermissionStatus::GRANTED;
         return blink::mojom::PermissionStatus::ASK;
+    case blink::PermissionType::CLIPBOARD_SANITIZED_WRITE:
+        if (settings->testAttribute(QWebEngineSettings::JavascriptCanAccessClipboard))
+            return blink::mojom::PermissionStatus::GRANTED;
+        return blink::mojom::PermissionStatus::ASK;
     default:
         return blink::mojom::PermissionStatus::ASK;
     }
diff --git a/src/webenginequick/api/qquickwebenginesettings.cpp b/src/webenginequick/api/qquickwebenginesettings.cpp
index 9a15e02f27c..abd8ea25bcb 100644
--- a/src/webenginequick/api/qquickwebenginesettings.cpp
+++ b/src/webenginequick/api/qquickwebenginesettings.cpp
@@ -71,11 +71,14 @@ bool QQuickWebEngineSettings::javascriptCanOpenWindows() const
 /*!
     \qmlproperty bool WebEngineSettings::javascriptCanAccessClipboard
 
-    Allows JavaScript programs to read from or write to the clipboard.
-    Writing to the clipboard is always allowed if it is specifically requested by the user.
+    Allows JavaScript programs to write (copy) sanitized content to the clipboard. A
+    sanitized write is done with the \c{write} and \c{writeText} JavaScript Clipboard API
+    calls and must be accompanied by user action.
 
-    To enable also the pasting of clipboard content from JavaScript,
-    use javascriptCanPaste.
+    Unsanitized writes, and reading from the clipboard, are
+    enabled by \l{javascriptCanPaste}.
+
+    Prior to Chromium version 81, this setting enabled all clipboard writes.
 
     Since unrestricted clipboard access is a potential security concern, it is
     recommended that applications leave this disabled and instead respond to
@@ -382,8 +385,13 @@ bool QQuickWebEngineSettings::webRTCPublicInterfacesOnly() const
     \qmlproperty bool WebEngineSettings::javascriptCanPaste
     \since QtWebEngine 1.7
 
-    Enables JavaScript \c{execCommand("paste")}.
-    This also requires enabling javascriptCanAccessClipboard.
+    Allows JavaScript programs to read (paste) from the clipboard and to write unsanitized
+    content. A sanitized write is done with the \c{write} and \c{writeText} JavaScript
+    Clipboard API calls and must be accompanied by user action; unsanitized writes are any
+    writes which do not meet these criteria.
+
+    For this setting to have any effect, \l{javascriptCanAccessClipboard} must also be
+    enabled.
 
     Since unrestricted clipboard access is a potential security concern, it is
     recommended that applications leave this disabled and instead respond to
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index c2e4ef210eb..b4eaeb37c18 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -1154,9 +1154,9 @@ void tst_QQuickWebEngineView::javascriptClipboard()
                 "if (result.state == 'prompt') accessPrompt = true;"
             "})"));
 
-    QTRY_COMPARE(evaluateJavaScriptSync(view, "accessGranted").toBool(), javascriptCanAccessClipboard && javascriptCanPaste);
+    QTRY_COMPARE(evaluateJavaScriptSync(view, "accessGranted").toBool(), javascriptCanAccessClipboard);
     QTRY_COMPARE(evaluateJavaScriptSync(view, "accessDenied").toBool(), false);
-    QTRY_COMPARE(evaluateJavaScriptSync(view, "accessPrompt").toBool(), !javascriptCanAccessClipboard || !javascriptCanPaste);
+    QTRY_COMPARE(evaluateJavaScriptSync(view, "accessPrompt").toBool(), !javascriptCanAccessClipboard);
 
     evaluateJavaScriptSync(view,
         QStringLiteral(
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index eae3761606b..c2f189bb78a 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -4013,18 +4013,22 @@ void tst_QWebEnginePage::clipboardReadWritePermissionInitialState_data()
 {
     QTest::addColumn<bool>("canAccessClipboard");
     QTest::addColumn<bool>("canPaste");
-    QTest::addColumn<QString>("permission");
-    QTest::newRow("access and paste should grant") << true << true << "granted";
-    QTest::newRow("no access should prompt") << false << true << "prompt";
-    QTest::newRow("no paste should prompt") << true << false << "prompt";
-    QTest::newRow("no access or paste should prompt") << false << false << "prompt";
+    QTest::addColumn<QString>("readPermission");
+    QTest::addColumn<QString>("writePermission");
+    QTest::newRow("access and paste should grant both") << true << true << "granted" << "granted";
+    QTest::newRow("paste only should prompt for both") << false << true << "prompt" << "prompt";
+    QTest::newRow("access only should grant for write only")
+            << true << false << "prompt" << "granted";
+    QTest::newRow("no access or paste should prompt for both")
+            << false << false << "prompt" << "prompt";
 }
 
 void tst_QWebEnginePage::clipboardReadWritePermissionInitialState()
 {
     QFETCH(bool, canAccessClipboard);
     QFETCH(bool, canPaste);
-    QFETCH(QString, permission);
+    QFETCH(QString, readPermission);
+    QFETCH(QString, writePermission);
 
     QWebEngineProfile otr;
     otr.setPersistentPermissionsPolicy(QWebEngineProfile::PersistentPermissionsPolicy::AskEveryTime);
@@ -4041,9 +4045,9 @@ void tst_QWebEnginePage::clipboardReadWritePermissionInitialState()
     QTRY_COMPARE(spy.size(), 1);
 
     evaluateJavaScriptSync(&page, clipboardPermissionQuery("readPermission", "clipboard-read"));
-    QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("readPermission")), permission);
+    QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("readPermission")), readPermission);
     evaluateJavaScriptSync(&page, clipboardPermissionQuery("writePermission", "clipboard-write"));
-    QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("writePermission")), permission);
+    QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("writePermission")), writePermission);
 }
 
 void tst_QWebEnginePage::clipboardReadWritePermission_data()

From 629da6d9ca1acb8e9e5dc78bcb6e531ac1533aa5 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Mon, 4 Nov 2024 11:48:08 +0000
Subject: [PATCH 195/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I33a921e176fd0deb0a77f211153cee01e13c77fe
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index eef523a86cf..4a92bd3a3e8 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 556e46460661f1f16baed4151289ef7c3ba7ba5c
+    ref: 9fb945184d6ef220fcdef4bc4a7b08df020a2bdd
     required: true
   ../qtpositioning:
-    ref: 7127083cd623a8fc4ddd5958b20a3ab066642b8e
+    ref: 75f7c7b108e5aa143afbe733a810c8b552c77d8b
     required: false
   ../qttools:
-    ref: 342a6332e320f32ac5cc26afd208467a456c0ed7
+    ref: 1d446b0b09cb8cde96c3642391d199850a09aa7a
     required: false
   ../qtwebchannel:
-    ref: 615bc04acdfa1cf56fb25468c4fd19fff884928b
+    ref: 30dacf6896eb0488bf203b72510d2bd69cb772fe
     required: false

From 11a1ecc252136decce7846737610b8b9bbe70ed4 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Tue, 17 Sep 2024 14:39:30 +0200
Subject: [PATCH 196/356] Remove nonexistent manifest file from
 tst_geopermission CMakeLists

This causes configure-time errors on Windows. The manifest file is
also unnecessary.

Pick-to: 6.7
Change-Id: Ic713f0309abdd8edb170980a15ab26eb1725748d
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit bf6df84eac99e879523514a8be03a993aa07b88c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 tests/manual/quick/geopermission/CMakeLists.txt | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/tests/manual/quick/geopermission/CMakeLists.txt b/tests/manual/quick/geopermission/CMakeLists.txt
index 088f248e1ac..6602ceb6ff6 100644
--- a/tests/manual/quick/geopermission/CMakeLists.txt
+++ b/tests/manual/quick/geopermission/CMakeLists.txt
@@ -18,13 +18,6 @@ qt_internal_add_manual_test(tst_geopermission
         Qt::WebEngineQuick
 )
 
-if(WIN32)
-    set_property(
-        TARGET tst_geopermission
-        APPEND PROPERTY
-            SOURCES tst_geopermission.exe.manifest)
-endif()
-
 set_target_properties(tst_geopermission PROPERTIES
     WIN32_EXECUTABLE TRUE
     MACOSX_BUNDLE TRUE

From 301158daac2ef6905231fea3754b8e2a63b1e998 Mon Sep 17 00:00:00 2001
From: Topi Reinio <topi.reinio@qt.io>
Date: Mon, 29 Jul 2024 10:55:40 +0000
Subject: [PATCH 197/356] Doc: Fix QWebEngineDesktopMediaRequest documentation

- Add missing documentation for the QML type
WebEngineDesktopMediaRequest.
- Add missing documentation for the signals
QWebEnginePage::desktopMediaRequested and
WebEngineView::desktopMediaRequested.
- Make some minor fixes to existing docs related to the type

Change-Id: I6fa824a9ac3c05a4e5aec259206bd00f64522e10
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Safiyyah Moosa <safiyyah.moosa@qt.io>
(cherry picked from commit 1a534819f9d98ea8eb90bf1344495626c48118c6)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 .../api/qwebenginedesktopmediarequest.cpp     | 13 ++--
 src/core/api/qwebenginepage.cpp               | 11 +++
 .../src/webengine_desktop_media_request.qdoc  | 67 +++++++++++++++++++
 .../doc/src/webengineview_lgpl.qdoc           | 11 +++
 4 files changed, 96 insertions(+), 6 deletions(-)
 create mode 100644 src/webenginequick/doc/src/webengine_desktop_media_request.qdoc

diff --git a/src/core/api/qwebenginedesktopmediarequest.cpp b/src/core/api/qwebenginedesktopmediarequest.cpp
index 1d93edc99ba..1fdbfa65527 100644
--- a/src/core/api/qwebenginedesktopmediarequest.cpp
+++ b/src/core/api/qwebenginedesktopmediarequest.cpp
@@ -28,11 +28,12 @@ QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QWebEngineDesktopMediaRequestPrivate)
 
     The data model's \e Qt::DisplayRole specifies the name of the source which is the title of a
     window or the number of the display.
-    The model is dynamically updates if the available list of sources has changed e.g a window is
-    opened/closed.
+    The model is dynamically updated if the available list of sources has changed;
+    e.g when a window is opened/closed.
+
+    The signal handler needs to then either call \l selectScreen() or \l selectWindow() to accept
+    the request and start screensharing.
 
-    The signal handler needs to then either call QWebEngineDesktopMediaRequest:selectScreen() or
-    QWebEngineDesktopMediaRequest::selectWindow() to accept the request and start screensharing.
     \sa QWebEnginePage::desktopMediaRequested().
 */
 
@@ -175,7 +176,7 @@ QAbstractListModel *QWebEngineDesktopMediaRequest::windowsModel() const
 }
 
 /*!
-    Selects the window on the \a index to be captured.
+    Selects the window at the \a index to be captured.
 
     \sa QWebEngineDesktopMediaRequest::selectScreen()
 */
@@ -185,7 +186,7 @@ void QWebEngineDesktopMediaRequest::selectWindow(const QModelIndex &index) const
 }
 
 /*!
-    Selects the screen on the \a index to be captured.
+    Selects the screen at the \a index to be captured.
 
     \sa QWebEngineDesktopMediaRequest::selectWindow()
 */
diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp
index f256daf4e63..d209e0ca965 100644
--- a/src/core/api/qwebenginepage.cpp
+++ b/src/core/api/qwebenginepage.cpp
@@ -1575,6 +1575,17 @@ bool QWebEnginePage::event(QEvent *e)
     return QObject::event(e);
 }
 
+/*!
+    \fn QWebEnginePage::desktopMediaRequested(const QWebEngineDesktopMediaRequest &request)
+    \since 6.7
+
+    This signal is emitted when a web application requests access to the contents of a display.
+
+    The \a request argument holds references to data models for windows and screens available
+    for capturing. To accept the request, the signal handler can call either
+    QWebEngineDesktopMediaRequest::selectScreen() or QWebEngineDesktopMediaRequest::selectWindow().
+*/
+
 void QWebEnginePagePrivate::desktopMediaRequested(
         QtWebEngineCore::DesktopMediaController *controller)
 {
diff --git a/src/webenginequick/doc/src/webengine_desktop_media_request.qdoc b/src/webenginequick/doc/src/webengine_desktop_media_request.qdoc
new file mode 100644
index 00000000000..c4d28acba80
--- /dev/null
+++ b/src/webenginequick/doc/src/webengine_desktop_media_request.qdoc
@@ -0,0 +1,67 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+    \qmltype WebEngineDesktopMediaRequest
+    \nativetype QWebEngineDesktopMediaRequest
+    \inqmlmodule QtWebEngine
+    \since 6.7
+    \brief A request for populating a dialog with available sources for screen capturing.
+
+    To allow web applications to capture contents of a display, applications must connect
+    to WebEngineView::desktopMediaRequested, which takes a WebEngineDesktopMediaRequest
+    instance as an argument.
+
+    If a web application requests access to the contents of a display,
+    WebEngineView::desktopMediaRequested will be emitted with a
+    WebEngineDesktopMediaRequest instance as an argument which holds references to
+    \l {ListModel}{ListModels} for available windows and screens that can be captured.
+
+    The data model's \e DisplayRole specifies the name of the source which is the title of a
+    window or the number of the display.
+    The model is dynamically updated if the available list of sources has changed;
+    e.g when a window is opened/closed.
+
+    The signal handler needs to then either call \l selectScreen() or \l selectWindow() to accept
+    the request and start screensharing.
+
+    \sa WebEngineView::desktopMediaRequested
+*/
+
+/*!
+    \qmlproperty ListModel WebEngineDesktopMediaRequest::screensModel
+
+    A ListModel containing a list of available screens.
+
+    \sa windowsModel
+*/
+
+/*!
+    \qmlproperty ListModel WebEngineDesktopMediaRequest::windowsModel
+
+    A ListModel containing a list of available windows.
+
+    \sa screensModel
+*/
+
+/*!
+    \qmlmethod void WebEngineDesktopMediaRequest::selectWindow(QModelIndex index)
+
+    Selects the window at the \a index to be captured.
+
+    \sa WebEngineDesktopMediaRequest::selectScreen()
+*/
+
+/*!
+    \qmlmethod void WebEngineDesktopMediaRequest::selectScreen(QModelIndex index)
+
+    Selects the screen at the \a index to be captured.
+
+    \sa WebEngineDesktopMediaRequest::selectWindow()
+*/
+
+/*!
+    \qmlmethod void WebEngineDesktopMediaRequest::cancel()
+
+    Rejects a request. Screen capturing will be aborted.
+*/
diff --git a/src/webenginequick/doc/src/webengineview_lgpl.qdoc b/src/webenginequick/doc/src/webengineview_lgpl.qdoc
index 04981acfa33..8c6b99dd7ea 100644
--- a/src/webenginequick/doc/src/webengineview_lgpl.qdoc
+++ b/src/webenginequick/doc/src/webengineview_lgpl.qdoc
@@ -1626,6 +1626,17 @@
     \sa QWebEngineWebAuthUxRequest
 */
 
+/*!
+    \qmlsignal WebEngineView::desktopMediaRequested(WebEngineDesktopMediaRequest request)
+    \since QtWebEngine 6.7
+
+    This signal is emitted when a web application requests access to the contents of a display.
+
+    The \a request argument holds references to data models for windows and screens available
+    for capturing. To accept the request, the signal handler can call either
+    WebEngineDesktopMediaRequest::selectScreen() or WebEngineDesktopMediaRequest::selectWindow().
+*/
+
 /*!
     \qmlsignal WebEngineView::zoomFactorChanged(qreal factor);
     \since QtWebEngine 6.8

From ac6961380ac989cfc2a66790327ba23e612db3bb Mon Sep 17 00:00:00 2001
From: Timur Pocheptsov <timur.pocheptsov@qt.io>
Date: Thu, 7 Nov 2024 14:39:02 +0100
Subject: [PATCH 198/356] tst_certificateerror: skip the handleError test
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

in case we build with macOS SDK below 15 and running on macOS 15.

Task-number: QTBUG-130500
Change-Id: I8e3fe7b28565aa754609f1477a8e1c15c89860d0
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit 1c90c7ce072134a8d105c4444d6db34933ca5671)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 .../core/certificateerror/tst_certificateerror.cpp  | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/tests/auto/core/certificateerror/tst_certificateerror.cpp b/tests/auto/core/certificateerror/tst_certificateerror.cpp
index 252e1544d64..25e5b89f52e 100644
--- a/tests/auto/core/certificateerror/tst_certificateerror.cpp
+++ b/tests/auto/core/certificateerror/tst_certificateerror.cpp
@@ -9,6 +9,9 @@
 
 #include <QtTest/QtTest>
 
+#include <QtCore/qoperatingsystemversion.h>
+#include <QtCore/qsystemdetection.h>
+
 class tst_CertificateError : public QObject
 {
     Q_OBJECT
@@ -68,6 +71,16 @@ void tst_CertificateError::handleError_data()
 
 void tst_CertificateError::handleError()
 {
+#ifdef Q_OS_MACOS
+#if !QT_MACOS_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(150000, 180000)
+    if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSSequoia
+        && QSslSocket::activeBackend() == QLatin1String("securetransport")) {
+        // Built with SDK < 15, with file-based keychains that no longer work on macOS >= 15.
+        QSKIP("SecureTransport will block the test server while accessing the login keychain");
+    }
+#endif
+#endif // Q_OS_MACOS
+
     HttpsServer server(":/resources/server.pem", ":/resources/server.key", "");
     server.setExpectError(false);
     QVERIFY(server.start());

From f6ab3bc889b3b399df9b3cd77d36a5036b7958f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Thu, 7 Nov 2024 10:19:22 +0100
Subject: [PATCH 199/356] [gcc] Update minimum version for Qt WebEngine 6.8

gcc 10 is the minimum required version now.

Fixes: QTBUG-130790
Change-Id: I80dbebe40c70b2d4b877a5434e06f8fefd9594ee
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
---
 configure.cmake                                  | 10 ++++++++++
 src/core/doc/src/qtwebengine-platform-notes.qdoc |  2 +-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/configure.cmake b/configure.cmake
index 5bc97afdc95..df1806d3f4f 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -591,6 +591,16 @@ add_check_for_support(
    MESSAGE
        "${CMAKE_CXX_COMPILER_ID} compiler is not supported."
 )
+
+add_check_for_support(
+   MODULES QtWebEngine QtPdf
+   CONDITION ((LINUX AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
+              (MINGW AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")) AND
+             CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0
+   MESSAGE
+       "GCC build requires version 10.0 or later. Version ${CMAKE_CXX_COMPILER_VERSION} is not supported."
+)
+
 if(WIN32)
     if(MSVC)
         if(MSVC_TOOLSET_VERSION EQUAL 142) # VS 2019 (16.0)
diff --git a/src/core/doc/src/qtwebengine-platform-notes.qdoc b/src/core/doc/src/qtwebengine-platform-notes.qdoc
index 33bac101a08..dc71931130e 100644
--- a/src/core/doc/src/qtwebengine-platform-notes.qdoc
+++ b/src/core/doc/src/qtwebengine-platform-notes.qdoc
@@ -57,7 +57,7 @@
 
     \section2 Linux
 
-    On Linux, Clang or GCC version 9 or later is required.
+    On Linux, Clang or GCC version 10 or later is required.
 
     \QWE requires \c pkg-config to detect most of its dependencies. The
     following \c pkg-config files are required:

From ad845ce65b5296e4fbe5428215d4d27c8a1be154 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Fri, 8 Nov 2024 14:25:24 +0100
Subject: [PATCH 200/356] Fixup: [gcc] Update minimum version for Qt WebEngine
 6.8

Condition was applied to all builds and caused a lot of them to be skipped.

Fixes: QTBUG-130790
Change-Id: Ic081b53295a75ab0817421abe9616e1543b3a34c
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
---
 configure.cmake | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/configure.cmake b/configure.cmake
index df1806d3f4f..7df4c2b797a 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -592,14 +592,15 @@ add_check_for_support(
        "${CMAKE_CXX_COMPILER_ID} compiler is not supported."
 )
 
-add_check_for_support(
-   MODULES QtWebEngine QtPdf
-   CONDITION ((LINUX AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
-              (MINGW AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")) AND
-             CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0
-   MESSAGE
-       "GCC build requires version 10.0 or later. Version ${CMAKE_CXX_COMPILER_VERSION} is not supported."
-)
+if (LINUX OR MINGW)
+    add_check_for_support(
+        MODULES QtWebEngine QtPdf
+        CONDITION NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR
+                  NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.0
+        MESSAGE
+            "GCC build requires version 10.0 or later. Version ${CMAKE_CXX_COMPILER_VERSION} is not supported."
+    )
+endif()
 
 if(WIN32)
     if(MSVC)

From cc37ca08729a40fe927b9c136ad8b80c493e1b8e Mon Sep 17 00:00:00 2001
From: Alexandru Croitor <alexandru.croitor@qt.io>
Date: Tue, 27 Aug 2024 17:37:10 +0200
Subject: [PATCH 201/356] coin: Enable git cloning

Cloning the git sources will:
- allow embedding the git sha1 into the SBOM generated by the build
  system
- ease development process in CI VMs when investigating issues.
- allows tools like 'reuse lint' to identify submodules, to skip
  license checks for 3rd party submodules, otherwise it will error
  out. In qtwebengine case, we need to ignore the chromium submodule.

Task-number: QTBUG-122899
Task-number: QTQAINFRA-6520
Change-Id: If28a4d71d9fb4b9383e867083ef946fc7992c86e
Reviewed-by: Lucie Gerard <lucie.gerard@qt.io>
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit 9228da724ea0d5219d06a4022fe7316b5f26abee)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 coin/module_config.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/coin/module_config.yaml b/coin/module_config.yaml
index f1d69a2778f..9c6e1d003e5 100644
--- a/coin/module_config.yaml
+++ b/coin/module_config.yaml
@@ -1,4 +1,5 @@
 version: 2
+tags: [git]
 accept_configuration:
   condition: property
   property: features

From c4ba60d8e3e3006407ad66961c0e3ea2f0669d0a Mon Sep 17 00:00:00 2001
From: Allan Sandfeld Jensen <allan.jensen@qt.io>
Date: Mon, 14 Oct 2024 10:39:06 +0200
Subject: [PATCH 202/356] Stop warnings about unexpected unsupported
 permissions

Treat NUM as an expected unsupported permission, and do not warn on the
toBlink side as we would already have seen the warning on the other side
first.

Change-Id: I329941fa2e76c17a03ed40f31c52766db6876622
Reviewed-by: Moss Heim <moss.heim@qt.io>
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
(cherry picked from commit 6271cff980ee1b8311dfdb030d398cf671a77c8d)
---
 src/core/permission_manager_qt.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index 33be3e8d789..247c1936fef 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -58,6 +58,7 @@ static QWebEnginePermission::PermissionType toQt(blink::PermissionType type)
     case blink::PermissionType::ACCESSIBILITY_EVENTS:
     case blink::PermissionType::CAMERA_PAN_TILT_ZOOM:
     case blink::PermissionType::WINDOW_MANAGEMENT:
+    case blink::PermissionType::NUM:
         return QWebEnginePermission::PermissionType::Unsupported;
     case blink::PermissionType::MIDI_SYSEX:
     case blink::PermissionType::PROTECTED_MEDIA_IDENTIFIER:
@@ -79,7 +80,6 @@ static QWebEnginePermission::PermissionType toQt(blink::PermissionType type)
     case blink::PermissionType::CAPTURED_SURFACE_CONTROL:
     case blink::PermissionType::SMART_CARD:
     case blink::PermissionType::WEB_PRINTING:
-    case blink::PermissionType::NUM:
         LOG(INFO) << "Unexpected unsupported Blink permission type: " << static_cast<int>(type);
         break;
     }
@@ -107,12 +107,14 @@ static blink::PermissionType toBlink(QWebEnginePermission::PermissionType permis
     case QWebEnginePermission::PermissionType::MouseLock:
         return (blink::PermissionType)ExtraPermissionType::POINTER_LOCK;
     case QWebEnginePermission::PermissionType::MediaAudioVideoCapture:
-    case QWebEnginePermission::PermissionType::Unsupported:
         LOG(INFO) << "Unexpected unsupported WebEngine permission type: " << static_cast<int>(permissionType);
+        Q_FALLTHROUGH();
+    case QWebEnginePermission::PermissionType::Unsupported:
         return blink::PermissionType::NUM;
     }
 
     Q_UNREACHABLE();
+    return blink::PermissionType::NUM;
 }
 
 static QWebEnginePermission::State toQt(blink::mojom::PermissionStatus state)

From 9e6cb74b34c0efc5d5837001dfbf222f02ab8949 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucie=20G=C3=A9rard?= <lucie.gerard@qt.io>
Date: Tue, 1 Oct 2024 12:24:54 +0200
Subject: [PATCH 203/356] Add REUSE.toml files and missing licenses

REUSE.toml files are read by reuse to complement or override the
copyright and licensing information found in file.

The use of REUSE.toml files was introduced in REUSE version 3.1.0a1.
This reuse version is compatible with reuse specification
version 3.2 [1].
With this commit's files,
* The SPDX document generated by reuse spdx conforms to SPDX 2.3,
* The reuse lint command reports that the Qt project is reuse compliant.

In order to be reuse compliant all the licenses referenced in file
or within a REUSE.toml file must be present in the LICENSES
directory at the base of the module.
The missing licenses are added.

[1]: https://reuse.software/spec-3.2/

Task-number: QTBUG-124453
Task-number: QTBUG-125211
Change-Id: Ic8c34b884bae1151f5d912f375bf87378e6e9a3d
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
(cherry picked from commit cf5db2b9242facf4797a7779ae50916326f75d0b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 LICENSES/Apache-2.0.txt                       |  61 ++++
 LICENSES/CC0-1.0.txt                          | 121 +++++++
 LICENSES/LGPL-2.0-or-later.txt                | 324 ++++++++++++++++++
 LICENSES/MIT.txt                              |  11 +
 REUSE.toml                                    | 121 +++++++
 dist/REUSE.toml                               |   8 +
 .../icons/3rdparty/REUSE.toml                 |  15 +
 .../contentmanipulation/REUSE.toml            |   8 +
 .../cookiebrowser/3rdparty/REUSE.toml         |  15 +
 .../resources/3rdparty/REUSE.toml             |  15 +
 .../recipebrowser/assets/3rdparty/REUSE.toml  |  13 +
 .../simplebrowser/data/3rdparty/REUSE.toml    |  15 +
 src/core/ozone/REUSE.toml                     |   7 +
 tests/auto/REUSE.toml                         |  13 +
 14 files changed, 747 insertions(+)
 create mode 100644 LICENSES/Apache-2.0.txt
 create mode 100644 LICENSES/CC0-1.0.txt
 create mode 100644 LICENSES/LGPL-2.0-or-later.txt
 create mode 100644 LICENSES/MIT.txt
 create mode 100644 REUSE.toml
 create mode 100644 dist/REUSE.toml
 create mode 100644 examples/webenginequick/quicknanobrowser/icons/3rdparty/REUSE.toml
 create mode 100644 examples/webenginewidgets/contentmanipulation/REUSE.toml
 create mode 100644 examples/webenginewidgets/cookiebrowser/3rdparty/REUSE.toml
 create mode 100644 examples/webenginewidgets/permissionbrowser/resources/3rdparty/REUSE.toml
 create mode 100644 examples/webenginewidgets/recipebrowser/assets/3rdparty/REUSE.toml
 create mode 100644 examples/webenginewidgets/simplebrowser/data/3rdparty/REUSE.toml
 create mode 100644 src/core/ozone/REUSE.toml
 create mode 100644 tests/auto/REUSE.toml

diff --git a/LICENSES/Apache-2.0.txt b/LICENSES/Apache-2.0.txt
new file mode 100644
index 00000000000..136d9004566
--- /dev/null
+++ b/LICENSES/Apache-2.0.txt
@@ -0,0 +1,61 @@
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+    1. Definitions.
+
+        "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+        "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+        "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+        "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+        "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+        "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+        "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+        "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+        "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+        "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+    2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+    3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+    4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+        (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+        (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+        (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+        (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+        You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+    5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+    6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+    7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+    8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+    9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/LICENSES/CC0-1.0.txt b/LICENSES/CC0-1.0.txt
new file mode 100644
index 00000000000..0e259d42c99
--- /dev/null
+++ b/LICENSES/CC0-1.0.txt
@@ -0,0 +1,121 @@
+Creative Commons Legal Code
+
+CC0 1.0 Universal
+
+    CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+    LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
+    ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
+    INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
+    REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
+    PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+    THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
+    HEREUNDER.
+
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer
+exclusive Copyright and Related Rights (defined below) upon the creator
+and subsequent owner(s) (each and all, an "owner") of an original work of
+authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for
+the purpose of contributing to a commons of creative, cultural and
+scientific works ("Commons") that the public can reliably and without fear
+of later claims of infringement build upon, modify, incorporate in other
+works, reuse and redistribute as freely as possible in any form whatsoever
+and for any purposes, including without limitation commercial purposes.
+These owners may contribute to the Commons to promote the ideal of a free
+culture and the further production of creative, cultural and scientific
+works, or to gain reputation or greater distribution for their Work in
+part through the use and efforts of others.
+
+For these and/or other purposes and motivations, and without any
+expectation of additional consideration or compensation, the person
+associating CC0 with a Work (the "Affirmer"), to the extent that he or she
+is an owner of Copyright and Related Rights in the Work, voluntarily
+elects to apply CC0 to the Work and publicly distribute the Work under its
+terms, with knowledge of his or her Copyright and Related Rights in the
+Work and the meaning and intended legal effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be
+protected by copyright and related or neighboring rights ("Copyright and
+Related Rights"). Copyright and Related Rights include, but are not
+limited to, the following:
+
+  i. the right to reproduce, adapt, distribute, perform, display,
+     communicate, and translate a Work;
+ ii. moral rights retained by the original author(s) and/or performer(s);
+iii. publicity and privacy rights pertaining to a person's image or
+     likeness depicted in a Work;
+ iv. rights protecting against unfair competition in regards to a Work,
+     subject to the limitations in paragraph 4(a), below;
+  v. rights protecting the extraction, dissemination, use and reuse of data
+     in a Work;
+ vi. database rights (such as those arising under Directive 96/9/EC of the
+     European Parliament and of the Council of 11 March 1996 on the legal
+     protection of databases, and under any national implementation
+     thereof, including any amended or successor version of such
+     directive); and
+vii. other similar, equivalent or corresponding rights throughout the
+     world based on applicable law or treaty, and any national
+     implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention
+of, applicable law, Affirmer hereby overtly, fully, permanently,
+irrevocably and unconditionally waives, abandons, and surrenders all of
+Affirmer's Copyright and Related Rights and associated claims and causes
+of action, whether now known or unknown (including existing as well as
+future claims and causes of action), in the Work (i) in all territories
+worldwide, (ii) for the maximum duration provided by applicable law or
+treaty (including future time extensions), (iii) in any current or future
+medium and for any number of copies, and (iv) for any purpose whatsoever,
+including without limitation commercial, advertising or promotional
+purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
+member of the public at large and to the detriment of Affirmer's heirs and
+successors, fully intending that such Waiver shall not be subject to
+revocation, rescission, cancellation, termination, or any other legal or
+equitable action to disrupt the quiet enjoyment of the Work by the public
+as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason
+be judged legally invalid or ineffective under applicable law, then the
+Waiver shall be preserved to the maximum extent permitted taking into
+account Affirmer's express Statement of Purpose. In addition, to the
+extent the Waiver is so judged Affirmer hereby grants to each affected
+person a royalty-free, non transferable, non sublicensable, non exclusive,
+irrevocable and unconditional license to exercise Affirmer's Copyright and
+Related Rights in the Work (i) in all territories worldwide, (ii) for the
+maximum duration provided by applicable law or treaty (including future
+time extensions), (iii) in any current or future medium and for any number
+of copies, and (iv) for any purpose whatsoever, including without
+limitation commercial, advertising or promotional purposes (the
+"License"). The License shall be deemed effective as of the date CC0 was
+applied by Affirmer to the Work. Should any part of the License for any
+reason be judged legally invalid or ineffective under applicable law, such
+partial invalidity or ineffectiveness shall not invalidate the remainder
+of the License, and in such case Affirmer hereby affirms that he or she
+will not (i) exercise any of his or her remaining Copyright and Related
+Rights in the Work or (ii) assert any associated claims and causes of
+action with respect to the Work, in either case contrary to Affirmer's
+express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
+    surrendered, licensed or otherwise affected by this document.
+ b. Affirmer offers the Work as-is and makes no representations or
+    warranties of any kind concerning the Work, express, implied,
+    statutory or otherwise, including without limitation warranties of
+    title, merchantability, fitness for a particular purpose, non
+    infringement, or the absence of latent or other defects, accuracy, or
+    the present or absence of errors, whether or not discoverable, all to
+    the greatest extent permissible under applicable law.
+ c. Affirmer disclaims responsibility for clearing rights of other persons
+    that may apply to the Work or any use thereof, including without
+    limitation any person's Copyright and Related Rights in the Work.
+    Further, Affirmer disclaims responsibility for obtaining any necessary
+    consents, permissions or other rights required for any use of the
+    Work.
+ d. Affirmer understands and acknowledges that Creative Commons is not a
+    party to this document and has no duty or obligation with respect to
+    this CC0 or use of the Work.
diff --git a/LICENSES/LGPL-2.0-or-later.txt b/LICENSES/LGPL-2.0-or-later.txt
new file mode 100644
index 00000000000..7d446668174
--- /dev/null
+++ b/LICENSES/LGPL-2.0-or-later.txt
@@ -0,0 +1,324 @@
+
+
+GNU LIBRARY GENERAL PUBLIC LICENSE
+
+Version 2, June 1991
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+
+Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General
+Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free
+for all its users.
+
+This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and
+to any other libraries whose authors decide to use it. You can use it for your libraries, too.
+
+When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure
+that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive
+source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that
+you know you can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender
+the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if
+you modify it.
+
+For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights
+that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them with the library, after making changes to the library and
+recompiling it. And you must show them these terms so they know their rights.
+
+Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you
+legal permission to copy, distribute and/or modify the library.
+
+Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this
+free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have
+is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing
+free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software.
+To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
+
+Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for
+utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license
+is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in
+the ordinary license.
+
+The reason we have a separate public license for some libraries is that they blur the distinction we usually make between
+modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in
+some sense simply using the library, and is analogous to running a utility program or application program. However, in a
+textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary
+General Public License treats it as such.
+
+Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote
+software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote
+sharing better.
+
+However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free
+status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs
+to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are
+incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as
+regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries.
+
+The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference
+between a "work based on the library" and a "work that uses the library". The former contains code derived from the library,
+while the latter only works together with the library.
+
+Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one.
+
+GNU LIBRARY GENERAL PUBLIC LICENSE
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+    0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other
+    authorized party saying it may be distributed under the terms of this Library General Public License (also called "this
+    License"). Each licensee
+    is addressed as "you".
+
+    A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application
+    programs (which use some of those functions and data) to form executables.
+
+    The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work
+    based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work
+    containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into
+    another language. (Hereinafter, translation is included without limitation in the term "modification".)
+
+    "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete
+    source code means all the source code for all modules it contains, plus any associated interface definition files, plus
+    the scripts used to control compilation and installation of the library.
+
+    Activities other than copying, distribution and modification are not covered by this License; they are outside its scope.
+    The act of running a program using the Library is not restricted, and output from such a program is covered only if its
+    contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether
+    that is true depends on what the Library does and what the program that uses the Library does.
+
+    1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium,
+    provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of
+    warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy
+    of this License along with the Library.
+
+    You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in
+    exchange for a fee.
+
+    2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and
+    copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of
+    these conditions:
+        a) The modified work must itself be a software library.
+        b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any
+        change.
+        c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this
+        License.
+        d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application
+        program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a
+        good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and
+        performs whatever part of its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent
+    of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function
+    must be optional: if the application does not supply it, the square root function must still compute square roots.)
+
+    These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the
+    Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms,
+    do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as
+    part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License,
+    whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who
+    wrote it.
+
+    Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you;
+    rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the
+    Library.
+
+    In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the
+    Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
+
+    3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of
+    the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary
+    GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU
+    General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change
+    in these notices.
+
+    Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License
+    applies to all subsequent copies and derivative works made from that copy.
+
+    This option is useful when you wish to copy part of the code of the Library into a program that is not a library.
+
+    4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable
+    form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding
+    machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily
+    used for software interchange.
+
+    If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access
+    to copy the source code from the same place satisfies the requirement to distribute the source code, even though third
+    parties are not compelled to copy the source along with the object code.
+
+    5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being
+    compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work
+    of the Library, and therefore falls outside the scope of this License.
+
+    However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library
+    (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore
+    covered by this License. Section 6 states terms for distribution of such executables.
+
+    When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the
+    work may be a derivative work of the Library even though the source code is not. Whether this is true is especially
+    significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to
+    be true is not precisely defined by law.
+
+    If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small
+    inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it
+    is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under
+    Section 6.)
+
+    Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of
+    Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with
+    the Library itself.
+
+    6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to
+    produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the
+    terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications.
+
+    You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use
+    are covered by this License. You must supply a copy of this License. If the work during execution displays copyright
+    notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to
+    the copy of this License. Also, you must do one of these things:
+        a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever
+        changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an
+        executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code
+        and/or source code, so that the user can modify the Library and then relink to produce a modified executable
+        containing the modified Library. (It is understood that the user who changes the contents of definitions files in
+        the Library will not necessarily be able to recompile the application to use the modified definitions.)
+        b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials
+        specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution.
+        c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access
+        to copy the above specified materials from the same place.
+        d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy.
+
+    For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed
+    for reproducing the executable from it. However, as a special exception, the source code distributed need not include
+    anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and
+    so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
+
+    It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not
+    normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together
+    in an executable that you distribute.
+
+    7. You may place library facilities that are a work based on the Library side-by-side in a single library together with
+    other library facilities not covered by this License, and distribute such a combined library, provided that the separate
+    distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided
+    that you do these two things:
+        a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library
+        facilities. This must be distributed under the terms of the Sections above.
+        b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and
+        explaining where to find the accompanying uncombined form of the same work.
+
+    8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this
+    License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will
+    automatically terminate your rights under this License. However, parties who have received copies, or rights, from you
+    under this License will not have their licenses terminated so long as such parties remain in full compliance.
+
+    9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission
+    to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this
+    License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your
+    acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library
+    or works based on it.
+
+    10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a
+    license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and
+    conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are
+    not responsible for enforcing compliance by third parties to this License.
+
+    11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to
+    patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the
+    conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as
+    to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence
+    you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution
+    of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy
+    both it and this License would be to refrain entirely from distribution of the Library.
+
+    If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the
+    section is intended to apply, and the section as a whole is intended to apply in other circumstances.
+
+    It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest
+    validity of any such claims; this section has the sole purpose of protecting the integrity of the free software
+    distribution system which is implemented by public license practices. Many people have made generous contributions to
+    the wide range of software distributed through that system in reliance on consistent application of that system; it
+    is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee
+    cannot impose that choice.
+
+    This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
+
+    12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted
+    interfaces, the original copyright holder who places the Library under this License may add an explicit geographical
+    distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus
+    excluded. In such case, this License incorporates the limitation as if written in the body of this License.
+    13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time
+    to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new
+    problems or concerns.
+
+    Each version is given a distinguishing version number. If the Library specifies a version number of this License which
+    applies to it and "any later version", you have the option of following the terms and conditions either of that version
+    or of any later version published by the Free Software Foundation. If the Library does not specify a license version
+    number, you may choose any version ever published by the Free Software Foundation.
+
+    14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible
+    with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation,
+    write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals
+    of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software
+    generally.
+
+    NO WARRANTY
+    15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY
+    APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY
+    "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY
+    IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+    16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY
+    WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,
+    SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT
+    LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
+    THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY
+    OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Libraries
+
+If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free
+software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or,
+alternatively, under the terms of the ordinary General Public License).
+
+To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source
+file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a
+pointer to where the full notice is found.
+
+one line to give the library's name and an idea of what it does.
+Copyright (C) year name of author
+
+This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free
+Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for
+the library, if necessary. Here is a sample; alter the names:
+
+Yoyodyne, Inc., hereby disclaims all copyright interest in
+the library `Frob' (a library for tweaking knobs) written
+by James Random Hacker.
+
+signature of Ty Coon, 1 April 1990
+Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/LICENSES/MIT.txt b/LICENSES/MIT.txt
new file mode 100644
index 00000000000..bc65af3cbd3
--- /dev/null
+++ b/LICENSES/MIT.txt
@@ -0,0 +1,11 @@
+
+
+MIT License
+
+Copyright (c) <year> <copyright holders>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/REUSE.toml b/REUSE.toml
new file mode 100644
index 00000000000..9474f351661
--- /dev/null
+++ b/REUSE.toml
@@ -0,0 +1,121 @@
+version = 1
+
+[[annotations]]
+path = ["src/core/doc/QtWebEngineDoc",
+        "src/core/doc/about_credits.tmpl",
+        "src/core/doc/about_credits_entry.tmpl",
+        "src/pdf/doc/about_credits.tmpl",
+        "src/pdf/doc/about_credits_entry.tmpl",
+        "src/pdf/doc/snippets/qtpdf-build.cmake",
+        "src/process/QtWebEngineProcess.entitlements",
+        "src/process/QtWebEngineProcess.exe.manifest",
+        "src/webenginequick/ui/information.png",
+        "src/webenginequick/ui/question.png",
+        "src/webenginewidgets/plugins/qwebengineview/images/qwebengineview.png"]
+precedence = "closest"
+comment = "module and plugin"
+SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
+SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only"
+
+[[annotations]]
+path = ["tests/auto/widgets/qwebenginepage/resources/*",
+        "tests/auto/widgets/qwebenginescript/resources/*",
+        "tests/auto/widgets/qwebengineview/resources/*",
+        "tests/auto/widgets/qwebengineprofile/resources/*",
+        "tests/auto/widgets/qwebenginehistory/resources/*",
+        "tests/auto/core/certificateerror/resources/*",
+        "tests/auto/core/origins/resources/subdir/*",
+        "tests/auto/widgets/favicon/resources/**",
+        "tests/auto/quick/qquickwebengineview/html/**",
+        "tests/auto/quick/qmltests/resources/*",
+        "tests/auto/core/origins/resources/*",
+        "tests/auto/core/qwebengineclientcertificatestore/resources/*",
+        "tests/auto/core/qwebenginecookiestore/resources/*",
+        "tests/auto/core/qwebengineurlrequestinterceptor/resources/*",
+        "tests/auto/core/webenginedriver/resources/*",
+        "tests/auto/core/qwebengineframe/resources/*",
+        "tests/auto/core/qwebengineurlrequestinterceptor/resources/icons/favicon.png",
+        "tests/auto/quick/qmltests/data/icons/*",
+        "tests/auto/bic/data/*",
+        "tests/auto/httpserver/data/**",
+        "tests/auto/pdfquick/multipageview/data/*",
+        "tests/auto/pdfquick/pdfpageimage/data/*",
+        "tests/auto/quick/qmltests/data/*",
+        "tests/auto/pdf/**",
+        "tests/auto/core/qwebengineglobalsettings/cert/*",
+        "tests/auto/core/qwebengineurlrequestjob/*",
+        "tests/auto/widgets/spellchecking/dict/*",
+        "tests/auto/widgets/spellchecking/resources/index.html",
+        "tests/auto/quick/dialogs/index.html",
+        "tests/auto/quick/inspectorserver/html/basic_page.html",
+        "tests/auto/quick/qmltests/mock-delegates/TestParams/qmldir",
+        "tests/auto/quick/qquickwebenginedefaultsurfaceformat/html/basic_page.html",
+        "tests/auto/quick/qtbug-70248/test.qml",
+        "tests/auto/widgets/defaultsurfaceformat/resources/index.html",
+        "tests/auto/widgets/offscreen/test.html",
+        "tests/auto/widgets/printing/resources/basic_printing_page.html",
+        "tests/auto/widgets/proxypac/proxy.pac",
+        "tests/manual/html/pointer-events.html",
+        "tests/manual/quick/geopermission/geolocation.html",
+        "tests/manual/quick/pdf/test.pdf",
+        "tests/manual/touchmocking/touchpoint.png",
+        "tests/manual/widgets/geolocation/geolocation.html",
+        "tests/manual/widgets/inputmethods/testdata.csv",
+        "tests/manual/widgets/printing/printing_example.html",
+        "tests/manual/widgets/webrtc/index.html",
+        "tests/manual/widgets/webrtc/mediaPicker.ui"]
+precedence = "closest"
+comment = "test"
+SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
+SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GPL-3.0-only"
+
+[[annotations]]
+path = ["**.pro", "**.qrc", "**CMakeLists.txt", ".cmake.conf", "**.yaml", "**.json",
+        "**.cfg", "**BLACKLIST", "**.plist", "**.plist.in", "**BUILD**.in"]
+precedence = "closest"
+comment = "build system"
+SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
+SPDX-License-Identifier = "BSD-3-Clause"
+
+[[annotations]]
+path = [".tag", "**/.gitattributes", "**.gitignore"]
+precedence = "closest"
+comment = "version control system. Licensed as build system"
+SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
+SPDX-License-Identifier = "BSD-3-Clause"
+
+[[annotations]]
+path = ["**/doc/images/**", "examples/**", "tests/manual/examples/**", "**/doc/snippets/**"]
+comment = "this must be after the build system table because example and snippets take precedence over build system"
+precedence = "closest"
+SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
+SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause"
+
+[[annotations]]
+path = ["**.qdocconf", "config_help.txt", ".gitmodules"]
+comment = "documentation"
+precedence = "closest"
+SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
+SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"
+
+[[annotations]]
+path = ["**.toml", "licenseRule.json"]
+comment = "documentation"
+precedence = "override"
+SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
+SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"
+
+[[annotations]]
+path = ["**/qt_attribution.json"]
+comment = "documentation"
+precedence = "override"
+SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
+SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"
+
+[[annotations]]
+path = ["**LICENSE*", "CHROMIUM_VERSION"]
+precedence = "override"
+comment = "License file."
+SPDX-FileCopyrightText = "None"
+SPDX-License-Identifier = "CC0-1.0"
+
diff --git a/dist/REUSE.toml b/dist/REUSE.toml
new file mode 100644
index 00000000000..f14104bf6f4
--- /dev/null
+++ b/dist/REUSE.toml
@@ -0,0 +1,8 @@
+version = 1
+
+[[annotations]]
+path = ["*"]
+precedence = "override"
+comment = "Licensed as documentation."
+SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
+SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"
diff --git a/examples/webenginequick/quicknanobrowser/icons/3rdparty/REUSE.toml b/examples/webenginequick/quicknanobrowser/icons/3rdparty/REUSE.toml
new file mode 100644
index 00000000000..62a59c992ac
--- /dev/null
+++ b/examples/webenginequick/quicknanobrowser/icons/3rdparty/REUSE.toml
@@ -0,0 +1,15 @@
+version = 1
+
+[[annotations]]
+path = "*.png"
+precedence = "closest"
+SPDX-FileCopyrightText = ["Ulisse Perusin <uli.peru@gmail.com>",
+                          "Steven Garrity <sgarrity@silverorange.com>",
+                          "Lapo Calamandrei <calamandrei@gmail.com>",
+                          "Ryan Collier <rcollier@novell.com>",
+                          "Rodney Dawes <dobey@novell.com>",
+                          "Andreas Nilsson <nisses.mail@home.se>",
+                          "Tuomas Kuosmanen <tigert@tigert.com>",
+                          "Garrett LeSage <garrett@novell.com>",
+                          "Jakub Steiner <jimmac@novell.com>"]
+SPDX-License-Identifier = "LicenseRef-Tango-Icons-Public-Domain"
diff --git a/examples/webenginewidgets/contentmanipulation/REUSE.toml b/examples/webenginewidgets/contentmanipulation/REUSE.toml
new file mode 100644
index 00000000000..f648b36f255
--- /dev/null
+++ b/examples/webenginewidgets/contentmanipulation/REUSE.toml
@@ -0,0 +1,8 @@
+version = 1
+
+[[annotations]]
+path = "jquery.min.js"
+comment = "license is not reuse readable."
+precedence = "closest"
+SPDX-FileCopyrightText = "Copyright (c) 2009 John Resig"
+SPDX-License-Identifier = "MIT"
diff --git a/examples/webenginewidgets/cookiebrowser/3rdparty/REUSE.toml b/examples/webenginewidgets/cookiebrowser/3rdparty/REUSE.toml
new file mode 100644
index 00000000000..340d98c0301
--- /dev/null
+++ b/examples/webenginewidgets/cookiebrowser/3rdparty/REUSE.toml
@@ -0,0 +1,15 @@
+version = 1
+
+[[annotations]]
+path = "view-refresh.png"
+precedence = "closest"
+SPDX-FileCopyrightText = ["Ulisse Perusin <uli.peru@gmail.com>",
+                          "Steven Garrity <sgarrity@silverorange.com>",
+                          "Lapo Calamandrei <calamandrei@gmail.com>",
+                          "Ryan Collier <rcollier@novell.com>",
+                          "Rodney Dawes <dobey@novell.com>",
+                          "Andreas Nilsson <nisses.mail@home.se>",
+                          "Tuomas Kuosmanen <tigert@tigert.com>",
+                          "Garrett LeSage <garrett@novell.com>",
+                          "Jakub Steiner <jimmac@novell.com>"]
+SPDX-License-Identifier = "LicenseRef-Tango-Icons-Public-Domain"
diff --git a/examples/webenginewidgets/permissionbrowser/resources/3rdparty/REUSE.toml b/examples/webenginewidgets/permissionbrowser/resources/3rdparty/REUSE.toml
new file mode 100644
index 00000000000..62a59c992ac
--- /dev/null
+++ b/examples/webenginewidgets/permissionbrowser/resources/3rdparty/REUSE.toml
@@ -0,0 +1,15 @@
+version = 1
+
+[[annotations]]
+path = "*.png"
+precedence = "closest"
+SPDX-FileCopyrightText = ["Ulisse Perusin <uli.peru@gmail.com>",
+                          "Steven Garrity <sgarrity@silverorange.com>",
+                          "Lapo Calamandrei <calamandrei@gmail.com>",
+                          "Ryan Collier <rcollier@novell.com>",
+                          "Rodney Dawes <dobey@novell.com>",
+                          "Andreas Nilsson <nisses.mail@home.se>",
+                          "Tuomas Kuosmanen <tigert@tigert.com>",
+                          "Garrett LeSage <garrett@novell.com>",
+                          "Jakub Steiner <jimmac@novell.com>"]
+SPDX-License-Identifier = "LicenseRef-Tango-Icons-Public-Domain"
diff --git a/examples/webenginewidgets/recipebrowser/assets/3rdparty/REUSE.toml b/examples/webenginewidgets/recipebrowser/assets/3rdparty/REUSE.toml
new file mode 100644
index 00000000000..cfddbb75dd1
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/assets/3rdparty/REUSE.toml
@@ -0,0 +1,13 @@
+version = 1
+
+[[annotations]]
+path = "marked.js"
+precedence = "closest"
+SPDX-FileCopyrightText = "Copyright (c) 2011-2018, Christopher Jeffrey"
+SPDX-License-Identifier = "MIT"
+
+[[annotations]]
+path = "markdown.css"
+precedence = "closest"
+SPDX-FileCopyrightText = "Copyright 2011 Kevin Burke Copyright Twitter Inc."
+SPDX-License-Identifier = "Apache-2.0"
diff --git a/examples/webenginewidgets/simplebrowser/data/3rdparty/REUSE.toml b/examples/webenginewidgets/simplebrowser/data/3rdparty/REUSE.toml
new file mode 100644
index 00000000000..62a59c992ac
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/3rdparty/REUSE.toml
@@ -0,0 +1,15 @@
+version = 1
+
+[[annotations]]
+path = "*.png"
+precedence = "closest"
+SPDX-FileCopyrightText = ["Ulisse Perusin <uli.peru@gmail.com>",
+                          "Steven Garrity <sgarrity@silverorange.com>",
+                          "Lapo Calamandrei <calamandrei@gmail.com>",
+                          "Ryan Collier <rcollier@novell.com>",
+                          "Rodney Dawes <dobey@novell.com>",
+                          "Andreas Nilsson <nisses.mail@home.se>",
+                          "Tuomas Kuosmanen <tigert@tigert.com>",
+                          "Garrett LeSage <garrett@novell.com>",
+                          "Jakub Steiner <jimmac@novell.com>"]
+SPDX-License-Identifier = "LicenseRef-Tango-Icons-Public-Domain"
diff --git a/src/core/ozone/REUSE.toml b/src/core/ozone/REUSE.toml
new file mode 100644
index 00000000000..e57f56e4b90
--- /dev/null
+++ b/src/core/ozone/REUSE.toml
@@ -0,0 +1,7 @@
+version = 1
+
+[[annotations]]
+path = ["BUILD.gn", "ozone_extra.gni"]
+precedence = "closest"
+SPDX-FileCopyrightText = "Copyright 2016 The Chromium Authors. All rights reserved."
+SPDX-License-Identifier = "BSD-3-Clause"
diff --git a/tests/auto/REUSE.toml b/tests/auto/REUSE.toml
new file mode 100644
index 00000000000..2a40d95a96e
--- /dev/null
+++ b/tests/auto/REUSE.toml
@@ -0,0 +1,13 @@
+version = 1
+
+[[annotations]]
+path = ["core/qwebengineframe/tst_qwebengineframe.cpp",
+        "core/qwebenginesettings/tst_qwebenginesettings.cpp",
+        "widgets/accessibility/tst_accessibility.cpp",
+        "widgets/qwebenginehistory/tst_qwebenginehistory.cpp",
+        "widgets/qwebenginepage/tst_qwebenginepage.cpp",
+        "widgets/qwebenginescript/tst_qwebenginescript.cpp",
+        "widgets/qwebengineview/tst_qwebengineview.cpp"]
+precedence = "aggregate"
+comment = "the license is not reuse readable"
+SPDX-License-Identifier = "LGPL-2.0-or-later"

From 5f08cba9e4909b40d174fd03b8667ea6f171dae5 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Tue, 12 Nov 2024 15:09:35 +0100
Subject: [PATCH 204/356] Fix various clang compiler warnings

Change-Id: I4c48a6d14df6eeb5b7dba0b82c9812fbc5ff4f39
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 44aa7dc0fef2b25084a2853533357a7e3b9bf5a4)
---
 src/core/accessibility_tree_formatter_qt.cpp     |  6 +-----
 src/core/content_browser_client_qt.cpp           |  2 +-
 src/core/content_client_qt.cpp                   | 13 ++++++++-----
 src/core/renderer/content_renderer_client_qt.cpp |  7 ++++---
 4 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/src/core/accessibility_tree_formatter_qt.cpp b/src/core/accessibility_tree_formatter_qt.cpp
index 3a3b30cb4a6..bea929c6dd1 100644
--- a/src/core/accessibility_tree_formatter_qt.cpp
+++ b/src/core/accessibility_tree_formatter_qt.cpp
@@ -144,12 +144,10 @@ void AccessibilityTreeFormatterQt::AddProperties(const BrowserAccessibility &nod
 
 std::string AccessibilityTreeFormatterQt::ProcessTreeForOutput(const base::Value::Dict &node) const
 {
-    std::string error_value;
     if (auto error_value = node.FindString("error"))
         return *error_value;
 
     std::string line;
-    std::string role_value;
     if (auto role_value = node.FindString("role"))
         WriteAttribute(true, base::StringPrintf("%s", role_value->c_str()), &line);
 
@@ -166,9 +164,7 @@ std::string AccessibilityTreeFormatterQt::ProcessTreeForOutput(const base::Value
     if (auto description_value = node.FindString("description"))
         WriteAttribute(false, base::StringPrintf("description='%s'", description_value->c_str()), &line);
 
-    int id_value;
-    if (auto maybe_id = node.FindInt("id"))
-        id_value = *maybe_id;
+    int id_value = node.FindInt("id").value_or(0);
     WriteAttribute(false, base::StringPrintf("id=%d", id_value), &line);
 
     return line + "\n";
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index 642c534e17b..0634a5a395d 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -184,7 +184,7 @@ bool IsHandledProtocol(base::StringPiece scheme)
         if (scheme == protocol)
             return true;
     }
-    if (const auto cs = url::CustomScheme::FindScheme(scheme))
+    if (url::CustomScheme::FindScheme(scheme))
         return true;
     return false;
 }
diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index b6a0909b01c..5d9cc7b3576 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -342,9 +342,12 @@ void ContentClientQt::AddContentDecryptionModules(std::vector<content::CdmInfo>
 {
     Q_UNUSED(cdm_host_file_paths);
     if (cdms) {
+#if defined(WIDEVINE_CDM_AVAILABLE_NOT_COMPONENT) || BUILDFLAG(ENABLE_LIBRARY_CDMS)
+        media::CdmCapability capability;
+#endif
+
 #if defined(WIDEVINE_CDM_AVAILABLE_NOT_COMPONENT)
         base::FilePath cdm_path;
-        media::CdmCapability capability;
         if (IsWidevineAvailable(&cdm_path, &capability)) {
             const base::Version version;
             cdms->push_back(content::CdmInfo(kWidevineKeySystem, Robustness::kSoftwareSecure, std::move(capability),
@@ -359,10 +362,10 @@ void ContentClientQt::AddContentDecryptionModules(std::vector<content::CdmInfo>
         base::FilePath clear_key_cdm_path = command_line->GetSwitchValuePath(switches::kClearKeyCdmPathForTesting);
         if (!clear_key_cdm_path.empty() && base::PathExists(clear_key_cdm_path)) {
             // Supported codecs are hard-coded in ExternalClearKeyProperties.
-            media::CdmCapability capability(
-                {}, {}, {media::EncryptionScheme::kCenc, media::EncryptionScheme::kCbcs},
-                {media::CdmSessionType::kTemporary,
-                 media::CdmSessionType::kPersistentLicense});
+            capability = media::CdmCapability(
+                    {}, {}, { media::EncryptionScheme::kCenc, media::EncryptionScheme::kCbcs },
+                    { media::CdmSessionType::kTemporary,
+                      media::CdmSessionType::kPersistentLicense });
 
             // Register media::kExternalClearKeyDifferentCdmTypeTestKeySystem first separately.
             // Otherwise, it'll be treated as a sub-key-system of normal
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp
index 0622fc27e13..a7733af772c 100644
--- a/src/core/renderer/content_renderer_client_qt.cpp
+++ b/src/core/renderer/content_renderer_client_qt.cpp
@@ -421,11 +421,12 @@ bool ContentRendererClientQt::OverrideCreatePlugin(content::RenderFrame *render_
 
 #if BUILDFLAG(ENABLE_PLUGINS)
     content::WebPluginInfo info;
-    std::string mime_type;
+    std::string actual_mime_type;
     bool found = false;
 
-    static_cast<content::RenderFrameImpl *>(render_frame)->GetPepperHost()->GetPluginInfo(
-                params.url, params.mime_type.Utf8(), &found, &info, &mime_type);
+    static_cast<content::RenderFrameImpl *>(render_frame)
+            ->GetPepperHost()
+            ->GetPluginInfo(params.url, params.mime_type.Utf8(), &found, &info, &actual_mime_type);
     if (!found) {
         *plugin = LoadablePluginPlaceholderQt::CreateLoadableMissingPlugin(render_frame, params)->plugin();
         return true;

From 8b81859feefedc5c7cee0f8239d3ed22f237592f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Thu, 14 Nov 2024 15:56:25 +0100
Subject: [PATCH 205/356] Update Chromium

Submodule src/3rdparty 6040f729..b942da2a:
  * [Backport] CVE-2024-11116: Inappropriate implementation in Paint
  * [Backport] Dependency for CVE-2024-11116
  * [Backport] CVE-2024-11117: Inappropriate implementation in FileSystem
  * [Backport] Security bug 356098278
  * [Backport] CVE-2024-11110: Inappropriate implementation in Blink
  * [Backport] Security bug 361651894
  * [Backport] CVE-2024-11112: Use after free in Media
  * [Backport] CVE-2024-11114: Inappropriate implementation in Views
  * [Backport] CVE-2024-10827: Use after free in Serial
  * Fix child process startup crash under certain locales
  * Disable DCHECK in frame_info.cc
  * FIXUP: Add conversion of ContiguousContainer iterators to pointer for MSVC

Fixes: QTBUG-131167
Change-Id: I2cbbba8e6bd8a9a9248b9eb52d224c4d80fba48f
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit cad7a523ca70319147cf27c12a5ef6598ffe31b0)
---
 CHROMIUM_VERSION                | 2 +-
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index 9b8609cca24..dbde2f0b30a 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
 Based on Chromium version:                                      122.0.6261.171
-Patched with security patches up to Chromium version:           130.0.6723.92
+Patched with security patches up to Chromium version:           131.0.6778.70
diff --git a/src/3rdparty b/src/3rdparty
index 6040f729684..b942da2a6b8 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit 6040f7296848acf59a45825edd7c2a8806f5ade8
+Subproject commit b942da2a6b80c8a7f0b7b641ba0bb03104302e07
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 1adcd1bb3c2..771894a0f63 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1268,7 +1268,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "130.0.6723.92"; // FIXME: Remember to update
+    return "131.0.6778.70"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From 7c4ae187758b9784754c8d6f7536067b19d5f762 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Mon, 18 Nov 2024 09:53:58 +0000
Subject: [PATCH 206/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I6bf660f7f353ab3de48f4e0f452bf03cb767bee7
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 4a92bd3a3e8..322729dde3c 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 9fb945184d6ef220fcdef4bc4a7b08df020a2bdd
+    ref: 88b82c561c1cc1e78fbd630cb3a827fb7cb51b30
     required: true
   ../qtpositioning:
-    ref: 75f7c7b108e5aa143afbe733a810c8b552c77d8b
+    ref: c9ff0aeccc37df73e2c81a6c2a5cc4823011a5b7
     required: false
   ../qttools:
-    ref: 1d446b0b09cb8cde96c3642391d199850a09aa7a
+    ref: 1639035dfbdaadb225ae814720a3b502bf03bdb2
     required: false
   ../qtwebchannel:
-    ref: 30dacf6896eb0488bf203b72510d2bd69cb772fe
+    ref: 2c2559fe93ccf2683ed72c501c30332c86a99d69
     required: false

From e20bd5347eacf3a21df7c2cbecf374904faa5512 Mon Sep 17 00:00:00 2001
From: Jani Heikkinen <jani.heikkinen@qt.io>
Date: Thu, 14 Nov 2024 09:57:40 +0000
Subject: [PATCH 207/356] Bump version to 6.8.2

Change-Id: I84fa49f649864f67a0689c6d249094a02554ab48
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 .cmake.conf | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.cmake.conf b/.cmake.conf
index dcfb220c1bc..02007225629 100644
--- a/.cmake.conf
+++ b/.cmake.conf
@@ -1,4 +1,4 @@
-set(QT_REPO_MODULE_VERSION "6.8.1")
+set(QT_REPO_MODULE_VERSION "6.8.2")
 set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1")
 set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_WEBENGINE "3.19")
 set(QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_NO_AS_CONST=1")

From 479bdfcca372971c7a83ff0b8ca7210040dc8ec7 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 7 Nov 2024 10:22:55 +0100
Subject: [PATCH 208/356] Reduce verboseness of WebEngineNotification qml auto
 test

It seems like leftover.

Change-Id: I996cc201afe721b3ef584e8b7671cdefcf16720c
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit d960fb3caea95b9e57db03d2f6a2b9894b9039fb)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 tests/auto/quick/qmltests/data/tst_notification.qml | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/tests/auto/quick/qmltests/data/tst_notification.qml b/tests/auto/quick/qmltests/data/tst_notification.qml
index df2bfa94ef7..7ebc628dcf9 100644
--- a/tests/auto/quick/qmltests/data/tst_notification.qml
+++ b/tests/auto/quick/qmltests/data/tst_notification.qml
@@ -17,8 +17,6 @@ TestWebEngineView {
 
     profile.persistentPermissionsPolicy: WebEngineProfile.PersistentPermissionsPolicy.AskEveryTime
 
-    signal consoleMessage(string message)
-
     SignalSpy {
         id: spyRequest
         target: view
@@ -41,7 +39,6 @@ TestWebEngineView {
         when: windowShown
 
         function resolverUrl(html) {
-            console.log(Shared.HttpServer.sharedDataDir())
             return Qt.resolvedUrl(Shared.HttpServer.sharedDataDir() + "/" + html)
         }
 

From 7555d6b4eb40e245af794b95e2b0a1574b5029c3 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Tue, 12 Nov 2024 14:19:34 +0100
Subject: [PATCH 209/356] Use designated initializers for initializing Vulkan
 structures

We tried to avoid designated initializers because they weren't supported
by old MSVC versions. Let's start to use them to avoid
-Wmissing-designated-field-initializers clang compiler warnings.

Change-Id: I857822e008bb36f28f6072ece097e34fc6df8922
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit ce0dfa48c53353c1cde56a7e6c9eb9b8ec4b4a42)
---
 .../native_skia_output_device_opengl.cpp      |  10 +-
 .../native_skia_output_device_vulkan.cpp      | 117 ++++++++++--------
 2 files changed, 72 insertions(+), 55 deletions(-)

diff --git a/src/core/compositor/native_skia_output_device_opengl.cpp b/src/core/compositor/native_skia_output_device_opengl.cpp
index 493050f7f4a..f1ae3651089 100644
--- a/src/core/compositor/native_skia_output_device_opengl.cpp
+++ b/src/core/compositor/native_skia_output_device_opengl.cpp
@@ -326,10 +326,12 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
         VkDeviceMemory importedImageMemory = vkImageInfo.fAlloc.fMemory;
         VkDeviceSize importedImageSize = vkImageInfo.fAlloc.fSize;
 
-        VkMemoryGetFdInfoKHR exportInfo = { VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR };
-        exportInfo.pNext = nullptr;
-        exportInfo.memory = importedImageMemory;
-        exportInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
+        VkMemoryGetFdInfoKHR exportInfo = {
+            .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
+            .pNext = nullptr,
+            .memory = importedImageMemory,
+            .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
+        };
 
         int fd = -1;
         if (vfp->vkGetMemoryFdKHR(vulkanDevice, &exportInfo, &fd) != VK_SUCCESS)
diff --git a/src/core/compositor/native_skia_output_device_vulkan.cpp b/src/core/compositor/native_skia_output_device_vulkan.cpp
index 60ceea00d8e..3aec31dcb56 100644
--- a/src/core/compositor/native_skia_output_device_vulkan.cpp
+++ b/src/core/compositor/native_skia_output_device_vulkan.cpp
@@ -121,14 +121,28 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
     }
 
     VkExternalMemoryImageCreateInfoKHR externalMemoryImageCreateInfo = {
-        VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR
+        .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR,
+        .pNext = nullptr,
+        .handleTypes = 0,
     };
 #if defined(USE_OZONE)
-    VkSubresourceLayout planeLayout = {};
+    base::ScopedFD scopedFd;
+
+    VkSubresourceLayout planeLayout = {
+        .offset = 0,
+        .size = 0,
+        .rowPitch = 0,
+        .arrayPitch = 0,
+        .depthPitch = 0,
+    };
+
     VkImageDrmFormatModifierExplicitCreateInfoEXT modifierInfo = {
-        VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT
+        .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT,
+        .pNext = nullptr,
+        .drmFormatModifier = 0,
+        .drmFormatModifierPlaneCount = 1,
+        .pPlaneLayouts = &planeLayout,
     };
-    base::ScopedFD scopedFd;
 
     if (nativePixmap) {
         gfx::NativePixmapHandle nativePixmapHandle = nativePixmap->ExportHandle();
@@ -136,28 +150,23 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
             qFatal("VULKAN: Multiple planes are not supported.");
 
         planeLayout.offset = nativePixmapHandle.planes[0].offset;
-        planeLayout.size = 0;
         planeLayout.rowPitch = nativePixmapHandle.planes[0].stride;
-        planeLayout.arrayPitch = 0;
-        planeLayout.depthPitch = 0;
-
         modifierInfo.drmFormatModifier = nativePixmapHandle.modifier;
-        modifierInfo.drmFormatModifierPlaneCount = 1;
-        modifierInfo.pPlaneLayouts = &planeLayout;
 
         externalMemoryImageCreateInfo.pNext = &modifierInfo;
         externalMemoryImageCreateInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
 
         scopedFd = std::move(nativePixmapHandle.planes[0].fd);
     } else {
-        externalMemoryImageCreateInfo.pNext = nullptr;
         externalMemoryImageCreateInfo.handleTypes =
                 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
 
-        VkMemoryGetFdInfoKHR exportInfo = { VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR };
-        exportInfo.pNext = nullptr;
-        exportInfo.memory = vkImageInfo.fAlloc.fMemory;
-        exportInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
+        VkMemoryGetFdInfoKHR exportInfo = {
+            .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
+            .pNext = nullptr,
+            .memory = vkImageInfo.fAlloc.fMemory,
+            .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
+        };
 
         gpu::VulkanFunctionPointers *vfp = gpu::GetVulkanFunctionPointers();
         gpu::VulkanDeviceQueue *vulkanDeviceQueue =
@@ -174,7 +183,6 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
     if (!scopedFd.is_valid())
         qFatal("VULKAN: Unable to extract file descriptor.");
 #elif defined(Q_OS_WIN)
-    externalMemoryImageCreateInfo.pNext = nullptr;
     externalMemoryImageCreateInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT;
 
     Q_ASSERT(overlayImage->type() == gl::DCLayerOverlayType::kNV12Texture);
@@ -201,23 +209,27 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
             | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT
             | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
 
-    VkImageCreateInfo importedImageCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
-    importedImageCreateInfo.pNext = &externalMemoryImageCreateInfo;
-    importedImageCreateInfo.flags = 0;
-    importedImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
-    importedImageCreateInfo.format = gpu::ToVkFormatSinglePlanar(m_frontBuffer->sharedImageFormat());
-    importedImageCreateInfo.extent.width = static_cast<uint32_t>(size().width());
-    importedImageCreateInfo.extent.height = static_cast<uint32_t>(size().height());
-    importedImageCreateInfo.extent.depth = 1;
-    importedImageCreateInfo.mipLevels = 1;
-    importedImageCreateInfo.arrayLayers = 1;
-    importedImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
-    importedImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
-    importedImageCreateInfo.usage = kUsage;
-    importedImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
-    importedImageCreateInfo.queueFamilyIndexCount = 0;
-    importedImageCreateInfo.pQueueFamilyIndices = nullptr;
-    importedImageCreateInfo.initialLayout = imageLayout;
+    VkImageCreateInfo importedImageCreateInfo = {
+        .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+        .pNext = &externalMemoryImageCreateInfo,
+        .flags = 0,
+        .imageType = VK_IMAGE_TYPE_2D,
+        .format = gpu::ToVkFormatSinglePlanar(m_frontBuffer->sharedImageFormat()),
+        .extent = {
+            .width = static_cast<uint32_t>(size().width()),
+            .height = static_cast<uint32_t>(size().height()),
+            .depth = 1,
+        },
+        .mipLevels = 1,
+        .arrayLayers = 1,
+        .samples = VK_SAMPLE_COUNT_1_BIT,
+        .tiling = VK_IMAGE_TILING_OPTIMAL,
+        .usage = kUsage,
+        .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
+        .queueFamilyIndexCount = 0,
+        .pQueueFamilyIndices = nullptr,
+        .initialLayout = imageLayout,
+    };
 
 #if defined(USE_OZONE)
     if (nativePixmap)
@@ -235,31 +247,23 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
 
 #if defined(USE_OZONE)
     VkImportMemoryFdInfoKHR importMemoryHandleInfo = {
-        VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR
+        .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
+        .pNext = nullptr,
+        .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
+        .fd = scopedFd.release(),
     };
-    importMemoryHandleInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
-    importMemoryHandleInfo.fd = scopedFd.release();
 
     if (nativePixmap)
         importMemoryHandleInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
 #elif defined(Q_OS_WIN)
     VkImportMemoryWin32HandleInfoKHR importMemoryHandleInfo = {
-        VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR
+        .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
+        .pNext = nullptr,
+        .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT,
+        .handle = sharedHandle,
     };
-    importMemoryHandleInfo.pNext = nullptr;
-    importMemoryHandleInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT;
-    importMemoryHandleInfo.handle = sharedHandle;
 #endif
 
-    VkMemoryDedicatedAllocateInfoKHR dedicatedMemoryInfo = {
-        VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR
-    };
-    dedicatedMemoryInfo.pNext = &importMemoryHandleInfo;
-    dedicatedMemoryInfo.image = importedImage;
-
-    VkMemoryAllocateInfo memoryAllocateInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
-    memoryAllocateInfo.pNext = &dedicatedMemoryInfo;
-
     VkMemoryRequirements requirements;
     df->vkGetImageMemoryRequirements(qtVulkanDevice, importedImage, &requirements);
     if (!requirements.memoryTypeBits)
@@ -282,8 +286,19 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
     if (memoryTypeIndex > kMaxIndex)
         qFatal("VULKAN: Cannot find valid memory type index.");
 
-    memoryAllocateInfo.allocationSize = requirements.size;
-    memoryAllocateInfo.memoryTypeIndex = memoryTypeIndex;
+    VkMemoryDedicatedAllocateInfoKHR dedicatedMemoryInfo = {
+        .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
+        .pNext = &importMemoryHandleInfo,
+        .image = importedImage,
+        .buffer = VK_NULL_HANDLE,
+    };
+
+    VkMemoryAllocateInfo memoryAllocateInfo = {
+        .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
+        .pNext = &dedicatedMemoryInfo,
+        .allocationSize = requirements.size,
+        .memoryTypeIndex = memoryTypeIndex,
+    };
 
     VkDeviceMemory importedImageMemory = VK_NULL_HANDLE;
     result = df->vkAllocateMemory(qtVulkanDevice, &memoryAllocateInfo, nullptr /* pAllocator */,

From e3e6bf6b050dd8ce3a17f546412aaf7760ad6369 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Wed, 20 Nov 2024 08:55:50 +0000
Subject: [PATCH 210/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Ia01d687122e049dfc3acd58b36b4077d554a0d22
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 322729dde3c..a2182daaced 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 88b82c561c1cc1e78fbd630cb3a827fb7cb51b30
+    ref: eba5ac070a1a35bf7acfef875f526970981d8692
     required: true
   ../qtpositioning:
-    ref: c9ff0aeccc37df73e2c81a6c2a5cc4823011a5b7
+    ref: 8bd4a48e3e1814239dd575e4752045dd9ebe7675
     required: false
   ../qttools:
-    ref: 1639035dfbdaadb225ae814720a3b502bf03bdb2
+    ref: 0cd8dda6775554b57d71c4cc905c1f36bde485f9
     required: false
   ../qtwebchannel:
-    ref: 2c2559fe93ccf2683ed72c501c30332c86a99d69
+    ref: 1a698614e29ea98166331fefd9d2d653ed63c5fe
     required: false

From d61cfcd9984e1a9c43e14ea2f5668c32815b2ead Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Wed, 20 Nov 2024 12:54:34 +0100
Subject: [PATCH 211/356] Update Chromium

Submodule src/3rdparty b942da2a..a7fd4fa2:
  * [Backport] Security bug 378541479

Fixes: QTBUG-131399
Change-Id: I3e50167df368d906a93ff3e0ab5cb254b8310e17
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit 672cd910ac6070ec11d7a0643d171aae0e894405)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/3rdparty | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/3rdparty b/src/3rdparty
index b942da2a6b8..a7fd4fa29e0 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit b942da2a6b80c8a7f0b7b641ba0bb03104302e07
+Subproject commit a7fd4fa29e0bd7cc44aa1c9dd3cf63b1144d1c74

From d661a4c7eddd7f2539d7a22aa4f55175c3f15303 Mon Sep 17 00:00:00 2001
From: Anu Aliyas <anu.aliyas@qt.io>
Date: Fri, 15 Nov 2024 11:01:06 +0100
Subject: [PATCH 212/356] Lazy initialization for offTheRecord setting
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

As per the current design when switching from profile from OTR to
non-OTR requires valid storage name. If it is not there, then QtWebEngine display a warning message and and don't switch to disk based behavior for qml. This impose the restriction on qml initialization order, for non-OTR profile, the initialization should be of the order given below
WebEngineProfile {
    offTheRecord: false
    storgaeName: 'Test'
}
Otherwise it won't switch to non-OTR profile. For example a setting like
WebEngineProfile {
        StorageName: 'Test'
        offTheRecord: false
}
won’t create a non-OTR profile. Though from an end user perspective
these two initialization are identical, the order of initialization is
different and due to which these two settings yield different profiles. Added a single shot signal handler on the offTheRecord setter to handle such cases, and it will switch the profile to non-OTR mode only when the storage name is set.

Amends 5f42c1b7877b0c74d939af0f04d09a23482bc74a

Fixes: QTBUG-131397
Change-Id: I1c1c21808cb49dfa3ba4340b000242a0f54e59e5
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 3477d952575a8ad8a8ca70c04a7cd3aa5d7d5f81)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 0123553c41c1ae896d2a99ee95e4adc11f83ed49)
---
 .../api/qquickwebengineprofile.cpp            | 12 ++++-
 .../quick/qmltests/data/tst_basicProfiles.qml | 46 +++++++++++++++++++
 2 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/src/webenginequick/api/qquickwebengineprofile.cpp b/src/webenginequick/api/qquickwebengineprofile.cpp
index 4654fdb84e6..eb6a3199595 100644
--- a/src/webenginequick/api/qquickwebengineprofile.cpp
+++ b/src/webenginequick/api/qquickwebengineprofile.cpp
@@ -518,7 +518,17 @@ void QQuickWebEngineProfile::setOffTheRecord(bool offTheRecord)
 
     if (!offTheRecord && d->profileAdapter()->storageName().isEmpty()) {
         qWarning("Storage name is empty. Cannot change profile from off-the-record "
-                 "to disk-based behavior as it requires a proper storage name");
+                 "to disk-based behavior until a proper storage name is set");
+        // Wait for the profile storage name is set
+        QObject::connect(
+                this, &QQuickWebEngineProfile::storageNameChanged, this,
+                [this]() {
+                    if (!storageName().isEmpty()) {
+                        qWarning("Switching to disk-based behavior");
+                        this->setOffTheRecord(false);
+                    }
+                },
+                Qt::SingleShotConnection);
         return;
     }
 
diff --git a/tests/auto/quick/qmltests/data/tst_basicProfiles.qml b/tests/auto/quick/qmltests/data/tst_basicProfiles.qml
index 6fcbb08ff8f..23c94428860 100644
--- a/tests/auto/quick/qmltests/data/tst_basicProfiles.qml
+++ b/tests/auto/quick/qmltests/data/tst_basicProfiles.qml
@@ -16,6 +16,7 @@ Item {
     property string downloadLocation: getPath(getPath(StandardPaths.writableLocation(StandardPaths.DownloadLocation).toString(), 3))
 
     TestCase {
+        id: basicProfileTest
         name: "BasicProfiles"
 
         function test_defaultProfile() {
@@ -79,5 +80,50 @@ Item {
             compare(p.httpCacheMaximumSize, 0)
             compare(p.persistentCookiesPolicy, WebEngineProfile.AllowPersistentCookies)
         }
+
+        function test_nonOtrProfileInitializationOrderCheck_data() {
+            return [
+                   { tag: "normal", isReverseOrder: false },
+                   { tag: "reverse", isReverseOrder: true },
+            ];
+        }
+
+        function test_nonOtrProfileInitializationOrderCheck(row) {
+           var isReverseOrder = row.isReverseOrder
+
+            var profileSetupQml = "";
+            if (row.isReverseOrder) {
+                profileSetupQml = "import QtWebEngine\n
+                                   WebEngineProfile {\n
+                                        storageName: 'ReverseOrder'\n
+                                        offTheRecord: false\n
+                                   }"
+            } else {
+                profileSetupQml = "import QtWebEngine\n
+                                   WebEngineProfile {\n
+                                        offTheRecord: false\n
+                                        storageName: 'NormalOrder'\n
+                                   }"
+            }
+
+            var p = Qt.createQmlObject(profileSetupQml, basicProfileTest);
+
+            compare(p.storageName, isReverseOrder ? 'ReverseOrder' : 'NormalOrder')
+            verify(!p.offTheRecord)
+
+            compare(getPath(p.downloadPath), downloadLocation)
+            compare(p.httpAcceptLanguage, '')
+            verify(p.httpUserAgent !== '')
+            compare(p.spellCheckEnabled, false)
+            compare(p.spellCheckLanguages, [])
+
+            compare(p.userScripts.collection, [])
+            compare(getPath(p.cachePath), cacheLocation + '/QtWebEngine/' + p.storageName)
+            compare(getPath(p.persistentStoragePath), appDataLocation + '/QtWebEngine/' + p.storageName)
+
+            compare(p.httpCacheType, WebEngineProfile.DiskHttpCache)
+            compare(p.httpCacheMaximumSize, 0)
+            compare(p.persistentCookiesPolicy, WebEngineProfile.AllowPersistentCookies)
+        }
     }
 }

From a073935b30e253d8f88956c239ba6a79f5843f6e Mon Sep 17 00:00:00 2001
From: Vladimir Belyavsky <belyavskyv@gmail.com>
Date: Mon, 23 Sep 2024 11:55:46 +0300
Subject: [PATCH 213/356] NativeSkiaOutputDevice: fix crash on BeginPaint()
 under some circumstances

Gracefully handle the case when SkiaGaneshImageRepresentation::BeginScopedWriteAccess()
returns nullptr for any reason. There are several conditions in
the Chromium code when nullptr can be returned, so we must not
crash on this in any case. Now we'll just print Qt warning instead
of crashing.

Task-number: QTBUG-129153
Change-Id: Ib61520a09c7c445128f4dc2ae08272d1a68ddda3
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
(cherry picked from commit fed0ecfc3b3d4817b4303baac32ca02bbf7e4db2)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/compositor/native_skia_output_device.cpp | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/core/compositor/native_skia_output_device.cpp b/src/core/compositor/native_skia_output_device.cpp
index 2f0115353f9..2f728f5e616 100644
--- a/src/core/compositor/native_skia_output_device.cpp
+++ b/src/core/compositor/native_skia_output_device.cpp
@@ -123,6 +123,9 @@ SkSurface *NativeSkiaOutputDevice::BeginPaint(std::vector<GrBackendSemaphore> *e
         }
     }
     auto surface = m_backBuffer->beginWriteSkia();
+    if (!surface)
+        return nullptr;
+
     *end_semaphores = m_backBuffer->takeEndWriteSkiaSemaphores();
     return surface;
 }
@@ -274,7 +277,10 @@ SkSurface *NativeSkiaOutputDevice::Buffer::beginWriteSkia()
     m_scopedSkiaWriteAccess = m_skiaRepresentation->BeginScopedWriteAccess(
             m_shape.sampleCount, surface_props, &beginSemaphores, &m_endSemaphores,
             gpu::SharedImageRepresentation::AllowUnclearedAccess::kYes);
-    DCHECK(m_scopedSkiaWriteAccess);
+    if (!m_scopedSkiaWriteAccess) {
+        qWarning("SKIA: Failed to begin write access.");
+        return nullptr;
+    }
     if (!beginSemaphores.empty()) {
         m_scopedSkiaWriteAccess->surface()->wait(beginSemaphores.size(), beginSemaphores.data(),
                                                  /*deleteSemaphoresAfterWait=*/false);

From b8b25bc19394177cd5ca55eb519e52bde440ca53 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 21 Nov 2024 10:32:03 +0100
Subject: [PATCH 214/356] Disable building Vulkan support on macOS

Vulkan support is disabled in Qt by default unless VULKAN_SDK
environment is set. QtWebEngine does not support molten-vk so disable
Vulkan even if Qt is configured with it.

Fixes: QTBUG-131342
Change-Id: Icfc94fcab233d2072f028b36dfca8aa00399c12b
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit 56d5ecc003a4b77b13a088ff888cea1b43335e7f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/api/configure.cmake | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/core/api/configure.cmake b/src/core/api/configure.cmake
index 47d72767180..9557e2eb1e6 100644
--- a/src/core/api/configure.cmake
+++ b/src/core/api/configure.cmake
@@ -160,6 +160,7 @@ qt_feature("webengine-vulkan" PRIVATE
     LABEL "Vulkan support"
     PURPOSE "Enables support for Vulkan rendering"
     CONDITION QT_FEATURE_vulkan
+    DISABLE MACOS
 )
 qt_feature("webengine-vaapi" PRIVATE
     SECTION "WebEngine"

From 08b3a4086ae970183cce50d1ae49dd340bd97fc7 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Mon, 25 Nov 2024 07:19:11 +0000
Subject: [PATCH 215/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Ib70be66b66c1b0058b77e899ef7cf397a467f88b
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index a2182daaced..0e710d10874 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: eba5ac070a1a35bf7acfef875f526970981d8692
+    ref: 8aee3140a329feb85afcc5eed5b50817c8c20bfd
     required: true
   ../qtpositioning:
-    ref: 8bd4a48e3e1814239dd575e4752045dd9ebe7675
+    ref: 16280581f96ce7e5dd6ed1a7eb0d8a7a214458e3
     required: false
   ../qttools:
-    ref: 0cd8dda6775554b57d71c4cc905c1f36bde485f9
+    ref: 5005193da801151e813e5ef252a09067ac9bb7ac
     required: false
   ../qtwebchannel:
-    ref: 1a698614e29ea98166331fefd9d2d653ed63c5fe
+    ref: e2369232b32e7a3d82b4f95ff8e13b498d84b605
     required: false

From a160ee920f5e37e6c86f7631e2a1c299c7eff2eb Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Wed, 27 Nov 2024 09:39:13 +0000
Subject: [PATCH 216/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Ic1552b0b68e50585a16167f30f8205b22b7dcf10
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 0e710d10874..78b882d8a4f 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 8aee3140a329feb85afcc5eed5b50817c8c20bfd
+    ref: b0e84f58e62b3d3f708bc4ede495c3ba054b4f48
     required: true
   ../qtpositioning:
-    ref: 16280581f96ce7e5dd6ed1a7eb0d8a7a214458e3
+    ref: b91194679c7a5e2ce9bde52b3df00a93bce09911
     required: false
   ../qttools:
-    ref: 5005193da801151e813e5ef252a09067ac9bb7ac
+    ref: fed01a3f28459de21f00734e267bcbbe2b3df966
     required: false
   ../qtwebchannel:
-    ref: e2369232b32e7a3d82b4f95ff8e13b498d84b605
+    ref: 7431b98939b163cb75ed3cb4f56f696fc39cf7ad
     required: false

From 8480e294fba3cc622d823188a432d5e0588b3537 Mon Sep 17 00:00:00 2001
From: Vladimir Belyavsky <belyavskyv@gmail.com>
Date: Tue, 26 Nov 2024 17:01:31 +0300
Subject: [PATCH 217/356] NativeSkiaOutputDeviceDirect3D11: don't crash on null
 device

It's not yet clear how this may happen, but we see that under
some circumstances QSGRendererInterface may return null device
resource for a window. So, let's handle this situation to avoid
crashing on nullptr dereferencing.

Task-number: QTBUG-131607
Change-Id: I3852c3c0864168515887140e36f551b4cdf059a4
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
(cherry picked from commit b8a9c4b813a2bb251ffb1b24ea4eff116ae37ece)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 .../compositor/native_skia_output_device_direct3d11.cpp     | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/core/compositor/native_skia_output_device_direct3d11.cpp b/src/core/compositor/native_skia_output_device_direct3d11.cpp
index 2f9d1dffcc2..c9e4b22c2c7 100644
--- a/src/core/compositor/native_skia_output_device_direct3d11.cpp
+++ b/src/core/compositor/native_skia_output_device_direct3d11.cpp
@@ -64,7 +64,11 @@ QSGTexture *NativeSkiaOutputDeviceDirect3D11::texture(QQuickWindow *win, uint32_
     QSGRendererInterface *ri = win->rendererInterface();
     ID3D11Device *device = static_cast<ID3D11Device *>(
             ri->getResource(win, QSGRendererInterface::DeviceResource));
-    Q_ASSERT(device);
+    if (!device) {
+        qWarning("D3D: No D3D device.");
+        ::CloseHandle(sharedHandle);
+        return nullptr;
+    }
 
     Microsoft::WRL::ComPtr<ID3D11Device1> device1;
     hr = device->QueryInterface(IID_PPV_ARGS(&device1));

From c18c9075be2c823088a4a3a068f28179cf1c5efb Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Fri, 29 Nov 2024 15:13:24 +0100
Subject: [PATCH 218/356] Force to release compositor resources when
 reparenting view

The connected QQuickWindow signal handlers are not expected to be
triggered before disconnecting them so force to do the clean-up.

Fixes: QTBUG-129153
Change-Id: I4c996918cff4046602c1ec2b1b401d7f26683264
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit 8e608e7a5647ac3be489bd913ad84c5a1dd6521d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/compositor/native_skia_output_device.cpp |  1 +
 .../render_widget_host_view_qt_delegate_item.cpp  | 15 ++++++++++++---
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/src/core/compositor/native_skia_output_device.cpp b/src/core/compositor/native_skia_output_device.cpp
index 2f728f5e616..fbe60277822 100644
--- a/src/core/compositor/native_skia_output_device.cpp
+++ b/src/core/compositor/native_skia_output_device.cpp
@@ -266,6 +266,7 @@ bool NativeSkiaOutputDevice::Buffer::initialize()
 SkSurface *NativeSkiaOutputDevice::Buffer::beginWriteSkia()
 {
     DCHECK(!m_scopedSkiaWriteAccess);
+    DCHECK(!m_scopedOverlayReadAccess);
     DCHECK(!m_presentCount);
     DCHECK(m_endSemaphores.empty());
 
diff --git a/src/core/render_widget_host_view_qt_delegate_item.cpp b/src/core/render_widget_host_view_qt_delegate_item.cpp
index 17a5c657518..6ece45f9bb2 100644
--- a/src/core/render_widget_host_view_qt_delegate_item.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_item.cpp
@@ -320,9 +320,18 @@ void RenderWidgetHostViewQtDelegateItem::itemChange(ItemChange change, const Ite
 {
     QQuickItem::itemChange(change, value);
     if (change == QQuickItem::ItemSceneChange) {
-        for (const QMetaObject::Connection &c : std::as_const(m_windowConnections))
-            disconnect(c);
-        m_windowConnections.clear();
+        if (!m_windowConnections.isEmpty()) {
+            for (const QMetaObject::Connection &c : std::as_const(m_windowConnections))
+                disconnect(c);
+            m_windowConnections.clear();
+
+            auto comp = compositor();
+            if (comp && comp->type() == Compositor::Type::Native) {
+                comp->releaseTexture();
+                comp->releaseResources();
+            }
+        }
+
         if (value.window) {
             m_windowConnections.append(connect(value.window, &QQuickWindow::beforeRendering,
                                                this, &RenderWidgetHostViewQtDelegateItem::onBeforeRendering, Qt::DirectConnection));

From 45e9cb61d96dc5fda1e783bcb3b07d7a9e207692 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Tue, 3 Dec 2024 20:31:22 +0000
Subject: [PATCH 219/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Iab5e45a85d61571c9cda4e599512311ee3d7f1dd
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 78b882d8a4f..11fed2d41c4 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: b0e84f58e62b3d3f708bc4ede495c3ba054b4f48
+    ref: 0011dad7f1f4f0945ae17876146619719b723e4d
     required: true
   ../qtpositioning:
-    ref: b91194679c7a5e2ce9bde52b3df00a93bce09911
+    ref: e2012e7529c83953e64e9dbee0cbcb2423960bc3
     required: false
   ../qttools:
-    ref: fed01a3f28459de21f00734e267bcbbe2b3df966
+    ref: 0d6b5c5fe5aa635d59c923c93377da1cd03f3e88
     required: false
   ../qtwebchannel:
-    ref: 7431b98939b163cb75ed3cb4f56f696fc39cf7ad
+    ref: 1449463a3c956468309e53b2924da13d78b9e9dc
     required: false

From a7cce88f2f0f70991f9c4cb6c9967198172d1837 Mon Sep 17 00:00:00 2001
From: Allan Sandfeld Jensen <allan.jensen@qt.io>
Date: Fri, 22 Nov 2024 10:00:26 +0100
Subject: [PATCH 220/356] Fix script execution when a render frame swaps hosts

This change fixes an issue where navigating between pages in a way
that triggers a RenderFrameHost swap would stop script execution
for the DocumentReady and Deferred injection points.

Fixed by adding scripts on RenderFrameHost changes after we have
removed scripts from the old host. This restores an old behavior of
double addition which the already handle later.

Fixes: QTBUG-131156
Change-Id: I8b7bb2d456224dce7ccc405bf2f68f103d3d0332
Reviewed-by: Szabolcs David <davidsz@inf.u-szeged.hu>
(cherry picked from commit 6c8fe2667ae79cb4efc092ca73e85849a84aeaf2)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 .../user_resource_controller_host.cpp         | 11 ++-
 .../web_channel_ipc_transport_host.cpp        | 10 +++
 .../web_channel_ipc_transport_host.h          |  1 +
 .../qwebenginescript/tst_qwebenginescript.cpp | 76 +++++++++++++++++++
 4 files changed, 95 insertions(+), 3 deletions(-)

diff --git a/src/core/renderer_host/user_resource_controller_host.cpp b/src/core/renderer_host/user_resource_controller_host.cpp
index f2a00fc72d3..1a6b9e935fa 100644
--- a/src/core/renderer_host/user_resource_controller_host.cpp
+++ b/src/core/renderer_host/user_resource_controller_host.cpp
@@ -42,10 +42,9 @@ UserResourceControllerHost::WebContentsObserverHelper::WebContentsObserverHelper
 
 void UserResourceControllerHost::WebContentsObserverHelper::RenderFrameCreated(content::RenderFrameHost *renderFrameHost)
 {
-    content::WebContents *contents = web_contents();
     auto &remote = m_controllerHost->GetUserResourceControllerRenderFrame(renderFrameHost);
-    const QList<UserScript> scripts = m_controllerHost->m_perContentsScripts.value(contents);
-    for (const UserScript &script : scripts)
+    const auto scripts = m_controllerHost->m_perContentsScripts.constFind(web_contents());
+    for (const UserScript &script : *scripts)
         remote->AddScript(script.data());
 }
 
@@ -56,6 +55,12 @@ void UserResourceControllerHost::WebContentsObserverHelper::RenderFrameHostChang
         auto &remote = m_controllerHost->GetUserResourceControllerRenderFrame(oldHost);
         remote->ClearScripts();
     }
+    if (newHost) {
+        auto &remote = m_controllerHost->GetUserResourceControllerRenderFrame(newHost);
+        const auto scripts = m_controllerHost->m_perContentsScripts.constFind(web_contents());
+        for (const UserScript &script : *scripts)
+            remote->AddScript(script.data());
+    }
 }
 
 void UserResourceControllerHost::WebContentsObserverHelper::RenderFrameDeleted(
diff --git a/src/core/renderer_host/web_channel_ipc_transport_host.cpp b/src/core/renderer_host/web_channel_ipc_transport_host.cpp
index 0824ed56d9d..613ca9dc044 100644
--- a/src/core/renderer_host/web_channel_ipc_transport_host.cpp
+++ b/src/core/renderer_host/web_channel_ipc_transport_host.cpp
@@ -107,6 +107,16 @@ void WebChannelIPCTransportHost::RenderFrameCreated(content::RenderFrameHost *fr
     setWorldId(frame, m_worldId);
 }
 
+void WebChannelIPCTransportHost::RenderFrameHostChanged(content::RenderFrameHost *oldHost, content::RenderFrameHost *newHost)
+{
+    if (oldHost) {
+        if (oldHost->IsRenderFrameLive())
+            GetWebChannelIPCTransportRemote(oldHost)->ResetWorldId();
+    }
+    if (newHost) // this might set it again, but that is harmless
+        setWorldId(newHost, m_worldId);
+}
+
 void WebChannelIPCTransportHost::RenderFrameDeleted(content::RenderFrameHost *rfh)
 {
     m_renderFrames.erase(rfh);
diff --git a/src/core/renderer_host/web_channel_ipc_transport_host.h b/src/core/renderer_host/web_channel_ipc_transport_host.h
index 9e003c222e7..16ff5178933 100644
--- a/src/core/renderer_host/web_channel_ipc_transport_host.h
+++ b/src/core/renderer_host/web_channel_ipc_transport_host.h
@@ -45,6 +45,7 @@ class WebChannelIPCTransportHost
 
     // WebContentsObserver
     void RenderFrameCreated(content::RenderFrameHost *frame) override;
+    void RenderFrameHostChanged(content::RenderFrameHost *oldHost, content::RenderFrameHost *newHost) override;
     void RenderFrameDeleted(content::RenderFrameHost *render_frame_host) override;
 
     // qtwebchannel::mojom::WebChannelTransportHost
diff --git a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
index 9ba13589f2a..1a4ee9c4b4b 100644
--- a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
+++ b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
@@ -69,6 +69,7 @@ private Q_SLOTS:
     void webChannelResettingAndUnsetting();
     void webChannelWithExistingQtObject();
     void navigation();
+    void navigation2();
     void webChannelWithBadString();
     void webChannelWithJavaScriptDisabled();
 #endif
@@ -577,6 +578,81 @@ void tst_QWebEngineScript::navigation()
     QCOMPARE(testObject.text(), url1);
 }
 
+void tst_QWebEngineScript::navigation2()
+{
+    QWebEngineProfile profile("navigation2");
+    QWebEnginePage page(&profile, nullptr);
+    QWebChannel channel;
+    page.setWebChannel(&channel);
+    QWebEngineScript s1;
+    s1.setInjectionPoint(QWebEngineScript::DocumentCreation);
+    // Check webchannel is installed before DocumentCreation scripts are run
+    // onload shouldn't have run, and neither should wasready
+    s1.setWorldId(QWebEngineScript::MainWorld);
+    s1.setSourceCode("document.passCreation = 0;" \
+                     "if (typeof qt !== undefined) document.passCreation++;" \
+                     "if (document.onloadran) document.passCreation++;" \
+                     "if (document.wasready) document.passCreation++;");
+    page.scripts().insert(s1);
+    QWebEngineScript s2;
+    s2.setInjectionPoint(QWebEngineScript::DocumentReady);
+    // onload shouldn't have run
+    s2.setWorldId(QWebEngineScript::MainWorld);
+    s2.setSourceCode("document.passReady = 0;" \
+                     "if (typeof qt !== undefined) document.passReady++;" \
+                     "if (document.passCreation > 0) document.passReady++;" \
+                     "if (document.passDeferred > 0) document.passReady++;" \
+                     "if (document.onloadran) document.passReady++;" \
+                     "if (document.wasready) document.passReady++;");
+    page.scripts().insert(s2);
+    QWebEngineScript s3;
+    s3.setInjectionPoint(QWebEngineScript::Deferred);
+    // all should have run
+    s3.setWorldId(QWebEngineScript::MainWorld);
+    s3.setSourceCode("document.passDeferred = 0;" \
+                     "if (typeof qt !== undefined) document.passDeferred++;" \
+                     "if (document.passCreation > 0) document.passDeferred++;" \
+                     "if (document.passReady > 0) document.passDeferred++;" \
+                     "if (document.onloadran) document.passDeferred++;" \
+                     "if (document.wasready) document.passDeferred++;");
+    page.scripts().insert(s3);
+
+
+    QString html("<html><head><script>" \
+                 "  document.onloadran = false; document.wasready = false;"\
+                 "  document.addEventListener(\"readystatechange\", (x) => { "\
+                 "      if (x.target.readyState === \"interactive\") document.wasready= true;"\
+                 "  });"\
+                 "  function bodyload() { document.onloadran = true; };"\
+                 "</script></head>" \
+                 "<body onload='bodyload()'><p>hello world</p></body></html>");
+    page.setHtml(html, QUrl("about:blank"));
+    QTRY_COMPARE(evaluateJavaScriptSyncInWorld(&page, "document.passCreation", QWebEngineScript::MainWorld),
+                 QVariant(1));
+    QTRY_COMPARE(evaluateJavaScriptSyncInWorld(&page, "document.passReady", QWebEngineScript::MainWorld),
+                 QVariant(3));
+    QTRY_COMPARE(evaluateJavaScriptSyncInWorld(&page, "document.passDeferred", QWebEngineScript::MainWorld),
+                 QVariant(5));
+
+    QString url2 = QStringLiteral("chrome://gpu/");
+    page.setUrl(url2);
+    QTRY_COMPARE(evaluateJavaScriptSyncInWorld(&page, "document.passCreation", QWebEngineScript::MainWorld),
+                 QVariant(1));
+    QTRY_COMPARE(evaluateJavaScriptSyncInWorld(&page, "document.passReady", QWebEngineScript::MainWorld),
+                 QVariant(2));
+    QTRY_COMPARE(evaluateJavaScriptSyncInWorld(&page, "document.passDeferred", QWebEngineScript::MainWorld),
+                 QVariant(3));
+
+    QString url3 = QStringLiteral("qrc:/resources/test_iframe_main.html");
+    page.setUrl(url3);
+    QTRY_COMPARE(evaluateJavaScriptSyncInWorld(&page, "document.passCreation", QWebEngineScript::MainWorld),
+                 QVariant(1));
+    QTRY_COMPARE(evaluateJavaScriptSyncInWorld(&page, "document.passReady", QWebEngineScript::MainWorld),
+                 QVariant(2));
+    QTRY_COMPARE(evaluateJavaScriptSyncInWorld(&page, "document.passDeferred", QWebEngineScript::MainWorld),
+                 QVariant(3));
+}
+
 // Try to set TestObject::text to an invalid UTF-16 string.
 //
 // See QTBUG-61969.

From 518bc89f68f2b792297e056ac85a14e92c5c8680 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Wed, 4 Dec 2024 11:15:10 +0100
Subject: [PATCH 221/356] Update Chromium

Submodule src/3rdparty a7fd4fa29..207acfe0:
  * [Backport] Security bug 378725734 (2/2)
  * [Backport] Security bug 378725734 (1/2)
  * [Backport] Security bug 378701682
  * Disable accelerated_2d_canvas for Intel on Linux
  * [Backport] Make "key" argument in std::erase_if predicate const.

Fixes: QTBUG-131873
Change-Id: Ia9655a02e23e5b85249a073f9315e8daa810322c
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
---
 CHROMIUM_VERSION                | 2 +-
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index dbde2f0b30a..f184ba63e7b 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
 Based on Chromium version:                                      122.0.6261.171
-Patched with security patches up to Chromium version:           131.0.6778.70
+Patched with security patches up to Chromium version:           131.0.6778.108
diff --git a/src/3rdparty b/src/3rdparty
index a7fd4fa29e0..207acfe0ee5 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit a7fd4fa29e0bd7cc44aa1c9dd3cf63b1144d1c74
+Subproject commit 207acfe0ee54df6dc713b2df6c60390fd8bf7748
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 771894a0f63..0c83db99216 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1268,7 +1268,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "131.0.6778.70"; // FIXME: Remember to update
+    return "131.0.6778.108"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From 223d069a7d07cde3a5df6643bf34cdfb3bc7c6f8 Mon Sep 17 00:00:00 2001
From: Anu Aliyas <anu.aliyas@qt.io>
Date: Mon, 2 Dec 2024 09:46:08 +0100
Subject: [PATCH 222/356] Fix for broken rendering when reparenting view
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When the dirty scene nodes are updated after reparenting the view, the
texture is not ready and as result rendering is broken. The parent
change triggers QQuickItem::ItemSceneChange, which in turn calls the
RenderWidgetHostViewQtDelegateClient::visualPropertiesChanged(). Even
though the window geometry is changed, this wouldn’t lead to generating
new texture, as the call to synchronize the visual properties is
missing. Invoked synchronizeVisualProperties to avoid such issues.

Fixes: QTBUG-131304
Change-Id: I29e6934c33b3fc9f54bfc6e17b29e5ea736cfee0
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
(cherry picked from commit cc9ab80c81af5fb9da878fc7baf8be8310c6436c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/render_widget_host_view_qt_delegate_client.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/core/render_widget_host_view_qt_delegate_client.cpp b/src/core/render_widget_host_view_qt_delegate_client.cpp
index ad4da26fcb7..a50eb9a4451 100644
--- a/src/core/render_widget_host_view_qt_delegate_client.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_client.cpp
@@ -199,8 +199,10 @@ void RenderWidgetHostViewQtDelegateClient::visualPropertiesChanged()
 
     bool screenInfoChanged = m_rwhv->updateScreenInfo();
 
-    if (m_viewRectInDips != oldViewRect || m_windowRectInDips != oldWindowRect)
+    if (m_viewRectInDips != oldViewRect || m_windowRectInDips != oldWindowRect) {
         m_rwhv->host()->SendScreenRects();
+        m_rwhv->synchronizeVisualProperties(std::nullopt);
+    }
 
     if (m_viewRectInDips.size() != oldViewRect.size() || screenInfoChanged)
         m_rwhv->synchronizeVisualProperties(absl::nullopt);

From bd50c00c04ec06fefd9e1013b6bedd3b30ce08b1 Mon Sep 17 00:00:00 2001
From: Anu Aliyas <anu.aliyas@qt.io>
Date: Thu, 12 Sep 2024 14:45:26 +0200
Subject: [PATCH 223/356] Fix wheel scrolling issue

As per the current design QtWeEngine combines wheel events when possible
to improve latency and perceived performance. The current logic updates
pending wheel events with new angleDelta values and positions instead
of accumulating it, which causes some events being missed. Since
angleDelta values are relative, when combining events, accumulate it.

Fixes: QTBUG-123095
Pick-to: 6.7
Change-Id: Idd5438407740f62a4315ea0fe50c24b777ac2ec2
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit cf37b4425cfe94e0b8afcb51a433256a4bfe173d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/core/web_event_factory.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp
index fcf14b45f57..86f10315b2b 100644
--- a/src/core/web_event_factory.cpp
+++ b/src/core/web_event_factory.cpp
@@ -1633,8 +1633,8 @@ bool WebEventFactory::coalesceWebWheelEvent(blink::WebMouseWheelEvent &webEvent,
     webEvent.SetPositionInScreen(static_cast<float>(ev->globalPosition().x()),
                                  static_cast<float>(ev->globalPosition().y()));
 
-    webEvent.wheel_ticks_x = ev->angleDelta().x() / static_cast<float>(QWheelEvent::DefaultDeltasPerStep);
-    webEvent.wheel_ticks_y = ev->angleDelta().y() / static_cast<float>(QWheelEvent::DefaultDeltasPerStep);
+    webEvent.wheel_ticks_x += ev->angleDelta().x() / static_cast<float>(QWheelEvent::DefaultDeltasPerStep);
+    webEvent.wheel_ticks_y += ev->angleDelta().y() / static_cast<float>(QWheelEvent::DefaultDeltasPerStep);
     setBlinkWheelEventDelta(webEvent);
 
     return true;

From e7c9f9a7ddca8fec772c893422b2eac4b12066d8 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Fri, 13 Dec 2024 10:40:42 +0000
Subject: [PATCH 224/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Ibb09d18ee7ff4c9bd674eb5ae7ccb3d1a922723a
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 11fed2d41c4..9415a399ba5 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 0011dad7f1f4f0945ae17876146619719b723e4d
+    ref: ac6425d3eca23da0463d68e61de912079aea17ab
     required: true
   ../qtpositioning:
-    ref: e2012e7529c83953e64e9dbee0cbcb2423960bc3
+    ref: a943bda6f483f3faa60127220035023bca17cce8
     required: false
   ../qttools:
-    ref: 0d6b5c5fe5aa635d59c923c93377da1cd03f3e88
+    ref: f2dbab334df5b001bd38d6b29f910f87fdaf5ab6
     required: false
   ../qtwebchannel:
-    ref: 1449463a3c956468309e53b2924da13d78b9e9dc
+    ref: 7bf5f5a79bb815bf82d7c1a4fabc99083ff957b5
     required: false

From 0c58e6581b3aabd0341d00ea7149bd668f6638f8 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Wed, 18 Dec 2024 08:48:02 +0000
Subject: [PATCH 225/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I6d467bab0f35e494716c85b7f5e942d2b3a5d2a6
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 9415a399ba5..3d63467546d 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: ac6425d3eca23da0463d68e61de912079aea17ab
+    ref: 0c85a2ac966b043b6c29c4bf433117cc8114f27e
     required: true
   ../qtpositioning:
-    ref: a943bda6f483f3faa60127220035023bca17cce8
+    ref: b88dda3aaa85dbe88acf8d8ae0910942ea32d0ab
     required: false
   ../qttools:
-    ref: f2dbab334df5b001bd38d6b29f910f87fdaf5ab6
+    ref: d027c6050b96cda00025aa9623c7331454d0731b
     required: false
   ../qtwebchannel:
-    ref: 7bf5f5a79bb815bf82d7c1a4fabc99083ff957b5
+    ref: 77cac0589a6ce0736a6b3a9f4ca2e5e716669d18
     required: false

From 3cdf0a2129448a7ac061d1a7eedc60842ce25a64 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Fri, 20 Dec 2024 13:07:44 +0000
Subject: [PATCH 226/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I6e2c1b86103076996225ae263b468f192928ad92
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 3d63467546d..f6d6cf7c443 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 0c85a2ac966b043b6c29c4bf433117cc8114f27e
+    ref: 28955a0dc80b7eb0bf5a02181f458161085a0823
     required: true
   ../qtpositioning:
-    ref: b88dda3aaa85dbe88acf8d8ae0910942ea32d0ab
+    ref: 7dabe03d504f020887d454e3f50ce5b01c2ea1f2
     required: false
   ../qttools:
-    ref: d027c6050b96cda00025aa9623c7331454d0731b
+    ref: cee47fe6d3034be007bf3e77dfc6c6283a2a4bba
     required: false
   ../qtwebchannel:
-    ref: 77cac0589a6ce0736a6b3a9f4ca2e5e716669d18
+    ref: cf2747f89861f9881ecb4e6e957795d094691564
     required: false

From 30122758f32a3aa8d6097caecf76ffd5d2981b6d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Thu, 9 Jan 2025 11:22:47 +0100
Subject: [PATCH 227/356] Update Chromium

Submodule src/3rdparty 207acfe0..c5287f4d:
  * [Backport] Security bug 379869752
  * [Backport] Security bug 384565015
  * [Backport] Security bug 379715150
  * [Backport] Security bug 382135228
  * [Backport] CVE-2024-12694: Use after free in Compositing
  * [Backport] CVE-2024-12693: Out of bounds memory access in V8

Fixes: QTBUG-132674
Fixes: QTBUG-132679
Task-number: QTBUG-131166
Change-Id: I6ec9526ad4c9d143a18a97b2cf7eae826d2bb8b7
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
---
 CHROMIUM_VERSION                | 2 +-
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index f184ba63e7b..c715e74aaba 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
 Based on Chromium version:                                      122.0.6261.171
-Patched with security patches up to Chromium version:           131.0.6778.108
+Patched with security patches up to Chromium version:           131.0.6778.265
diff --git a/src/3rdparty b/src/3rdparty
index 207acfe0ee5..c5287f4d6a0 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit 207acfe0ee54df6dc713b2df6c60390fd8bf7748
+Subproject commit c5287f4d6a0e64d357e7405599ecb6c7d2d4e5fd
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 0c83db99216..39027b35467 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1268,7 +1268,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "131.0.6778.108"; // FIXME: Remember to update
+    return "131.0.6778.265"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From 460809c089cfd5dbe0f12ca16f85aa89e928dbcb Mon Sep 17 00:00:00 2001
From: Andreas Eliasson <andreas.eliasson@qt.io>
Date: Wed, 11 Dec 2024 13:53:13 +0100
Subject: [PATCH 228/356] Doc: Remove left-over text
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The example that this text used to refer to has been removed from Qt 6.

Fixes: QTBUG-131896
Pick-to: 6.7 6.5
Change-Id: I4abd12028880267bbc7d8eb707841af30b04e84f
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
(cherry picked from commit 5ff1c88091befd0d9c3ffc1e6ecdd71ff709c0aa)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit b3fee7ef9aa46a56ad26b1fa4ee036dd568a03fa)
---
 src/core/doc/src/qtwebengine-features.qdoc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/doc/src/qtwebengine-features.qdoc b/src/core/doc/src/qtwebengine-features.qdoc
index c7221677cd1..1dc58a133ea 100644
--- a/src/core/doc/src/qtwebengine-features.qdoc
+++ b/src/core/doc/src/qtwebengine-features.qdoc
@@ -457,7 +457,7 @@
     WebEngineView::javaScriptDialogRequested(),
     WebEngineView::colorDialogRequested(),
     WebEngineView::fileDialogRequested(), and
-    WebEngineView::formValidationMessageRequested() signals. For an example,
+    WebEngineView::formValidationMessageRequested() signals.
 
     \section1 PDF File Viewing
 

From 7e1eb0a370f2ce5031ef2dfbf9da3648ebc5edad Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Mon, 6 Jan 2025 15:47:42 +0100
Subject: [PATCH 229/356] qwebengine_convert_dict: fix word length limit

The conversion tool had an implicit limit of 128 bytes, which was too
short for the entries in the supplied Bengali dic file. Instead we read
into a dynamically sized std::string.

Fixes: QTBUG-132564
Change-Id: I250904ef809ccbd9a110e87cd6b940c401f71f78
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit 95e926d3b9452d38289e3832e3e044c08b4a7e32)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 9c4230280d78c1f2e4f5aae20fd0c89b5d932800)
---
 src/core/tools/qwebengine_convert_dict/main.cpp | 12 ++++++------
 tests/auto/widgets/spellchecking/dict/en-US.dic |  1 +
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/core/tools/qwebengine_convert_dict/main.cpp b/src/core/tools/qwebengine_convert_dict/main.cpp
index 17dd3eec6aa..8b82b930f5d 100644
--- a/src/core/tools/qwebengine_convert_dict/main.cpp
+++ b/src/core/tools/qwebengine_convert_dict/main.cpp
@@ -93,20 +93,20 @@ inline bool VerifyWords(const convert_dict::DicReader::WordList& org_words,
 
     int affix_ids[hunspell::BDict::MAX_AFFIXES_PER_WORD];
 
-    static const int buf_size = 128;
-    char buf[buf_size];
     for (size_t i = 0; i < org_words.size(); i++) {
-        int affix_matches = iter.Advance(buf, buf_size, affix_ids);
+        auto buf_size = org_words[i].first.size() + 1;
+        std::string buf(buf_size, '\0');
+        int affix_matches = iter.Advance(buf.data(), buf_size, affix_ids);
         if (affix_matches == 0) {
             out << "Found the end before we expected\n";
             return false;
         }
 
-        if (org_words[i].first != buf) {
+        if (buf.back() != '\0' || buf.compare(0, buf_size - 1, org_words[i].first) != 0) {
             out << "Word does not match!\n"
                 << "  Index:    " << i << "\n"
                 << "  Expected: " << QString::fromStdString(org_words[i].first) << "\n"
-                << "  Actual:   " << QString::fromUtf8(buf) << "\n";
+                << "  Actual:   " << QString::fromStdString(buf) << "\n";
             return false;
         }
 
@@ -118,7 +118,7 @@ inline bool VerifyWords(const convert_dict::DicReader::WordList& org_words,
                         [](int a, int b) { return a == b; })) {
             out << "Affixes do not match!\n"
                 << "  Index:    " << i << "\n"
-                << "  Word:     " << QString::fromUtf8(buf) << "\n"
+                << "  Word:     " << QString::fromStdString(buf) << "\n"
                 << "  Expected: " << expectedAffixes << "\n"
                 << "  Actual:   " << actualAffixes << "\n";
             return false;
diff --git a/tests/auto/widgets/spellchecking/dict/en-US.dic b/tests/auto/widgets/spellchecking/dict/en-US.dic
index 63e9164ccd5..93c7198a385 100644
--- a/tests/auto/widgets/spellchecking/dict/en-US.dic
+++ b/tests/auto/widgets/spellchecking/dict/en-US.dic
@@ -10,3 +10,4 @@ she/Q
 they/Q
 we/Q
 you/Q
+very-long-word-to-test-old-fixed-size-buffer-limit-QTBUG-132564-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Q

From 00ab2112377d579d80bad289df8a15cb976eaf6b Mon Sep 17 00:00:00 2001
From: Alexandru Croitor <alexandru.croitor@qt.io>
Date: Thu, 14 Nov 2024 17:14:24 +0100
Subject: [PATCH 230/356] CMake: Create separate SBOM documents for QtWebEngine
 and QtPdf

Because QtWebEngine and QtPdf can be installed as separate components
in the online installer, as well as because they are shipped as
separate packages in Boot2Qt, create two separate SBOM documents for
them.

Fixes: QTBUG-128893
Task-number: QTBUG-122899
Task-number: QTBUG-129901
Change-Id: Icdcc8766e3338304ae7d85fa777ca74a59c14b06
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit a29566090106af219f3b19b342ef5005e130b336)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit f19df5e7c81041a4f80e03c8e2310231a1b79d35)
---
 CMakeLists.txt     | 3 +++
 src/CMakeLists.txt | 9 +++++++++
 2 files changed, 12 insertions(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7388dd55bd8..c647140e604 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -45,4 +45,7 @@ if(MATRIX_BUILD AND NOT MATRIX_SUBBUILD AND NOT QT_SUPERBUILD)
     return()
 endif()
 
+# Don't auto create the SBOM projects, they will be manually created
+# for each sub-project.
+set(QT_SKIP_SBOM_AUTO_PROJECT TRUE)
 qt_build_repo()
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index eb36e70539d..c58bccb8d05 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -63,6 +63,8 @@ cmake_minimum_required(VERSION ${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_WEB
 #  MODULES
 ##
 
+# Use implicit PROJECT_NAME.
+qt_internal_sbom_begin_qt_repo_project()
 if(QT_FEATURE_qtwebengine_core_build)
    add_subdirectory(core)
    add_subdirectory(process)
@@ -73,7 +75,9 @@ endif()
 if(QT_FEATURE_qtwebengine_quick_build)
    add_subdirectory(webenginequick)
 endif()
+qt_internal_sbom_end_qt_repo_project()
 
+qt_internal_sbom_begin_qt_repo_project(SBOM_PROJECT_NAME QtPdf)
 if(QT_FEATURE_qtpdf_build)
    add_subdirectory(pdf)
    # keep log order, pdf build after webengine
@@ -98,6 +102,11 @@ endif()
 #  NINJA PROJECT
 ##
 
+# No SBOM information will be generated for any targets created past this point in the file
+# or any add_subdirectory calls. For the external project GN, we'll have to come up with some
+# additional API.
+qt_internal_sbom_end_qt_repo_project()
+
 set(installDir ${PROJECT_BINARY_DIR}/install)
 
 if(NOT Ninja_FOUND)

From 0beb588245230f5d4034d475d279cac6e4806056 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Fri, 17 Jan 2025 19:55:56 +0000
Subject: [PATCH 231/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Idf5b673ec7df8c024ec0d6add07a5ab4059b67be
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index f6d6cf7c443..7fc7934cd49 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 28955a0dc80b7eb0bf5a02181f458161085a0823
+    ref: 2f13709a649bfbaf17f619da7f5f04d0641e08fb
     required: true
   ../qtpositioning:
-    ref: 7dabe03d504f020887d454e3f50ce5b01c2ea1f2
+    ref: 4ebea88f0ffc2bb1c43ffae0097cfcb9c9c41f1b
     required: false
   ../qttools:
-    ref: cee47fe6d3034be007bf3e77dfc6c6283a2a4bba
+    ref: 1500ab1758e8bb37f94ec788aa89b7aa03f82533
     required: false
   ../qtwebchannel:
-    ref: cf2747f89861f9881ecb4e6e957795d094691564
+    ref: 1d9b0323b70e83461aedec08093da03aa48fcf8a
     required: false

From 54ecf0cc289cb5f71a8ad63ac4a778e4c46ce0fc Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Mon, 20 Jan 2025 07:35:47 +0000
Subject: [PATCH 232/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I34827dcb4af62e1b2fcd5710ab16c4165720fe3b
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 7fc7934cd49..3bd4179f484 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 2f13709a649bfbaf17f619da7f5f04d0641e08fb
+    ref: d9d4c8c948b21e2ff96d5e90ab7bf78f77258329
     required: true
   ../qtpositioning:
-    ref: 4ebea88f0ffc2bb1c43ffae0097cfcb9c9c41f1b
+    ref: f9f194cf33ed5ebe9eb0dd6b79feeb21838037a2
     required: false
   ../qttools:
-    ref: 1500ab1758e8bb37f94ec788aa89b7aa03f82533
+    ref: d2a55ba82b692c9403fe0df95bd30591c154cfc8
     required: false
   ../qtwebchannel:
-    ref: 1d9b0323b70e83461aedec08093da03aa48fcf8a
+    ref: 0a0648ea62f5359082c88240cba7842a6bf1d78b
     required: false

From 91c0e422414070e778bdb672bd436436f98e0343 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Mon, 6 Jan 2025 15:58:02 +0100
Subject: [PATCH 233/356] Fix scaling and positioning of popup windows in
 WebEngineQuick

When using QQuickItem::scale to scale up the UI, popups were misplaced
when a WebEngineView was a child of this scaled item.

After trying different approaches similar to other popups in Qt Quick,
it turned out that the approach that we use to handle rotation can also
be applied to handle scaled items.

This also adds the handling of rotation and scale of items higher up
the item tree.

Fixes: QTBUG-130608
Change-Id: If6b6c39113d0f07146d633e9d11d0745f6b0ff15
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit a245afb450d49f4a5f77742fb39f31c44549b134)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 7044fe6887adb198a8b57dee5e62a41f8042c7ac)
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit 8987a7b480dbc27f20fd042a8a83c2d1741c329a)
---
 ...dget_host_view_qt_delegate_quickwindow.cpp | 44 +++++++++++++++----
 ...dget_host_view_qt_delegate_quickwindow_p.h |  2 +-
 2 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp
index 090b0928109..b507d760b79 100644
--- a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp
+++ b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp
@@ -7,6 +7,25 @@
 
 namespace QtWebEngineCore {
 
+struct ItemTransform {
+    qreal rotation = 0.;
+    qreal scale = 1.;
+};
+
+// Helper function to calculate the cumulative rotation and scale.
+static inline struct ItemTransform getTransformValuesFromItemTree(QQuickItem *item)
+{
+    struct ItemTransform returnValue;
+
+    while (item) {
+        returnValue.rotation += item->rotation();
+        returnValue.scale *= item->scale();
+        item = item->parentItem();
+    }
+
+    return returnValue;
+}
+
 static inline QPoint getOffset(QQuickItem *item)
 {
     // get parent window (scene) offset
@@ -32,7 +51,7 @@ static inline QPointF transformPoint(const QPointF &point, const QTransform &tra
 
 RenderWidgetHostViewQtDelegateQuickWindow::RenderWidgetHostViewQtDelegateQuickWindow(
         RenderWidgetHostViewQtDelegateItem *realDelegate, QWindow *parent)
-    : QQuickWindow(parent), m_realDelegate(realDelegate), m_virtualParent(nullptr), m_rotated(false)
+    : QQuickWindow(parent), m_realDelegate(realDelegate), m_virtualParent(nullptr), m_transformed(false)
 {
     setFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
     realDelegate->setParentItem(contentItem());
@@ -56,9 +75,13 @@ void RenderWidgetHostViewQtDelegateQuickWindow::setVirtualParent(QQuickItem *vir
 // chromium knows nothing about local transformation
 void RenderWidgetHostViewQtDelegateQuickWindow::InitAsPopup(const QRect &rect)
 {
-    m_rotated = m_virtualParent->rotation() > 0 || m_virtualParent->parentItem()->rotation() > 0;
-    if (m_rotated) {
-        // code below tries to cover the case where webengine view is rotated,
+    // To decide if there is a scale or rotation, we check it from the transfrom
+    // to also cover the case where the scale is higher up in the item tree.
+    QTransform transform = m_virtualParent->itemTransform(nullptr, nullptr);
+    m_transformed = transform.isRotating() || transform.isScaling();
+
+    if (m_transformed) {
+        // code below tries to cover the case where webengine view is rotated or scaled,
         // the code assumes the rotation is in the form of  90, 180, 270 degrees
         // to archive that we keep chromium unaware of transformation and we transform
         // just the window content.
@@ -67,7 +90,6 @@ void RenderWidgetHostViewQtDelegateQuickWindow::InitAsPopup(const QRect &rect)
         QPointF offset = m_virtualParent->mapFromScene(QPoint(0, 0));
         offset = m_virtualParent->mapToGlobal(offset);
         // get local transform
-        QTransform transform = m_virtualParent->itemTransform(nullptr, nullptr);
         QPointF tl = transformPoint(rect.topLeft(), transform, offset, m_virtualParent);
         QPointF br = transformPoint(rect.bottomRight(), transform, offset, m_virtualParent);
         QRectF popupRect(tl, br);
@@ -80,7 +102,13 @@ void RenderWidgetHostViewQtDelegateQuickWindow::InitAsPopup(const QRect &rect)
         m_realDelegate->setX(-rect.width() / 2.0 + geometry().width() / 2.0);
         m_realDelegate->setY(-rect.height() / 2.0 + geometry().height() / 2.0);
         m_realDelegate->setTransformOrigin(QQuickItem::Center);
-        m_realDelegate->setRotation(m_virtualParent->parentItem()->rotation());
+
+        // We need to read the values for scale and rotation from the item tree as it is not
+        // sufficient to only use the virtual parent item and its parent for the case that the
+        // scale or rotation is applied higher up the item tree.
+        struct ItemTransform transformValues = getTransformValuesFromItemTree(m_virtualParent);
+        m_realDelegate->setRotation(transformValues.rotation);
+        m_realDelegate->setScale(transformValues.scale);
     } else {
         QRect geometry(rect);
         geometry.moveTo(rect.topLeft() - getOffset(m_virtualParent));
@@ -93,13 +121,13 @@ void RenderWidgetHostViewQtDelegateQuickWindow::InitAsPopup(const QRect &rect)
 
 void RenderWidgetHostViewQtDelegateQuickWindow::Resize(int width, int height)
 {
-    if (!m_rotated)
+    if (!m_transformed)
         QQuickWindow::resize(width, height);
 }
 
 void RenderWidgetHostViewQtDelegateQuickWindow::MoveWindow(const QPoint &screenPos)
 {
-    if (!m_rotated)
+    if (!m_transformed)
         QQuickWindow::setPosition(screenPos - getOffset(m_virtualParent));
 }
 
diff --git a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow_p.h b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow_p.h
index 3559bd2f080..691fceb5257 100644
--- a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow_p.h
+++ b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow_p.h
@@ -49,7 +49,7 @@ class RenderWidgetHostViewQtDelegateQuickWindow : public QQuickWindow , public W
     QPointer<RenderWidgetHostViewQtDelegateItem> m_realDelegate;
     QQuickItem *m_virtualParent;
     QRect m_rect;
-    bool m_rotated;
+    bool m_transformed;
 };
 
 } // namespace QtWebEngineCore

From f2001e30f9c4d6d2045c531addde6e217526485e Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Mon, 20 Jan 2025 13:30:20 +0100
Subject: [PATCH 234/356] Fix conflicting rtti GN configs for Windows build

no_rtti is a default compiler config in Chromium. We enable rtti for
QtWebEngineCore build on Windows. Remove the no_rtti config first to
silence warning:

cl : Command line warning D9025 : overriding '/GR-' with '/GR'

Change-Id: I0ccf592095e39a7d83dd2d959ab50aa0c0aca097
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Reviewed-by: Moss Heim <moss.heim@qt.io>
(cherry picked from commit 9458886d3490f0981021d98e5ec276bccce47ad7)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 6c2b6c12c8bf94021ab7ab8df509b5f7179f117b)
---
 src/core/configure/BUILD.root.gn.in | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/core/configure/BUILD.root.gn.in b/src/core/configure/BUILD.root.gn.in
index 0e913f1d44b..42b06d4f7b7 100644
--- a/src/core/configure/BUILD.root.gn.in
+++ b/src/core/configure/BUILD.root.gn.in
@@ -170,6 +170,7 @@ shared_library("QtWebEngineCore") {
   }
 
   if (is_win) {
+    configs -= [ "//build/config/compiler:no_rtti" ]
     configs += [ "//build/config/compiler:rtti" ]
     data_deps += [ ":QtWebEngineCoreSandbox" ]
   }

From b744f9189f45b7fbf822e8f9357a874ec1b7ae8d Mon Sep 17 00:00:00 2001
From: Alexandru Croitor <alexandru.croitor@qt.io>
Date: Mon, 20 Jan 2025 16:13:51 +0100
Subject: [PATCH 235/356] CMake: Only create sbom documents when the respective
 feature is on

Previously if -DFEATURE_qtwebengine_build=OFF was passed to configure,
we still installed an almost empty sbom document for the qtwebengine
project. Same for qtpdf.

Guard the creation and installation of the sbom documents with the
appropriate feature checks, for both QtWebEngine and QtPdf.

Amends a29566090106af219f3b19b342ef5005e130b336

Fixes: QTBUG-128893
Task-number: QTBUG-122899
Task-number: QTBUG-129901
Change-Id: If123dfcae9408f1d559939f885009f920c09eac6
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Reviewed-by: Moss Heim <moss.heim@qt.io>
(cherry picked from commit 74e88184d11514288aff41851de71ee0b55641cb)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit ba890f909a5ed1440b55dac17d1fda49a4dfe07e)
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
---
 src/CMakeLists.txt | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c58bccb8d05..789f15bc630 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -63,8 +63,10 @@ cmake_minimum_required(VERSION ${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_WEB
 #  MODULES
 ##
 
-# Use implicit PROJECT_NAME.
-qt_internal_sbom_begin_qt_repo_project()
+if(QT_FEATURE_qtwebengine_build)
+    # Use implicit PROJECT_NAME.
+    qt_internal_sbom_begin_qt_repo_project()
+endif()
 if(QT_FEATURE_qtwebengine_core_build)
    add_subdirectory(core)
    add_subdirectory(process)
@@ -75,10 +77,12 @@ endif()
 if(QT_FEATURE_qtwebengine_quick_build)
    add_subdirectory(webenginequick)
 endif()
-qt_internal_sbom_end_qt_repo_project()
+if(QT_FEATURE_qtwebengine_build)
+    qt_internal_sbom_end_qt_repo_project()
+endif()
 
-qt_internal_sbom_begin_qt_repo_project(SBOM_PROJECT_NAME QtPdf)
 if(QT_FEATURE_qtpdf_build)
+   qt_internal_sbom_begin_qt_repo_project(SBOM_PROJECT_NAME QtPdf)
    add_subdirectory(pdf)
    # keep log order, pdf build after webengine
    if(QT_FEATURE_qtwebengine_core_build)
@@ -105,7 +109,9 @@ endif()
 # No SBOM information will be generated for any targets created past this point in the file
 # or any add_subdirectory calls. For the external project GN, we'll have to come up with some
 # additional API.
-qt_internal_sbom_end_qt_repo_project()
+if(QT_FEATURE_qtpdf_build)
+    qt_internal_sbom_end_qt_repo_project()
+endif()
 
 set(installDir ${PROJECT_BINARY_DIR}/install)
 

From 200f19cf94380039130bc9e056e1f2a4460591ec Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Mon, 27 Jan 2025 08:54:51 +0000
Subject: [PATCH 236/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I7dccab03a6dbe37d88ca106e65c255456dc31dcc
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 3bd4179f484..96ab7fdd72b 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: d9d4c8c948b21e2ff96d5e90ab7bf78f77258329
+    ref: 6aa1a9772709feba9761574e607a4d66fc0215de
     required: true
   ../qtpositioning:
-    ref: f9f194cf33ed5ebe9eb0dd6b79feeb21838037a2
+    ref: 8c21d8b72c25dd9cf1631f4fb9935fa075e7dd41
     required: false
   ../qttools:
-    ref: d2a55ba82b692c9403fe0df95bd30591c154cfc8
+    ref: bb53cfd19768fdf38cee17ce17e4e67857ee3802
     required: false
   ../qtwebchannel:
-    ref: 0a0648ea62f5359082c88240cba7842a6bf1d78b
+    ref: ed8af9fd6da84e75a414f7d683456b6281e7b617
     required: false

From 8ff002c1091f6499f7e2250766239d63ff35cfd7 Mon Sep 17 00:00:00 2001
From: Jani Heikkinen <jani.heikkinen@qt.io>
Date: Thu, 23 Jan 2025 09:03:18 +0000
Subject: [PATCH 237/356] Bump version to 6.8.3

Change-Id: I3c888b2073774042aa5a2420ad6be92893cd95dc
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 .cmake.conf | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.cmake.conf b/.cmake.conf
index 02007225629..81507b42a70 100644
--- a/.cmake.conf
+++ b/.cmake.conf
@@ -1,4 +1,4 @@
-set(QT_REPO_MODULE_VERSION "6.8.2")
+set(QT_REPO_MODULE_VERSION "6.8.3")
 set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1")
 set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_WEBENGINE "3.19")
 set(QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_NO_AS_CONST=1")

From 7a4b0f128baf2c7d5bc92ecd5742c8d848e7a3ea Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Tue, 28 Jan 2025 11:22:00 +0000
Subject: [PATCH 238/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Ibf6555c646b042c91c55e825d63e5b093497d947
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 96ab7fdd72b..25d2b4fb594 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 6aa1a9772709feba9761574e607a4d66fc0215de
+    ref: ca9ff6bd040372c91b2b493d89bb58b231a82afc
     required: true
   ../qtpositioning:
-    ref: 8c21d8b72c25dd9cf1631f4fb9935fa075e7dd41
+    ref: be59c8f65b84f9c008f45bf8110668c6eab0d9a5
     required: false
   ../qttools:
-    ref: bb53cfd19768fdf38cee17ce17e4e67857ee3802
+    ref: 2d2f9c09fafba1bcf50dfb5eb4c82351a5610997
     required: false
   ../qtwebchannel:
-    ref: ed8af9fd6da84e75a414f7d683456b6281e7b617
+    ref: ebd28d7bab9237c661b88d4fca971302cf7ec860
     required: false

From 60f8c89e9cdf5fff032d213d84315c191fca39c6 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Thu, 9 Jan 2025 12:10:27 +0100
Subject: [PATCH 239/356] Add sync headers dependency to recursvie ninja run

During chromium part build we do generate some mocs
which can include headers synced by syncqt.
Chromium part is built before linking the WebEngineCore
and it can happen than syncqt was not executed yet
as there was not direct dependency on sync headers task,
only WebEngineCore target had this dependency.

Add missing direct dependency.

Change-Id: I16a29764805cdfcf32776c9f1cb8318704164b93
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit e372bb3dad121465d61cc15de18c06c85f938072)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 694eab07885772b465555b75e1f714ce4c86d558)
---
 cmake/Functions.cmake   | 7 ++++---
 src/core/CMakeLists.txt | 1 +
 src/pdf/CMakeLists.txt  | 1 +
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/cmake/Functions.cmake b/cmake/Functions.cmake
index 93be1725e9a..f957bea42e9 100644
--- a/cmake/Functions.cmake
+++ b/cmake/Functions.cmake
@@ -1122,7 +1122,7 @@ endmacro()
 
 function(add_ninja_command)
     cmake_parse_arguments(PARSE_ARGV 0 arg
-        "" "TARGET;BUILDDIR;MODULE" "OUTPUT;BYPRODUCTS"
+        "" "TARGET;BUILDDIR;MODULE" "OUTPUT;BYPRODUCTS;DEPENDS"
     )
     _qt_internal_validate_all_args_are_parsed(arg)
 
@@ -1142,7 +1142,7 @@ function(add_ninja_command)
         USES_TERMINAL
         VERBATIM
         COMMAND_EXPAND_LISTS
-        DEPENDS run_${arg_MODULE}_NinjaReady
+        DEPENDS run_${arg_MODULE}_NinjaReady ${arg_DEPENDS}
     )
 endfunction()
 
@@ -1172,7 +1172,7 @@ endfunction()
 
 function(add_gn_build_artifacts_to_target)
     cmake_parse_arguments(PARSE_ARGV 0 arg
-        "" "CMAKE_TARGET;NINJA_TARGET;BUILDDIR;MODULE;COMPLETE_STATIC;NINJA_STAMP;NINJA_DATA_STAMP" ""
+        "" "CMAKE_TARGET;NINJA_TARGET;BUILDDIR;MODULE;COMPLETE_STATIC;NINJA_STAMP;NINJA_DATA_STAMP;DEPENDS" ""
     )
     _qt_internal_validate_all_args_are_parsed(arg)
 
@@ -1200,6 +1200,7 @@ function(add_gn_build_artifacts_to_target)
                 OUTPUT ${stamps}
                 BUILDDIR ${arg_BUILDDIR}/${config}/${arch}
                 MODULE ${arg_MODULE}
+                DEPENDS ${arg_DEPENDS}
             )
             add_dependencies(run_${arg_MODULE}_NinjaDone ${target})
             set_target_properties(${arg_CMAKE_TARGET} PROPERTIES
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index de52226456a..3d871f65205 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -597,6 +597,7 @@ add_gn_build_artifacts_to_target(
     CMAKE_TARGET WebEngineCore
     NINJA_TARGET QtWebEngineCore
     MODULE core
+    DEPENDS WebEngineCore_sync_headers
     BUILDDIR ${buildDir}
     COMPLETE_STATIC FALSE
     NINJA_STAMP QtWebEngineCore.stamp
diff --git a/src/pdf/CMakeLists.txt b/src/pdf/CMakeLists.txt
index fcb5f1186cc..95931a261f8 100644
--- a/src/pdf/CMakeLists.txt
+++ b/src/pdf/CMakeLists.txt
@@ -253,6 +253,7 @@ add_gn_build_artifacts_to_target(
     CMAKE_TARGET Pdf
     NINJA_TARGET QtPdf
     MODULE pdf
+    DEPENDS Pdf_sync_headers
     BUILDDIR ${buildDir}
     COMPLETE_STATIC TRUE
     NINJA_STAMP QtPdf.stamp

From f6ba4e58ece5ea5873dbce4d5bc19c788a8823ab Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Wed, 29 Jan 2025 08:07:51 +0000
Subject: [PATCH 240/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I1455381f5ec728ab0123d368c1f183c069efe68e
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 25d2b4fb594..f2ecdedc7b7 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: ca9ff6bd040372c91b2b493d89bb58b231a82afc
+    ref: fcd48036a29428a333e5ee0a0301994edd5025fa
     required: true
   ../qtpositioning:
-    ref: be59c8f65b84f9c008f45bf8110668c6eab0d9a5
+    ref: 4637d0a4e9b91f6f525d1ed21363baadc291d61f
     required: false
   ../qttools:
-    ref: 2d2f9c09fafba1bcf50dfb5eb4c82351a5610997
+    ref: f66065751b537bb3fa3cc0957759dcd248ded716
     required: false
   ../qtwebchannel:
-    ref: ebd28d7bab9237c661b88d4fca971302cf7ec860
+    ref: 96ba65c4ff8e02b742e68c5e5ecc8d46c37f210f
     required: false

From 17d252f02da75a1e30349a2b3919b00a1a295bea Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Thu, 30 Jan 2025 08:14:57 +0000
Subject: [PATCH 241/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I0692fff9a384b9408aeeca0de6605dc523afc082
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index f2ecdedc7b7..6b4c0c5a26f 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: fcd48036a29428a333e5ee0a0301994edd5025fa
+    ref: 72d314d1e51709a71d856fa0bf1eb0d146013f8e
     required: true
   ../qtpositioning:
-    ref: 4637d0a4e9b91f6f525d1ed21363baadc291d61f
+    ref: d439b858a902e16f198a973ac605bdc13c171ad7
     required: false
   ../qttools:
-    ref: f66065751b537bb3fa3cc0957759dcd248ded716
+    ref: 53798d1ceb1ff9fa4fc1b291b49f656929f8059d
     required: false
   ../qtwebchannel:
-    ref: 96ba65c4ff8e02b742e68c5e5ecc8d46c37f210f
+    ref: fcfe7c1a7d3f841111bb6e5409411e46d0f5b116
     required: false

From d6bc753576b506701c41839ac7d4fe2b77a6f8e5 Mon Sep 17 00:00:00 2001
From: Anu Aliyas <anu.aliyas@qt.io>
Date: Fri, 10 Jan 2025 14:21:50 +0100
Subject: [PATCH 242/356] Use the reduced User-Agent header

User-Agent reduction minimizes the identifying information shared in
the User-Agent string, which may be used for passive fingerprinting.
Chromium already uses the reduced User-Agent.  With this change,
webengine also uses the reduced User-Agent for improved security.

Fixes: QTBUG-132411
Change-Id: Idc3314ca1744bc95e20ba2b23859093739146d58
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 208fe51a84a173404efa37aec40f08199b653701)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 145a30d433cd06ff21f8864b5afe094ce401cdf0)
---
 src/core/content_browser_client_qt.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index 0634a5a395d..44d8ce0e278 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -32,6 +32,7 @@
 #include "content/public/common/content_switches.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/common/user_agent.h"
+#include "base/version_info/version_info.h"
 #include "ipc/ipc_channel_proxy.h"
 #include "extensions/buildflags/buildflags.h"
 #include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
@@ -977,8 +978,8 @@ std::string ContentBrowserClientQt::getUserAgent()
 {
     // Mention the Chromium version we're based on to get passed stupid UA-string-based feature detection (several WebRTC demos need this)
     return content::BuildUserAgentFromProduct("QtWebEngine/" + std::string(qWebEngineVersion())
-                                              + " Chrome/"
-                                              + std::string(qWebEngineChromiumVersion()));
+                                              + " Chrome/" + version_info::GetMajorVersionNumber()
+                                              + ".0.0.0");
 }
 
 blink::UserAgentMetadata ContentBrowserClientQt::GetUserAgentMetadata()

From 2c782af9655b58e954c3fb37ee1bac9ad0529102 Mon Sep 17 00:00:00 2001
From: Anu Aliyas <anu.aliyas@qt.io>
Date: Wed, 18 Dec 2024 16:15:46 +0100
Subject: [PATCH 243/356] Do not warn needlessly about missing dictionaries
 directory
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The warning message will be displayed only when trying to enable spell
checking and the dictionary path is empty. The function has been
modified so that it doesn’t perform any action if the new state and
the current state are the  same.

Fixes: QTBUG-131969
Change-Id: Ib69422cdd0285392a6fda967012f9779c950401d
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
(cherry picked from commit a069e0bba44e59c9041205a5432b736bfd980be0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 7f05c72cb05db9475c1258eddf66f19025fc6928)
---
 src/core/pref_service_adapter.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/core/pref_service_adapter.cpp b/src/core/pref_service_adapter.cpp
index 2512c3c44f3..7a7abf2c48c 100644
--- a/src/core/pref_service_adapter.cpp
+++ b/src/core/pref_service_adapter.cpp
@@ -205,7 +205,10 @@ QStringList PrefServiceAdapter::spellCheckLanguages() const
 
 void PrefServiceAdapter::setSpellCheckEnabled(bool enabled)
 {
-    if (!WebEngineLibraryInfo::getPath(base::DIR_APP_DICTIONARIES, true).empty()) {
+    if (enabled == m_prefService->GetBoolean(spellcheck::prefs::kSpellCheckEnable))
+        return;
+
+    if (!WebEngineLibraryInfo::getPath(base::DIR_APP_DICTIONARIES, enabled).empty()) {
         m_prefService->SetBoolean(spellcheck::prefs::kSpellCheckEnable, enabled);
         m_prefService->SchedulePendingLossyWrites();
     }

From 84dd8008b637e2bb9ec723ebc2343ba590ce4ed2 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 30 Jan 2025 16:27:22 +0100
Subject: [PATCH 244/356] Fix flaky tst_QWebEngineProfile::clearDataFromCache
 on Windows

Wait for dereferencing http cache entries.

Change-Id: Iab3e9a56fa4008f60552f737b16b9716d69c376e
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit a807b591a0e367ea9645448338edc3c2b6737f64)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 6f3265cf38f4832dab0b9a7e43b3d20724ec8510)
---
 .../widgets/qwebengineprofile/tst_qwebengineprofile.cpp     | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index d9997d50c36..866daa77305 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -205,6 +205,12 @@ void tst_QWebEngineProfile::clearDataFromCache()
     // Wait for GET /favicon.ico
     QTRY_COMPARE(serverSpy.size(), 3);
 
+#if defined(Q_OS_WIN)
+    // FIXME: A http cache entry might be still in use after all the wait above and this blocks
+    //        clearing the http cache. Find a better way to wait for cache entries.
+    QTest::qWait(500);
+#endif
+
     QVERIFY(cacheDir.exists("Cache"));
     qint64 sizeBeforeClear = totalSize(cacheDir);
     QCOMPARE_GT(sizeBeforeClear, 0);

From a3e47b5b10e2f90fc465042d92d7331d2a047028 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Fri, 31 Jan 2025 12:50:15 +0100
Subject: [PATCH 245/356] Fix flaky WebEngineViewLoadUrl::test_stopStatus

The test fail was reproducible on arm64 macOS but it could happen on any
platform if it is fast enough.

The value of WebEngineView.url property is just not reliable when a
page's load status is changed to LoadStoppedStatus. If the navigation
events are processed fast enough the navigation request can be committed
right before we call stop() on the view. If the request is
committed it has already updated the url of the current page.

As a fix just ignore the current page url after calling stop in the
test.

Change-Id: I9605696dfb1a0e15343afc384fcc2097cfa2994a
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit ccff8d6d518c402759725723e34b5302fdbcf9e1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 8ba624747ab9f29a9fdf059b9c939c91712b0c96)
---
 tests/auto/quick/qmltests/data/tst_loadUrl.qml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/tests/auto/quick/qmltests/data/tst_loadUrl.qml b/tests/auto/quick/qmltests/data/tst_loadUrl.qml
index 757343703c5..e43c8d5d983 100644
--- a/tests/auto/quick/qmltests/data/tst_loadUrl.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadUrl.qml
@@ -265,7 +265,6 @@ TestWebEngineView {
             compare(loadRequest.status, WebEngineView.LoadStoppedStatus);
             compare(loadRequest.status, WebEngineLoadingInfo.LoadStoppedStatus);
             compare(loadRequest.url, stoppedUrl);
-            compare(loadRequest.activeUrl, initialUrl);
             webEngineView.clear();
         }
 

From cca5fb10472ae6528c1a7bccbd48de395bfd4400 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 9 Jan 2025 17:04:23 +0100
Subject: [PATCH 246/356] Do not try to import native textures with offscreen
 platform plugin

Native texture import implementations rely on platform specific APIs
which may not be working with offscreen platform plugin.

Fixes: QTBUG-132682
Change-Id: I6d68dacaa54fa42c8464c3ba2d29a879dad8a1e5
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit a9944c7c0a704ded9fcfb9365688c240dc1303e0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 13bddc733f435167ae9f7140c7b3752d1687fd89)
---
 src/core/compositor/native_skia_output_device_opengl.cpp | 1 +
 src/core/render_widget_host_view_qt_delegate_item.cpp    | 8 ++++++++
 2 files changed, 9 insertions(+)

diff --git a/src/core/compositor/native_skia_output_device_opengl.cpp b/src/core/compositor/native_skia_output_device_opengl.cpp
index f1ae3651089..a65cb2dc155 100644
--- a/src/core/compositor/native_skia_output_device_opengl.cpp
+++ b/src/core/compositor/native_skia_output_device_opengl.cpp
@@ -231,6 +231,7 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
 
 #if defined(USE_OZONE)
     QOpenGLContext *glContext = QOpenGLContext::currentContext();
+    Q_ASSERT(glContext);
     auto glFun = glContext->functions();
     GLuint glTexture = 0;
 
diff --git a/src/core/render_widget_host_view_qt_delegate_item.cpp b/src/core/render_widget_host_view_qt_delegate_item.cpp
index 6ece45f9bb2..94f786d1ca8 100644
--- a/src/core/render_widget_host_view_qt_delegate_item.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_item.cpp
@@ -14,6 +14,8 @@
 #include <QtGui/qaccessible.h>
 #endif
 
+using namespace Qt::StringLiterals;
+
 namespace QtWebEngineCore {
 
 RenderWidgetHostViewQtDelegateItem::RenderWidgetHostViewQtDelegateItem(RenderWidgetHostViewQtDelegateClient *client, bool isPopup)
@@ -368,6 +370,12 @@ QSGNode *RenderWidgetHostViewQtDelegateItem::updatePaintNode(QSGNode *oldNode, U
     if (!comp)
         return oldNode;
 
+    if (comp->type() == Compositor::Type::Native
+        && QGuiApplication::platformName() == "offscreen"_L1) {
+        comp->swapFrame();
+        return oldNode;
+    }
+
     QQuickWindow *win = QQuickItem::window();
 
     QSGImageNode *node = nullptr;

From 3488e143b2b145fec22fbbbd8875709aa9ae2ec5 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Mon, 27 Jan 2025 09:47:42 +0100
Subject: [PATCH 247/356] Add float QImage format support to toQImage

Change-Id: I759c02641bbb519135375054465795e7f3b1347f
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 4c8ec6a5d35a773a2c4b358a4f150acf798b23ab)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit c5c5c624c7df52b24814a5b191028c6c35633126)
---
 src/core/type_conversion.cpp | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/src/core/type_conversion.cpp b/src/core/type_conversion.cpp
index 0a3c2489c45..1d821df8c1a 100644
--- a/src/core/type_conversion.cpp
+++ b/src/core/type_conversion.cpp
@@ -23,8 +23,6 @@ QImage toQImage(const SkBitmap &bitmap)
     QImage image;
     switch (bitmap.colorType()) {
     case kUnknown_SkColorType:
-    case kRGBA_F16_SkColorType:
-    case kRGBA_F32_SkColorType:
     case kRGBA_F16Norm_SkColorType:
     case kR8G8_unorm_SkColorType:
     case kA16_float_SkColorType:
@@ -137,6 +135,36 @@ QImage toQImage(const SkBitmap &bitmap)
             break;
         }
         break;
+    case kRGBA_F16_SkColorType:
+        switch (bitmap.alphaType()) {
+        case kUnknown_SkAlphaType:
+            break;
+        case kUnpremul_SkAlphaType:
+            image = toQImage(bitmap, QImage::Format_RGBA16FPx4);
+            break;
+        case kOpaque_SkAlphaType:
+            image = toQImage(bitmap, QImage::Format_RGBX16FPx4);
+            break;
+        case kPremul_SkAlphaType:
+            image = toQImage(bitmap, QImage::Format_RGBA16FPx4_Premultiplied);
+            break;
+        }
+        break;
+    case kRGBA_F32_SkColorType:
+        switch (bitmap.alphaType()) {
+        case kUnknown_SkAlphaType:
+            break;
+        case kUnpremul_SkAlphaType:
+            image = toQImage(bitmap, QImage::Format_RGBA32FPx4);
+            break;
+        case kOpaque_SkAlphaType:
+            image = toQImage(bitmap, QImage::Format_RGBX32FPx4);
+            break;
+        case kPremul_SkAlphaType:
+            image = toQImage(bitmap, QImage::Format_RGBA32FPx4_Premultiplied);
+            break;
+        }
+        break;
     }
     return image;
 }

From 3493538f94029b04ea9a43c44482937af4bdc423 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Mon, 20 Jan 2025 10:51:37 +0100
Subject: [PATCH 248/356] Fix discarded QFile::open() results

Also validate return value of QIODevice::open() and QBuffer::open()
calls.

Change-Id: I71ea58f62cab5aafdd2b4eca217394dddf0033cd
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Reviewed-by: Moss Heim <moss.heim@qt.io>
(cherry picked from commit 90fb632348ea5226a9aefd1e3707f112b80aa6b9)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 73eb4a364eac89454dcf078ec4fecb4f69271808)
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
---
 .../webenginewidgets/clientcertificate/client.cpp    | 10 ++++++++--
 .../webenginewidgets/clientcertificate/server.cpp    |  5 ++++-
 .../contentmanipulation/mainwindow.cpp               |  5 ++++-
 src/core/net/resource_request_body_qt.cpp            | 11 ++++++++++-
 .../tst_qwebengineclientcertificatestore.cpp         | 12 ++++++------
 .../tst_qwebengineurlrequestinterceptor.cpp          |  3 ++-
 .../tst_qwebengineurlrequestjob.cpp                  |  7 ++++---
 tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp     |  2 +-
 .../tst_qwebenginedownloadrequest.cpp                |  4 ++--
 .../widgets/qwebenginepage/tst_qwebenginepage.cpp    |  2 +-
 .../qwebengineprofile/tst_qwebengineprofile.cpp      |  6 +++---
 .../qwebenginescript/tst_qwebenginescript.cpp        |  5 ++++-
 12 files changed, 49 insertions(+), 23 deletions(-)

diff --git a/examples/webenginewidgets/clientcertificate/client.cpp b/examples/webenginewidgets/clientcertificate/client.cpp
index 1227fa28e8a..de09120ca0d 100644
--- a/examples/webenginewidgets/clientcertificate/client.cpp
+++ b/examples/webenginewidgets/clientcertificate/client.cpp
@@ -21,11 +21,17 @@ int main(int argc, char *argv[])
     QApplication app(argc, argv);
 
     QFile certFile(":/resources/client.pem");
-    certFile.open(QIODevice::ReadOnly);
+    if (!certFile.open(QIODevice::ReadOnly)) {
+        qFatal("Failed to read cert file %s: %s", qPrintable(certFile.fileName()),
+               qPrintable(certFile.errorString()));
+    }
     const QSslCertificate cert(certFile.readAll(), QSsl::Pem);
 
     QFile keyFile(":/resources/client.key");
-    keyFile.open(QIODevice::ReadOnly);
+    if (!keyFile.open(QIODevice::ReadOnly)) {
+        qFatal("Failed to read key file %s: %s", qPrintable(keyFile.fileName()),
+               qPrintable(keyFile.errorString()));
+    }
     const QSslKey sslKey(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, "");
 
     QWebEngineProfile::defaultProfile()->clientCertificateStore()->add(cert, sslKey);
diff --git a/examples/webenginewidgets/clientcertificate/server.cpp b/examples/webenginewidgets/clientcertificate/server.cpp
index ee83dab8a59..0d1bf771030 100644
--- a/examples/webenginewidgets/clientcertificate/server.cpp
+++ b/examples/webenginewidgets/clientcertificate/server.cpp
@@ -38,7 +38,10 @@ int main(int argc, char *argv[])
     configuration.setPeerVerifyMode(QSslSocket::VerifyPeer);
 
     QFile keyFile(":/resources/server.key");
-    keyFile.open(QIODevice::ReadOnly);
+    if (!keyFile.open(QIODevice::ReadOnly)) {
+        qFatal("Failed to read key file %s: %s", qPrintable(keyFile.fileName()),
+               qPrintable(keyFile.errorString()));
+    }
 
     QSslKey key(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
     configuration.setPrivateKey(key);
diff --git a/examples/webenginewidgets/contentmanipulation/mainwindow.cpp b/examples/webenginewidgets/contentmanipulation/mainwindow.cpp
index 3990be2b8a7..4e661f4d825 100644
--- a/examples/webenginewidgets/contentmanipulation/mainwindow.cpp
+++ b/examples/webenginewidgets/contentmanipulation/mainwindow.cpp
@@ -12,7 +12,10 @@ MainWindow::MainWindow(const QUrl& url)
 
     QFile file;
     file.setFileName(":/jquery.min.js");
-    file.open(QIODevice::ReadOnly);
+    if (!file.open(QIODevice::ReadOnly)) {
+        qFatal("Failed to read jQuery file %s: %s", qPrintable(file.fileName()),
+               qPrintable(file.errorString()));
+    }
     jQuery = file.readAll();
     jQuery.append("\nvar qt = { 'jQuery': jQuery.noConflict(true) };");
     file.close();
diff --git a/src/core/net/resource_request_body_qt.cpp b/src/core/net/resource_request_body_qt.cpp
index d0d54784dd9..429d1f8048e 100644
--- a/src/core/net/resource_request_body_qt.cpp
+++ b/src/core/net/resource_request_body_qt.cpp
@@ -9,6 +9,8 @@
 #include "services/network/public/mojom/url_request.mojom-shared.h"
 #include "mojo/public/cpp/bindings/remote.h"
 
+using namespace Qt::StringLiterals;
+
 namespace QtWebEngineCore {
 
 ResourceRequestBody::ResourceRequestBody(network::ResourceRequestBody *requestBody, QObject *parent)
@@ -110,7 +112,14 @@ void ResourceRequestBody::readDataElementFile(const base::FilePath &filePath, co
     const std::size_t fileSize = std::min(file.size(), length) - realOffset;
     const std::size_t bytesToRead = std::min(fileSize, static_cast<std::size_t>(maxSize));
 
-    file.open(QFile::ReadOnly);
+    if (!file.open(QFile::ReadOnly)) {
+        m_dataElementsIdx++;
+        m_dataElementFileIdx = 0;
+        setErrorString(u"Error while reading from file, skipping remaining content of "_s
+                       % file.fileName() % u": "_s % file.errorString());
+        return;
+    }
+
     file.seek(realOffset);
 
     std::memcpy(*data, file.read(bytesToRead).data(), bytesToRead);
diff --git a/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp b/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp
index 27ef7383a3b..42c394a847b 100644
--- a/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp
+++ b/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp
@@ -55,22 +55,22 @@ void tst_QWebEngineClientCertificateStore::addAndListCertificates()
 {
     // Load QSslCertificate
     QFile certFile(":/resources/certificate.crt");
-    certFile.open(QIODevice::ReadOnly);
+    QVERIFY2(certFile.open(QIODevice::ReadOnly), qPrintable(certFile.errorString()));
     const QSslCertificate cert(certFile.readAll(), QSsl::Pem);
 
     // Load QSslKey
     QFile keyFile(":/resources/privatekey.key");
-    keyFile.open(QIODevice::ReadOnly);
+    QVERIFY2(keyFile.open(QIODevice::ReadOnly), qPrintable(keyFile.errorString()));
     const QSslKey sslKey(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, "");
 
     // Load second QSslCertificate
     QFile certFileSecond(":/resources/certificate1.crt");
-    certFileSecond.open(QIODevice::ReadOnly);
+    QVERIFY2(certFileSecond.open(QIODevice::ReadOnly), qPrintable(certFileSecond.errorString()));
     const QSslCertificate certSecond(certFileSecond.readAll(), QSsl::Pem);
 
     // Load second QSslKey
     QFile keyFileSecond(":/resources/privatekey1.key");
-    keyFileSecond.open(QIODevice::ReadOnly);
+    QVERIFY2(keyFileSecond.open(QIODevice::ReadOnly), qPrintable(keyFileSecond.errorString()));
     const QSslKey sslKeySecond(keyFileSecond.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, "");
 
     // Add certificates to in-memory store
@@ -138,11 +138,11 @@ void tst_QWebEngineClientCertificateStore::clientAuthentication()
     });
 
     QFile certFile(client_certificate);
-    certFile.open(QIODevice::ReadOnly);
+    QVERIFY2(certFile.open(QIODevice::ReadOnly), qPrintable(certFile.errorString()));
     const QSslCertificate cert(certFile.readAll(), QSsl::Pem);
 
     QFile keyFile(client_key);
-    keyFile.open(QIODevice::ReadOnly);
+    QVERIFY2(keyFile.open(QIODevice::ReadOnly), qPrintable(keyFile.errorString()));
     const QSslKey sslKey(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, "");
 
     if (in_memory)
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
index c84de3599f8..7f8e040158f 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
@@ -962,7 +962,8 @@ class TestPostRequestInterceptor : public QWebEngineUrlRequestInterceptor
             info.d_ptr->appendFileToResourceRequestBodyForTest(":/resources/postBodyFile.txt");
         }
 
-        requestBodyDevice->open(QIODevice::ReadOnly);
+        QVERIFY2(requestBodyDevice->open(QIODevice::ReadOnly),
+                 qPrintable(requestBodyDevice->errorString()));
 
         const QString webKitBoundary = requestBodyDevice->read(40);
         QVERIFY(webKitBoundary.contains("------WebKitFormBoundary"));
diff --git a/tests/auto/core/qwebengineurlrequestjob/tst_qwebengineurlrequestjob.cpp b/tests/auto/core/qwebengineurlrequestjob/tst_qwebengineurlrequestjob.cpp
index acddfb0e021..8552ba441b7 100644
--- a/tests/auto/core/qwebengineurlrequestjob/tst_qwebengineurlrequestjob.cpp
+++ b/tests/auto/core/qwebengineurlrequestjob/tst_qwebengineurlrequestjob.cpp
@@ -77,7 +77,7 @@ class AdditionalResponseHeadersHandler : public QWebEngineUrlSchemeHandler
         job->setAdditionalResponseHeaders(additionalResponseHeaders);
 
         QFile *file = new QFile(QStringLiteral(":additionalResponseHeadersScript.html"), job);
-        file->open(QIODevice::ReadOnly);
+        QVERIFY2(file->open(QIODevice::ReadOnly), qPrintable(file->errorString()));
 
         job->reply(QByteArrayLiteral("text/html"), file);
     }
@@ -106,12 +106,13 @@ class RequestBodyHandler : public QWebEngineUrlSchemeHandler
         QCOMPARE(job->requestMethod(), QByteArrayLiteral("POST"));
 
         QIODevice *requestBodyDevice = job->requestBody();
-        requestBodyDevice->open(QIODevice::ReadOnly);
+        QVERIFY2(requestBodyDevice->open(QIODevice::ReadOnly),
+                 qPrintable(requestBodyDevice->errorString()));
         QByteArray requestBody = requestBodyDevice->readAll();
         requestBodyDevice->close();
 
         QBuffer *buf = new QBuffer(job);
-        buf->open(QBuffer::ReadWrite);
+        QVERIFY2(buf->open(QBuffer::ReadWrite), qPrintable(buf->errorString()));
         buf->write(requestBody);
         job->reply(QByteArrayLiteral("text/plain"), buf);
         buf->close();
diff --git a/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp b/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp
index 45d1d5a7b01..1e90b221d2d 100644
--- a/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp
+++ b/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp
@@ -62,7 +62,7 @@ struct TemporaryPdf: public QTemporaryFile
 
 TemporaryPdf::TemporaryPdf():QTemporaryFile(QStringLiteral("qpdfdocument"))
 {
-    open();
+    QVERIFY2(open(), qPrintable(errorString()));
     pageLayout = QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF());
 
     {
diff --git a/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp b/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
index a47bdbcc4d3..455fa5e73ef 100644
--- a/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
+++ b/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
@@ -921,13 +921,13 @@ void tst_QWebEngineDownloadRequest::downloadUniqueFilenameWithTimestamp()
     // Create the first empty file without uniquifier.
     {
         QFile file(m_profile->downloadPath() + "/" + fileName);
-        file.open(QIODevice::ReadWrite);
+        QVERIFY2(file.open(QIODevice::ReadWrite), qPrintable(file.errorString()));
     }
 
     // Create 99 empty files with uniquifier.
     for (int i = 1; i < 100; i++) {
         QFile file(m_profile->downloadPath() + "/" + baseName + " (" + QString::number(i) + ")." + extension);
-        file.open(QIODevice::ReadWrite);
+        QVERIFY2(file.open(QIODevice::ReadWrite), qPrintable(file.errorString()));
     }
 
     // Create 100th (kMaxUniqueFiles) empty file with uniquifier.
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index c2f189bb78a..e8dac91e788 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -2687,7 +2687,7 @@ void tst_QWebEnginePage::setContent_data()
     QTest::newRow("UTF-8 plain text") << "text/plain; charset=utf-8" << str.toUtf8() << str;
 
     QBuffer out16;
-    out16.open(QIODevice::WriteOnly);
+    QVERIFY2(out16.open(QIODevice::WriteOnly), qPrintable(out16.errorString()));
     QTextStream stream16(&out16);
     stream16.setEncoding(QStringConverter::Utf16);
     stream16 << str;
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index 866daa77305..e7492ce7e28 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -173,7 +173,7 @@ class TestServer : public HttpServer
         }
 
         QFile file(resourceDir.filePath(path));
-        file.open(QIODevice::ReadOnly);
+        QVERIFY2(file.open(QIODevice::ReadOnly), qPrintable(file.errorString()));
         QByteArray data = file.readAll();
         rr->setResponseBody(data);
         QMimeDatabase db;
@@ -671,7 +671,7 @@ class XhrStatusUrlSchemeHandler : public QWebEngineUrlSchemeHandler
         QString path = job->requestUrl().path();
         if (path == "/") {
             QBuffer *buffer = new QBuffer(job);
-            buffer->open(QBuffer::ReadWrite);
+            QVERIFY2(buffer->open(QBuffer::ReadWrite), qPrintable(buffer->errorString()));
             buffer->write(QByteArrayLiteral(R"(
 <html>
   <body>
@@ -695,7 +695,7 @@ class XhrStatusUrlSchemeHandler : public QWebEngineUrlSchemeHandler
             job->reply("text/html", buffer);
         } else if (path == "/qwebchannel.js") {
             QFile *file = new QFile(":/qtwebchannel/qwebchannel.js", job);
-            file->open(QFile::ReadOnly);
+            QVERIFY2(file->open(QFile::ReadOnly), qPrintable(file->errorString()));
             job->reply("application/javascript", file);
         } else if (path == "/ok") {
             QBuffer *buffer = new QBuffer(job);
diff --git a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
index 1a4ee9c4b4b..1dfa94565e7 100644
--- a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
+++ b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
@@ -359,7 +359,10 @@ class TestObject : public QObject
 static QString readFile(const QString &path)
 {
     QFile file(path);
-    file.open(QFile::ReadOnly);
+    if (!file.open(QFile::ReadOnly)) {
+        qWarning("Failed to read file %s: %s", qPrintable(path), qPrintable(file.errorString()));
+        return QString();
+    }
     QByteArray contents = file.readAll();
     file.close();
     return contents;

From 941b917aa260dc9ba1b8d67a5dcfe8a66fd53b96 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Mon, 27 Jan 2025 10:54:46 +0100
Subject: [PATCH 249/356] Add logging category for graphics integration

The logging can be enabled with
QT_LOGGING_RULES="qt.webengine.compositor=true"

Change-Id: Ibf48c7bd9a6bf560e2ef2c88abb5f6c4fe122916
Reviewed-by: Moss Heim <moss.heim@qt.io>
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 36c8d988aa1cb9566bc1d41af6ddc8c6596cfb53)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 31651eb566d483bf49f9a45cf1802ef12a5a6481)
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
---
 src/core/api/qtwebenginecoreglobal_p.h        |  1 +
 src/core/compositor/compositor.cpp            | 22 +++++++++++++++++++
 src/core/compositor/compositor.h              |  4 +++-
 .../compositor/display_skia_output_device.cpp |  8 +++++++
 .../compositor/native_skia_output_device.cpp  | 18 +++++++++++++--
 .../native_skia_output_device_direct3d11.cpp  |  4 ++++
 .../native_skia_output_device_metal.cpp       |  4 ++++
 .../native_skia_output_device_opengl.cpp      |  9 ++++++++
 .../native_skia_output_device_vulkan.cpp      |  5 +++++
 9 files changed, 72 insertions(+), 3 deletions(-)

diff --git a/src/core/api/qtwebenginecoreglobal_p.h b/src/core/api/qtwebenginecoreglobal_p.h
index a63568c8acd..0b8f40e562c 100644
--- a/src/core/api/qtwebenginecoreglobal_p.h
+++ b/src/core/api/qtwebenginecoreglobal_p.h
@@ -18,6 +18,7 @@
 #include <QtWebEngineCore/qtwebenginecoreglobal.h>
 #include <QtCore/private/qglobal_p.h>
 #include <QtWebEngineCore/private/qtwebenginecore-config_p.h>
+#include <QLoggingCategory>
 
 #ifdef QT_WEBENGINE_LOGGING
 #define QT_NOT_YET_IMPLEMENTED fprintf(stderr, "function %s not implemented! - %s:%d\n", __func__, __FILE__, __LINE__);
diff --git a/src/core/compositor/compositor.cpp b/src/core/compositor/compositor.cpp
index 35b30234f14..1ea92250501 100644
--- a/src/core/compositor/compositor.cpp
+++ b/src/core/compositor/compositor.cpp
@@ -6,12 +6,15 @@
 #include "base/memory/ref_counted.h"
 #include "components/viz/common/surfaces/frame_sink_id.h"
 
+#include <QGuiApplication>
 #include <QHash>
 #include <QMutex>
 #include <QQuickWindow>
 
 namespace QtWebEngineCore {
 
+Q_LOGGING_CATEGORY(lcWebEngineCompositor, "qt.webengine.compositor");
+
 // Compositor::Id
 
 Compositor::Id::Id(viz::FrameSinkId fid) : client_id(fid.client_id()), sink_id(fid.sink_id()) { }
@@ -161,6 +164,25 @@ bool Compositor::textureIsFlipped()
 
 void Compositor::releaseResources() { }
 
+Compositor::Compositor(Type type) : m_type(type)
+{
+    if (Q_UNLIKELY(lcWebEngineCompositor().isDebugEnabled())) {
+        switch (m_type) {
+        case Type::Software:
+            qCDebug(lcWebEngineCompositor, "Compositor Type: Software");
+            break;
+        case Type::OpenGL:
+            qCDebug(lcWebEngineCompositor, "Compositor Type: OpenGL");
+            break;
+        case Type::Native:
+            qCDebug(lcWebEngineCompositor, "Compositor Type: Native");
+            break;
+        }
+    }
+    qCDebug(lcWebEngineCompositor, "QPA Platform Plugin: %s",
+            qPrintable(QGuiApplication::platformName()));
+}
+
 Compositor::~Compositor()
 {
     DCHECK(!m_binding); // check that unbind() was called by derived final class
diff --git a/src/core/compositor/compositor.h b/src/core/compositor/compositor.h
index 5d3033f8ef4..041835dd0c2 100644
--- a/src/core/compositor/compositor.h
+++ b/src/core/compositor/compositor.h
@@ -18,6 +18,8 @@ class FrameSinkId;
 
 namespace QtWebEngineCore {
 
+Q_DECLARE_LOGGING_CATEGORY(lcWebEngineCompositor);
+
 // Produces composited frames for display.
 //
 // Used by quick/widgets libraries for accessing the frames and
@@ -136,7 +138,7 @@ class Q_WEBENGINECORE_EXPORT Compositor
     virtual void releaseResources();
 
 protected:
-    Compositor(Type type) : m_type(type) { }
+    Compositor(Type type);
     virtual ~Compositor();
 
 private:
diff --git a/src/core/compositor/display_skia_output_device.cpp b/src/core/compositor/display_skia_output_device.cpp
index 800e2cc1b24..07986278e80 100644
--- a/src/core/compositor/display_skia_output_device.cpp
+++ b/src/core/compositor/display_skia_output_device.cpp
@@ -26,6 +26,10 @@ class DisplaySkiaOutputDevice::Buffer
     }
     void initialize()
     {
+        qCDebug(lcWebEngineCompositor, "Initializing buffer %p with GrBackendTexture:", this);
+        qCDebug(lcWebEngineCompositor, "  Pixels size: %dx%d", m_shape.imageInfo.width(),
+                m_shape.imageInfo.height());
+
         const auto &colorType = m_shape.imageInfo.colorType();
         DCHECK(colorType != kUnknown_SkColorType);
 
@@ -95,6 +99,8 @@ DisplaySkiaOutputDevice::DisplaySkiaOutputDevice(
     , m_contextState(contextState)
     , m_requiresAlpha(requiresAlpha)
 {
+    qCDebug(lcWebEngineCompositor, "Display Skia Output Device: OpenGL");
+
     capabilities_.uses_default_gl_framebuffer = false;
     capabilities_.supports_surfaceless = true;
     capabilities_.preserve_buffer_content = true;
@@ -194,6 +200,8 @@ void DisplaySkiaOutputDevice::waitForTexture()
 
 QSGTexture *DisplaySkiaOutputDevice::texture(QQuickWindow *win, uint32_t textureOptions)
 {
+    qCDebug(lcWebEngineCompositor, "OPENGL: Importing shared GL Texture.");
+
     if (!m_frontBuffer)
         return nullptr;
 
diff --git a/src/core/compositor/native_skia_output_device.cpp b/src/core/compositor/native_skia_output_device.cpp
index fbe60277822..64688f9a018 100644
--- a/src/core/compositor/native_skia_output_device.cpp
+++ b/src/core/compositor/native_skia_output_device.cpp
@@ -60,6 +60,8 @@ NativeSkiaOutputDevice::NativeSkiaOutputDevice(
     m_isNativeBufferSupported = ui::OzonePlatform::GetInstance()
                                         ->GetPlatformRuntimeProperties()
                                         .supports_native_pixmaps;
+    qCDebug(lcWebEngineCompositor, "Native Buffer Supported: %s",
+            m_isNativeBufferSupported ? "yes" : "no");
 #endif
 }
 
@@ -226,17 +228,29 @@ NativeSkiaOutputDevice::Buffer::~Buffer()
 // found in the LICENSE file.
 bool NativeSkiaOutputDevice::Buffer::initialize()
 {
+    qCDebug(lcWebEngineCompositor, "Initializing buffer %p with SharedImage:", this);
+
     uint32_t kDefaultSharedImageUsage = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ
             | gpu::SHARED_IMAGE_USAGE_DISPLAY_WRITE
             | gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT;
+
     if (m_parent->m_isNativeBufferSupported)
         kDefaultSharedImageUsage |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
 
+    qCDebug(lcWebEngineCompositor, "  Usage: %s",
+            gpu::CreateLabelForSharedImageUsage(kDefaultSharedImageUsage).c_str());
+    qCDebug(lcWebEngineCompositor, "  Pixels size: %dx%d", m_shape.imageInfo.width(),
+            m_shape.imageInfo.height());
+
     auto mailbox = gpu::Mailbox::GenerateForSharedImage();
 
-    SkColorType skColorType = m_shape.imageInfo.colorType();
+    const SkColorType skColorType = m_shape.imageInfo.colorType();
+    const viz::SharedImageFormat sharedImageFormat =
+            viz::SkColorTypeToSinglePlaneSharedImageFormat(skColorType);
+    qCDebug(lcWebEngineCompositor, "  Format: %s", sharedImageFormat.ToString().c_str());
+
     if (!m_parent->m_factory->CreateSharedImage(
-                mailbox, viz::SkColorTypeToSinglePlaneSharedImageFormat(skColorType),
+                mailbox, sharedImageFormat,
                 { m_shape.imageInfo.width(), m_shape.imageInfo.height() }, m_shape.colorSpace,
                 kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, m_parent->m_deps->GetSurfaceHandle(),
                 kDefaultSharedImageUsage, "QWE_SharedImageBuffer")) {
diff --git a/src/core/compositor/native_skia_output_device_direct3d11.cpp b/src/core/compositor/native_skia_output_device_direct3d11.cpp
index c9e4b22c2c7..e2f33506890 100644
--- a/src/core/compositor/native_skia_output_device_direct3d11.cpp
+++ b/src/core/compositor/native_skia_output_device_direct3d11.cpp
@@ -21,6 +21,8 @@ NativeSkiaOutputDeviceDirect3D11::NativeSkiaOutputDeviceDirect3D11(
                              shared_image_factory, shared_image_representation_factory,
                              didSwapBufferCompleteCallback)
 {
+    qCDebug(lcWebEngineCompositor, "Native Skia Output Device: Direct3D11");
+
     SkColorType skColorType = kRGBA_8888_SkColorType;
     capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBA_8888)] = skColorType;
     capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBX_8888)] = skColorType;
@@ -41,6 +43,8 @@ QSGTexture *NativeSkiaOutputDeviceDirect3D11::texture(QQuickWindow *win, uint32_
         return nullptr;
     }
 
+    qCDebug(lcWebEngineCompositor, "D3D: Importing DXGI Resource into D3D11 Texture.");
+
     Q_ASSERT(overlayImage->type() == gl::DCLayerOverlayType::kNV12Texture);
     Microsoft::WRL::ComPtr<ID3D11Texture2D> chromeTexture = overlayImage->nv12_texture();
     if (!chromeTexture) {
diff --git a/src/core/compositor/native_skia_output_device_metal.cpp b/src/core/compositor/native_skia_output_device_metal.cpp
index a9d6e4fd53b..5ca0a58b689 100644
--- a/src/core/compositor/native_skia_output_device_metal.cpp
+++ b/src/core/compositor/native_skia_output_device_metal.cpp
@@ -18,6 +18,8 @@ NativeSkiaOutputDeviceMetal::NativeSkiaOutputDeviceMetal(
                              shared_image_factory, shared_image_representation_factory,
                              didSwapBufferCompleteCallback)
 {
+    qCDebug(lcWebEngineCompositor, "Native Skia Output Device: Metal");
+
     SkColorType skColorType = kRGBA_8888_SkColorType;
     capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBA_8888)] = skColorType;
     capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBX_8888)] = skColorType;
@@ -42,6 +44,8 @@ QSGTexture *NativeSkiaOutputDeviceMetal::texture(QQuickWindow *win, uint32_t tex
         return nullptr;
     }
 
+    qCDebug(lcWebEngineCompositor, "METAL: Importing IOSurface into Metal Texture.");
+
     // This is a workaround to not to release metal texture too early.
     // In RHI, QMetalTexture wraps MTLTexture. QMetalTexture seems to be only destructed after the
     // next MTLTexture is imported. The "old" MTLTexture can be still pontentially used by RHI
diff --git a/src/core/compositor/native_skia_output_device_opengl.cpp b/src/core/compositor/native_skia_output_device_opengl.cpp
index a65cb2dc155..ac967f26da9 100644
--- a/src/core/compositor/native_skia_output_device_opengl.cpp
+++ b/src/core/compositor/native_skia_output_device_opengl.cpp
@@ -142,6 +142,8 @@ NativeSkiaOutputDeviceOpenGL::NativeSkiaOutputDeviceOpenGL(
                              shared_image_factory, shared_image_representation_factory,
                              didSwapBufferCompleteCallback)
 {
+    qCDebug(lcWebEngineCompositor, "Native Skia Output Device: OpenGL");
+
     SkColorType skColorType = kRGBA_8888_SkColorType;
 #if BUILDFLAG(IS_OZONE_X11)
     if (GLContextHelper::getGlxPlatformInterface()
@@ -240,6 +242,8 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
 
 #if BUILDFLAG(IS_OZONE_X11)
         if (GLContextHelper::getGlxPlatformInterface()) {
+            qCDebug(lcWebEngineCompositor, "GLX: Importing NativePixmap into GL Texture.");
+
             x11::Pixmap pixmapId =
                     XPixmapFromNativePixmap(*(gfx::NativePixmapDmaBuf *)nativePixmap.get());
             if (pixmapId == x11::Pixmap::None)
@@ -270,6 +274,8 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
 #endif // BUILDFLAG(IS_OZONE_X11)
 
         if (GLContextHelper::getEglPlatformInterface()) {
+            qCDebug(lcWebEngineCompositor, "EGL: Importing NativePixmap into GL Texture.");
+
             EGLHelper *eglHelper = EGLHelper::instance();
             auto *eglFun = eglHelper->functions();
 
@@ -317,6 +323,7 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
         }
     } else {
 #if BUILDFLAG(ENABLE_VULKAN)
+        qCDebug(lcWebEngineCompositor, "VULKAN: Importing VkImage into GL Texture.");
         Q_ASSERT(m_contextState->gr_context_type() == gpu::GrContextType::kVulkan);
 
         gpu::VulkanFunctionPointers *vfp = gpu::GetVulkanFunctionPointers();
@@ -378,9 +385,11 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
     texture = QNativeInterface::QSGOpenGLTexture::fromNative(glTexture, win, size(), texOpts);
     Q_ASSERT(glFun->glGetError() == GL_NO_ERROR);
 #elif defined(Q_OS_WIN)
+    qCDebug(lcWebEngineCompositor, "WGL: Importing DXGI Resource into GL Texture.");
     // TODO: Add WGL support over ANGLE.
     QT_NOT_YET_IMPLEMENTED
 #elif defined(Q_OS_MACOS)
+    qCDebug(lcWebEngineCompositor, "CGL: Importing IOSurface into GL Texture.");
     uint32_t glTexture = makeCGLTexture(win, ioSurface.get(), size());
     texture = QNativeInterface::QSGOpenGLTexture::fromNative(glTexture, win, size(), texOpts);
 
diff --git a/src/core/compositor/native_skia_output_device_vulkan.cpp b/src/core/compositor/native_skia_output_device_vulkan.cpp
index 3aec31dcb56..1e3ba2d51c3 100644
--- a/src/core/compositor/native_skia_output_device_vulkan.cpp
+++ b/src/core/compositor/native_skia_output_device_vulkan.cpp
@@ -37,6 +37,8 @@ NativeSkiaOutputDeviceVulkan::NativeSkiaOutputDeviceVulkan(
                              shared_image_factory, shared_image_representation_factory,
                              didSwapBufferCompleteCallback)
 {
+    qCDebug(lcWebEngineCompositor, "Native Skia Output Device: Vulkan");
+
     SkColorType skColorType = kRGBA_8888_SkColorType;
     capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBA_8888)] = skColorType;
     capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBX_8888)] = skColorType;
@@ -145,6 +147,7 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
     };
 
     if (nativePixmap) {
+        qCDebug(lcWebEngineCompositor, "VULKAN: Importing NativePixmap into VkImage.");
         gfx::NativePixmapHandle nativePixmapHandle = nativePixmap->ExportHandle();
         if (nativePixmapHandle.planes.size() != 1)
             qFatal("VULKAN: Multiple planes are not supported.");
@@ -158,6 +161,7 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
 
         scopedFd = std::move(nativePixmapHandle.planes[0].fd);
     } else {
+        qCDebug(lcWebEngineCompositor, "VULKAN: Importing VkImage into VkImage.");
         externalMemoryImageCreateInfo.handleTypes =
                 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
 
@@ -183,6 +187,7 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
     if (!scopedFd.is_valid())
         qFatal("VULKAN: Unable to extract file descriptor.");
 #elif defined(Q_OS_WIN)
+    qCDebug(lcWebEngineCompositor, "VULKAN: Importing DXGI Resource into VkImage.");
     externalMemoryImageCreateInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT;
 
     Q_ASSERT(overlayImage->type() == gl::DCLayerOverlayType::kNV12Texture);

From 5d031d4425cfed541e6abaffb2c1d99daa0c07e3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Thu, 23 Jan 2025 09:37:42 +0100
Subject: [PATCH 250/356] Update Chromium

Submodule src/3rdparty c5287f4d..c8dcfa48:
  * [Backport] Security bug 385386138
  * [Backport] CVE-2025-0611: Object corruption in V8
  * [Backport] CVE-2025-0437: Out of bounds read in Metrics
  * [Backport] CVE-2025-0447: Inappropriate implementation in Navigation
  * [Backport] CVE-2025-0441: Inappropriate implementation in Fenced Frames
  * [Backport] CVE-2025-0443: Insufficient data validation in Extensions
  * [Backport] CVE-2025-0438: Stack buffer overflow in Tracing
  * [Backport] CVE-2025-0436: Integer overflow in Skia

Task-number: QTBUG-133105
Fixes: QTBUG-133107
Fixes: QTBUG-133108
Change-Id: I0a0670b356905a51ae7a063970bfda3259e11b1a
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit d3c9c1d8cb8f9dac09e1fd3457a5850e029090d7)
---
 CHROMIUM_VERSION                | 2 +-
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index c715e74aaba..4a17fe015bd 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
 Based on Chromium version:                                      122.0.6261.171
-Patched with security patches up to Chromium version:           131.0.6778.265
+Patched with security patches up to Chromium version:           132.0.6834.111
diff --git a/src/3rdparty b/src/3rdparty
index c5287f4d6a0..c8dcfa4891c 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit c5287f4d6a0e64d357e7405599ecb6c7d2d4e5fd
+Subproject commit c8dcfa4891c8dcf733b0c6ecc6ddcfe781d4567d
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 39027b35467..52c017dffb9 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1268,7 +1268,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "131.0.6778.265"; // FIXME: Remember to update
+    return "132.0.6834.111"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From 24ee881290f8d1fc3292f14f726de34d2d81217e Mon Sep 17 00:00:00 2001
From: Allan Sandfeld Jensen <allan.jensen@qt.io>
Date: Fri, 31 Jan 2025 09:55:48 +0100
Subject: [PATCH 251/356] Set rtc_use_h264 to true again

Enables H264 on Windows with proprietary codecs.

Pick-to: 6.5
Task-number: QTBUG-117478
Change-Id: Ie46fcce555fac751e7eb5e90c0e079462dcadc0c
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
Reviewed-by: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
(cherry picked from commit 4a43f458ee9971aca82c1b28586be58f88ce8a8b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 073857250cc13c6627bb80dcba86d77d00345155)
---
 src/core/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 3d871f65205..8059d1dcf90 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -417,7 +417,7 @@ foreach(arch ${archs})
             CONDITION QT_FEATURE_webengine_kerberos
         )
         extend_gn_list(gnArgArg
-            ARGS proprietary_codecs
+            ARGS proprietary_codecs rtc_use_h264
             CONDITION QT_FEATURE_webengine_proprietary_codecs
         )
         if(QT_FEATURE_webengine_proprietary_codecs)

From 3d88b5e9011c92beff016fea6f2af51330398c26 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Wed, 22 Jan 2025 17:32:52 +0100
Subject: [PATCH 252/356] Unify and modernize Latin1 string literals

- Fix some deprecated string literal compiler warnings
- Replace deprecated QLatin1String usages
- Use QLatin1StringView where QString conversion is not needed
- Replace QLatin1StringView usages with shorter _L1 suffix

Change-Id: I8adb6dcd06ac5dfc248d39455c14a26957876512
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit 900ae370f5d6c06a29b08fd94523d30bdc089b88)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit fca622c2cc915fa9d980d7a715d88cc2dc8b443b)
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
---
 .../accessibility_activation_observer.cpp     |   7 +-
 src/core/api/qwebenginepage.cpp               |  27 ++--
 src/core/api/qwebenginescript.cpp             |   3 +-
 src/core/clipboard_qt.cpp                     |   4 +-
 src/core/content_client_qt.cpp                |  52 ++++----
 src/core/devtools_manager_delegate_qt.cpp     |   3 +-
 src/core/download_manager_delegate_qt.cpp     |   6 +-
 src/core/file_picker_controller.cpp           |  18 +--
 src/core/net/qrc_url_scheme_handler.cpp       |   4 +-
 src/core/permission_manager_qt.cpp            |   7 +-
 src/core/pref_service_adapter.cpp             |   7 +-
 .../printing/print_view_manager_base_qt.cpp   |   6 +-
 src/core/profile_adapter.cpp                  |  11 +-
 .../tools/qwebengine_convert_dict/main.cpp    |  11 +-
 src/core/web_contents_adapter.cpp             |  16 ++-
 src/core/web_contents_delegate_qt.cpp         |   3 +-
 src/core/web_engine_context.cpp               |  91 ++++++-------
 src/core/web_engine_library_info.cpp          | 124 ++++++++----------
 src/core/web_event_factory.cpp                |  12 +-
 19 files changed, 212 insertions(+), 200 deletions(-)

diff --git a/src/core/accessibility_activation_observer.cpp b/src/core/accessibility_activation_observer.cpp
index 4f25a35ffed..4e90b9b3b38 100644
--- a/src/core/accessibility_activation_observer.cpp
+++ b/src/core/accessibility_activation_observer.cpp
@@ -5,6 +5,8 @@
 
 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
 
+using namespace Qt::StringLiterals;
+
 namespace QtWebEngineCore {
 
 namespace {
@@ -14,9 +16,8 @@ bool isAccessibilityEnabled() {
     // QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY environment variable to 0. For details,
     // see QTBUG-59922.
 #ifdef Q_OS_LINUX
-    static bool accessibility_enabled
-            = qEnvironmentVariable("QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY", QLatin1String("1"))
-                == QLatin1String("1");
+    static bool accessibility_enabled =
+            qEnvironmentVariable("QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY", u"1"_s) == "1"_L1;
 #else
     const bool accessibility_enabled = true;
 #endif
diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp
index d209e0ca965..b180b58b99d 100644
--- a/src/core/api/qwebenginepage.cpp
+++ b/src/core/api/qwebenginepage.cpp
@@ -57,6 +57,7 @@
 
 QT_BEGIN_NAMESPACE
 
+using namespace Qt::StringLiterals;
 using namespace QtWebEngineCore;
 
 static QWebEnginePage::WebWindowType toWindowType(WebContentsAdapterClient::WindowOpenDisposition disposition)
@@ -1341,11 +1342,10 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
             QString linkText = d->view->lastContextMenuRequest()->linkText().toHtmlEscaped();
             QString title = d->view->lastContextMenuRequest()->titleText();
             if (!title.isEmpty())
-                title = QStringLiteral(" title=\"%1\"").arg(title.toHtmlEscaped());
+                title = " title=\""_L1 + title.toHtmlEscaped() + u'"';
             QMimeData *data = new QMimeData();
             data->setText(urlString);
-            QString html = QStringLiteral("<a href=\"") + urlString + QStringLiteral("\"") + title + QStringLiteral(">")
-                         + linkText + QStringLiteral("</a>");
+            QString html = "<a href=\""_L1 + urlString + u'"' + title + u'>' + linkText + "</a>"_L1;
             data->setHtml(html);
             data->setUrls(QList<QUrl>() << d->view->lastContextMenuRequest()->linkUrl());
             QGuiApplication::clipboard()->setMimeData(data);
@@ -1376,13 +1376,13 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
                     d->view->lastContextMenuRequest()->mediaUrl().toString(QUrl::FullyEncoded);
             QString alt = d->view->lastContextMenuRequest()->altText();
             if (!alt.isEmpty())
-                alt = QStringLiteral(" alt=\"%1\"").arg(alt.toHtmlEscaped());
+                alt = " alt=\""_L1 + alt.toHtmlEscaped() + u'"';
             QString title = d->view->lastContextMenuRequest()->titleText();
             if (!title.isEmpty())
-                title = QStringLiteral(" title=\"%1\"").arg(title.toHtmlEscaped());
+                title = " title=\""_L1 + title.toHtmlEscaped() + u'"';
             QMimeData *data = new QMimeData();
             data->setText(urlString);
-            QString html = QStringLiteral("<img src=\"") + urlString + QStringLiteral("\"") + title + alt + QStringLiteral("></img>");
+            QString html = "<img src=\""_L1 + urlString + u'"' + title + alt + "></img>"_L1;
             data->setHtml(html);
             data->setUrls(QList<QUrl>() << d->view->lastContextMenuRequest()->mediaUrl());
             QGuiApplication::clipboard()->setMimeData(data);
@@ -1406,16 +1406,15 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
                     d->view->lastContextMenuRequest()->mediaUrl().toString(QUrl::FullyEncoded);
             QString title = d->view->lastContextMenuRequest()->titleText();
             if (!title.isEmpty())
-                title = QStringLiteral(" title=\"%1\"").arg(title.toHtmlEscaped());
+                title = " title=\""_L1 + title.toHtmlEscaped() + u'"';
             QMimeData *data = new QMimeData();
             data->setText(urlString);
-            if (d->view->lastContextMenuRequest()->mediaType()
-                == QWebEngineContextMenuRequest::MediaTypeAudio)
-                data->setHtml(QStringLiteral("<audio src=\"") + urlString + QStringLiteral("\"") + title +
-                              QStringLiteral("></audio>"));
-            else
-                data->setHtml(QStringLiteral("<video src=\"") + urlString + QStringLiteral("\"") + title +
-                              QStringLiteral("></video>"));
+            const bool isAudio = d->view->lastContextMenuRequest()->mediaType()
+                    == QWebEngineContextMenuRequest::MediaTypeAudio;
+            const auto avTagName = isAudio ? "audio"_L1 : "video"_L1;
+            QString html = u'<' + avTagName + "src=\""_L1 + urlString + u'"' + title + "></"_L1
+                    + avTagName + u'>';
+            data->setHtml(html);
             data->setUrls(QList<QUrl>() << d->view->lastContextMenuRequest()->mediaUrl());
             QGuiApplication::clipboard()->setMimeData(data);
         }
diff --git a/src/core/api/qwebenginescript.cpp b/src/core/api/qwebenginescript.cpp
index 846b011967c..8d1ff46bf49 100644
--- a/src/core/api/qwebenginescript.cpp
+++ b/src/core/api/qwebenginescript.cpp
@@ -7,6 +7,7 @@
 #include <QtCore/QDebug>
 #include <QtCore/QFile>
 
+using namespace Qt::StringLiterals;
 using QtWebEngineCore::UserScript;
 
 QT_BEGIN_NAMESPACE
@@ -161,7 +162,7 @@ void QWebEngineScript::setSourceUrl(const QUrl &url)
     QFile file;
     if (url.isLocalFile()) {
         file.setFileName(url.toLocalFile());
-    } else if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) {
+    } else if (url.scheme().compare("qrc"_L1, Qt::CaseInsensitive) == 0) {
         if (url.authority().isEmpty())
             file.setFileName(QLatin1Char(':') + url.path());
     }
diff --git a/src/core/clipboard_qt.cpp b/src/core/clipboard_qt.cpp
index 1140164ae98..cd63b0b6f29 100644
--- a/src/core/clipboard_qt.cpp
+++ b/src/core/clipboard_qt.cpp
@@ -32,6 +32,8 @@
 
 #include <memory>
 
+using namespace Qt::StringLiterals;
+
 namespace QtWebEngineCore {
 
 static void registerMetaTypes()
@@ -139,7 +141,7 @@ void ClipboardQt::WriteHTML(base::StringPiece markup, absl::optional<base::Strin
     // We need to prepend the charset on macOS to prevent garbled Unicode characters
     // when pasting to certain applications (e.g. Notes, TextEdit)
     // Mirrors the behavior in ui/base/clipboard/clipboard_mac.mm in Chromium.
-    markup_string.prepend(QLatin1String("<meta charset='utf-8'>"));
+    markup_string.prepend("<meta charset='utf-8'>"_L1);
 #endif
 
 #if !defined(Q_OS_WIN)
diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index 5d9cc7b3576..95d6ec4e3c6 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -57,13 +57,15 @@ const char kWidevineCdmFileName[] =
 const char kPdfPluginPath[] = "internal-pdf-viewer";
 #endif // QT_CONFIG(webengine_printing_and_pdf)
 
+using namespace Qt::StringLiterals;
 using Robustness = content::CdmInfo::Robustness;
 
 static QString webenginePluginsPath()
 {
     // Look for plugins in /plugins/webengine or application dir.
     static bool initialized = false;
-    static QString potentialPluginsPath = QLibraryInfo::path(QLibraryInfo::PluginsPath) % QLatin1String("/webengine");
+    static QString potentialPluginsPath =
+            QLibraryInfo::path(QLibraryInfo::PluginsPath) % "/webengine"_L1;
     if (!initialized) {
         initialized = true;
         if (!QFileInfo::exists(potentialPluginsPath))
@@ -107,7 +109,8 @@ static QString ppapiPluginsPath()
 {
     // Look for plugins in /plugins/ppapi or application dir.
     static bool initialized = false;
-    static QString potentialPluginsPath = QLibraryInfo::path(QLibraryInfo::PluginsPath) % QLatin1String("/ppapi");
+    static QString potentialPluginsPath =
+            QLibraryInfo::path(QLibraryInfo::PluginsPath) % "/ppapi"_L1;
     if (!initialized) {
         initialized = true;
         if (!QFileInfo::exists(potentialPluginsPath))
@@ -151,7 +154,7 @@ namespace QtWebEngineCore {
 static const QDir widevineCdmDirHint(const QDir &widevineDir)
 {
     const QString hintFilePath = widevineDir.absolutePath() % QDir::separator()
-            % QLatin1String("latest-component-updated-widevine-cdm");
+            % "latest-component-updated-widevine-cdm"_L1;
     if (!QFileInfo::exists(hintFilePath)) {
         // CDM hint file does not exist.
         return widevineDir;
@@ -189,32 +192,33 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path,
     if (!widevine_argument.empty())
         pluginPaths << QtWebEngineCore::toQt(widevine_argument);
     else {
-        pluginPaths << webenginePluginsPath() + QStringLiteral("/") + QString::fromLatin1(kWidevineCdmFileName);
+        pluginPaths << webenginePluginsPath() + QStringLiteral("/") + QLatin1StringView(kWidevineCdmFileName);
 #if QT_CONFIG(webengine_pepper_plugins)
-        pluginPaths << ppapiPluginsPath() + QStringLiteral("/") + QString::fromLatin1(kWidevineCdmFileName);
+        pluginPaths << ppapiPluginsPath() + QStringLiteral("/") + QLatin1StringView(kWidevineCdmFileName);
 #endif
 #if defined(Q_OS_OSX)
     QDir potentialWidevineDir("/Applications/Google Chrome.app/Contents/Frameworks");
     if (potentialWidevineDir.exists()) {
         QFileInfoList widevineVersionDirs = potentialWidevineDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot,
                                                                                QDir::Name | QDir::Reversed);
-        const QString library = QLatin1String("/Versions/Current/Libraries/"
-                                              "WidevineCdm/_platform_specific/mac_x64/libwidevinecdm.dylib");
+        const auto library =
+                "/Versions/Current/Libraries/WidevineCdm/_platform_specific/mac_x64/libwidevinecdm.dylib"_L1;
         for (const QFileInfo &info : widevineVersionDirs)
             pluginPaths << info.absoluteFilePath() + library;
     }
 
-    QDir oldPotentialWidevineDir(QDir::homePath() + "/Library/Application Support/Google/Chrome/WidevineCDM");
+    QDir oldPotentialWidevineDir(QDir::homePath() + "/Library/Application Support/Google/Chrome/WidevineCDM"_L1);
     if (oldPotentialWidevineDir.exists()) {
         QFileInfoList widevineVersionDirs = oldPotentialWidevineDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed);
         for (int i = 0; i < widevineVersionDirs.size(); ++i) {
             QString versionDirPath(widevineVersionDirs.at(i).absoluteFilePath());
-            QString potentialWidevinePluginPath = versionDirPath + "/_platform_specific/mac_x64/" + QString::fromLatin1(kWidevineCdmFileName);
+            QString potentialWidevinePluginPath = versionDirPath + "/_platform_specific/mac_x64/"_L1
+                    + QLatin1StringView(kWidevineCdmFileName);
             pluginPaths << potentialWidevinePluginPath;
         }
     }
 #elif defined(Q_OS_WIN)
-    const QString googleChromeDir = QLatin1String("/Google/Chrome/Application");
+    const auto googleChromeDir = "/Google/Chrome/Application"_L1;
     const QStringList programFileDirs{getProgramFilesDir() + googleChromeDir,
                                       getProgramFilesDir(true) + googleChromeDir};
     for (const QString &dir : programFileDirs) {
@@ -225,26 +229,26 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path,
                 QString versionDirPath(widevineVersionDirs.at(i).absoluteFilePath());
 #ifdef WIN64
                 QString potentialWidevinePluginPath = versionDirPath +
-                                                        "/WidevineCdm/_platform_specific/win_x64/" +
-                                                        QString::fromLatin1(kWidevineCdmFileName);
+                                                        "/WidevineCdm/_platform_specific/win_x64/"_L1 +
+                                                        QLatin1StringView(kWidevineCdmFileName);
 #else
                 QString potentialWidevinePluginPath = versionDirPath +
-                                                        "/WidevineCdm/_platform_specific/win_x86/" +
-                                                        QString::fromLatin1(kWidevineCdmFileName);
+                                                        "/WidevineCdm/_platform_specific/win_x86/"_L1 +
+                                                        QLatin1StringView(kWidevineCdmFileName);
 #endif
                 pluginPaths << potentialWidevinePluginPath;
             }
         }
     }
-    QDir potentialWidevineDir(getLocalAppDataDir() + "/Google/Chrome/User Data/WidevineCDM");
+    QDir potentialWidevineDir(getLocalAppDataDir() + "/Google/Chrome/User Data/WidevineCDM"_L1);
     if (potentialWidevineDir.exists()) {
         QFileInfoList widevineVersionDirs = potentialWidevineDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed);
         for (int i = 0; i < widevineVersionDirs.size(); ++i) {
             QString versionDirPath(widevineVersionDirs.at(i).absoluteFilePath());
 #ifdef WIN64
-            QString potentialWidevinePluginPath = versionDirPath + "/_platform_specific/win_x64/" + QString::fromLatin1(kWidevineCdmFileName);
+            QString potentialWidevinePluginPath = versionDirPath + "/_platform_specific/win_x64/"_L1 + QLatin1StringView(kWidevineCdmFileName);
 #else
-            QString potentialWidevinePluginPath = versionDirPath + "/_platform_specific/win_x86/" + QString::fromLatin1(kWidevineCdmFileName);
+            QString potentialWidevinePluginPath = versionDirPath + "/_platform_specific/win_x86/"_L1 + QLatin1StringView(kWidevineCdmFileName);
 #endif
             pluginPaths << potentialWidevinePluginPath;
         }
@@ -253,23 +257,23 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path,
         QList<QDir> potentialWidevineVersionDirs;
 
         // Google Chrome widevine modules
-        QDir chromeWidevineDir(QDir::homePath() + "/.config/google-chrome/WidevineCdm");
+        QDir chromeWidevineDir(QDir::homePath() + "/.config/google-chrome/WidevineCdm"_L1);
         if (chromeWidevineDir.exists())
             potentialWidevineVersionDirs << widevineCdmDirHint(chromeWidevineDir);
 
         // Firefox widevine modules
-        QDir firefoxPotentialProfilesDir(QDir::homePath() + "/.mozilla/firefox");
+        QDir firefoxPotentialProfilesDir(QDir::homePath() + "/.mozilla/firefox"_L1);
         if (firefoxPotentialProfilesDir.exists()) {
             QFileInfoList firefoxProfileDirs = firefoxPotentialProfilesDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed);
             for (const QFileInfo &info : firefoxProfileDirs) {
-                QDir widevinePluginsDir(info.absoluteFilePath() + "/gmp-widevinecdm");
+                QDir widevinePluginsDir(info.absoluteFilePath() + "/gmp-widevinecdm"_L1);
                 if (widevinePluginsDir.exists())
                     potentialWidevineVersionDirs << widevinePluginsDir;
             }
         }
 
         // Chromium widevine modules (might not work with proprietary codecs)
-        QDir chromiumWidevineDir(QDir::homePath() + "/.config/chromium/WidevineCdm");
+        QDir chromiumWidevineDir(QDir::homePath() + "/.config/chromium/WidevineCdm"_L1);
         if (chromiumWidevineDir.exists())
             potentialWidevineVersionDirs << widevineCdmDirHint(chromiumWidevineDir);
 
@@ -279,12 +283,12 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path,
             widevineVersionDirs.prepend(QFileInfo(dir.absolutePath()));
             // ### alternatively look up in the manifest.json and take the path from there.
 #if Q_PROCESSOR_WORDSIZE == 8
-            const QString library = QLatin1String("/_platform_specific/linux_x64/libwidevinecdm.so");
+            const auto library = "/_platform_specific/linux_x64/libwidevinecdm.so"_L1;
 #else
-            const QString library = QLatin1String("/_platform_specific/linux_x86/libwidevinecdm.so");
+            const auto library = "/_platform_specific/linux_x86/libwidevinecdm.so"_L1;
 #endif
             for (const QFileInfo &info : widevineVersionDirs) {
-                pluginPaths << info.absoluteFilePath() + "/libwidevinecdm.so";
+                pluginPaths << info.absoluteFilePath() + "/libwidevinecdm.so"_L1;
                 pluginPaths << info.absoluteFilePath() + library;
             }
         }
diff --git a/src/core/devtools_manager_delegate_qt.cpp b/src/core/devtools_manager_delegate_qt.cpp
index 6654ead0ec6..433effed4d8 100644
--- a/src/core/devtools_manager_delegate_qt.cpp
+++ b/src/core/devtools_manager_delegate_qt.cpp
@@ -20,6 +20,7 @@
 #include "net/socket/tcp_server_socket.h"
 #include "ui/base/resource/resource_bundle.h"
 
+using namespace Qt::StringLiterals;
 using content::DevToolsAgentHost;
 
 namespace {
@@ -52,7 +53,7 @@ class TCPServerSocketFactory : public content::DevToolsSocketFactory {
 namespace QtWebEngineCore {
 
 DevToolsServerQt::DevToolsServerQt()
-    : m_bindAddress(QLatin1String("127.0.0.1"))
+    : m_bindAddress(u"127.0.0.1"_s)
     , m_port(0)
     , m_valid(false)
     , m_isStarted(false)
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index 7ccd063ffda..61f789c79ec 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -22,6 +22,8 @@
 #include "type_conversion.h"
 #include "web_contents_delegate_qt.h"
 
+using namespace Qt::StringLiterals;
+
 namespace QtWebEngineCore {
 
 DownloadManagerDelegateQt::DownloadManagerDelegateQt(ProfileAdapter *profileAdapter)
@@ -262,8 +264,8 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content
     }
 
     if (suggestedFilePath.isEmpty()) {
-        suggestedFilePath = QFileInfo(toQt(suggested_path.AsUTF8Unsafe())).completeBaseName()
-                + QStringLiteral(".mhtml");
+        suggestedFilePath +=
+                QFileInfo(toQt(suggested_path.AsUTF8Unsafe())).completeBaseName() + ".mhtml"_L1;
     } else {
         acceptedByDefault = true;
     }
diff --git a/src/core/file_picker_controller.cpp b/src/core/file_picker_controller.cpp
index fb124df7bb8..fc52a387daa 100644
--- a/src/core/file_picker_controller.cpp
+++ b/src/core/file_picker_controller.cpp
@@ -18,6 +18,8 @@
 #include <QStringList>
 #include <QVariant>
 
+using namespace Qt::StringLiterals;
+
 namespace QtWebEngineCore {
 
 class FilePickerControllerPrivate {
@@ -75,7 +77,7 @@ void FilePickerController::accepted(const QStringList &files)
             continue;
         }
 
-        if (urlString.startsWith("file:")) {
+        if (urlString.startsWith("file:"_L1)) {
             base::FilePath filePath = toFilePath(urlString).NormalizePathSeparators();
             std::vector<base::FilePath::StringType> pathComponents;
             // Splits the file URL into scheme, host name, path and file name.
@@ -91,7 +93,7 @@ void FilePickerController::accepted(const QStringList &files)
 #if defined(Q_OS_WIN)
                 // There is no slash at the end of the file scheme and it is valid on Windows: file:C:/
                 if (scheme.size() == 7 && scheme.at(5).isLetter() && scheme.at(6) == ':') {
-                    absolutePath += scheme.at(5) + ":/";
+                    absolutePath += scheme.at(5) + ":/"_L1;
                 } else {
 #endif
                     qWarning("Ignoring invalid item in FilePickerController::accepted(QStringList): %s", qPrintable(urlString));
@@ -107,7 +109,7 @@ void FilePickerController::accepted(const QStringList &files)
                 && !base::FilePath::IsSeparator(urlString.at(7).toLatin1())) {
 #if defined(Q_OS_WIN)
                 if (urlString.at(8) != ':' && pathComponents.size() > 2) {
-                    absolutePath += "//";
+                    absolutePath += "//"_L1;
 #else
                 if (pathComponents.size() > 2) {
                     absolutePath += "/";
@@ -161,7 +163,7 @@ static QStringList listRecursively(const QDir &dir)
     const QFileInfoList infoList(dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden));
     for (const QFileInfo &fileInfo : infoList) {
         if (fileInfo.isDir()) {
-            ret.append(fileInfo.absolutePath() + QStringLiteral("/.")); // Match chromium's behavior. See chrome/browser/file_select_helper.cc
+            ret.append(fileInfo.absolutePath() + "/."_L1); // Match chromium's behavior. See chrome/browser/file_select_helper.cc
             ret.append(listRecursively(QDir(fileInfo.absoluteFilePath())));
         } else
             ret.append(fileInfo.absoluteFilePath());
@@ -256,7 +258,7 @@ QStringList FilePickerController::nameFilters(const QStringList &acceptedMimeTyp
             if (mimeType.isValid()) {
                 QString glob = "*" + type;
                 acceptedGlobs.append(glob);
-                nameFilters.append(mimeType.comment() + " (" + glob + ")");
+                nameFilters.append(mimeType.comment() + " ("_L1 + glob + ")");
             }
         } else if (type.contains("/") && !type.endsWith("*")) {
             // All suffixes for a given MIME type
@@ -264,9 +266,9 @@ QStringList FilePickerController::nameFilters(const QStringList &acceptedMimeTyp
             if (mimeType.isValid() && !mimeType.globPatterns().isEmpty()) {
                 QString globs = mimeType.globPatterns().join(" ");
                 acceptedGlobs.append(mimeType.globPatterns());
-                nameFilters.append(mimeType.comment() + " (" + globs + ")");
+                nameFilters.append(mimeType.comment() + " ("_L1 + globs + ")");
             }
-        } else if (type.endsWith("/*")) {
+        } else if (type.endsWith("/*"_L1)) {
             // All MIME types for audio/*, image/* or video/*
             // as separate filters as Chrome does
             static const QList<QMimeType> &allMimeTypes = mimeDatabase.allMimeTypes();
@@ -275,7 +277,7 @@ QStringList FilePickerController::nameFilters(const QStringList &acceptedMimeTyp
                 if (m.name().startsWith(type) && !m.globPatterns().isEmpty()) {
                     QString globs = m.globPatterns().join(" ");
                     acceptedGlobs.append(m.globPatterns());
-                    nameFilters.append(m.comment() + " (" + globs + ")");
+                    nameFilters.append(m.comment() + " ("_L1 + globs + ")");
                 }
             }
         } else {
diff --git a/src/core/net/qrc_url_scheme_handler.cpp b/src/core/net/qrc_url_scheme_handler.cpp
index a8b4e4388a2..82554827ead 100644
--- a/src/core/net/qrc_url_scheme_handler.cpp
+++ b/src/core/net/qrc_url_scheme_handler.cpp
@@ -12,6 +12,8 @@
 
 #include <memory>
 
+using namespace Qt::StringLiterals;
+
 namespace QtWebEngineCore {
 
 void QrcUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job)
@@ -33,7 +35,7 @@ void QrcUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job)
     QFileInfo fileInfo(*file);
     QMimeDatabase mimeDatabase;
     QMimeType mimeType = mimeDatabase.mimeTypeForFile(fileInfo);
-    if (mimeType.name() == QStringLiteral("application/x-extension-html"))
+    if (mimeType.name() == "application/x-extension-html"_L1)
         job->reply("text/html", file.release());
     else
         job->reply(mimeType.name().toUtf8(), file.release());
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index 247c1936fef..058cefddcb7 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -26,6 +26,8 @@
 #include "web_contents_delegate_qt.h"
 #include "web_engine_settings.h"
 
+using namespace Qt::StringLiterals;
+
 namespace QtWebEngineCore {
 
 // Extra permission types that don't exist on the Chromium side.
@@ -198,14 +200,15 @@ PermissionManagerQt::PermissionManagerQt(ProfileAdapter *profileAdapter)
     factory.set_command_line_prefs(base::MakeRefCounted<ChromeCommandLinePrefStore>(
             base::CommandLine::ForCurrentProcess()));
 
-    QString userPrefStorePath = profileAdapter->dataPath();
+    QString userPrefStorePath;
+    userPrefStorePath += profileAdapter->dataPath();
     auto prefRegistry = base::MakeRefCounted<PrefRegistrySimple>();
 
     auto policy = profileAdapter->persistentPermissionsPolicy();
     if (!profileAdapter->isOffTheRecord() && policy == ProfileAdapter::PersistentPermissionsPolicy::StoreOnDisk &&
             !userPrefStorePath.isEmpty() && profileAdapter->ensureDataPathExists()) {
         userPrefStorePath += QDir::separator();
-        userPrefStorePath += QStringLiteral("permissions.json");
+        userPrefStorePath += "permissions.json"_L1;
         factory.set_user_prefs(base::MakeRefCounted<JsonPrefStore>(toFilePath(userPrefStorePath)));
     } else {
         factory.set_user_prefs(new InMemoryPrefStore);
diff --git a/src/core/pref_service_adapter.cpp b/src/core/pref_service_adapter.cpp
index 7a7abf2c48c..210d900e25a 100644
--- a/src/core/pref_service_adapter.cpp
+++ b/src/core/pref_service_adapter.cpp
@@ -55,6 +55,8 @@ namespace {
 static const char kPrefMediaDeviceIDSalt[] = "qtwebengine.media_device_salt_id";
 }
 
+using namespace Qt::StringLiterals;
+
 namespace QtWebEngineCore {
 
 void PrefServiceAdapter::setup(const ProfileAdapter &profileAdapter)
@@ -64,11 +66,12 @@ void PrefServiceAdapter::setup(const ProfileAdapter &profileAdapter)
     factory.set_command_line_prefs(base::MakeRefCounted<ChromeCommandLinePrefStore>(
             base::CommandLine::ForCurrentProcess()));
 
-    QString userPrefStorePath = profileAdapter.dataPath();
+    QString userPrefStorePath;
+    userPrefStorePath += profileAdapter.dataPath();
     if (!profileAdapter.isOffTheRecord() && !userPrefStorePath.isEmpty() &&
             const_cast<ProfileAdapter *>(&profileAdapter)->ensureDataPathExists()) {
         userPrefStorePath += QDir::separator();
-        userPrefStorePath += QStringLiteral("user_prefs.json");
+        userPrefStorePath += "user_prefs.json"_L1;
         factory.set_user_prefs(base::MakeRefCounted<JsonPrefStore>(toFilePath(userPrefStorePath)));
     } else {
         factory.set_user_prefs(new InMemoryPrefStore);
diff --git a/src/core/printing/print_view_manager_base_qt.cpp b/src/core/printing/print_view_manager_base_qt.cpp
index a691bc2b64b..a8af1f6037b 100644
--- a/src/core/printing/print_view_manager_base_qt.cpp
+++ b/src/core/printing/print_view_manager_base_qt.cpp
@@ -33,6 +33,10 @@
 #include "printing/print_job_constants.h"
 #include "printing/printed_document.h"
 
+#include <string>
+
+using namespace std::string_literals;
+
 namespace QtWebEngineCore {
 
 namespace {
@@ -160,7 +164,7 @@ void PrintViewManagerBaseQt::NavigationStopped()
 
 std::u16string PrintViewManagerBaseQt::RenderSourceName()
 {
-     return toString16(QLatin1String(""));
+    return u""s;
 }
 
 void PrintViewManagerBaseQt::PrintDocument(scoped_refptr<base::RefCountedMemory> print_data,
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index a74ecc8cf38..c5cc86eb15c 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -44,13 +44,16 @@
 #include <QString>
 #include <QStandardPaths>
 
+using namespace Qt::StringLiterals;
+
 namespace {
 inline QString buildLocationFromStandardPath(const QString &standardPath, const QString &name) {
-    QString location = standardPath;
+    QString location;
+    location += standardPath;
     if (location.isEmpty())
-        location = QDir::homePath() % QLatin1String("/.") % QCoreApplication::applicationName();
+        location += QDir::homePath() % "/."_L1 % QCoreApplication::applicationName();
 
-    location.append(QLatin1String("/QtWebEngine/") % name);
+    location += "/QtWebEngine/"_L1 % name;
     return location;
 }
 }
@@ -307,7 +310,7 @@ QString ProfileAdapter::httpCachePath() const
         return QString();
     QString basePath = cachePath();
     if (!basePath.isEmpty())
-        return basePath % QLatin1String("/Cache");
+        return basePath % "/Cache"_L1;
     return QString();
 }
 
diff --git a/src/core/tools/qwebengine_convert_dict/main.cpp b/src/core/tools/qwebengine_convert_dict/main.cpp
index 8b82b930f5d..b49ae0279a5 100644
--- a/src/core/tools/qwebengine_convert_dict/main.cpp
+++ b/src/core/tools/qwebengine_convert_dict/main.cpp
@@ -32,6 +32,8 @@
 #include <QDir>
 #include <QCoreApplication>
 
+using namespace Qt::StringLiterals;
+
 // see also src/core/type_conversion.h
 inline base::FilePath::StringType toFilePathString(const QString &str)
 {
@@ -131,8 +133,8 @@ inline bool VerifyWords(const convert_dict::DicReader::WordList& org_words,
 #if defined(Q_OS_DARWIN) && defined(QT_MAC_FRAMEWORK_BUILD)
 QString frameworkIcuDataPath()
 {
-    return QLibraryInfo::location(QLibraryInfo::LibrariesPath) +
-            QStringLiteral("/QtWebEngineCore.framework/Resources/");
+    return QLibraryInfo::location(QLibraryInfo::LibrariesPath)
+            + "/QtWebEngineCore.framework/Resources/"_L1;
 }
 #endif
 
@@ -155,15 +157,14 @@ int main(int argc, char *argv[])
     }
 #if defined(USE_ICU_FILE)
     bool icuDataDirFound = false;
-    QString icuDataDir = QLibraryInfo::path(QLibraryInfo::DataPath)
-            % QLatin1String("/resources");
+    QString icuDataDir = QLibraryInfo::path(QLibraryInfo::DataPath) % "/resources"_L1;
 
     // Try to look up the path to the ICU data directory via an environment variable
     // (e.g. for the case when the tool is ran during build phase, and regular installed
     // ICU data file is not available).
     const QString icuPossibleEnvDataDir = qEnvironmentVariable("QT_WEBENGINE_ICU_DATA_DIR");
     const QString appPath = QCoreApplication::applicationDirPath();
-    QLatin1String icuDataFilePath("/icudtl.dat");
+    const auto icuDataFilePath = "/icudtl.dat"_L1;
     if (!icuPossibleEnvDataDir.isEmpty() && QFileInfo::exists(icuPossibleEnvDataDir)) {
         icuDataDir = icuPossibleEnvDataDir;
         icuDataDirFound = true;
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index f98c6a9300d..238c81504f1 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -93,6 +93,8 @@
 #include "extensions/extension_web_contents_observer_qt.h"
 #endif
 
+using namespace Qt::StringLiterals;
+
 namespace QtWebEngineCore {
 
 #define CHECK_INITIALIZED(return_value)         \
@@ -659,12 +661,12 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
     Q_UNUSED(guard);
 
     // Add URL scheme if missing from view-source URL.
-    if (request.url().scheme() == content::kViewSourceScheme) {
+    if (request.url().scheme() == QLatin1StringView(content::kViewSourceScheme)) {
         QUrl pageUrl = QUrl(request.url().toString().remove(0,
                                                            strlen(content::kViewSourceScheme) + 1));
         if (pageUrl.scheme().isEmpty()) {
             QUrl extendedUrl = QUrl::fromUserInput(pageUrl.toString());
-            extendedUrl = QUrl(QString("%1:%2").arg(content::kViewSourceScheme,
+            extendedUrl = QUrl(QString("%1:%2").arg(QLatin1StringView(content::kViewSourceScheme),
                                                     extendedUrl.toString()));
             gurl = toGurl(extendedUrl);
         }
@@ -1620,7 +1622,8 @@ static QMimeData *mimeDataFromDropData(const content::DropData &dropData)
     if (!dropData.custom_data.empty()) {
         base::Pickle pickle;
         ui::WriteCustomDataToPickle(dropData.custom_data, &pickle);
-        mimeData->setData(QLatin1String(ui::kMimeTypeWebCustomData), QByteArray((const char*)pickle.data(), pickle.size()));
+        mimeData->setData(QLatin1StringView(ui::kMimeTypeWebCustomData),
+                          QByteArray((const char *)pickle.data(), pickle.size()));
     }
     return mimeData;
 }
@@ -1750,8 +1753,9 @@ static void fillDropDataFromMimeData(content::DropData *dropData, const QMimeDat
         dropData->html = toOptionalString16(mimeData->html());
     if (mimeData->hasText())
         dropData->text = toOptionalString16(mimeData->text());
-    if (mimeData->hasFormat(QLatin1String(ui::kMimeTypeWebCustomData))) {
-        const QByteArray customData = mimeData->data(QLatin1String(ui::kMimeTypeWebCustomData));
+    const QString mimeType = QString::fromLatin1(ui::kMimeTypeWebCustomData);
+    if (mimeData->hasFormat(mimeType)) {
+        const QByteArray customData = mimeData->data(mimeType);
         const base::span custom_data(customData.constData(), (long unsigned)customData.length());
         if (auto maybe_data = ui::ReadCustomDataIntoMap(base::as_bytes(custom_data)))
             dropData->custom_data = *std::move(maybe_data);
@@ -1966,7 +1970,7 @@ QString WebContentsAdapter::frameHtmlName(quint64 id) const
 {
     CHECK_INITIALIZED_AND_VALID_FRAME(id, ftn, QString());
     auto &maybeName = ftn->html_name();
-    return maybeName ? QString::fromStdString(*maybeName) : QString("");
+    return maybeName ? QString::fromStdString(*maybeName) : ""_L1;
 }
 
 QList<quint64> WebContentsAdapter::frameChildren(quint64 id) const
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index d0bbb98564d..de045da4ee1 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -199,7 +199,8 @@ QUrl WebContentsDelegateQt::url(content::WebContents *source) const
         if (source->GetVisibleURL().SchemeIs(content::kViewSourceScheme) &&
             (url.has_password() || url.has_username() || url.has_ref())) {
             GURL strippedUrl = net::SimplifyUrlForRequest(url);
-            newUrl = QUrl(QString("%1:%2").arg(content::kViewSourceScheme, QString::fromStdString(strippedUrl.spec())));
+            newUrl = QUrl(QString("%1:%2").arg(QLatin1StringView(content::kViewSourceScheme),
+                                               QString::fromStdString(strippedUrl.spec())));
         }
         // If there is a visible entry there are special cases where we dont wan't to use the actual URL
         if (newUrl.isEmpty())
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 52c017dffb9..da1aea48de8 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -127,6 +127,8 @@ QT_END_NAMESPACE
 #define STRINGIFY_LITERAL(x) #x
 #define STRINGIFY_EXPANDED(x) STRINGIFY_LITERAL(x)
 
+using namespace Qt::StringLiterals;
+
 namespace QtWebEngineCore {
 
 Q_LOGGING_CATEGORY(webEngineContextLog, "qt.webenginecontext")
@@ -203,23 +205,23 @@ class GPUInfo
         return Unknown;
     }
 
-    static Vendor deviceNameToVendor(const QString &deviceName)
+    static Vendor deviceNameToVendor(QLatin1StringView deviceName)
     {
         // TODO: Test and add more vendors to the list.
-        if (deviceName.contains(QLatin1StringView("AMD"), Qt::CaseInsensitive))
+        if (deviceName.contains("AMD"_L1, Qt::CaseInsensitive))
             return AMD;
-        if (deviceName.contains(QLatin1StringView("Intel"), Qt::CaseInsensitive))
+        if (deviceName.contains("Intel"_L1, Qt::CaseInsensitive))
             return Intel;
-        if (deviceName.contains(QLatin1StringView("Nvidia"), Qt::CaseInsensitive))
+        if (deviceName.contains("Nvidia"_L1, Qt::CaseInsensitive))
             return Nvidia;
 
 #if defined(USE_OZONE)
-        if (deviceName.contains(QLatin1StringView("Mesa llvmpipe")))
+        if (deviceName.contains("Mesa llvmpipe"_L1))
             return Mesa;
 #endif
 
 #if defined(Q_OS_MACOS)
-        if (deviceName.contains(QLatin1StringView("Apple")))
+        if (deviceName.contains("Apple"_L1))
             return Apple;
 #endif
 
@@ -356,7 +358,7 @@ static bool usingSupportedSGBackend()
     QString device = QQuickWindow::sceneGraphBackend();
 
     for (int index = 0; index < args.count(); ++index) {
-        if (args.at(index).startsWith(QLatin1StringView("--device="))) {
+        if (args.at(index).startsWith("--device="_L1)) {
             device = args.at(index).mid(9);
             break;
         }
@@ -367,7 +369,7 @@ static bool usingSupportedSGBackend()
     if (device.isEmpty())
         device = qEnvironmentVariable("QMLSCENE_DEVICE");
 
-    return device.isEmpty() || device == QLatin1StringView("rhi");
+    return device.isEmpty() || device == "rhi"_L1;
 }
 
 #if QT_CONFIG(opengl)
@@ -495,43 +497,33 @@ void dummyGetPluginCallback(const std::vector<content::WebPluginInfo>&)
 static void logContext(const std::string &glType, base::CommandLine *cmd)
 {
     if (Q_UNLIKELY(webEngineContextLog().isDebugEnabled())) {
-        QStringList log;
-        log << QLatin1StringView("\n");
-
-        log << QLatin1StringView("Chromium GL Backend: " + glType) << QLatin1StringView("\n");
-        log << QLatin1StringView("Chromium ANGLE Backend: " + getAngleType(glType, cmd))
-            << QLatin1StringView("\n");
-        log << QLatin1StringView("Chromium Vulkan Backend: " + getVulkanType(cmd))
-            << QLatin1StringView("\n");
-        log << QLatin1StringView("\n");
-
-        log << QLatin1StringView("QSG RHI Backend:") << QSGRhiSupport::instance()->rhiBackendName()
-            << QLatin1StringView("\n");
-        log << QLatin1StringView("QSG RHI Backend Supported:")
-            << QLatin1StringView(usingSupportedSGBackend() ? "yes" : "no")
-            << QLatin1StringView("\n");
-        log << QLatin1StringView("GPU Vendor: "
-                                 + GPUInfo::vendorToString(GPUInfo::instance()->vendor()))
-            << QLatin1StringView("\n");
-        log << QLatin1StringView("\n");
+        QString log;
+        log += u'\n';
+
+        log += "Chromium GL Backend: "_L1 + QLatin1StringView(glType) + "\n"_L1;
+        log += "Chromium ANGLE Backend: "_L1 + QLatin1StringView(getAngleType(glType, cmd)) + u'\n';
+        log += "Chromium Vulkan Backend: "_L1 + QLatin1StringView(getVulkanType(cmd)) + u'\n';
+        log += u'\n';
+
+        log += "QSG RHI Backend: "_L1 + QSGRhiSupport::instance()->rhiBackendName() + u'\n';
+        log += "QSG RHI Backend Supported: "_L1 + (usingSupportedSGBackend() ? "yes"_L1 : "no"_L1)
+                + u'\n';
+        log += "GPU Vendor: "_L1
+                + QLatin1StringView(GPUInfo::vendorToString(GPUInfo::instance()->vendor())) + u'\n';
+        log += u'\n';
 
 #if QT_CONFIG(opengl)
 #if defined(USE_OZONE)
-        log << QLatin1StringView("Using GLX:")
-            << QLatin1StringView(GLContextHelper::getGlxPlatformInterface() ? "yes" : "no")
-            << QLatin1StringView("\n");
-        log << QLatin1StringView("Using EGL:")
-            << QLatin1StringView(GLContextHelper::getEglPlatformInterface() ? "yes" : "no")
-            << QLatin1StringView("\n");
+        log += "Using GLX: "_L1 + (GLContextHelper::getGlxPlatformInterface() ? "yes"_L1 : "no"_L1)
+                + u'\n';
+        log += "Using EGL: "_L1 + (GLContextHelper::getEglPlatformInterface() ? "yes"_L1 : "no"_L1)
+                + u'\n';
 #endif
 #if defined(USE_OZONE) || defined(Q_OS_WIN)
-        log << QLatin1StringView("Using Shared GL:")
-            << QLatin1StringView(qt_gl_global_share_context() ? "yes" : "no")
-            << QLatin1StringView("\n");
+        log += "Using Shared GL: "_L1 + (qt_gl_global_share_context() ? "yes"_L1 : "no"_L1) + u'\n';
         if (qt_gl_global_share_context()) {
-            log << QLatin1StringView("Using Software Dynamic GL:")
-                << QLatin1StringView(usingSoftwareDynamicGL() ? "yes" : "no")
-                << QLatin1StringView("\n");
+            log += "Using Software Dynamic GL: "_L1
+                    + (usingSoftwareDynamicGL() ? "yes"_L1 : "no"_L1) + u'\n';
 
             const QSurfaceFormat sharedFormat = qt_gl_global_share_context()
                     ? qt_gl_global_share_context()->format()
@@ -541,24 +533,21 @@ static void logContext(const std::string &glType, base::CommandLine *cmd)
                             sharedFormat.profile());
             const auto type = QMetaEnum::fromType<QSurfaceFormat::RenderableType>().valueToKey(
                     sharedFormat.renderableType());
-            log << QLatin1StringView("Surface Type:") << QLatin1StringView(type)
-                << QLatin1StringView("\n");
-            log << QLatin1StringView("Surface Profile:") << QLatin1StringView(profile)
-                << QLatin1StringView("\n");
-            log << QStringLiteral("Surface Version: %1.%2\n")
-                            .arg(sharedFormat.majorVersion())
-                            .arg(sharedFormat.minorVersion());
+            log += "Surface Type: "_L1 + QLatin1StringView(type) + u'\n';
+            log += "Surface Profile: "_L1 + QLatin1StringView(profile) + u'\n';
+            log += "Surface Version: "_L1 + QString::number(sharedFormat.majorVersion()) + u'.'
+                    + QString::number(sharedFormat.minorVersion()) + u'\n';
         }
-        log << QLatin1StringView("\n");
+        log += u'\n';
 #endif // defined(USE_OZONE) || defined(Q_OS_WIN)
 #endif // QT_CONFIG(opengl)
 
-        log << QLatin1StringView("Init Parameters:\n");
+        log += "Init Parameters:\n"_L1;
         const base::CommandLine::SwitchMap switchMap = cmd->GetSwitches();
         for (const auto &pair : switchMap)
-            log << QStringLiteral(" *  %1 %2\n").arg(toQt(pair.first)).arg(toQt(pair.second));
+            log += " *  "_L1 + toQt(pair.first) + u' ' + toQt(pair.second) + u'\n';
 
-        qCDebug(webEngineContextLog) << qPrintable(log.join(QLatin1Char(' ')));
+        qCDebug(webEngineContextLog, "%ls", qUtf16Printable(log));
     }
 }
 
@@ -570,7 +559,7 @@ static void setupProxyPac(base::CommandLine *commandLine)
         QUrl pac_url(toQt(commandLine->GetSwitchValueASCII(switches::kProxyPacUrl)));
         if (pac_url.isValid()
             && (pac_url.isLocalFile()
-                || !pac_url.scheme().compare(QLatin1StringView("qrc"), Qt::CaseInsensitive))) {
+                || !pac_url.scheme().compare("qrc"_L1, Qt::CaseInsensitive))) {
             QFile file;
             if (pac_url.isLocalFile())
                 file.setFileName(pac_url.toLocalFile());
diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp
index b6b8fc76340..b3a0050ba63 100644
--- a/src/core/web_engine_library_info.cpp
+++ b/src/core/web_engine_library_info.cpp
@@ -34,6 +34,7 @@
 #error "No name defined for QtWebEngine's process"
 #endif
 
+using namespace Qt::StringLiterals;
 using namespace QtWebEngineCore;
 
 Q_LOGGING_CATEGORY(webEngineLibraryInfoLog, "qt.webengine.libraryinfo")
@@ -41,7 +42,7 @@ Q_LOGGING_CATEGORY(webEngineLibraryInfoLog, "qt.webengine.libraryinfo")
 namespace {
 
 QString fallbackDir() {
-    static QString directory = QDir::homePath() % QLatin1String("/.") % QCoreApplication::applicationName();
+    static QString directory = QDir::homePath() % "/."_L1 % QCoreApplication::applicationName();
     return directory;
 }
 
@@ -57,8 +58,8 @@ static QString getBundlePath(CFBundleRef frameworkBundle)
     // The following is a fix for QtWebEngineProcess crashes on OS X 10.7 and before.
     // We use it for the other OS X versions as well to make sure it works and because
     // the directory structure should be the same.
-    if (qApp->applicationName() == QLatin1String(qWebEngineProcessName())) {
-        path = QDir::cleanPath(qApp->applicationDirPath() % QLatin1String("/../../../.."));
+    if (qApp->applicationName() == QLatin1StringView(qWebEngineProcessName())) {
+        path = QDir::cleanPath(qApp->applicationDirPath() % "/../../../.."_L1);
     } else if (frameworkBundle) {
         CFURLRef bundleUrl = CFBundleCopyBundleURL(frameworkBundle);
         CFStringRef bundlePath = CFURLCopyFileSystemPath(bundleUrl, kCFURLPOSIXPathStyle);
@@ -75,8 +76,8 @@ static QString getResourcesPath(CFBundleRef frameworkBundle)
     // The following is a fix for QtWebEngineProcess crashes on OS X 10.7 and before.
     // We use it for the other OS X versions as well to make sure it works and because
     // the directory structure should be the same.
-    if (qApp->applicationName() == QLatin1String(qWebEngineProcessName())) {
-        path = getBundlePath(frameworkBundle) % QLatin1String("/Resources");
+    if (qApp->applicationName() == QLatin1StringView(qWebEngineProcessName())) {
+        path = getBundlePath(frameworkBundle) % "/Resources"_L1;
     } else if (frameworkBundle) {
         CFURLRef resourcesRelativeUrl = CFBundleCopyResourcesDirectoryURL(frameworkBundle);
         CFStringRef resourcesRelativePath = CFURLCopyFileSystemPath(resourcesRelativeUrl, kCFURLPOSIXPathStyle);
@@ -121,9 +122,9 @@ QString subProcessPath()
     static QString processPath;
     if (processPath.isEmpty()) {
 #if defined(Q_OS_WIN)
-        const QString processBinary = QLatin1String(qWebEngineProcessName()) % QLatin1String(".exe");
+        const QString processBinary = QLatin1StringView(qWebEngineProcessName()) % ".exe"_L1;
 #else
-        const QString processBinary = QLatin1String(qWebEngineProcessName());
+        const auto processBinary = QLatin1StringView(qWebEngineProcessName());
 #endif
 
         QStringList candidatePaths;
@@ -133,8 +134,8 @@ QString subProcessPath()
             candidatePaths << fromEnv;
         } else {
 #if defined(Q_OS_DARWIN) && defined(QT_MAC_FRAMEWORK_BUILD)
-            candidatePaths << getBundlePath(frameworkBundle()) % QStringLiteral("/Helpers/")
-                            % qWebEngineProcessName() % QStringLiteral(".app/Contents/MacOS/")
+            candidatePaths << getBundlePath(frameworkBundle()) % "/Helpers/"_L1
+                            % qWebEngineProcessName() % ".app/Contents/MacOS/"_L1
                             % qWebEngineProcessName();
 #else
             candidatePaths << QLibraryInfo::path(QLibraryInfo::LibraryExecutablesPath)
@@ -155,18 +156,16 @@ QString subProcessPath()
             }
         }
         if (processPath.isEmpty()) {
-            QStringList errorMessage;
-            errorMessage.append(
-                    QStringLiteral("The following paths were searched for Qt WebEngine Process:"));
+            QString errorMessage;
+            errorMessage += "The following paths were searched for Qt WebEngine Process:\n"_L1;
             for (const QString &candidate : std::as_const(candidatePaths))
-                errorMessage.append(QStringLiteral("  ") % candidate);
-            errorMessage.append(QStringLiteral("but could not find it."));
+                errorMessage += "  "_L1 + candidate + u'\n';
+            errorMessage += "but could not find it.\n"_L1;
             if (fromEnv.isEmpty()) {
-                errorMessage.append(
-                        QStringLiteral("You may override the default search path by using "
-                                       "QTWEBENGINEPROCESS_PATH environment variable."));
+                errorMessage += "You may override the default search path by using "
+                                "QTWEBENGINEPROCESS_PATH environment variable.\n"_L1;
             }
-            qFatal("%s", qPrintable(errorMessage.join('\n')));
+            qFatal("%ls", qUtf16Printable(errorMessage));
         }
 
 #if defined(Q_OS_WIN)
@@ -189,11 +188,7 @@ QString localesPath()
     if (potentialLocalesPath.isEmpty()) {
         QStringList candidatePaths;
         const QString translationPakFilename =
-#if QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
-                QLatin1String(WebEngineLibraryInfo::getResolvedLocale() + ".pak");
-#else
-                QLatin1String((WebEngineLibraryInfo::getResolvedLocale() + ".pak").c_str());
-#endif
+                QLatin1StringView(WebEngineLibraryInfo::getResolvedLocale()) % ".pak"_L1;
         const QString fromEnv = qEnvironmentVariable("QTWEBENGINE_LOCALES_PATH");
         if (!fromEnv.isEmpty()) {
             // Only search in QTWEBENGINE_LOCALES_PATH if set
@@ -201,10 +196,10 @@ QString localesPath()
         } else {
 #if defined(Q_OS_DARWIN) && defined(QT_MAC_FRAMEWORK_BUILD)
             candidatePaths << getResourcesPath(frameworkBundle()) % QDir::separator()
-                            % QLatin1String("qtwebengine_locales");
+                            % "qtwebengine_locales"_L1;
 #endif
             candidatePaths << QLibraryInfo::path(QLibraryInfo::TranslationsPath) % QDir::separator()
-                            % QLatin1String("qtwebengine_locales");
+                            % "qtwebengine_locales"_L1;
             candidatePaths << fallbackDir();
         }
 
@@ -218,22 +213,18 @@ QString localesPath()
         }
 
         if (potentialLocalesPath.isEmpty()) {
-            QStringList warningMessage;
-            warningMessage.append(
-                    QStringLiteral("The following paths were searched for Qt WebEngine locales:"));
+            QString warningMessage;
+            warningMessage += "The following paths were searched for Qt WebEngine locales:\n"_L1;
             for (const QString &candidate : std::as_const(candidatePaths))
-                warningMessage.append(QStringLiteral("  ") % candidate);
-            warningMessage.append(
-                    QStringLiteral(
-                            "but could not find the translation file for the current locale: ")
-                    % translationPakFilename);
+                warningMessage += "  "_L1 % candidate + u'\n';
+            warningMessage += "but could not find the translation file for the current locale: "_L1
+                    + translationPakFilename + u'\n';
             if (fromEnv.isEmpty()) {
-                warningMessage.append(
-                        QStringLiteral("You may override the default search paths by using "
-                                       "QTWEBENGINE_LOCALES_PATH environment variable."));
+                warningMessage += "You may override the default search paths by using "
+                                  "QTWEBENGINE_LOCALES_PATH environment variable.\n"_L1;
             }
-            warningMessage.append(QStringLiteral("Translations WILL NOT be correct."));
-            qWarning("%s", qPrintable(warningMessage.join('\n')));
+            warningMessage += "Translations WILL NOT be correct.\n"_L1;
+            qWarning("%ls", qUtf16Printable(warningMessage));
         }
     }
 
@@ -244,7 +235,7 @@ QString localesPath()
 QString dictionariesPath(bool showWarnings)
 {
     static QString potentialDictionariesPath;
-    static QStringList warningMessage;
+    static QString warningMessage;
     static bool initialized = false;
     QStringList candidatePaths;
     if (!initialized) {
@@ -258,22 +249,22 @@ QString dictionariesPath(bool showWarnings)
             // First try to find dictionaries near the application.
 #ifdef Q_OS_DARWIN
             QString resourcesDictionariesPath = getMainApplicationResourcesPath()
-                    % QDir::separator() % QLatin1String("qtwebengine_dictionaries");
+                    % QDir::separator() % "qtwebengine_dictionaries"_L1;
             candidatePaths << resourcesDictionariesPath;
 #endif
             QString applicationDictionariesPath = QCoreApplication::applicationDirPath()
-                    % QDir::separator() % QLatin1String("qtwebengine_dictionaries");
+                    % QDir::separator() % "qtwebengine_dictionaries"_L1;
             candidatePaths << applicationDictionariesPath;
 
             // Then try to find dictionaries near the installed library.
 #if defined(Q_OS_DARWIN) && defined(QT_MAC_FRAMEWORK_BUILD)
-            QString frameworkDictionariesPath = getResourcesPath(frameworkBundle())
-                    % QLatin1String("/qtwebengine_dictionaries");
+            QString frameworkDictionariesPath =
+                    getResourcesPath(frameworkBundle()) % "/qtwebengine_dictionaries"_L1;
             candidatePaths << frameworkDictionariesPath;
 #endif
 
             QString libraryDictionariesPath = QLibraryInfo::path(QLibraryInfo::DataPath)
-                    % QDir::separator() % QLatin1String("qtwebengine_dictionaries");
+                    % QDir::separator() % "qtwebengine_dictionaries"_L1;
             candidatePaths << libraryDictionariesPath;
         }
 
@@ -286,22 +277,21 @@ QString dictionariesPath(bool showWarnings)
             }
         }
         if (potentialDictionariesPath.isEmpty()) {
-            warningMessage.append(QStringLiteral(
-                    "The following paths were searched for Qt WebEngine dictionaries:"));
+            warningMessage +=
+                    "The following paths were searched for Qt WebEngine dictionaries:\n"_L1;
             for (const QString &candidate : std::as_const(candidatePaths))
-                warningMessage.append(QStringLiteral("  ") % candidate);
-            warningMessage.append(QStringLiteral("but could not find it."));
+                warningMessage += "  "_L1 + candidate + u'\n';
+            warningMessage += "but could not find it.\n"_L1;
             if (fromEnv.isEmpty()) {
-                warningMessage.append(
-                        QStringLiteral("You may override the default search path by using "
-                                       "QTWEBENGINE_DICTIONARIES_PATH environment variable."));
+                warningMessage += "You may override the default search path by using "
+                                  "QTWEBENGINE_DICTIONARIES_PATH environment variable.\n"_L1;
             }
-            warningMessage.append(QStringLiteral("Spellchecking can not be enabled."));
+            warningMessage += "Spellchecking can not be enabled.\n"_L1;
         }
     }
 
     if (showWarnings && !warningMessage.isEmpty()) {
-        qWarning("%s", qPrintable(warningMessage.join('\n')));
+        qWarning("%ls", qUtf16Printable(warningMessage));
     }
 
     return potentialDictionariesPath;
@@ -313,7 +303,7 @@ QString resourcesPath()
     static QString potentialResourcesPath;
     if (potentialResourcesPath.isEmpty()) {
         QStringList candidatePaths;
-        const QString resourcesPakFilename = QLatin1String("qtwebengine_resources.pak");
+        const auto resourcesPakFilename = "qtwebengine_resources.pak"_L1;
         const QString fromEnv = qEnvironmentVariable("QTWEBENGINE_RESOURCES_PATH");
         if (!fromEnv.isEmpty()) {
             // Only search in QTWEBENGINE_RESOURCES_PATH if set
@@ -323,7 +313,7 @@ QString resourcesPath()
             candidatePaths << getResourcesPath(frameworkBundle());
 #endif
             candidatePaths << QLibraryInfo::path(QLibraryInfo::DataPath) % QDir::separator()
-                            % QLatin1String("resources");
+                            % "resources"_L1;
             candidatePaths << QLibraryInfo::path(QLibraryInfo::DataPath);
             candidatePaths << QCoreApplication::applicationDirPath();
             candidatePaths << fallbackDir();
@@ -339,18 +329,16 @@ QString resourcesPath()
         }
 
         if (potentialResourcesPath.isEmpty()) {
-            QStringList errorMessage;
-            errorMessage.append(QStringLiteral(
-                    "The following paths were searched for Qt WebEngine resources:"));
+            QString errorMessage;
+            errorMessage += "The following paths were searched for Qt WebEngine resources:\n"_L1;
             for (const QString &candidate : std::as_const(candidatePaths))
-                errorMessage.append(QStringLiteral("  ") % candidate);
-            errorMessage.append(QStringLiteral("but could not find any."));
+                errorMessage += "  "_L1 + candidate + u'\n';
+            errorMessage += "but could not find any.\n"_L1;
             if (fromEnv.isEmpty()) {
-                errorMessage.append(
-                        QStringLiteral("You may override the default search paths by using "
-                                       "QTWEBENGINE_RESOURCES_PATH environment variable."));
+                errorMessage += "You may override the default search paths by using "
+                                "QTWEBENGINE_RESOURCES_PATH environment variable.\n"_L1;
             }
-            qFatal("%s", qPrintable(errorMessage.join('\n')));
+            qFatal("%ls", qUtf16Printable(errorMessage));
         }
     }
 
@@ -363,13 +351,13 @@ base::FilePath WebEngineLibraryInfo::getPath(int key, bool showWarnings)
     QString directory;
     switch (key) {
     case QT_RESOURCES_PAK:
-        return toFilePath(resourcesPath() % QLatin1String("/qtwebengine_resources.pak"));
+        return toFilePath(resourcesPath() % "/qtwebengine_resources.pak"_L1);
     case QT_RESOURCES_100P_PAK:
-        return toFilePath(resourcesPath() % QLatin1String("/qtwebengine_resources_100p.pak"));
+        return toFilePath(resourcesPath() % "/qtwebengine_resources_100p.pak"_L1);
     case QT_RESOURCES_200P_PAK:
-        return toFilePath(resourcesPath() % QLatin1String("/qtwebengine_resources_200p.pak"));
+        return toFilePath(resourcesPath() % "/qtwebengine_resources_200p.pak"_L1);
     case QT_RESOURCES_DEVTOOLS_PAK:
-        return toFilePath(resourcesPath() % QLatin1String("/qtwebengine_devtools_resources.pak"));
+        return toFilePath(resourcesPath() % "/qtwebengine_devtools_resources.pak"_L1);
 #if defined(Q_OS_DARWIN) && defined(QT_MAC_FRAMEWORK_BUILD)
     case QT_FRAMEWORK_BUNDLE:
         return toFilePath(getBundlePath(frameworkBundle()));
diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp
index 86f10315b2b..d47d6a9ced1 100644
--- a/src/core/web_event_factory.cpp
+++ b/src/core/web_event_factory.cpp
@@ -51,6 +51,8 @@
 #endif
 #include <QWheelEvent>
 
+using namespace Qt::StringLiterals;
+
 namespace QtWebEngineCore {
 
 using namespace blink;
@@ -61,24 +63,24 @@ static KeyboardDriver keyboardDriverImpl()
 {
     QString platformName = QGuiApplication::platformName();
 
-    if (platformName == QLatin1String("windows"))
+    if (platformName == "windows"_L1)
         return KeyboardDriver::Windows;
 
-    if (platformName == QLatin1String("cocoa"))
+    if (platformName == "cocoa"_L1)
         return KeyboardDriver::Cocoa;
 
-    if (platformName == QLatin1String("xcb") || platformName == QLatin1String("wayland"))
+    if (platformName == "xcb"_L1 || platformName == "wayland"_L1)
         return KeyboardDriver::Xkb;
 
 #if QT_CONFIG(libinput)
     // Based on QEglFSIntegration::createInputHandlers and QLibInputKeyboard::processKey.
-    if (platformName == QLatin1String("eglfs") && !qEnvironmentVariableIntValue("QT_QPA_EGLFS_NO_LIBINPUT"))
+    if (platformName == "eglfs"_L1 && !qEnvironmentVariableIntValue("QT_QPA_EGLFS_NO_LIBINPUT"))
         return KeyboardDriver::Xkb;
 #endif
 
 #if QT_CONFIG(evdev)
     // Based on QEglFSIntegration::createInputHandlers.
-    if (platformName == QLatin1String("eglfs"))
+    if (platformName == "eglfs"_L1)
         return KeyboardDriver::Evdev;
 #endif
 

From 95690ca93a791f691cd894c28f8d21459c174554 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 23 Jan 2025 16:28:37 +0100
Subject: [PATCH 253/356] Use unicode character literals

- Fix QStringBuilder warnings when concatenating 8 bit characters
- Prefer single character over one character long string literals

Change-Id: Ibfec384b6e5421cb64255a5a52a43001724bf301
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit 6a67fd58bd3c8a4d0483e7f55672d0d07273940e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit ce7a29201777a85da3d89b10c12f0af6ebb94eee)
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
---
 src/core/content_browser_client_qt.cpp     |  2 +-
 src/core/content_client_qt.cpp             |  4 +--
 src/core/devtools_manager_delegate_qt.cpp  |  2 +-
 src/core/download_manager_delegate_qt.cpp  |  2 +-
 src/core/file_picker_controller.cpp        | 35 ++++++++++++----------
 src/core/net/qrc_url_scheme_handler.cpp    |  2 +-
 src/core/select_file_dialog_factory_qt.cpp |  2 +-
 7 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index 44d8ce0e278..1c12a72eaa5 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -991,7 +991,7 @@ blink::UserAgentMetadata ContentBrowserClientQt::GetUserAgentMetadata()
 
 std::string ContentBrowserClientQt::GetProduct()
 {
-    QString productName(qApp->applicationName() % '/' % qApp->applicationVersion());
+    QString productName(qApp->applicationName() % u'/' % qApp->applicationVersion());
     return productName.toStdString();
 }
 
diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index 95d6ec4e3c6..19302c2d9ed 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -192,9 +192,9 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path,
     if (!widevine_argument.empty())
         pluginPaths << QtWebEngineCore::toQt(widevine_argument);
     else {
-        pluginPaths << webenginePluginsPath() + QStringLiteral("/") + QLatin1StringView(kWidevineCdmFileName);
+        pluginPaths << webenginePluginsPath() + u'/' + QLatin1StringView(kWidevineCdmFileName);
 #if QT_CONFIG(webengine_pepper_plugins)
-        pluginPaths << ppapiPluginsPath() + QStringLiteral("/") + QLatin1StringView(kWidevineCdmFileName);
+        pluginPaths << ppapiPluginsPath() + u'/' + QLatin1StringView(kWidevineCdmFileName);
 #endif
 #if defined(Q_OS_OSX)
     QDir potentialWidevineDir("/Applications/Google Chrome.app/Contents/Frameworks");
diff --git a/src/core/devtools_manager_delegate_qt.cpp b/src/core/devtools_manager_delegate_qt.cpp
index 433effed4d8..47651929e6e 100644
--- a/src/core/devtools_manager_delegate_qt.cpp
+++ b/src/core/devtools_manager_delegate_qt.cpp
@@ -73,7 +73,7 @@ void DevToolsServerQt::parseAddressAndPort()
     if (commandLine.HasSwitch(switches::kRemoteDebuggingPort)) {
         portStr = QString::fromStdString(commandLine.GetSwitchValueASCII(switches::kRemoteDebuggingPort));
     } else if (!inspectorEnv.isEmpty()) {
-        int portColonPos = inspectorEnv.lastIndexOf(':');
+        int portColonPos = inspectorEnv.lastIndexOf(u':');
         if (portColonPos != -1) {
             portStr = inspectorEnv.mid(portColonPos + 1);
             m_bindAddress = inspectorEnv.mid(0, portColonPos);
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index 61f789c79ec..393e96ad0c2 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -154,7 +154,7 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
         suggestedFilename = QStringLiteral("qwe_download");
         QMimeType mimeType = QMimeDatabase().mimeTypeForName(mimeTypeString);
         if (mimeType.isValid() && !mimeType.preferredSuffix().isEmpty())
-            suggestedFilename += QStringLiteral(".") + mimeType.preferredSuffix();
+            suggestedFilename += u'.' + mimeType.preferredSuffix();
     }
 
     QDir defaultDownloadDirectory(m_profileAdapter->downloadPath());
diff --git a/src/core/file_picker_controller.cpp b/src/core/file_picker_controller.cpp
index fc52a387daa..098f1b40022 100644
--- a/src/core/file_picker_controller.cpp
+++ b/src/core/file_picker_controller.cpp
@@ -85,14 +85,14 @@ void FilePickerController::accepted(const QStringList &files)
 
             QString absolutePath;
 #if !defined(Q_OS_WIN)
-            absolutePath = "/";
+            absolutePath += u'/';
 #endif
 
             QString scheme = toQt(pathComponents[0]);
             if (scheme.size() > 5) {
 #if defined(Q_OS_WIN)
                 // There is no slash at the end of the file scheme and it is valid on Windows: file:C:/
-                if (scheme.size() == 7 && scheme.at(5).isLetter() && scheme.at(6) == ':') {
+                if (scheme.size() == 7 && scheme.at(5).isLetter() && scheme.at(6) == u':') {
                     absolutePath += scheme.at(5) + ":/"_L1;
                 } else {
 #endif
@@ -108,11 +108,11 @@ void FilePickerController::accepted(const QStringList &files)
                 && base::FilePath::IsSeparator(urlString.at(6).toLatin1())
                 && !base::FilePath::IsSeparator(urlString.at(7).toLatin1())) {
 #if defined(Q_OS_WIN)
-                if (urlString.at(8) != ':' && pathComponents.size() > 2) {
+                if (urlString.at(8) != u':' && pathComponents.size() > 2) {
                     absolutePath += "//"_L1;
 #else
                 if (pathComponents.size() > 2) {
-                    absolutePath += "/";
+                    absolutePath += u'/';
 #endif
                 } else {
                     qWarning("Ignoring invalid item in FilePickerController::accepted(QStringList): %s", qPrintable(urlString));
@@ -120,9 +120,12 @@ void FilePickerController::accepted(const QStringList &files)
                 }
             }
 
-            // Build absolute path from file URI componenets.
-            for (size_t j = 1; j < pathComponents.size(); j++)
-                absolutePath += toQt(pathComponents[j]) + (j != pathComponents.size()-1 ? "/" : "");
+            // Build absolute path from file URI components.
+            for (size_t j = 1; j < pathComponents.size(); j++) {
+                absolutePath += toQt(pathComponents[j]);
+                if (j != pathComponents.size() - 1)
+                    absolutePath += u'/';
+            }
 
             if (toFilePath(absolutePath).IsAbsolute()) {
                 stringList.append(absolutePath);
@@ -250,23 +253,23 @@ QStringList FilePickerController::nameFilters(const QStringList &acceptedMimeTyp
         return nameFilters;
 
     for (QString type : acceptedMimeTypes) {
-        if (type.startsWith(".")) {
+        if (type.startsWith(u'.')) {
             // A single suffix
             // Filename.type doesn't have to exist and mimeTypeForFile() supports
             // custom suffixes as valid (but unknown) MIME types.
             const QMimeType &mimeType = mimeDatabase.mimeTypeForFile("filename" + type);
             if (mimeType.isValid()) {
-                QString glob = "*" + type;
+                QString glob = u'*' + type;
                 acceptedGlobs.append(glob);
-                nameFilters.append(mimeType.comment() + " ("_L1 + glob + ")");
+                nameFilters.append(mimeType.comment() + " ("_L1 + glob + u')');
             }
-        } else if (type.contains("/") && !type.endsWith("*")) {
+        } else if (type.contains(u'/') && !type.endsWith(u'*')) {
             // All suffixes for a given MIME type
             const QMimeType &mimeType = mimeDatabase.mimeTypeForName(type);
             if (mimeType.isValid() && !mimeType.globPatterns().isEmpty()) {
-                QString globs = mimeType.globPatterns().join(" ");
+                QString globs = mimeType.globPatterns().join(u' ');
                 acceptedGlobs.append(mimeType.globPatterns());
-                nameFilters.append(mimeType.comment() + " ("_L1 + globs + ")");
+                nameFilters.append(mimeType.comment() + " ("_L1 + globs + u')');
             }
         } else if (type.endsWith("/*"_L1)) {
             // All MIME types for audio/*, image/* or video/*
@@ -275,9 +278,9 @@ QStringList FilePickerController::nameFilters(const QStringList &acceptedMimeTyp
             type = type.remove("/*");
             for (const QMimeType &m : allMimeTypes) {
                 if (m.name().startsWith(type) && !m.globPatterns().isEmpty()) {
-                    QString globs = m.globPatterns().join(" ");
+                    QString globs = m.globPatterns().join(u' ');
                     acceptedGlobs.append(m.globPatterns());
-                    nameFilters.append(m.comment() + " ("_L1 + globs + ")");
+                    nameFilters.append(m.comment() + " ("_L1 + globs + u')');
                 }
             }
         } else {
@@ -287,7 +290,7 @@ QStringList FilePickerController::nameFilters(const QStringList &acceptedMimeTyp
 
     const QString filter =
         QCoreApplication::translate("FilePickerController",
-                                    "Accepted types (%1)").arg(acceptedGlobs.join(' '));
+                                    "Accepted types (%1)").arg(acceptedGlobs.join(u' '));
     nameFilters.prepend(filter);
 
     return nameFilters;
diff --git a/src/core/net/qrc_url_scheme_handler.cpp b/src/core/net/qrc_url_scheme_handler.cpp
index 82554827ead..f1925da14dd 100644
--- a/src/core/net/qrc_url_scheme_handler.cpp
+++ b/src/core/net/qrc_url_scheme_handler.cpp
@@ -26,7 +26,7 @@ void QrcUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job)
 
     QUrl requestUrl = job->requestUrl();
     QString requestPath = requestUrl.path();
-    auto file = std::make_unique<QFile>(':' + requestPath, job);
+    auto file = std::make_unique<QFile>(u':' + requestPath, job);
     if (!file->exists() || file->size() == 0) {
         qWarning("QResource '%s' not found or is empty", qUtf8Printable(requestPath));
         job->fail(QWebEngineUrlRequestJob::UrlNotFound);
diff --git a/src/core/select_file_dialog_factory_qt.cpp b/src/core/select_file_dialog_factory_qt.cpp
index 1f897a805c3..f3f35c1aa6a 100644
--- a/src/core/select_file_dialog_factory_qt.cpp
+++ b/src/core/select_file_dialog_factory_qt.cpp
@@ -119,7 +119,7 @@ void SelectFileDialogQt::SelectFileImpl(Type type, const std::u16string &title,
     if (file_types) {
         for (const auto &type : file_types->extensions) {
             for (const auto &extension : type)
-                acceptedSuffixes.append("." + toQt(extension));
+                acceptedSuffixes.append(u'.' + toQt(extension));
         }
     }
 

From 093df5a6c33820adfedd2c48339e817b2c81753d Mon Sep 17 00:00:00 2001
From: Andreas Eliasson <andreas.eliasson@qt.io>
Date: Wed, 18 Dec 2024 13:34:00 +0100
Subject: [PATCH 254/356] Doc: Add link to qt_add_webengine_dictionary in spell
 checker section

The cmake command qt_add_webengine_dictionary was introduced in 6.3.
Add a link and a short description of the command in the spell checker
section.

Fixes: QTBUG-131904
Change-Id: I5f5a2f307ce972b36c5d57c4d2ba37dab2c37343
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit d813d9b8b37289d3c9773b443479e64d32faf9ec)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 5c48638af3b31560305e6f1ad5617348d965b62f)
---
 src/core/doc/src/qtwebengine-features.qdoc | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/core/doc/src/qtwebengine-features.qdoc b/src/core/doc/src/qtwebengine-features.qdoc
index 1dc58a133ea..6599a229f96 100644
--- a/src/core/doc/src/qtwebengine-features.qdoc
+++ b/src/core/doc/src/qtwebengine-features.qdoc
@@ -643,6 +643,11 @@
     When the \QWE spellchecker initializes, it will try to load the
     \c bdict dictionaries and to check them for consistency.
 
+    For CMake, you can use the \l qt_add_webengine_dictionary command to convert
+    Hunspell \c .dic files into the \c .bdic binary format. The command creates
+    a \c qtwebengine_dictionaries target, which your project can use a
+    dependency.
+
     If \c QTWEBENGINE_DICTIONARIES_PATH is set, the spellchecker uses the
     dictionaries in the specified directory without looking anywere else.
     Otherwise, it uses the \e qtwebengine_dictionaries directory relative to the

From 04981e005db976d9740ac357c42b6c8203ba0c3d Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Thu, 6 Feb 2025 16:22:23 +0100
Subject: [PATCH 255/356] Bump permissionbrowser example cmake version

All our other examples use 3.16, and cmake 3.30 now gives a deprecation
warning about this.

Change-Id: If2aff723cedab0339ba506484b44bddd89858307
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit 7feb1ff93040ad1e40e86fadf04c107aa9f4806c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 6ba27b8bc8ab191c743f046d4b58d574b4abf5a1)
---
 examples/webenginewidgets/permissionbrowser/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/examples/webenginewidgets/permissionbrowser/CMakeLists.txt b/examples/webenginewidgets/permissionbrowser/CMakeLists.txt
index c4d8f9cd43e..c7d241d8f67 100644
--- a/examples/webenginewidgets/permissionbrowser/CMakeLists.txt
+++ b/examples/webenginewidgets/permissionbrowser/CMakeLists.txt
@@ -1,7 +1,7 @@
 # Copyright (C) 2024 The Qt Company Ltd.
 # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
 
-cmake_minimum_required(VERSION 3.5)
+cmake_minimum_required(VERSION 3.16)
 project(permissionbrowser LANGUAGES CXX)
 
 set(CMAKE_AUTOMOC ON)

From eb24f979145df02bbd9384c9b664d2e98aa72a7a Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Tue, 10 Dec 2024 09:35:12 +0100
Subject: [PATCH 256/356] Fix clang libraries path detection

So far we passed clang_base_path and clang_version
as major version of clang compiler so gn could assemble
clang runtime libraries path.

However this approach does not always correctly work
as some machines can have single or multiple number version.
In this case path can take a form of:
../XcodeDefault.xctoolchain/usr/lib/clang/16
some other machines have major,minor,patch level form, like:
../XcodeDefault.xctoolchain/usr/lib/clang/15.0.0

Moreover clang compiler version is 4 digit value, so this can
still have different variations.

Instead of trying guess the path based on some logic
simply ask clang compiler what is runtime dir path.

Unfortunately we can just push this path to gn since
this path has to be adjusted for target or host clang
runtime libs during gn run.

Therefore get runtime libs path from clang compiler, however
use it to extract version number which is used in filesystem
and this later is used to assemble library path in gn.

Cache the variable so we run this check once during configure.

Change-Id: I912ab7d5d7b32e1cbe19fa3e8da012f669f6bec7
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit f13bb554d14bab8ba35d814d14c0e72c485f023b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit af78aa72e2425421cbb2919bdfbc8dbcc894ee11)
---
 cmake/Functions.cmake | 29 ++++++++++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/cmake/Functions.cmake b/cmake/Functions.cmake
index f957bea42e9..8d5a977771d 100644
--- a/cmake/Functions.cmake
+++ b/cmake/Functions.cmake
@@ -887,6 +887,25 @@ macro(append_build_type_setup)
     )
 endmacro()
 
+function(get_clang_version_from_runtime_path result)
+if(CLANG AND CMAKE_CXX_COMPILER)
+    if( NOT DEFINED CLANG_RUNTIME_PATH)
+       execute_process(
+           COMMAND ${CMAKE_CXX_COMPILER} -print-runtime-dir
+           OUTPUT_VARIABLE clang_output
+           ERROR_QUIET
+           OUTPUT_STRIP_TRAILING_WHITESPACE
+        )
+        cmake_path(CONVERT "${clang_output}" TO_CMAKE_PATH_LIST clang_output NORMALIZE)
+        set(CLANG_RUNTIME_PATH "${clang_output}" CACHE INTERNAL "internal")
+        mark_as_advanced(CLANG_RUNTIME_PATH)
+     endif()
+     string(REGEX MATCH "\\/([0-9.]+)\\/" clang_run_time_path_version "${CLANG_RUNTIME_PATH}")
+     string(REPLACE "/" "" clang_run_time_path_version ${clang_run_time_path_version})
+     set(${result} ${clang_run_time_path_version} PARENT_SCOPE)
+endif()
+endfunction()
+
 macro(append_compiler_linker_sdk_setup)
     if(CMAKE_CXX_COMPILER_LAUNCHER)
         list(APPEND gnArgArg cc_wrapper="${CMAKE_CXX_COMPILER_LAUNCHER}")
@@ -907,12 +926,16 @@ macro(append_compiler_linker_sdk_setup)
             get_filename_component(clangBasePath ${CMAKE_CXX_COMPILER} DIRECTORY)
             get_filename_component(clangBasePath ${clangBasePath} DIRECTORY)
         endif()
-
-        string(REGEX MATCH "[0-9]+" clangVersion ${CMAKE_CXX_COMPILER_VERSION})
+            get_clang_version_from_runtime_path(clang_version)
+        if (NOT DEFINED clang_version)
+            message(FATAL_ERROR "Clang version for runtime is missing."
+                    "Please open bug report.Found clang runtime path: ${CLANG_RUNTIME_PATH}"
+            )
+        endif()
         list(APPEND gnArgArg
             clang_base_path="${clangBasePath}"
+            clang_version="${clang_version}"
             clang_use_chrome_plugins=false
-            clang_version=${clangVersion}
             fatal_linker_warnings=false
         )
 

From 78863287a4c019651ffd36dfc78d6f9f776c4fc6 Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Thu, 6 Feb 2025 16:21:03 +0100
Subject: [PATCH 257/356] Remove unused lambda captures

Clang warns about these when compiling.

Change-Id: Idf0daf9f4b7c71fefaddb4531d9ed164e90d118e
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit c4cd6aa4df40e8c62f2f1209e036286e6cec1b1f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit a922d5905c4e329688db482c47476beb48794d4e)
---
 examples/webenginewidgets/clientcertificate/client.cpp | 2 +-
 examples/webenginewidgets/maps/mainwindow.cpp          | 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/examples/webenginewidgets/clientcertificate/client.cpp b/examples/webenginewidgets/clientcertificate/client.cpp
index de09120ca0d..c10cff24769 100644
--- a/examples/webenginewidgets/clientcertificate/client.cpp
+++ b/examples/webenginewidgets/clientcertificate/client.cpp
@@ -42,7 +42,7 @@ int main(int argc, char *argv[])
 
     QObject::connect(
             &page, &QWebEnginePage::selectClientCertificate, &page,
-            [&cert](QWebEngineClientCertificateSelection selection) {
+            [](QWebEngineClientCertificateSelection selection) {
                 QDialog dialog;
                 QVBoxLayout *layout = new QVBoxLayout;
                 QLabel *label = new QLabel(QLatin1String("Select certificate"));
diff --git a/examples/webenginewidgets/maps/mainwindow.cpp b/examples/webenginewidgets/maps/mainwindow.cpp
index 07b8d8ab3da..31cc0bbf0cb 100644
--- a/examples/webenginewidgets/maps/mainwindow.cpp
+++ b/examples/webenginewidgets/maps/mainwindow.cpp
@@ -13,8 +13,7 @@ MainWindow::MainWindow(QWidget *parent)
 
     QWebEnginePage *page = m_view->page();
 
-    connect(page, &QWebEnginePage::permissionRequested,
-            [this, page](QWebEnginePermission permission) {
+    connect(page, &QWebEnginePage::permissionRequested, [this](QWebEnginePermission permission) {
         if (permission.permissionType() != QWebEnginePermission::PermissionType::Geolocation)
             return;
 

From b9231f8b20914498a3fa697d65df68d23eb3818f Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 6 Feb 2025 12:37:41 +0100
Subject: [PATCH 258/356] macOS: Fix code signing for manual tests

- Fix path for -debug-and-release build
- Fix ".app: is already signed" error during build

Change-Id: I63c8a34be9e531fa07e2ac2f39ad4f6a67b4be65
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit 9a66024228ecbc2251f7ea4185bda74d11c2c600)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit ba8f5af7e688aa5e17c55ff96d2db6c3fe92031a)
---
 tests/manual/quick/geopermission/CMakeLists.txt | 7 ++++++-
 tests/manual/widgets/geolocation/CMakeLists.txt | 7 ++++++-
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/tests/manual/quick/geopermission/CMakeLists.txt b/tests/manual/quick/geopermission/CMakeLists.txt
index 6602ceb6ff6..e6f91356074 100644
--- a/tests/manual/quick/geopermission/CMakeLists.txt
+++ b/tests/manual/quick/geopermission/CMakeLists.txt
@@ -49,8 +49,13 @@ if (APPLE)
 
     if (NOT CMAKE_GENERATOR STREQUAL "Xcode")
         # Need to sign application for location permissions to work
+        if(QT_FEATURE_debug_and_release)
+            set(exe_path "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/")
+        else()
+            unset(exe_path)
+        endif()
         add_custom_command(TARGET tst_geopermission
-            POST_BUILD COMMAND codesign -s - tst_geopermission.app)
+            POST_BUILD COMMAND codesign --force -s - ${exe_path}tst_geopermission.app)
     endif()
 endif()
 
diff --git a/tests/manual/widgets/geolocation/CMakeLists.txt b/tests/manual/widgets/geolocation/CMakeLists.txt
index 2ca8c2f524b..25704bfdff2 100644
--- a/tests/manual/widgets/geolocation/CMakeLists.txt
+++ b/tests/manual/widgets/geolocation/CMakeLists.txt
@@ -49,7 +49,12 @@ if (APPLE)
 
     if (NOT CMAKE_GENERATOR STREQUAL "Xcode")
         # Need to sign application for location permissions to work
+        if(QT_FEATURE_debug_and_release)
+            set(exe_path "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/")
+        else()
+            unset(exe_path)
+        endif()
         add_custom_command(TARGET geolocation
-            POST_BUILD COMMAND codesign -s - geolocation.app)
+            POST_BUILD COMMAND codesign --force -s - ${exe_path}geolocation.app)
     endif()
 endif()

From fc9e81c808e837433f8ad08af4efe1767b786df8 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Fri, 7 Feb 2025 15:15:04 +0100
Subject: [PATCH 259/356] Fix Widevine path detection on ARM macOS

The path to the Widevine CDM plugin on macOS was hardcoded to where it's
located on x64 machines, which led to DRM content not working on
ARM-based machines.

Fixes: QTBUG-133558
Change-Id: I723033dfd7d011b1d8635fb88549c7fd58331856
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit b13fd82027b73bc4addab727f9fa818d65c1dde0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 50b7e625daab642aba6d33546a366d5783e734cd)
---
 src/core/content_client_qt.cpp | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index 19302c2d9ed..0b16c01e9b2 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -29,6 +29,7 @@
 #include <QFile>
 #include <QLibraryInfo>
 #include <QString>
+#include <QSysInfo>
 
 
 #if BUILDFLAG(ENABLE_LIBRARY_CDMS)
@@ -198,13 +199,16 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path,
 #endif
 #if defined(Q_OS_OSX)
     QDir potentialWidevineDir("/Applications/Google Chrome.app/Contents/Frameworks");
+    const auto archDir = QSysInfo::currentCpuArchitecture() == "x86_64"_L1
+                       ? "mac_x64/"_L1
+                       : "mac_arm64/"_L1;
     if (potentialWidevineDir.exists()) {
         QFileInfoList widevineVersionDirs = potentialWidevineDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot,
                                                                                QDir::Name | QDir::Reversed);
-        const auto library =
-                "/Versions/Current/Libraries/WidevineCdm/_platform_specific/mac_x64/libwidevinecdm.dylib"_L1;
+        const auto libraryBase = "/Versions/Current/Libraries/WidevineCdm/_platform_specific/"_L1;
+        const auto libraryFilename = "libwidevinecdm.dylib"_L1;
         for (const QFileInfo &info : widevineVersionDirs)
-            pluginPaths << info.absoluteFilePath() + library;
+            pluginPaths << info.absoluteFilePath() + libraryBase + archDir + libraryFilename;
     }
 
     QDir oldPotentialWidevineDir(QDir::homePath() + "/Library/Application Support/Google/Chrome/WidevineCDM"_L1);
@@ -212,7 +216,7 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path,
         QFileInfoList widevineVersionDirs = oldPotentialWidevineDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed);
         for (int i = 0; i < widevineVersionDirs.size(); ++i) {
             QString versionDirPath(widevineVersionDirs.at(i).absoluteFilePath());
-            QString potentialWidevinePluginPath = versionDirPath + "/_platform_specific/mac_x64/"_L1
+            QString potentialWidevinePluginPath = versionDirPath + "/_platform_specific/"_L1 + archDir
                     + QLatin1StringView(kWidevineCdmFileName);
             pluginPaths << potentialWidevinePluginPath;
         }

From b35886854e4595369791343a58cb66187219fd1e Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Tue, 11 Feb 2025 14:11:05 +0100
Subject: [PATCH 260/356] Fix flaky tst_QWebEngineView::keyboardFocusAfterPopup
 on macOS

On macOS, Qt closes all popups when NSWindowDidResignKeyNotification
event is triggered by the OS, see QTBUG-105474.

This event somehow is triggered after we call show() on a widget. The
event might be triggered while the QCompleter's popup is already open
and it breaks the test.

Wait for the OS events to be processed with qWaitForWindowExposed().

Fixes: QTBUG-133590
Change-Id: I51b05df375046fcfb28ae213173a517d60216ae2
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit 6845b1d256efd2abf5f45b333de3b03bb80a58a2)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 3670fe65d797a012cce3882df39c378eee61c12c)
---
 tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 2eec0901a69..d44167d9de8 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -1620,6 +1620,7 @@ void tst_QWebEngineView::keyboardFocusAfterPopup()
     connect(window.lineEdit, &QLineEdit::editingFinished, [&] { window.webView->setHtml(html); });
     window.webView->settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
     window.show();
+    QVERIFY(QTest::qWaitForWindowExposed(&window));
 
     // Focus will initially go to the QLineEdit.
     QTRY_COMPARE(QApplication::focusWidget(), window.lineEdit);

From 6da5aeb5dae0e72358297f8655ca29de27b62721 Mon Sep 17 00:00:00 2001
From: Anu Aliyas <anu.aliyas@qt.io>
Date: Wed, 12 Feb 2025 16:19:22 +0100
Subject: [PATCH 261/356] Perform the focus check earlier
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

While loading URLs, QtWebEngine will remove the old widget from the
layout and then add the new widget. When hiding the old widget from the
layout, it loses focus. As a result, the focus is not set to the new
widget. Modified the code to check whether the old widget has focus
before it is hidden.

Amends e227bbddbfc03c45735978f5b83994235225569a

Fixes: QTBUG-133649
Change-Id: Iac4b1317ed469bfa32e18f0e18361a2279b77cf6
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
(cherry picked from commit c8f8749e8810e33396b1dbf7f65e3b58f7b8be39)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 4942d3cee3f2c7bf643dea6901765252923509ed)
---
 src/webenginewidgets/api/qwebengineview.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index 0ef881b5ae7..4a96a92fce2 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -439,6 +439,7 @@ void QWebEngineViewPrivate::widgetChanged(QtWebEngineCore::WebEngineQuickWidget
 {
     Q_Q(QWebEngineView);
 
+    bool hasFocus = oldWidget ? oldWidget->hasFocus() : false;
     if (oldWidget) {
         q->layout()->removeWidget(oldWidget);
         oldWidget->hide();
@@ -457,7 +458,7 @@ void QWebEngineViewPrivate::widgetChanged(QtWebEngineCore::WebEngineQuickWidget
 #endif
         q->layout()->addWidget(newWidget);
         q->setFocusProxy(newWidget);
-        if (oldWidget && oldWidget == QApplication::focusWidget())
+        if (hasFocus)
             newWidget->setFocus();
         newWidget->show();
     }

From 7eb5f8a92c2ab02fc8cb97748ad1cea598880438 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Mon, 10 Feb 2025 15:52:07 +0100
Subject: [PATCH 262/356] qwebengine_convert_dict: Avoid to construct QString
 for a character

Change-Id: Icd44c96715358c92f21e82e42352e58c3c8bc4d7
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit cb8527103f0f21155694345e75ed11afd7aeb8db)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit ea6fac65ce76b2fac827579994e793d1c0659d1c)
---
 src/core/tools/qwebengine_convert_dict/main.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/core/tools/qwebengine_convert_dict/main.cpp b/src/core/tools/qwebengine_convert_dict/main.cpp
index b49ae0279a5..5dc750ee261 100644
--- a/src/core/tools/qwebengine_convert_dict/main.cpp
+++ b/src/core/tools/qwebengine_convert_dict/main.cpp
@@ -70,11 +70,11 @@ template<class T>
 QTextStream &operator<<(QTextStream &out, base::span<T> span)
 {
     out << '[';
-    QString prefix;
+    QLatin1StringView prefix;
     for (const auto &element : span) {
         out << prefix;
         out << element;
-        prefix = QStringLiteral(",");
+        prefix = ","_L1;
     }
     out << ']';
     return out;

From 70149a85de61c6775a335f734778421f2d7220a6 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Wed, 12 Feb 2025 15:50:33 +0100
Subject: [PATCH 263/356] Fix source file path reported in "js" logging
 category

Also add auto tests for validating javaScriptConsoleMessage()
arguments.

Change-Id: Ife6a2db66898a15071b6f8d082195794f2f45e27
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit ef4e9a07bda2e676a02435080355be30dc0abf09)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 4a6ff28b8797e16460d44675d85d57f11a1c6138)
---
 src/core/api/qwebenginepage.cpp               |  2 +-
 .../html/resources/hello.js                   |  7 ++
 .../qquickwebengineview/html/resources/hi.js  |  8 ++
 .../qquickwebengineview/html/script2.html     |  4 +
 .../tst_qquickwebengineview.cpp               | 79 +++++++++++++++++++
 .../widgets/qwebenginepage/CMakeLists.txt     |  3 +
 .../widgets/qwebenginepage/resources/hello.js |  7 ++
 .../widgets/qwebenginepage/resources/hi.js    |  8 ++
 .../qwebenginepage/resources/script2.html     |  4 +
 .../qwebenginepage/tst_qwebenginepage.cpp     | 77 +++++++++++++++++-
 10 files changed, 197 insertions(+), 2 deletions(-)
 create mode 100644 tests/auto/quick/qquickwebengineview/html/resources/hello.js
 create mode 100644 tests/auto/quick/qquickwebengineview/html/resources/hi.js
 create mode 100644 tests/auto/quick/qquickwebengineview/html/script2.html
 create mode 100644 tests/auto/widgets/qwebenginepage/resources/hello.js
 create mode 100644 tests/auto/widgets/qwebenginepage/resources/hi.js
 create mode 100644 tests/auto/widgets/qwebenginepage/resources/script2.html

diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp
index b180b58b99d..826d8ce492c 100644
--- a/src/core/api/qwebenginepage.cpp
+++ b/src/core/api/qwebenginepage.cpp
@@ -2283,7 +2283,7 @@ bool QWebEnginePage::javaScriptPrompt(const QUrl &securityOrigin, const QString
 void QWebEnginePage::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID)
 {
     static QLoggingCategory loggingCategory("js", QtWarningMsg);
-    static QByteArray file = sourceID.toUtf8();
+    const QByteArray file = sourceID.toUtf8();
     QMessageLogger logger(file.constData(), lineNumber, nullptr, loggingCategory.categoryName());
 
     switch (level) {
diff --git a/tests/auto/quick/qquickwebengineview/html/resources/hello.js b/tests/auto/quick/qquickwebengineview/html/resources/hello.js
new file mode 100644
index 00000000000..6f5e79ebf4d
--- /dev/null
+++ b/tests/auto/quick/qquickwebengineview/html/resources/hello.js
@@ -0,0 +1,7 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+function sayHello()
+{
+    console.warn("hello");
+}
diff --git a/tests/auto/quick/qquickwebengineview/html/resources/hi.js b/tests/auto/quick/qquickwebengineview/html/resources/hi.js
new file mode 100644
index 00000000000..30e7cc972d1
--- /dev/null
+++ b/tests/auto/quick/qquickwebengineview/html/resources/hi.js
@@ -0,0 +1,8 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+function sayHi()
+{
+    // Placeholder
+    console.warn("hi");
+}
diff --git a/tests/auto/quick/qquickwebengineview/html/script2.html b/tests/auto/quick/qquickwebengineview/html/script2.html
new file mode 100644
index 00000000000..5faf58daab3
--- /dev/null
+++ b/tests/auto/quick/qquickwebengineview/html/script2.html
@@ -0,0 +1,4 @@
+<html><head>
+<script language="javascript" type="text/javascript" src="resources/hello.js"></script>
+<script language="javascript" type="text/javascript" src="resources/hi.js"></script>
+</head></html>
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index b4eaeb37c18..1177d8adf53 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -27,6 +27,8 @@
 
 #include <functional>
 
+using namespace Qt::StringLiterals;
+
 class tst_QQuickWebEngineView : public QObject {
     Q_OBJECT
 public:
@@ -80,6 +82,7 @@ private Q_SLOTS:
     void htmlSelectPopup();
     void savePage_data();
     void savePage();
+    void javaScriptConsoleMessage();
 
 private:
     inline QQuickWebEngineView *newWebEngineView();
@@ -1362,6 +1365,82 @@ void tst_QQuickWebEngineView::savePage()
              originalData);
 }
 
+class TestJSMessageHandler
+{
+public:
+    inline static QList<QtMsgType> levels;
+    inline static QStringList messages;
+    inline static QList<int> lineNumbers;
+    inline static QStringList sourceIDs;
+
+    static void handler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
+    {
+        if (strcmp(context.category, "js") != 0) {
+            m_originalHandler(type, context, msg);
+            return;
+        }
+
+        levels.append(type);
+        messages.append(msg);
+        lineNumbers.append(context.line);
+        sourceIDs.append(context.file);
+    }
+
+    TestJSMessageHandler() { m_originalHandler = qInstallMessageHandler(handler); }
+    ~TestJSMessageHandler() { qInstallMessageHandler(m_originalHandler); }
+
+private:
+    inline static QtMessageHandler m_originalHandler = nullptr;
+};
+
+void tst_QQuickWebEngineView::javaScriptConsoleMessage()
+{
+    QQuickWebEngineView *view = webEngineView();
+
+    // Test QQuickWebEngineView::javaScriptConsoleMessage() signal.
+    {
+        QSignalSpy jsSpy(
+                view,
+                SIGNAL(javaScriptConsoleMessage(QQuickWebEngineView::JavaScriptConsoleMessageLevel,
+                                                const QString &, int, const QString &)));
+        view->setUrl(urlFromTestPath("html/script2.html"));
+        QVERIFY(waitForLoadSucceeded(view));
+
+        runJavaScript("sayHello()");
+        QTRY_COMPARE(jsSpy.size(), 1);
+        QCOMPARE(jsSpy.last().at(0).toInt(), QWebEnginePage::WarningMessageLevel);
+        QCOMPARE(jsSpy.last().at(1).toString(), "hello"_L1);
+        QCOMPARE(jsSpy.last().at(2).toInt(), 6);
+        QCOMPARE(jsSpy.last().at(3).toString(), urlFromTestPath("html/resources/hello.js"));
+
+        runJavaScript("sayHi()");
+        QTRY_COMPARE(jsSpy.size(), 2);
+        QCOMPARE(jsSpy.last().at(0).toInt(), QWebEnginePage::WarningMessageLevel);
+        QCOMPARE(jsSpy.last().at(1).toString(), "hi"_L1);
+        QCOMPARE(jsSpy.last().at(2).toInt(), 7);
+        QCOMPARE(jsSpy.last().at(3).toString(), urlFromTestPath("html/resources/hi.js"));
+    }
+
+    // Test default QQuickWebEngineViewPrivate::javaScriptConsoleMessage() handler.
+    {
+        TestJSMessageHandler handler;
+        view->setUrl(urlFromTestPath("html/script2.html"));
+        QVERIFY(waitForLoadSucceeded(view));
+
+        evaluateJavaScriptSync(view, "sayHello()");
+        QCOMPARE(handler.levels.last(), QtMsgType::QtWarningMsg);
+        QCOMPARE(handler.messages.last(), "hello"_L1);
+        QCOMPARE(handler.lineNumbers.last(), 6);
+        QCOMPARE(handler.sourceIDs.last(), urlFromTestPath("html/resources/hello.js"));
+
+        evaluateJavaScriptSync(view, "sayHi()");
+        QCOMPARE(handler.levels.last(), QtMsgType::QtWarningMsg);
+        QCOMPARE(handler.messages.last(), "hi"_L1);
+        QCOMPARE(handler.lineNumbers.last(), 7);
+        QCOMPARE(handler.sourceIDs.last(), urlFromTestPath("html/resources/hi.js"));
+    }
+}
+
 #if QT_CONFIG(accessibility)
 static QByteArrayList params = QByteArrayList()
     << "--force-renderer-accessibility";
diff --git a/tests/auto/widgets/qwebenginepage/CMakeLists.txt b/tests/auto/widgets/qwebenginepage/CMakeLists.txt
index 55c35af8810..a0470e25a37 100644
--- a/tests/auto/widgets/qwebenginepage/CMakeLists.txt
+++ b/tests/auto/widgets/qwebenginepage/CMakeLists.txt
@@ -30,6 +30,8 @@ set(tst_qwebenginepage_resource_files
     "resources/frame_c.html"
     "resources/framedindex.html"
     "resources/fullscreen.html"
+    "resources/hello.js"
+    "resources/hi.js"
     "resources/iframe.html"
     "resources/iframe2.html"
     "resources/iframe3.html"
@@ -40,6 +42,7 @@ set(tst_qwebenginepage_resource_files
     "resources/path with spaces.txt"
     "resources/reload.html"
     "resources/script.html"
+    "resources/script2.html"
     "resources/style.css"
     "resources/test1.html"
     "resources/test2.html"
diff --git a/tests/auto/widgets/qwebenginepage/resources/hello.js b/tests/auto/widgets/qwebenginepage/resources/hello.js
new file mode 100644
index 00000000000..6f5e79ebf4d
--- /dev/null
+++ b/tests/auto/widgets/qwebenginepage/resources/hello.js
@@ -0,0 +1,7 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+function sayHello()
+{
+    console.warn("hello");
+}
diff --git a/tests/auto/widgets/qwebenginepage/resources/hi.js b/tests/auto/widgets/qwebenginepage/resources/hi.js
new file mode 100644
index 00000000000..30e7cc972d1
--- /dev/null
+++ b/tests/auto/widgets/qwebenginepage/resources/hi.js
@@ -0,0 +1,8 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+function sayHi()
+{
+    // Placeholder
+    console.warn("hi");
+}
diff --git a/tests/auto/widgets/qwebenginepage/resources/script2.html b/tests/auto/widgets/qwebenginepage/resources/script2.html
new file mode 100644
index 00000000000..7d511503771
--- /dev/null
+++ b/tests/auto/widgets/qwebenginepage/resources/script2.html
@@ -0,0 +1,4 @@
+<html><head>
+<script language="javascript" type="text/javascript" src="hello.js"></script>
+<script language="javascript" type="text/javascript" src="hi.js"></script>
+</head></html>
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index e8dac91e788..31c82b28a8b 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -80,6 +80,8 @@
 #include <QQuickRenderControl>
 #include <QQuickWindow>
 
+using namespace Qt::StringLiterals;
+
 static void removeRecursive(const QString& dirname)
 {
     QDir dir(dirname);
@@ -137,6 +139,7 @@ private Q_SLOTS:
     void backActionUpdate();
     void localStorageVisibility();
     void consoleOutput();
+    void javaScriptConsoleMessage();
     void userAgentNewlineStripping();
     void renderWidgetHostViewNotShowTopLevel();
     void getUserMediaRequest_data();
@@ -613,7 +616,7 @@ class ConsolePage : public QWebEnginePage
         sourceIDs.append(sourceID);
     }
 
-    QList<int> levels;
+    QList<JavaScriptConsoleMessageLevel> levels;
     QStringList messages;
     QList<int> lineNumbers;
     QStringList sourceIDs;
@@ -628,6 +631,78 @@ void tst_QWebEnginePage::consoleOutput()
     QCOMPARE(page.lineNumbers.at(0), 1);
 }
 
+class TestJSMessageHandler
+{
+public:
+    inline static QList<QtMsgType> levels;
+    inline static QStringList messages;
+    inline static QList<int> lineNumbers;
+    inline static QStringList sourceIDs;
+
+    static void handler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
+    {
+        if (strcmp(context.category, "js") != 0) {
+            m_originalHandler(type, context, msg);
+            return;
+        }
+
+        levels.append(type);
+        messages.append(msg);
+        lineNumbers.append(context.line);
+        sourceIDs.append(context.file);
+    }
+
+    TestJSMessageHandler() { m_originalHandler = qInstallMessageHandler(handler); }
+    ~TestJSMessageHandler() { qInstallMessageHandler(m_originalHandler); }
+
+private:
+    inline static QtMessageHandler m_originalHandler = nullptr;
+};
+
+void tst_QWebEnginePage::javaScriptConsoleMessage()
+{
+    // Test overridden QWebEnginePage::javaScriptConsoleMessage().
+    {
+        ConsolePage page;
+        QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+        page.load(QUrl("qrc:///resources/script2.html"));
+        QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
+
+        evaluateJavaScriptSync(&page, "sayHello()");
+        QCOMPARE(page.levels.last(), QWebEnginePage::WarningMessageLevel);
+        QCOMPARE(page.messages.last(), "hello"_L1);
+        QCOMPARE(page.lineNumbers.last(), 6);
+        QCOMPARE(page.sourceIDs.last(), "qrc:///resources/hello.js"_L1);
+
+        evaluateJavaScriptSync(&page, "sayHi()");
+        QCOMPARE(page.levels.last(), QWebEnginePage::WarningMessageLevel);
+        QCOMPARE(page.messages.last(), "hi"_L1);
+        QCOMPARE(page.lineNumbers.last(), 7);
+        QCOMPARE(page.sourceIDs.last(), "qrc:///resources/hi.js"_L1);
+    }
+
+    // Test default QWebEnginePage::javaScriptConsoleMessage() handler.
+    {
+        TestJSMessageHandler handler;
+        QWebEnginePage page;
+        QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+        page.load(QUrl("qrc:///resources/script2.html"));
+        QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
+
+        evaluateJavaScriptSync(&page, "sayHello()");
+        QCOMPARE(handler.levels.last(), QtMsgType::QtWarningMsg);
+        QCOMPARE(handler.messages.last(), "hello"_L1);
+        QCOMPARE(handler.lineNumbers.last(), 6);
+        QCOMPARE(handler.sourceIDs.last(), "qrc:///resources/hello.js"_L1);
+
+        evaluateJavaScriptSync(&page, "sayHi()");
+        QCOMPARE(handler.levels.last(), QtMsgType::QtWarningMsg);
+        QCOMPARE(handler.messages.last(), "hi"_L1);
+        QCOMPARE(handler.lineNumbers.last(), 7);
+        QCOMPARE(handler.sourceIDs.last(), "qrc:///resources/hi.js"_L1);
+    }
+}
+
 class TestPage : public QWebEnginePage {
     Q_OBJECT
 public:

From 89a0f31c2532c4b621556767161dea22e8766370 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Fri, 14 Feb 2025 10:41:14 +0100
Subject: [PATCH 264/356] Fix flaky
 tst_QWebEnginePage::discardAbortsPendingLoadAndPreservesCommittedLoad

The test fail was reproducible on arm64 macOS but it could happen on any
platform if it is fast enough.

The about:blank page load is interrupted by Discarded lifecycle state in
the test. Loading about:blank can be so fast that the navigation is
committed before we could send the QWebEnginePage::loadStarted signal.
Interrupting the load at this point won't restore the previous commit
and breaks the test.

As a fix, load a page from the disk which load time is potentially
longer than the about:blank page's load time.

Change-Id: Id885f8a67b5566c5ad9024e40ce36153ff03f832
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit 0730ae7dd64aeef7a23a3a108b95c5057292c56f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 2d3eb5d56da519bf788704f24545082f82b176db)
---
 tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 31c82b28a8b..9fd9d2a58c0 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -4789,7 +4789,7 @@ void tst_QWebEnginePage::discardAbortsPendingLoadAndPreservesCommittedLoad()
 
     connect(&page, &QWebEnginePage::loadStarted,
             [&]() { page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded); });
-    QString url2 = QStringLiteral("about:blank");
+    QString url2 = QStringLiteral("qrc:/resources/test1.html");
     page.setUrl(url2);
     QTRY_COMPARE(loadStartedSpy.size(), 1);
     loadStartedSpy.clear();

From 77a14558feb6e97fa7b03d2c8e49b2c7d12e35db Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 6 Feb 2025 15:22:21 +0100
Subject: [PATCH 265/356] Do not assign the first part of string in case of
 concatenations

This may avoid unnecessary QString allocations.

Change-Id: I9b1c2d3ce06c6798f6b777660f897c02deb8fbfd
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit 12f8f37e1a81fd9dcb5c2925e5a9b5e0df500ad1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 3dcf43316be6f3383d232d649ae2a6c78a977fce)
---
 src/core/clipboard_qt.cpp                 | 5 +++--
 src/core/download_manager_delegate_qt.cpp | 2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/core/clipboard_qt.cpp b/src/core/clipboard_qt.cpp
index cd63b0b6f29..39955719005 100644
--- a/src/core/clipboard_qt.cpp
+++ b/src/core/clipboard_qt.cpp
@@ -136,13 +136,14 @@ void ClipboardQt::WriteHTML(base::StringPiece markup, absl::optional<base::Strin
                             ui::ClipboardContentType /*content_type*/)
 {
 
-    QString markup_string = toQString(markup);
+    QString markup_string;
 #if defined (Q_OS_MACOS)
     // We need to prepend the charset on macOS to prevent garbled Unicode characters
     // when pasting to certain applications (e.g. Notes, TextEdit)
     // Mirrors the behavior in ui/base/clipboard/clipboard_mac.mm in Chromium.
-    markup_string.prepend("<meta charset='utf-8'>"_L1);
+    markup_string += "<meta charset='utf-8'>"_L1;
 #endif
+    markup_string += toQString(markup);
 
 #if !defined(Q_OS_WIN)
     getUncommittedData()->setHtml(markup_string);
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index 393e96ad0c2..ec80d548a91 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -151,7 +151,7 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
     }
 
     if (suggestedFilename.isEmpty()) {
-        suggestedFilename = QStringLiteral("qwe_download");
+        suggestedFilename += QStringLiteral("qwe_download");
         QMimeType mimeType = QMimeDatabase().mimeTypeForName(mimeTypeString);
         if (mimeType.isValid() && !mimeType.preferredSuffix().isEmpty())
             suggestedFilename += u'.' + mimeType.preferredSuffix();

From 06b0c1f0c36f994721fb6e4a84101fabd3ceb160 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 23 Jan 2025 16:42:00 +0100
Subject: [PATCH 266/356] Remove unnecessary QString conversions

Some of them fix compiler warnings.

Change-Id: I93a605090567ae9cd2a101d83eeaac88f39b9ffa
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit ecb4782cbc058047068603f41140fe3e28e7d9a3)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 64893881c14ba36ce7002e5177b9df2c19c18a88)
---
 src/core/devtools_manager_delegate_qt.cpp   | 5 +++--
 src/core/file_picker_controller.cpp         | 2 +-
 src/core/net/cookie_monster_delegate_qt.cpp | 2 +-
 src/core/render_view_context_menu_qt.cpp    | 2 +-
 src/core/user_script.cpp                    | 2 +-
 5 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/core/devtools_manager_delegate_qt.cpp b/src/core/devtools_manager_delegate_qt.cpp
index 47651929e6e..838964d01be 100644
--- a/src/core/devtools_manager_delegate_qt.cpp
+++ b/src/core/devtools_manager_delegate_qt.cpp
@@ -124,8 +124,9 @@ void DevToolsServerQt::stop()
 void DevToolsManagerDelegateQt::Initialized(const net::IPEndPoint *ip_address)
 {
     if (ip_address && ip_address->address().size()) {
-        QString addressAndPort = QString::fromStdString(ip_address->ToString());
-        qWarning("Remote debugging server started successfully. Try pointing a Chromium-based browser to http://%s", qPrintable(addressAndPort));
+        qWarning("Remote debugging server started successfully. "
+                 "Try pointing a Chromium-based browser to http://%s",
+                 ip_address->ToString().c_str());
     }
     else
         qWarning("Couldn't start the inspector server on bind address. In case of invalid input, try something like: \"12345\" or \"192.168.2.14:12345\" (with the address of one of this host's interface).");
diff --git a/src/core/file_picker_controller.cpp b/src/core/file_picker_controller.cpp
index 098f1b40022..e7b7de7b192 100644
--- a/src/core/file_picker_controller.cpp
+++ b/src/core/file_picker_controller.cpp
@@ -275,7 +275,7 @@ QStringList FilePickerController::nameFilters(const QStringList &acceptedMimeTyp
             // All MIME types for audio/*, image/* or video/*
             // as separate filters as Chrome does
             static const QList<QMimeType> &allMimeTypes = mimeDatabase.allMimeTypes();
-            type = type.remove("/*");
+            type.chop(2);
             for (const QMimeType &m : allMimeTypes) {
                 if (m.name().startsWith(type) && !m.globPatterns().isEmpty()) {
                     QString globs = m.globPatterns().join(u' ');
diff --git a/src/core/net/cookie_monster_delegate_qt.cpp b/src/core/net/cookie_monster_delegate_qt.cpp
index d107c520c41..da5f50c75cc 100644
--- a/src/core/net/cookie_monster_delegate_qt.cpp
+++ b/src/core/net/cookie_monster_delegate_qt.cpp
@@ -50,7 +50,7 @@ class CookieAccessFilter : public network::mojom::CookieRemoteAccessFilter
 
 static GURL sourceUrlForCookie(const QNetworkCookie &cookie)
 {
-    QString urlFragment = QStringLiteral("%1%2").arg(cookie.domain()).arg(cookie.path());
+    const QString urlFragment = cookie.domain() % cookie.path();
     return net::cookie_util::CookieOriginToURL(urlFragment.toStdString(), /* is_https */ cookie.isSecure());
 }
 
diff --git a/src/core/render_view_context_menu_qt.cpp b/src/core/render_view_context_menu_qt.cpp
index b7aabfd5b66..089b9202003 100644
--- a/src/core/render_view_context_menu_qt.cpp
+++ b/src/core/render_view_context_menu_qt.cpp
@@ -36,7 +36,7 @@ namespace QtWebEngineCore {
             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "Save page"),
             QT_TRANSLATE_NOOP("RenderViewContextMenuQt", "View page source")
         };
-        return QCoreApplication::translate("RenderViewContextMenuQt", qUtf8Printable(names[menuItem]));
+        return QCoreApplication::translate("RenderViewContextMenuQt", names[menuItem]);
     }
 
     RenderViewContextMenuQt::RenderViewContextMenuQt(QWebEngineContextMenuRequest *request)
diff --git a/src/core/user_script.cpp b/src/core/user_script.cpp
index c33fb908178..a91d470ed24 100644
--- a/src/core/user_script.cpp
+++ b/src/core/user_script.cpp
@@ -62,7 +62,7 @@ QString UserScript::name() const
 void UserScript::setName(const QString &name)
 {
     m_name = name;
-    m_scriptData.url = GURL(QStringLiteral("userScript:%1").arg(name).toStdString());
+    m_scriptData.url = GURL("userScript:" + name.toStdString());
 }
 
 QString UserScript::sourceCode() const

From 4cdfbbf0908d4d4b3799465c2a7079d8d4e1e6d7 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Wed, 5 Feb 2025 14:42:49 +0100
Subject: [PATCH 267/356] Fix flaky tst_QWebEngineDownloadRequest auto tests

Some of the test cases rely on context menu triggered by simulated user
action. Input events are suppressed by blink if the page is not painted
yet because the cc compositor deferred a commit.
See SuppressingInputEventsBits::kDeferCommits and
WidgetInputHandlerManager::DispatchEvent().

Wait for the HTML <body> element to be painted to make sure the
simulated mouse events will trigger the context menu.

Change-Id: Ic41c03fbceb4a12ff90fc601560d48a50db6488c
Reviewed-by: Moss Heim <moss.heim@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit ff77f316eb322b252155886f572e6561c5a2916f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 2ff00521ffa7e422fefddb5b56040aad7c2fc5e2)
---
 .../tst_qwebenginedownloadrequest.cpp         | 42 ++++++++++++++++++-
 1 file changed, 40 insertions(+), 2 deletions(-)

diff --git a/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp b/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
index 455fa5e73ef..30c480f951f 100644
--- a/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
+++ b/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
@@ -16,6 +16,38 @@
 #include <QWebEngineView>
 #include <httpserver.h>
 
+using namespace Qt::StringLiterals;
+
+// Based on PageWithPaintListeners in tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+// TODO: Factor PageWithPaintListeners out to tests/auto/util/util.h
+class TestPage : public QWebEnginePage
+{
+    Q_OBJECT
+public:
+    TestPage(QWebEngineProfile *profile) : QWebEnginePage(profile)
+    {
+        QObject::connect(this, &QWebEnginePage::loadFinished, [this]() {
+            const QString jsLCPObserver = QStringLiteral(
+                    "new PerformanceObserver((list) => {"
+                    "    const entries = list.getEntries();"
+                    "    const lastEntry = entries[entries.length - 1];"
+                    "    console.log('largestContentfulPaint: ' + lastEntry.element);"
+                    "}).observe({type: 'largest-contentful-paint', buffered: true});");
+            runJavaScript(jsLCPObserver);
+        });
+    }
+
+    void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel, const QString &message, int,
+                                  const QString &) override
+    {
+        if (message == "largestContentfulPaint: [object HTMLBodyElement]"_L1)
+            emit htmlBodyElementPainted();
+    }
+
+signals:
+    void htmlBodyElementPainted();
+};
+
 class tst_QWebEngineDownloadRequest : public QObject
 {
     Q_OBJECT
@@ -66,7 +98,7 @@ private Q_SLOTS:
 
     HttpServer *m_server;
     QWebEngineProfile *m_profile;
-    QWebEnginePage *m_page;
+    TestPage *m_page;
     QWebEngineView *m_view;
     QSet<QWebEngineDownloadRequest *> m_requestedDownloads;
     QSet<QWebEngineDownloadRequest *> m_finishedDownloads;
@@ -91,7 +123,7 @@ void tst_QWebEngineDownloadRequest::initTestCase()
             m_finishedDownloads.insert(item);
         });
     });
-    m_page = new QWebEnginePage(m_profile);
+    m_page = new TestPage(m_profile);
     m_view = new QWebEngineView;
     m_view->setPage(m_page);
     m_view->resize(640, 480);
@@ -452,10 +484,12 @@ void tst_QWebEngineDownloadRequest::downloadLink()
     // The only variation being whether the <a> element has a "download"
     // attribute or not.
     QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished);
+    QSignalSpy paintSpy(m_page, &TestPage::htmlBodyElementPainted);
     m_view->load(m_server->url());
     QTRY_COMPARE(loadSpy.size(), 1);
     QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true);
     QCOMPARE(indexRequestCount, 1);
+    QTRY_COMPARE(paintSpy.size(), 1);
 
     simulateUserAction(QPoint(10, 10), userAction);
 
@@ -550,9 +584,11 @@ void tst_QWebEngineDownloadRequest::downloadTwoLinks()
     });
 
     QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished);
+    QSignalSpy paintSpy(m_page, &TestPage::htmlBodyElementPainted);
     m_view->load(m_server->url());
     QTRY_COMPARE(loadSpy.size(), 1);
     QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true);
+    QTRY_COMPARE(paintSpy.size(), 1);
 
     // Trigger downloads
     simulateUserAction(QPoint(10, 10), action1);
@@ -1273,9 +1309,11 @@ void tst_QWebEngineDownloadRequest::downloadDataUrls()
     });
 
     QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished);
+    QSignalSpy paintSpy(m_page, &TestPage::htmlBodyElementPainted);
     m_view->load(m_server->url());
     QTRY_COMPARE(loadSpy.size(), 1);
     QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true);
+    QTRY_COMPARE(paintSpy.size(), 1);
 
     // Trigger download
     simulateUserAction(QPoint(10, 10), UserAction::ClickLink);

From 9755cc0963f63aacc19895870a58d7ba76c1f32a Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Wed, 12 Feb 2025 10:51:32 +0100
Subject: [PATCH 268/356] Fix tst_QWebEngineView::pageWithPaintListeners on
 macOS

macOS hides scrollbars by default, skip the scrollbar test.

Also replace QTRY_VERIFY with QTRY_COMPARE to get meaningful messages on
test failure.

Change-Id: I22b9cb55cd952ad0424271cb86ac68c7793281c2
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit 845b4ed898183606a5cd4c18fb379a2723c7cf74)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit cc21b907007b5d8c9b444871813ec6b616b76685)
---
 .../qwebengineview/tst_qwebengineview.cpp        | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index d44167d9de8..86852ae35ef 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -288,20 +288,20 @@ void tst_QWebEngineView::pageWithPaintListeners()
 
     page.setHtml(empty);
     QTest::qWait(500); // empty page should not trigger
-    QVERIFY(firstContentfulPaintSpy.size() == 0);
-    QVERIFY(largestContentfulPaintSpy.size() == 0);
+    QCOMPARE(firstContentfulPaintSpy.size(), 0);
+    QCOMPARE(largestContentfulPaintSpy.size(), 0);
 
     page.setHtml(backgroundColor);
-    QTRY_VERIFY(firstContentfulPaintSpy.size() == 1);
+    QTRY_COMPARE(firstContentfulPaintSpy.size(), 1);
 
     page.setHtml(text);
-    QTRY_VERIFY(firstContentfulPaintSpy.size() == 2);
-    QTRY_VERIFY(largestContentfulPaintSpy.size() == 1);
+    QTRY_COMPARE(firstContentfulPaintSpy.size(), 2);
+    QTRY_COMPARE(largestContentfulPaintSpy.size(), 1);
 
-#if !QT_CONFIG(webengine_embedded_build)
-    // Embedded builds have different scrollbars that are only painted on hover
+#if !QT_CONFIG(webengine_embedded_build) && !defined(Q_OS_MACOS)
+    // Embedded builds and macOS have different scrollbars that are only painted on hover
     page.setHtml(scrollBars);
-    QTRY_VERIFY(firstContentfulPaintSpy.size() == 3);
+    QTRY_COMPARE(firstContentfulPaintSpy.size(), 3);
 #endif
 }
 

From 26533ea5b67ed62082e6f973516c373f9d6d0480 Mon Sep 17 00:00:00 2001
From: Shawn Rutledge <shawn.rutledge@qt.io>
Date: Fri, 14 Feb 2025 16:00:05 +0100
Subject: [PATCH 269/356] Warn when PdfDocument.source can't be opened; add
 note to docs

When PdfDocument is instantiated in some QML file that comes from
application resources, it can be surprising when giving a plain file
path to the source property that it tries to resolve it as a resource
URL instead of a filesystem URL. But this behavior is consistent with
how we handle URLs in other components, such as Image; and Image also
generates a QML warning if the file cannot be found.

Followup to 3159ac9ff7edf0eea93fa8331ea6cb8abc201ca2

Fixes: QTBUG-131841
Change-Id: I8fb66b321406e14c88ff1eb253d46742c0c99b5a
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit 8c07478a3b1d5eac8db3df0144e824fd0263f9ef)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit f26d74681fcc46dec443155f684287e1cf7701d3)
---
 src/pdfquick/qquickpdfdocument.cpp | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/pdfquick/qquickpdfdocument.cpp b/src/pdfquick/qquickpdfdocument.cpp
index 268036d39fe..6bf1744f666 100644
--- a/src/pdfquick/qquickpdfdocument.cpp
+++ b/src/pdfquick/qquickpdfdocument.cpp
@@ -7,6 +7,7 @@
 #include <QtCore/qstandardpaths.h>
 #include <QtQml/qqmlcontext.h>
 #include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlinfo.h>
 #include <QtQuick/qquickitem.h>
 #include <QtQml/qqmlfile.h>
 
@@ -63,7 +64,13 @@ void QQuickPdfDocument::classBegin()
 
     This property holds a URL pointing to the PDF file to be loaded.
 
-    \note At this time, only local filesystem URLs are supported.
+    \note At this time, only local filesystem and
+    \l {The Qt Resource System} {resource} URLs are supported. Nevertheless,
+    the \c source property is a \l {QUrl}{URL}, not merely a filesystem path.
+    PdfDocument resolves it via QQmlContext::resolvedUrl(). You should
+    typically ensure that the URL starts with a \c {file://} scheme, unless you
+    mean to load the PDF file from resources, or it comes from some component
+    (such as \l {QtQuick.Controls::}{FileDialog}) that resolves it in advance.
 */
 void QQuickPdfDocument::setSource(QUrl source)
 {
@@ -80,6 +87,8 @@ void QQuickPdfDocument::setSource(QUrl source)
     m_resolvedSource = context ? context->resolvedUrl(source) : source;
     if (m_resolvedSource.isValid())
         m_doc->load(QQmlFile::urlToLocalFileOrQrc(m_resolvedSource));
+    else
+        qmlWarning(this) << QQuickPdfDocument::tr("Cannot open: %1").arg(m_resolvedSource.toString());
 }
 
 /*!

From f4ad6f6f3914be174f408391acdb96a86818dfb2 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Tue, 18 Feb 2025 14:41:18 +0100
Subject: [PATCH 270/356] Fix flaky tst_QWebEngineView::deferredDelete

A replacement widget for the obsolete QDesktopWidget might be created
while hovering a widget in an earlier test during destruction. The extra
widget is destructed together with QApplication so it is listed by
QApplication::allWidgets() in the subsequent tests.

For reproducing this issue run
./tst_qwebengine doNotSendMouseKeyboardEventsWhenDisabled deferredDelete
and keep the mouse cursor above the window while running
tst_QWebEngineView::doNotSendMouseKeybooardEventsWhenDisabled().

As a workaround take the extra widget into account when testing the size
of QApplication::allWidgets().

Change-Id: I84cfb75fcee944e8a22b7c12a725f131e96b3719
Reviewed-by: Moss Heim <moss.heim@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 5436b61f42e616d0d591e5b55d1e2a586dd4e5f9)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit f60a380de78504c6e9e446d75a420e8a9fcf8893)
---
 .../auto/widgets/qwebengineview/tst_qwebengineview.cpp | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 86852ae35ef..5dfdd147c2f 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -4011,16 +4011,22 @@ void tst_QWebEngineView::longKeyEventText()
 
 void tst_QWebEngineView::deferredDelete()
 {
+    // TODO: Remove this workaround when temporary qt_desktopWidget is removed from
+    //       qapplication.cpp.
+    const size_t desktopWidget = QApplication::allWidgets().size();
+    QVERIFY(desktopWidget <= 1);
+
     {
         QWebEngineView view;
         QSignalSpy loadFinishedSpy(view.page(), &QWebEnginePage::loadFinished);
         view.load(QUrl("chrome://qt"));
         view.show();
         QTRY_VERIFY(loadFinishedSpy.size());
-        QCOMPARE(QApplication::allWidgets().size(), 2); // QWebEngineView and WebEngineQuickWidget
+        // QWebEngineView and WebEngineQuickWidget
+        QCOMPARE(QApplication::allWidgets().size(), desktopWidget + 2);
     }
 
-    QCOMPARE(QApplication::allWidgets().size(), 0);
+    QCOMPARE(QApplication::allWidgets().size(), desktopWidget);
 }
 
 // QTBUG-111927

From 03cd9ecba4caf4f759836adb5a08b2dc736e0a71 Mon Sep 17 00:00:00 2001
From: Szabolcs David <davidsz@inf.u-szeged.hu>
Date: Wed, 12 Feb 2025 15:16:34 +0100
Subject: [PATCH 271/356] Fix download behavior when network error occurs

We assume that DownloadManagerDelegateQt::DetermineDownloadTarget() is
always the starting point of a download request, but there are special
cases when a download item needs more than one target determination
(for example when the server is being killed during a large download,
Content API tries to check the target again before reporting the error).
Handle this case by not decreasing m_currentId and preventing the
manager class adding itself as an observer of the same item multiple
times.

Due to the weird internal state of DownloadItem
(INTERRUPTED_TARGET_PENDING_INTERNAL) it still counts as an in progress
download and its functions (e.g. Resume()) are inactive. Don't expose
this state to our users, just re-use the already provided target path
again and they will be informed about the issue in the next
OnDownloadUpdated().

Task-number: QTBUG-132479
Task-number: QTBUG-132473
Change-Id: Id8d39881b9225d76456edec150035e4331e752c7
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit 56fbb0fa569287ab00538fbefd6abefe05c3141d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 95badf9e679cbf4cc5c90ea6569cb683894d8291)
---
 src/core/download_manager_delegate_qt.cpp | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index ec80d548a91..05d3d77c609 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -26,6 +26,20 @@ using namespace Qt::StringLiterals;
 
 namespace QtWebEngineCore {
 
+void provideDownloadTarget(download::DownloadItem *item, download::DownloadTargetCallback *callback,
+                           const base::FilePath &target)
+{
+    download::DownloadTargetInfo target_info;
+    target_info.target_disposition = download::DownloadItem::TARGET_DISPOSITION_OVERWRITE;
+    target_info.danger_type = download::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT;
+    target_info.insecure_download_status = download::DownloadItem::VALIDATED;
+    target_info.mime_type = item->GetMimeType();
+    target_info.display_name = item->GetFileNameToReportUser();
+    target_info.target_path = target;
+    target_info.intermediate_path = target.AddExtensionASCII("download");
+    std::move(*callback).Run(std::move(target_info));
+}
+
 DownloadManagerDelegateQt::DownloadManagerDelegateQt(ProfileAdapter *profileAdapter)
     : m_profileAdapter(profileAdapter)
     , m_currentId(0)
@@ -88,6 +102,14 @@ void DownloadManagerDelegateQt::removeDownload(quint32 downloadId)
 bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *item,
                                                         download::DownloadTargetCallback *callback)
 {
+    // The item came back for another round of target determination; this happens for example when
+    // network error occurs. We already gave it a target path, let it use that, then it can report
+    // the reason of its failure in OnDownloadUpdated().
+    if (m_currentId >= item->GetId() && !item->GetTargetFilePath().empty()) {
+        provideDownloadTarget(item, callback, item->GetTargetFilePath());
+        return true;
+    }
+
     m_currentId = item->GetId();
 
     // Keep the forced file path if set, also as the temporary file, so the check for existence
@@ -165,7 +187,6 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
     item->AddObserver(this);
     QList<ProfileAdapterClient*> clients = m_profileAdapter->clients();
     if (!clients.isEmpty()) {
-        Q_ASSERT(m_currentId == item->GetId());
         ProfileAdapterClient::DownloadItemInfo info = {
             item->GetId(),
             toQt(item->GetURL()),

From 00ff092949b735e0e7079da606fddb6552b00336 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 13 Feb 2025 16:52:06 +0100
Subject: [PATCH 272/356] Use QL1SV where QString conversion is not needed

Change-Id: I1e819d5f570eb52d703691b6e7bd0de29adc9318
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit 676eea8bbe4c3c943058561e4ceb02800fd6d76e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 131ddcbf9e7bf04d46f5bdc5c0c28d6179a8ed60)
---
 src/core/download_manager_delegate_qt.cpp |  2 +-
 src/core/file_picker_controller.cpp       |  2 +-
 src/core/net/resource_request_body_qt.cpp |  4 ++--
 src/core/web_engine_context.cpp           | 11 +++++------
 4 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index 05d3d77c609..e67b59d02cf 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -173,7 +173,7 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
     }
 
     if (suggestedFilename.isEmpty()) {
-        suggestedFilename += QStringLiteral("qwe_download");
+        suggestedFilename += "qwe_download"_L1;
         QMimeType mimeType = QMimeDatabase().mimeTypeForName(mimeTypeString);
         if (mimeType.isValid() && !mimeType.preferredSuffix().isEmpty())
             suggestedFilename += u'.' + mimeType.preferredSuffix();
diff --git a/src/core/file_picker_controller.cpp b/src/core/file_picker_controller.cpp
index e7b7de7b192..1c98b90c74c 100644
--- a/src/core/file_picker_controller.cpp
+++ b/src/core/file_picker_controller.cpp
@@ -257,7 +257,7 @@ QStringList FilePickerController::nameFilters(const QStringList &acceptedMimeTyp
             // A single suffix
             // Filename.type doesn't have to exist and mimeTypeForFile() supports
             // custom suffixes as valid (but unknown) MIME types.
-            const QMimeType &mimeType = mimeDatabase.mimeTypeForFile("filename" + type);
+            const QMimeType &mimeType = mimeDatabase.mimeTypeForFile("filename"_L1 + type);
             if (mimeType.isValid()) {
                 QString glob = u'*' + type;
                 acceptedGlobs.append(glob);
diff --git a/src/core/net/resource_request_body_qt.cpp b/src/core/net/resource_request_body_qt.cpp
index 429d1f8048e..bc7fffdf2be 100644
--- a/src/core/net/resource_request_body_qt.cpp
+++ b/src/core/net/resource_request_body_qt.cpp
@@ -163,8 +163,8 @@ void ResourceRequestBody::readDataElementPipe(
             *data += bytesToRead;
             bytesRead += bytesToRead;
         } else if (result != MOJO_RESULT_SHOULD_WAIT && result != MOJO_RESULT_FAILED_PRECONDITION) {
-            setErrorString(QString::fromLatin1("Error while reading from data pipe, skipping"
-                                               "remaining content of data pipe. Mojo error code: ")
+            setErrorString("Error while reading from data pipe, skipping "
+                           "remaining content of data pipe. Mojo error code: "_L1
                            + QString::number(result));
         }
     } while ((result == MOJO_RESULT_SHOULD_WAIT || result == MOJO_RESULT_OK)
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index da1aea48de8..0946238d656 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1186,14 +1186,13 @@ base::CommandLine *WebEngineContext::initCommandLine(bool &useEmbeddedSwitches,
         }
     }
 #if defined(QTWEBENGINE_EMBEDDED_SWITCHES)
-    useEmbeddedSwitches = !appArgs.contains(QStringLiteral("--disable-embedded-switches"));
+    useEmbeddedSwitches = !appArgs.contains("--disable-embedded-switches"_L1);
 #else
-    useEmbeddedSwitches = appArgs.contains(QStringLiteral("--enable-embedded-switches"));
+    useEmbeddedSwitches = appArgs.contains("--enable-embedded-switches"_L1);
 #endif
-    enableGLSoftwareRendering =
-            appArgs.removeAll(QStringLiteral("--enable-webgl-software-rendering"));
-    appArgs.removeAll(QStringLiteral("--disable-embedded-switches"));
-    appArgs.removeAll(QStringLiteral("--enable-embedded-switches"));
+    enableGLSoftwareRendering = appArgs.removeAll("--enable-webgl-software-rendering"_L1);
+    appArgs.removeAll("--disable-embedded-switches"_L1);
+    appArgs.removeAll("--enable-embedded-switches"_L1);
 
     bool isRemoteDebugPort =
             (-1

From 4c35b99d0f3d6899b3397576eea5fbfa28c1b8e4 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 13 Feb 2025 14:43:22 +0100
Subject: [PATCH 273/356] Optimize removing quality values from Accept-Language
 string

Also add auto test for QWebEngineProfile::setHttpAcceptLanguage() to
validate if argument with quality values is parsed properly.

Change-Id: Ide3acfe93bfe2d4c6afd76bd7239f471942ea467
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 9164704c9a3b89c33f0c1cade84c4a11740c1833)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit da5f1c1cb51de0988f1a96a872d911a529969c40)
---
 src/core/profile_adapter.cpp                           | 10 +++++-----
 .../qwebengineprofile/tst_qwebengineprofile.cpp        |  8 ++++++++
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index c5cc86eb15c..765841b89ff 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -594,12 +594,12 @@ QList<QWebEnginePermission> ProfileAdapter::listPermissions(const QUrl &origin,
 
 QString ProfileAdapter::httpAcceptLanguageWithoutQualities() const
 {
-    const QStringList list = m_httpAcceptLanguage.split(QLatin1Char(','));
     QString out;
-    for (const QString &str : list) {
-        if (!out.isEmpty())
-            out.append(QLatin1Char(','));
-        out.append(str.split(QLatin1Char(';')).first());
+    auto sep = ""_L1;
+    for (auto lang : m_httpAcceptLanguage.tokenize(u',')) {
+        out += sep;
+        out += *lang.tokenize(u';').begin(); // tokenize() is never empty with KeepEmptyParts!
+        sep = ","_L1;
     }
     return out;
 }
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index e7492ce7e28..97e5bd6017f 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -26,6 +26,8 @@
 #include <map>
 #include <mutex>
 
+using namespace Qt::StringLiterals;
+
 class tst_QWebEngineProfile : public QObject
 {
     Q_OBJECT
@@ -847,6 +849,12 @@ void tst_QWebEngineProfile::httpAcceptLanguage()
     // Test changing an existing page and profile
     QWebEngineProfile::defaultProfile()->setHttpAcceptLanguage(testLang);
     QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("navigator.languages")).toStringList(), QStringList(testLang));
+
+    // Test language list with quality values
+    QWebEngineProfile::defaultProfile()->setHttpAcceptLanguage(
+            u"en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7"_s);
+    QCOMPARE(evaluateJavaScriptSync(&page, u"navigator.languages"_s).toStringList(),
+             QStringList({u"en-US"_s, u"en"_s, u"zh-CN"_s, u"zh"_s}));
 }
 
 void tst_QWebEngineProfile::downloadItem()

From 20319ec5c2f430655d61aa41d25fba6752ab49bd Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 13 Feb 2025 14:52:24 +0100
Subject: [PATCH 274/356] Remove more unnecessary QString conversions

Change-Id: Ifb8e87cb5e49d71d7d8a61f99305d86a986aa032
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit 100682f8954ba1de309976cd54c86982f5130ae7)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 3dee4ca7b3cbf078f7c5bb310f425ccb67ca26f9)
---
 src/core/browser_accessibility_qt.cpp | 4 ++--
 src/core/web_event_factory.cpp        | 8 +++++---
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp
index 60e5390e3d0..f2959350d0a 100644
--- a/src/core/browser_accessibility_qt.cpp
+++ b/src/core/browser_accessibility_qt.cpp
@@ -159,8 +159,8 @@ BrowserAccessibilityInterface::BrowserAccessibilityInterface(BrowserAccessibilit
 {
     if (parent() && parent()->object()) {
         m_object = new QObject(parent()->object());
-        QString name = toQt(q->GetAuthorUniqueId());
-        if (!name.isEmpty())
+        const std::u16string name = q->GetAuthorUniqueId();
+        if (!name.empty())
             m_object->setObjectName(name);
     }
 
diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp
index d47d6a9ced1..6457d456ee2 100644
--- a/src/core/web_event_factory.cpp
+++ b/src/core/web_event_factory.cpp
@@ -38,6 +38,7 @@
 #include "native_web_keyboard_event_qt.h"
 #include "render_widget_host_view_qt_delegate.h"
 
+#include <QtCore/private/qstringiterator_p.h>
 #include <QtGui/private/qtgui-config_p.h>
 
 #include <QCoreApplication>
@@ -1682,9 +1683,10 @@ content::NativeWebKeyboardEvent WebEventFactory::toWebKeyboardEvent(QKeyEvent *e
 
     if (qtKey >= Qt::Key_Escape)
         webKitEvent.dom_key = domKeyForQtKey(qtKey);
-    else if (!qtText.isEmpty())
-        webKitEvent.dom_key = ui::DomKey::FromCharacter(qtText.toUcs4().first());
-    else {
+    else if (!qtText.isEmpty()) {
+        QStringIterator it(qtText);
+        webKitEvent.dom_key = ui::DomKey::FromCharacter(it.next());
+    } else {
         QChar ch(qtKey);
         if (!(qtModifiers & Qt::ShiftModifier)) // No way to check for caps lock
             ch = ch.toLower();

From 4d13c5071ebdad3aab57dba52973d2d42ab515ae Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 6 Feb 2025 17:20:41 +0100
Subject: [PATCH 275/356] Use QSL where the string is converted to QString

Change-Id: I14bf140ba6dbfdedf1b010070ca8d92078fee8ea
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit c93e694728cf0661009851d4c3e547dd609924eb)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 5b543d32952802553257df9c401e2d13bc583169)
---
 src/core/content_client_qt.cpp  | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index 0b16c01e9b2..1dc60cdf195 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -198,7 +198,7 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path,
         pluginPaths << ppapiPluginsPath() + u'/' + QLatin1StringView(kWidevineCdmFileName);
 #endif
 #if defined(Q_OS_OSX)
-    QDir potentialWidevineDir("/Applications/Google Chrome.app/Contents/Frameworks");
+    QDir potentialWidevineDir(u"/Applications/Google Chrome.app/Contents/Frameworks"_s);
     const auto archDir = QSysInfo::currentCpuArchitecture() == "x86_64"_L1
                        ? "mac_x64/"_L1
                        : "mac_arm64/"_L1;
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 0946238d656..f123a9f1ee0 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1171,7 +1171,7 @@ base::CommandLine *WebEngineContext::initCommandLine(bool &useEmbeddedSwitches,
     }
 
     base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess();
-    int index = appArgs.indexOf(QRegularExpression(QLatin1StringView("--webEngineArgs"),
+    int index = appArgs.indexOf(QRegularExpression(u"--webEngineArgs"_s,
                                                    QRegularExpression::CaseInsensitiveOption));
     if (qEnvironmentVariableIsSet(kChromiumFlagsEnv)) {
         appArgs = appArgs.mid(0, 1); // Take application name and drop the rest

From d7b9205c7246d1a7d774a839cdedcb4beb7bf896 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 13 Feb 2025 16:57:16 +0100
Subject: [PATCH 276/356] Concatenate strings with QStringBuilder instead of
 QString::arg()

Change-Id: I07423cdaf68e7a7333e270f25983584655467e85
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit df367e1ffa8c166016dff2f1ec5b547033a9b5ba)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit b1ba0a4cb74ba2bf42eebd0467908649af7d3b53)
---
 src/core/web_contents_adapter.cpp     | 4 ++--
 src/core/web_contents_delegate_qt.cpp | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 238c81504f1..c570ba033f5 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -666,8 +666,8 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
                                                            strlen(content::kViewSourceScheme) + 1));
         if (pageUrl.scheme().isEmpty()) {
             QUrl extendedUrl = QUrl::fromUserInput(pageUrl.toString());
-            extendedUrl = QUrl(QString("%1:%2").arg(QLatin1StringView(content::kViewSourceScheme),
-                                                    extendedUrl.toString()));
+            extendedUrl = QUrl(QLatin1StringView(content::kViewSourceScheme) + u':'
+                               + extendedUrl.toString());
             gurl = toGurl(extendedUrl);
         }
     }
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index de045da4ee1..5ce99761351 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -199,8 +199,8 @@ QUrl WebContentsDelegateQt::url(content::WebContents *source) const
         if (source->GetVisibleURL().SchemeIs(content::kViewSourceScheme) &&
             (url.has_password() || url.has_username() || url.has_ref())) {
             GURL strippedUrl = net::SimplifyUrlForRequest(url);
-            newUrl = QUrl(QString("%1:%2").arg(QLatin1StringView(content::kViewSourceScheme),
-                                               QString::fromStdString(strippedUrl.spec())));
+            newUrl = QUrl(QLatin1StringView(content::kViewSourceScheme) + u':'
+                          + QString::fromStdString(strippedUrl.spec()));
         }
         // If there is a visible entry there are special cases where we dont wan't to use the actual URL
         if (newUrl.isEmpty())

From af3d521a539b57f7a934a3f19e28d03288566333 Mon Sep 17 00:00:00 2001
From: Allan Sandfeld Jensen <allan.jensen@qt.io>
Date: Mon, 20 Jan 2025 12:18:51 +0100
Subject: [PATCH 277/356] Fix failing test

Wait for the last interceptor to intercept

Change-Id: I830f2c71e75ab99bb037562445081eb23412e61f
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Moss Heim <moss.heim@qt.io>
(cherry picked from commit 5d7a87193f976f9b118b45724603436b6c6ef84e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 8fcecc184e5450645a81ba191906e08f3ad3b300)
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
---
 .../tst_qwebengineurlrequestinterceptor.cpp   | 25 ++++++++++---------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
index 7f8e040158f..bf82194f50f 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
@@ -159,7 +159,7 @@ class TestRequestInterceptor : public QWebEngineUrlRequestInterceptor
     {
         QList<RequestInfo> infos;
 
-        foreach (auto requestInfo, requestInfos) {
+        for (const auto &requestInfo : requestInfos) {
             if (shouldSkipRequest(requestInfo))
                 continue;
 
@@ -172,7 +172,7 @@ class TestRequestInterceptor : public QWebEngineUrlRequestInterceptor
 
     bool hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceType type)
     {
-        foreach (auto requestInfo, requestInfos) {
+        for (const auto &requestInfo : requestInfos) {
             if (shouldSkipRequest(requestInfo))
                 continue;
 
@@ -802,17 +802,17 @@ void tst_QWebEngineUrlRequestInterceptor::jsServiceWorker()
 void tst_QWebEngineUrlRequestInterceptor::replaceInterceptor_data()
 {
     QTest::addColumn<bool>("firstInterceptIsInPage");
-    QTest::addColumn<bool>("keepInterceptionPoint");
+    QTest::addColumn<bool>("secondInterceptIsInPage");
     QTest::newRow("page")         << true << true;
     QTest::newRow("page-profile") << true << false;
-    QTest::newRow("profile")      << false << true;
-    QTest::newRow("profile-page") << false << false;
+    QTest::newRow("profile")      << false << false;
+    QTest::newRow("profile-page") << false << true;
 }
 
 void tst_QWebEngineUrlRequestInterceptor::replaceInterceptor()
 {
     QFETCH(bool, firstInterceptIsInPage);
-    QFETCH(bool, keepInterceptionPoint);
+    QFETCH(bool, secondInterceptIsInPage);
 
     HttpServer server;
     server.setResourceDirs({ ":/resources" });
@@ -837,17 +837,14 @@ void tst_QWebEngineUrlRequestInterceptor::replaceInterceptor()
         requestsOnReplace.push_back(interceptors[currentInterceptorIndex].requestInfos.size());
 
         bool isFirstReinstall = currentInterceptorIndex == 0;
-        bool interceptInPage = keepInterceptionPoint ? firstInterceptIsInPage : (isFirstReinstall ^ firstInterceptIsInPage);
+        bool interceptInPage = isFirstReinstall ? firstInterceptIsInPage : secondInterceptIsInPage;
         setInterceptor(&interceptors[++currentInterceptorIndex], interceptInPage);
-        if (!keepInterceptionPoint)
-            setInterceptor(nullptr, !interceptInPage);
+        setInterceptor(nullptr, !interceptInPage);
 
         if (isFirstReinstall) {
             page.triggerAction(QWebEnginePage::Reload);
         } else {
-            page.runJavaScript("fetch('http://nonexistent.invalid').catch(() => {})", [&, interceptInPage] (const QVariant &) {
-                requestsOnReplace.push_back(interceptors.back().requestInfos.size());
-                setInterceptor(nullptr, interceptInPage);
+            page.runJavaScript("fetch('http://nonexistent.invalid').catch(() => {})", [&fetchFinished] (const QVariant &) {
                 fetchFinished = true;
             });
         }
@@ -856,6 +853,10 @@ void tst_QWebEngineUrlRequestInterceptor::replaceInterceptor()
     page.setUrl(server.url("/favicon.html"));
     QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 2, 20000);
     QTRY_VERIFY(fetchFinished);
+    QTRY_VERIFY(!interceptors.back().requestInfos.isEmpty());
+    setInterceptor(nullptr, true);
+    setInterceptor(nullptr, false);
+    requestsOnReplace.push_back(interceptors.back().requestInfos.size());
 
     QString s; QDebug d(&s);
     for (auto i = 0u; i < interceptors.size(); ++i) {

From 56321460212a5c2f0659369376d4029e3a281511 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Fri, 14 Feb 2025 14:55:10 +0100
Subject: [PATCH 278/356] Port away from foreach

All containers are non-const local variables, and the loop bodies
clearly do not modify the container, so can use ranged for loops
with std::as_const() to avoid the detach (attempt).

Fixes: QTBUG-115805
Change-Id: Ie3eec615112a32c44ef81e4c2e5879997e5dc619
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit 0ff112a78af56ba03042872b4bb3066754f367f9)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit eb3cdb90d3f802680df60a18e558f8db8b2b8c21)
---
 .../tst_qwebengineurlrequestinterceptor.cpp   | 32 +++++++++----------
 .../tst_qquickwebengineview.cpp               |  6 ++--
 .../qwebengineview/tst_qwebengineview.cpp     |  6 ++--
 3 files changed, 19 insertions(+), 25 deletions(-)

diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
index bf82194f50f..e366bab969e 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
@@ -1,8 +1,6 @@
 // Copyright (C) 2017 The Qt Company Ltd.
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
-#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
-
 #include <util.h>
 #include <QtTest/QtTest>
 #include <QtWebEngineCore/qwebengineurlrequestinfo.h>
@@ -572,43 +570,43 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrlHttp()
     // Stylesheet
     QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeStylesheet));
     infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeStylesheet);
-    foreach (auto info, infos)
+    for (const RequestInfo &info : std::as_const(infos))
         QCOMPARE(info.firstPartyUrl, firstPartyUrl);
 
     // Script
     QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeScript));
     infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeScript);
-    foreach (auto info, infos)
+    for (const RequestInfo &info : std::as_const(infos))
         QCOMPARE(info.firstPartyUrl, firstPartyUrl);
 
     // Image
     QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeImage));
     infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeImage);
-    foreach (auto info, infos)
+    for (const RequestInfo &info : std::as_const(infos))
         QCOMPARE(info.firstPartyUrl, firstPartyUrl);
 
     // FontResource
     QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeFontResource));
     infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeFontResource);
-    foreach (auto info, infos)
+    for (const RequestInfo &info : std::as_const(infos))
         QCOMPARE(info.firstPartyUrl, firstPartyUrl);
 
     // Media
     QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeMedia));
     infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeMedia);
-    foreach (auto info, infos)
+    for (const RequestInfo &info : std::as_const(infos))
         QCOMPARE(info.firstPartyUrl, firstPartyUrl);
 
     // Favicon
     QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeFavicon));
     infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeFavicon);
-    foreach (auto info, infos)
+    for (const RequestInfo &info : std::as_const(infos))
         QCOMPARE(info.firstPartyUrl, firstPartyUrl);
 
     // XMLHttpRequest
     QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeXhr));
     infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeXhr);
-    foreach (auto info, infos)
+    for (const RequestInfo &info : std::as_const(infos))
         QCOMPARE(info.firstPartyUrl, firstPartyUrl);
 }
 
@@ -724,43 +722,43 @@ void tst_QWebEngineUrlRequestInterceptor::initiator()
     // Stylesheet
     QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeStylesheet));
     infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeStylesheet);
-    foreach (auto info, infos)
+    for (const RequestInfo &info : std::as_const(infos))
         QVERIFY(interceptor.requestInitiatorUrls[info.requestUrl].contains(info.initiator));
 
     // Script
     QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeScript));
     infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeScript);
-    foreach (auto info, infos)
+    for (const RequestInfo &info : std::as_const(infos))
         QVERIFY(interceptor.requestInitiatorUrls[info.requestUrl].contains(info.initiator));
 
     // Image
     QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeImage));
     infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeImage);
-    foreach (auto info, infos)
+    for (const RequestInfo &info : std::as_const(infos))
         QVERIFY(interceptor.requestInitiatorUrls[info.requestUrl].contains(info.initiator));
 
     // FontResource
     QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeFontResource));
     infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeFontResource);
-    foreach (auto info, infos)
+    for (const RequestInfo &info : std::as_const(infos))
         QVERIFY(interceptor.requestInitiatorUrls[info.requestUrl].contains(info.initiator));
 
     // Media
     QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeMedia));
     infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeMedia);
-    foreach (auto info, infos)
+    for (const RequestInfo &info : std::as_const(infos))
         QVERIFY(interceptor.requestInitiatorUrls[info.requestUrl].contains(info.initiator));
 
     // Favicon
     QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeFavicon));
     infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeFavicon);
-    foreach (auto info, infos)
+    for (const RequestInfo &info : std::as_const(infos))
         QVERIFY(interceptor.requestInitiatorUrls[info.requestUrl].contains(info.initiator));
 
     // XMLHttpRequest
     QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeXhr));
     infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeXhr);
-    foreach (auto info, infos)
+    for (const RequestInfo &info : std::as_const(infos))
         QVERIFY(interceptor.requestInitiatorUrls[info.requestUrl].contains(info.initiator));
 }
 
@@ -793,7 +791,7 @@ void tst_QWebEngineUrlRequestInterceptor::jsServiceWorker()
     // Service Worker
     QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeServiceWorker));
     infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeServiceWorker);
-    foreach (auto info, infos)
+    for (const RequestInfo &info : std::as_const(infos))
         QCOMPARE(info.firstPartyUrl, firstPartyUrl);
 
     QVERIFY(server.stop());
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index 1177d8adf53..1fdccb7d4b3 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -1,8 +1,6 @@
 // Copyright (C) 2016 The Qt Company Ltd.
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
-#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
-
 #include "testwindow.h"
 #include "quickutil.h"
 #include "util.h"
@@ -617,7 +615,7 @@ void tst_QQuickWebEngineView::inputContextQueryInput()
     QTest::mouseClick(view->window(), Qt::LeftButton, {}, textInputCenter);
     QTRY_COMPARE(testContext.infos.size(), 2);
     QCOMPARE(evaluateJavaScriptSync(view, "document.activeElement.id").toString(), QStringLiteral("input1"));
-    foreach (const InputMethodInfo &info, testContext.infos) {
+    for (const InputMethodInfo &info : std::as_const(testContext.infos)) {
         QCOMPARE(info.cursorPosition, 0);
         QCOMPARE(info.anchorPosition, 0);
         QCOMPARE(info.surroundingText, QStringLiteral(""));
@@ -712,7 +710,7 @@ void tst_QQuickWebEngineView::inputContextQueryInput()
         QGuiApplication::sendEvent(qApp->focusObject(), &event);
     }
     QTRY_COMPARE(testContext.infos.size(), 2);
-    foreach (const InputMethodInfo &info, testContext.infos) {
+    for (const InputMethodInfo &info : std::as_const(testContext.infos)) {
         QCOMPARE(info.cursorPosition, 0);
         QCOMPARE(info.anchorPosition, 0);
         QCOMPARE(info.surroundingText, QStringLiteral("QtWebEngine!"));
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 5dfdd147c2f..0d9b078c064 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -19,8 +19,6 @@
     Boston, MA 02110-1301, USA.
 */
 
-#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
-
 #include <QtWebEngineCore/private/qtwebenginecore-config_p.h>
 #include <qtest.h>
 #include <util.h>
@@ -2078,7 +2076,7 @@ void tst_QWebEngineView::inputContextQueryInput()
     QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
     QTRY_COMPARE(testContext.infos.size(), 2);
     QCOMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
-    foreach (const InputMethodInfo &info, testContext.infos) {
+    for (const InputMethodInfo &info : std::as_const(testContext.infos)) {
         QCOMPARE(info.cursorPosition, 0);
         QCOMPARE(info.anchorPosition, 0);
         QCOMPARE(info.surroundingText, QStringLiteral(""));
@@ -2177,7 +2175,7 @@ void tst_QWebEngineView::inputContextQueryInput()
         QApplication::sendEvent(view.focusProxy(), &event);
     }
     QTRY_COMPARE(testContext.infos.size(), 2);
-    foreach (const InputMethodInfo &info, testContext.infos) {
+    for (const InputMethodInfo &info : std::as_const(testContext.infos)) {
         QCOMPARE(info.cursorPosition, 0);
         QCOMPARE(info.anchorPosition, 0);
         QCOMPARE(info.surroundingText, QStringLiteral("QtWebEngine!"));

From 9d0dceb1e6645c1a511face787c7df4a9a049e9d Mon Sep 17 00:00:00 2001
From: Teemu Jokitulppo <teemu.jokitulppo@qt.io>
Date: Mon, 24 Feb 2025 12:05:06 +0200
Subject: [PATCH 279/356] Fix spdx files not included in MinGW/LLVM content

Missing entries in qt-installer-package-config.json
file caused some spdx files be excluded from Qt PDF
installations. Fixed this by adding those entries.

Task-number: QTBUG-133970
Change-Id: I9a8d857a05c2b93fbe6ff2fd70f2cd8c3644e53b
Reviewed-by: Antti Kokko <antti.kokko@qt.io>
(cherry picked from commit ca222db0ac6780e1867adc598a919bdfe2777722)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 2668a8e64de9e857714c4f1e5223391087cc873d)
---
 coin/qt-installer-package-config.json | 1 +
 1 file changed, 1 insertion(+)

diff --git a/coin/qt-installer-package-config.json b/coin/qt-installer-package-config.json
index aec45688b39..433ddfd824a 100644
--- a/coin/qt-installer-package-config.json
+++ b/coin/qt-installer-package-config.json
@@ -3,6 +3,7 @@
     "module-split": {
         "qtpdf": [
             "**/bin/*Pdf*",
+            "**/sbom/qtpdf*",
             "**/include/*QtPdf*/**/*",
             "**/lib/cmake/Qt*Gui/*Pdf*",
             "**/lib/cmake/Qt*Pdf*/*",

From fe20ccb46b0cc8a6f13b2c847fcc93d90851b211 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 6 Feb 2025 15:22:21 +0100
Subject: [PATCH 280/356] Make QString and QByteArray strings constants if not
 modified

Merge conflict resolution for 6.8:
- No QWebEngineDownloadeRequestPrivate::answer() in 6.8

Change-Id: If6c704cf5dada72d2c5c069fcbbcfea16af845ac
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit 2ccca2f0663e866b94fd1d7f0195ebff280583fb)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit ae8651a621cb9f2b8a6678aabd57648a699acc59)
---
 src/core/api/qwebenginehttprequest.cpp        |  4 ++--
 src/core/api/qwebenginepage.cpp               | 19 ++++++++++---------
 src/core/api/qwebenginescript.cpp             |  2 +-
 src/core/client_cert_select_controller.cpp    |  2 +-
 src/core/clipboard_qt.cpp                     |  4 ++--
 src/core/content_client_qt.cpp                |  6 +++---
 src/core/native_web_keyboard_event_qt_mac.mm  |  2 +-
 src/core/net/client_cert_store_data.cpp       |  4 ++--
 src/core/net/qrc_url_scheme_handler.cpp       |  6 +++---
 src/core/profile_adapter.cpp                  |  6 +++---
 ...er_widget_host_view_qt_delegate_client.cpp |  4 ++--
 .../web_channel_ipc_transport_host.cpp        |  2 +-
 src/core/web_contents_adapter.cpp             |  2 +-
 src/core/web_engine_context.cpp               |  2 +-
 src/core/web_engine_library_info.cpp          |  3 ++-
 src/core/web_event_factory.cpp                |  4 ++--
 16 files changed, 37 insertions(+), 35 deletions(-)

diff --git a/src/core/api/qwebenginehttprequest.cpp b/src/core/api/qwebenginehttprequest.cpp
index 050213d1e2d..0039533d687 100644
--- a/src/core/api/qwebenginehttprequest.cpp
+++ b/src/core/api/qwebenginehttprequest.cpp
@@ -148,8 +148,8 @@ QWebEngineHttpRequest QWebEngineHttpRequest::postRequest(const QUrl &url,
 
     QByteArray buffer;
     for (QMap<QString, QString>::const_iterator it = postData.begin(); it != postData.end(); it++) {
-        QByteArray key = QUrl::toPercentEncoding(it.key());
-        QByteArray value = QUrl::toPercentEncoding(it.value());
+        const QByteArray key = QUrl::toPercentEncoding(it.key());
+        const QByteArray value = QUrl::toPercentEncoding(it.value());
 
         if (buffer.size() > 0)
             buffer += '&';
diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp
index 826d8ce492c..640e2c5e938 100644
--- a/src/core/api/qwebenginepage.cpp
+++ b/src/core/api/qwebenginepage.cpp
@@ -1337,15 +1337,16 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
         break;
     case CopyLinkToClipboard:
         if (d->view && d->view->lastContextMenuRequest() && !d->view->lastContextMenuRequest()->linkUrl().isEmpty()) {
-            QString urlString = d->view->lastContextMenuRequest()->linkUrl().toString(
-                    QUrl::FullyEncoded);
-            QString linkText = d->view->lastContextMenuRequest()->linkText().toHtmlEscaped();
+            const QString urlString =
+                    d->view->lastContextMenuRequest()->linkUrl().toString(QUrl::FullyEncoded);
+            const QString linkText = d->view->lastContextMenuRequest()->linkText().toHtmlEscaped();
             QString title = d->view->lastContextMenuRequest()->titleText();
             if (!title.isEmpty())
                 title = " title=\""_L1 + title.toHtmlEscaped() + u'"';
             QMimeData *data = new QMimeData();
             data->setText(urlString);
-            QString html = "<a href=\""_L1 + urlString + u'"' + title + u'>' + linkText + "</a>"_L1;
+            const QString html =
+                    "<a href=\""_L1 + urlString + u'"' + title + u'>' + linkText + "</a>"_L1;
             data->setHtml(html);
             data->setUrls(QList<QUrl>() << d->view->lastContextMenuRequest()->linkUrl());
             QGuiApplication::clipboard()->setMimeData(data);
@@ -1372,7 +1373,7 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
         if (d->view && d->view->lastContextMenuRequest() && d->view->lastContextMenuRequest()->mediaUrl().isValid()
             && d->view->lastContextMenuRequest()->mediaType()
                     == QWebEngineContextMenuRequest::MediaTypeImage) {
-            QString urlString =
+            const QString urlString =
                     d->view->lastContextMenuRequest()->mediaUrl().toString(QUrl::FullyEncoded);
             QString alt = d->view->lastContextMenuRequest()->altText();
             if (!alt.isEmpty())
@@ -1382,7 +1383,7 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
                 title = " title=\""_L1 + title.toHtmlEscaped() + u'"';
             QMimeData *data = new QMimeData();
             data->setText(urlString);
-            QString html = "<img src=\""_L1 + urlString + u'"' + title + alt + "></img>"_L1;
+            const QString html = "<img src=\""_L1 + urlString + u'"' + title + alt + "></img>"_L1;
             data->setHtml(html);
             data->setUrls(QList<QUrl>() << d->view->lastContextMenuRequest()->mediaUrl());
             QGuiApplication::clipboard()->setMimeData(data);
@@ -1402,7 +1403,7 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
                         == QWebEngineContextMenuRequest::MediaTypeAudio
                 || d->view->lastContextMenuRequest()->mediaType()
                         == QWebEngineContextMenuRequest::MediaTypeVideo)) {
-            QString urlString =
+            const QString urlString =
                     d->view->lastContextMenuRequest()->mediaUrl().toString(QUrl::FullyEncoded);
             QString title = d->view->lastContextMenuRequest()->titleText();
             if (!title.isEmpty())
@@ -1412,8 +1413,8 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
             const bool isAudio = d->view->lastContextMenuRequest()->mediaType()
                     == QWebEngineContextMenuRequest::MediaTypeAudio;
             const auto avTagName = isAudio ? "audio"_L1 : "video"_L1;
-            QString html = u'<' + avTagName + "src=\""_L1 + urlString + u'"' + title + "></"_L1
-                    + avTagName + u'>';
+            const QString html = u'<' + avTagName + "src=\""_L1 + urlString + u'"' + title
+                    + "></"_L1 + avTagName + u'>';
             data->setHtml(html);
             data->setUrls(QList<QUrl>() << d->view->lastContextMenuRequest()->mediaUrl());
             QGuiApplication::clipboard()->setMimeData(data);
diff --git a/src/core/api/qwebenginescript.cpp b/src/core/api/qwebenginescript.cpp
index 8d1ff46bf49..772dd7dfb2c 100644
--- a/src/core/api/qwebenginescript.cpp
+++ b/src/core/api/qwebenginescript.cpp
@@ -172,7 +172,7 @@ void QWebEngineScript::setSourceUrl(const QUrl &url)
         return;
     }
 
-    QString source = QString::fromUtf8(file.readAll());
+    const QString source = QString::fromUtf8(file.readAll());
     setSourceCode(source);
 }
 
diff --git a/src/core/client_cert_select_controller.cpp b/src/core/client_cert_select_controller.cpp
index d6af984c187..e898da618ae 100644
--- a/src/core/client_cert_select_controller.cpp
+++ b/src/core/client_cert_select_controller.cpp
@@ -75,7 +75,7 @@ void ClientCertSelectController::select(const QSslCertificate &certificate)
         LOG(WARNING) << "ClientCertSelectController::select() certificate already selected";
         return;
     }
-    QByteArray derCertificate = certificate.toDer();
+    const QByteArray derCertificate = certificate.toDer();
     scoped_refptr<net::X509Certificate> selectedCert =
             net::X509Certificate::CreateFromBytes(base::make_span((const unsigned char *)derCertificate.constData(),
                                                                   (long unsigned)derCertificate.length()));
diff --git a/src/core/clipboard_qt.cpp b/src/core/clipboard_qt.cpp
index 39955719005..25ea8897136 100644
--- a/src/core/clipboard_qt.cpp
+++ b/src/core/clipboard_qt.cpp
@@ -185,8 +185,8 @@ void ClipboardQt::WriteBookmark(base::StringPiece title_in, base::StringPiece ur
 {
     // FIXME: Untested, seems to be used only for drag-n-drop.
     // Write as a mozilla url (UTF16: URL, newline, title).
-    QString url = toQString(url_in);
-    QString title = toQString(title_in);
+    const QString url = toQString(url_in);
+    const QString title = toQString(title_in);
 
     QByteArray data;
     data.append(reinterpret_cast<const char *>(url.utf16()), url.size() * 2);
diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index 1dc60cdf195..88eebed23cf 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -215,7 +215,7 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path,
     if (oldPotentialWidevineDir.exists()) {
         QFileInfoList widevineVersionDirs = oldPotentialWidevineDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed);
         for (int i = 0; i < widevineVersionDirs.size(); ++i) {
-            QString versionDirPath(widevineVersionDirs.at(i).absoluteFilePath());
+            const QString versionDirPath = widevineVersionDirs.at(i).absoluteFilePath();
             QString potentialWidevinePluginPath = versionDirPath + "/_platform_specific/"_L1 + archDir
                     + QLatin1StringView(kWidevineCdmFileName);
             pluginPaths << potentialWidevinePluginPath;
@@ -230,7 +230,7 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path,
         if (d.exists()) {
             QFileInfoList widevineVersionDirs = d.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed);
             for (int i = 0; i < widevineVersionDirs.size(); ++i) {
-                QString versionDirPath(widevineVersionDirs.at(i).absoluteFilePath());
+                const QString versionDirPath = widevineVersionDirs.at(i).absoluteFilePath();
 #ifdef WIN64
                 QString potentialWidevinePluginPath = versionDirPath +
                                                         "/WidevineCdm/_platform_specific/win_x64/"_L1 +
@@ -248,7 +248,7 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path,
     if (potentialWidevineDir.exists()) {
         QFileInfoList widevineVersionDirs = potentialWidevineDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed);
         for (int i = 0; i < widevineVersionDirs.size(); ++i) {
-            QString versionDirPath(widevineVersionDirs.at(i).absoluteFilePath());
+            const QString versionDirPath = widevineVersionDirs.at(i).absoluteFilePath();
 #ifdef WIN64
             QString potentialWidevinePluginPath = versionDirPath + "/_platform_specific/win_x64/"_L1 + QLatin1StringView(kWidevineCdmFileName);
 #else
diff --git a/src/core/native_web_keyboard_event_qt_mac.mm b/src/core/native_web_keyboard_event_qt_mac.mm
index 0f5b12db43d..1499631eb23 100644
--- a/src/core/native_web_keyboard_event_qt_mac.mm
+++ b/src/core/native_web_keyboard_event_qt_mac.mm
@@ -103,7 +103,7 @@
         key = QAppleKeyMapper::fromCocoaKey(character);
     }
 
-    QString text = QString::fromNSString(characters);
+    const QString text = QString::fromNSString(characters);
     bool autorep = nsevent.ARepeat;
 
     return new QKeyEvent(type, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers,
diff --git a/src/core/net/client_cert_store_data.cpp b/src/core/net/client_cert_store_data.cpp
index 0de6885df85..5f9c8243af9 100644
--- a/src/core/net/client_cert_store_data.cpp
+++ b/src/core/net/client_cert_store_data.cpp
@@ -92,8 +92,8 @@ namespace QtWebEngineCore {
 
 void ClientCertificateStoreData::add(const QSslCertificate &certificate, const QSslKey &privateKey)
 {
-    QByteArray sslKeyInBytes = privateKey.toPem();
-    QByteArray certInBytes = certificate.toDer();
+    const QByteArray sslKeyInBytes = privateKey.toPem();
+    const QByteArray certInBytes = certificate.toDer();
 
     Entry *data = new Entry;
     data->keyPtr = wrapOpenSSLPrivateKey(sslKeyInBytes);
diff --git a/src/core/net/qrc_url_scheme_handler.cpp b/src/core/net/qrc_url_scheme_handler.cpp
index f1925da14dd..876c7d2031f 100644
--- a/src/core/net/qrc_url_scheme_handler.cpp
+++ b/src/core/net/qrc_url_scheme_handler.cpp
@@ -18,14 +18,14 @@ namespace QtWebEngineCore {
 
 void QrcUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job)
 {
-    QByteArray requestMethod = job->requestMethod();
+    const QByteArray requestMethod = job->requestMethod();
     if (requestMethod != "GET") {
         job->fail(QWebEngineUrlRequestJob::RequestDenied);
         return;
     }
 
-    QUrl requestUrl = job->requestUrl();
-    QString requestPath = requestUrl.path();
+    const QUrl requestUrl = job->requestUrl();
+    const QString requestPath = requestUrl.path();
     auto file = std::make_unique<QFile>(u':' + requestPath, job);
     if (!file->exists() || file->size() == 0) {
         qWarning("QResource '%s' not found or is empty", qUtf8Printable(requestPath));
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index 765841b89ff..89ecdfcacb3 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -308,7 +308,7 @@ QString ProfileAdapter::httpCachePath() const
 {
     if (m_offTheRecord)
         return QString();
-    QString basePath = cachePath();
+    const QString basePath = cachePath();
     if (!basePath.isEmpty())
         return basePath % "/Cache"_L1;
     return QString();
@@ -523,7 +523,7 @@ void ProfileAdapter::removeUrlSchemeHandler(QWebEngineUrlSchemeHandler *handler)
 
 void ProfileAdapter::removeUrlScheme(const QByteArray &scheme)
 {
-    QByteArray canonicalScheme = scheme.toLower();
+    const QByteArray canonicalScheme = scheme.toLower();
     if (schemeType(canonicalScheme) == SchemeType::Protected) {
         qWarning("Cannot remove the URL scheme handler for an internal scheme: %s", scheme.constData());
         return;
@@ -535,7 +535,7 @@ void ProfileAdapter::removeUrlScheme(const QByteArray &scheme)
 void ProfileAdapter::installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler)
 {
     Q_ASSERT(handler);
-    QByteArray canonicalScheme = scheme.toLower();
+    const QByteArray canonicalScheme = scheme.toLower();
     SchemeType type = schemeType(canonicalScheme);
 
     if (type == SchemeType::Protected) {
diff --git a/src/core/render_widget_host_view_qt_delegate_client.cpp b/src/core/render_widget_host_view_qt_delegate_client.cpp
index a50eb9a4451..934df0ce489 100644
--- a/src/core/render_widget_host_view_qt_delegate_client.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_client.cpp
@@ -738,8 +738,8 @@ void RenderWidgetHostViewQtDelegateClient::handleInputMethodEvent(QInputMethodEv
     if (!m_rwhv->host())
         return;
 
-    QString commitString = event->commitString();
-    QString preeditString = event->preeditString();
+    const QString commitString = event->commitString();
+    const QString preeditString = event->preeditString();
 
     int cursorPositionInPreeditString = -1;
     gfx::Range selectionRange = gfx::Range::InvalidRange();
diff --git a/src/core/renderer_host/web_channel_ipc_transport_host.cpp b/src/core/renderer_host/web_channel_ipc_transport_host.cpp
index 613ca9dc044..41ef98c8bb9 100644
--- a/src/core/renderer_host/web_channel_ipc_transport_host.cpp
+++ b/src/core/renderer_host/web_channel_ipc_transport_host.cpp
@@ -48,7 +48,7 @@ uint WebChannelIPCTransportHost::worldId() const
 void WebChannelIPCTransportHost::sendMessage(const QJsonObject &message)
 {
     QJsonDocument doc(message);
-    QByteArray json = doc.toJson(QJsonDocument::Compact);
+    const QByteArray json = doc.toJson(QJsonDocument::Compact);
     content::RenderFrameHost *frame = web_contents()->GetPrimaryMainFrame();
     qCDebug(log).nospace() << "sending webchannel message to " << frame << ": " << doc;
     GetWebChannelIPCTransportRemote(frame)->DispatchWebChannelMessage(
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index c570ba033f5..60c3febc0e1 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -735,7 +735,7 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT
 
     WebEngineSettings::get(m_adapterClient->webEngineSettings())->doApply();
 
-    QByteArray encodedData = data.toPercentEncoding();
+    const QByteArray encodedData = data.toPercentEncoding();
     std::string urlString;
     if (!mimeType.isEmpty())
         urlString = std::string("data:") + mimeType.toStdString() + std::string(",");
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index f123a9f1ee0..cdb967c4857 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -566,7 +566,7 @@ static void setupProxyPac(base::CommandLine *commandLine)
             else
                 file.setFileName(pac_url.path().prepend(QLatin1Char(':')));
             if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text)) {
-                QByteArray ba = file.readAll();
+                const QByteArray ba = file.readAll();
                 commandLine->RemoveSwitch(switches::kProxyPacUrl);
                 commandLine->AppendSwitchASCII(switches::kProxyPacUrl,
                         ba.toBase64().prepend("data:application/x-javascript-config;base64,").toStdString());
diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp
index b3a0050ba63..960b768d701 100644
--- a/src/core/web_engine_library_info.cpp
+++ b/src/core/web_engine_library_info.cpp
@@ -42,7 +42,8 @@ Q_LOGGING_CATEGORY(webEngineLibraryInfoLog, "qt.webengine.libraryinfo")
 namespace {
 
 QString fallbackDir() {
-    static QString directory = QDir::homePath() % "/."_L1 % QCoreApplication::applicationName();
+    static const QString directory =
+            QDir::homePath() % "/."_L1 % QCoreApplication::applicationName();
     return directory;
 }
 
diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp
index 6457d456ee2..fc15134eb27 100644
--- a/src/core/web_event_factory.cpp
+++ b/src/core/web_event_factory.cpp
@@ -62,7 +62,7 @@ enum class KeyboardDriver { Unknown, Windows, Cocoa, Xkb, Evdev };
 
 static KeyboardDriver keyboardDriverImpl()
 {
-    QString platformName = QGuiApplication::platformName();
+    const QString platformName = QGuiApplication::platformName();
 
     if (platformName == "windows"_L1)
         return KeyboardDriver::Windows;
@@ -1676,7 +1676,7 @@ content::NativeWebKeyboardEvent WebEventFactory::toWebKeyboardEvent(QKeyEvent *e
     int qtKey = qtKeyForKeyEvent(ev);
     Qt::KeyboardModifiers qtModifiers =
             isBackTabWithoutModifier ? Qt::ShiftModifier : qtModifiersForEvent(ev);
-    QString qtText = qtTextForKeyEvent(ev, qtKey, qtModifiers);
+    const QString qtText = qtTextForKeyEvent(ev, qtKey, qtModifiers);
 
     webKitEvent.native_key_code = nativeKeyCodeForKeyEvent(ev);
     webKitEvent.windows_key_code = windowsKeyCodeForQtKey(qtKey, qtModifiers & Qt::KeypadModifier);

From d4e58bab669ad02b92070d696b2ac535fe8713c3 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 23 Jan 2025 15:50:33 +0100
Subject: [PATCH 281/356] Replace QStringLiteral with shorter u""_s notation

Merge conflict resolution for 6.8:
- Adapt change to initializer list in
  DownloadManagerDelegateQt::ChooseSavePath()

Change-Id: I6d45505c808a48a1ea52ddbd39e74ada4c29136d
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit dbb7830eb9ed95ab9c2f105b850586a9a517cf16)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 6736cf6e65cc83f74473c5c8863ec88b625a4c0c)
---
 src/core/api/qwebenginepage.cpp           | 33 ++++++++++++++---------
 src/core/content_client_qt.cpp            | 17 ++++++------
 src/core/download_manager_delegate_qt.cpp |  2 +-
 src/core/net/resource_request_body_qt.cpp |  4 +--
 src/core/profile_adapter.cpp              |  4 +--
 src/core/web_contents_adapter.cpp         |  2 +-
 src/core/web_contents_delegate_qt.cpp     | 13 ++++++---
 src/core/web_engine_context.cpp           |  6 ++---
 src/core/web_engine_settings.cpp          |  4 ++-
 9 files changed, 50 insertions(+), 35 deletions(-)

diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp
index 640e2c5e938..ee9af797e86 100644
--- a/src/core/api/qwebenginepage.cpp
+++ b/src/core/api/qwebenginepage.cpp
@@ -1491,40 +1491,47 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
         QTimer::singleShot(0, this, [d](){ d->adapter->viewSource(); });
         break;
     case ToggleBold:
-        runJavaScript(QStringLiteral("document.execCommand('bold');"), QWebEngineScript::ApplicationWorld);
+        runJavaScript(u"document.execCommand('bold');"_s, QWebEngineScript::ApplicationWorld);
         break;
     case ToggleItalic:
-        runJavaScript(QStringLiteral("document.execCommand('italic');"), QWebEngineScript::ApplicationWorld);
+        runJavaScript(u"document.execCommand('italic');"_s, QWebEngineScript::ApplicationWorld);
         break;
     case ToggleUnderline:
-        runJavaScript(QStringLiteral("document.execCommand('underline');"), QWebEngineScript::ApplicationWorld);
+        runJavaScript(u"document.execCommand('underline');"_s, QWebEngineScript::ApplicationWorld);
         break;
     case ToggleStrikethrough:
-        runJavaScript(QStringLiteral("document.execCommand('strikethrough');"), QWebEngineScript::ApplicationWorld);
+        runJavaScript(u"document.execCommand('strikethrough');"_s,
+                      QWebEngineScript::ApplicationWorld);
         break;
     case AlignLeft:
-        runJavaScript(QStringLiteral("document.execCommand('justifyLeft');"), QWebEngineScript::ApplicationWorld);
+        runJavaScript(u"document.execCommand('justifyLeft');"_s,
+                      QWebEngineScript::ApplicationWorld);
         break;
     case AlignCenter:
-        runJavaScript(QStringLiteral("document.execCommand('justifyCenter');"), QWebEngineScript::ApplicationWorld);
+        runJavaScript(u"document.execCommand('justifyCenter');"_s,
+                      QWebEngineScript::ApplicationWorld);
         break;
     case AlignRight:
-        runJavaScript(QStringLiteral("document.execCommand('justifyRight');"), QWebEngineScript::ApplicationWorld);
+        runJavaScript(u"document.execCommand('justifyRight');"_s,
+                      QWebEngineScript::ApplicationWorld);
         break;
     case AlignJustified:
-        runJavaScript(QStringLiteral("document.execCommand('justifyFull');"), QWebEngineScript::ApplicationWorld);
+        runJavaScript(u"document.execCommand('justifyFull');"_s,
+                      QWebEngineScript::ApplicationWorld);
         break;
     case Indent:
-        runJavaScript(QStringLiteral("document.execCommand('indent');"), QWebEngineScript::ApplicationWorld);
+        runJavaScript(u"document.execCommand('indent');"_s, QWebEngineScript::ApplicationWorld);
         break;
     case Outdent:
-        runJavaScript(QStringLiteral("document.execCommand('outdent');"), QWebEngineScript::ApplicationWorld);
+        runJavaScript(u"document.execCommand('outdent');"_s, QWebEngineScript::ApplicationWorld);
         break;
     case InsertOrderedList:
-        runJavaScript(QStringLiteral("document.execCommand('insertOrderedList');"), QWebEngineScript::ApplicationWorld);
+        runJavaScript(u"document.execCommand('insertOrderedList');"_s,
+                      QWebEngineScript::ApplicationWorld);
         break;
     case InsertUnorderedList:
-        runJavaScript(QStringLiteral("document.execCommand('insertUnorderedList');"), QWebEngineScript::ApplicationWorld);
+        runJavaScript(u"document.execCommand('insertUnorderedList');"_s,
+                      QWebEngineScript::ApplicationWorld);
         break;
     case ChangeTextDirectionLTR:
         d->adapter->changeTextDirection(true /*left to right*/);
@@ -2015,7 +2022,7 @@ void QWebEnginePage::toPlainText(const std::function<void(const QString &)> &res
 
 void QWebEnginePage::setHtml(const QString &html, const QUrl &baseUrl)
 {
-    setContent(html.toUtf8(), QStringLiteral("text/html;charset=UTF-8"), baseUrl);
+    setContent(html.toUtf8(), u"text/html;charset=UTF-8"_s, baseUrl);
 }
 
 void QWebEnginePage::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl)
diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index 88eebed23cf..b5f40590a3c 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -298,17 +298,18 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path,
         }
 
         // Fixed paths:
-        pluginPaths << QStringLiteral("/usr/lib/chromium/libwidevinecdm.so") // Arch
-                    << QStringLiteral("/usr/lib/chromium-browser/libwidevinecdm.so") // Ubuntu/neon
-                    << QStringLiteral("/usr/lib64/chromium/libwidevinecdm.so") // OpenSUSE style
+        pluginPaths
+                << u"/usr/lib/chromium/libwidevinecdm.so"_s // Arch
+                << u"/usr/lib/chromium-browser/libwidevinecdm.so"_s // Ubuntu/neon
+                << u"/usr/lib64/chromium/libwidevinecdm.so"_s // OpenSUSE style
 #if Q_PROCESSOR_WORDSIZE == 8
-                    << QStringLiteral("/usr/lib64/chromium-browser/WidevineCdm/_platform_specific/linux_x64/libwidevinecdm.so") // Gentoo
-                    << QStringLiteral("/opt/google/chrome/WidevineCdm/_platform_specific/linux_x64/libwidevinecdm.so") // Old Google Chrome
+                << u"/usr/lib64/chromium-browser/WidevineCdm/_platform_specific/linux_x64/libwidevinecdm.so"_s // Gentoo
+                << u"/opt/google/chrome/WidevineCdm/_platform_specific/linux_x64/libwidevinecdm.so"_s // Old Google Chrome
 #else
-                    << QStringLiteral("/usr/lib/chromium-browser/WidevineCdm/_platform_specific/linux_x86/libwidevinecdm.so") // Gentoo
-                    << QStringLiteral("/opt/google/chrome/WidevineCdm/_platform_specific/linux_x86/libwidevinecdm.so") // Old Google Chrome
+                << u"/usr/lib/chromium-browser/WidevineCdm/_platform_specific/linux_x86/libwidevinecdm.so"_s // Gentoo
+                << u"/opt/google/chrome/WidevineCdm/_platform_specific/linux_x86/libwidevinecdm.so"_s // Old Google Chrome
 #endif
-                    << QStringLiteral("/opt/google/chrome/libwidevinecdm.so"); // Older Google Chrome
+                << u"/opt/google/chrome/libwidevinecdm.so"_s; // Older Google Chrome
 #endif
     }
 
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index e67b59d02cf..43a853fdca5 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -309,7 +309,7 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content
         download::DownloadItem::IN_PROGRESS,
         -1, /* totalBytes */
         0, /* receivedBytes */
-        QStringLiteral("application/x-mimearchive"),
+        u"application/x-mimearchive"_s,
         suggestedFilePath,
         suggestedSaveFormat,
         acceptedByDefault,
diff --git a/src/core/net/resource_request_body_qt.cpp b/src/core/net/resource_request_body_qt.cpp
index bc7fffdf2be..e41da9e6806 100644
--- a/src/core/net/resource_request_body_qt.cpp
+++ b/src/core/net/resource_request_body_qt.cpp
@@ -60,8 +60,8 @@ qint64 ResourceRequestBody::readData(char *data, qint64 maxSize)
                 break;
             }
             case network::mojom::DataElementDataView::Tag::kChunkedDataPipe: {
-                setErrorString(QStringLiteral("Chunked data pipe is used in request body upload, which "
-                                              "is currently not supported"));
+                setErrorString(u"Chunked data pipe is used in request body upload, which "
+                               "is currently not supported"_s);
                 // Nothing should come before or after DataElementChunkedDataPipe
                 return -1;
             }
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index 89ecdfcacb3..9f8fc958680 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -256,9 +256,9 @@ QString ProfileAdapter::dataPath() const
     // a location to do so.
     QString name = m_name;
     if (m_offTheRecord)
-        name = QStringLiteral("OffTheRecord");
+        name = u"OffTheRecord"_s;
     else if (m_name.isEmpty())
-        name = QStringLiteral("UnknownProfile");
+        name = u"UnknownProfile"_s;
     return buildLocationFromStandardPath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), name);
 }
 
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 60c3febc0e1..adbae106017 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -2232,7 +2232,7 @@ void WebContentsAdapter::discard()
 
     if (m_webContents->IsLoading()) {
         m_webContentsDelegate->didFailLoad(m_webContentsDelegate->url(webContents()), net::Error::ERR_ABORTED,
-                                           QStringLiteral("Discarded"));
+                                           u"Discarded"_s);
         m_webContentsDelegate->DidStopLoading();
     }
 
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 5ce99761351..5371e9a5448 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -57,6 +57,8 @@
 #include <QTimer>
 #include <QWindow>
 
+using namespace Qt::StringLiterals;
+
 namespace QtWebEngineCore {
 
 static WebContentsAdapterClient::JavaScriptConsoleMessageLevel mapToJavascriptConsoleMessageLevel(blink::mojom::ConsoleMessageLevel log_level)
@@ -778,10 +780,13 @@ void WebContentsDelegateQt::launchExternalURL(const QUrl &url, ui::PageTransitio
 
     if (!navigationAllowedByPolicy || !navigationRequestAccepted) {
         QString errorDescription;
-        if (!navigationAllowedByPolicy)
-            errorDescription = QStringLiteral("Launching external protocol forbidden by WebEngineSettings::UnknownUrlSchemePolicy");
-        else
-            errorDescription = QStringLiteral("Launching external protocol suppressed by 'navigationRequested' API");
+        if (!navigationAllowedByPolicy) {
+            errorDescription = u"Launching external protocol forbidden by "
+                               "WebEngineSettings::UnknownUrlSchemePolicy"_s;
+        } else {
+            errorDescription = u"Launching external protocol suppressed by "
+                               "'navigationRequested' API"_s;
+        }
         didFailLoad(url, net::Error::ERR_ABORTED, errorDescription);
     }
 }
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index cdb967c4857..c8de0a83cd9 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1196,16 +1196,16 @@ base::CommandLine *WebEngineContext::initCommandLine(bool &useEmbeddedSwitches,
 
     bool isRemoteDebugPort =
             (-1
-             != appArgs.indexOf(QRegularExpression(QStringLiteral("--remote-debugging-port=.*"),
+             != appArgs.indexOf(QRegularExpression(u"--remote-debugging-port=.*"_s,
                                                    QRegularExpression::CaseInsensitiveOption)))
             || !qEnvironmentVariable("QTWEBENGINE_REMOTE_DEBUGGING").isEmpty();
     bool isRemoteAllowOrigins =
             (-1
-             != appArgs.indexOf(QRegularExpression(QStringLiteral("--remote-allow-origins=.*"),
+             != appArgs.indexOf(QRegularExpression(u"--remote-allow-origins=.*"_s,
                                                    QRegularExpression::CaseInsensitiveOption)));
 
     if (isRemoteDebugPort && !isRemoteAllowOrigins) {
-        appArgs.append(QStringLiteral("--remote-allow-origins=*"));
+        appArgs.append(u"--remote-allow-origins=*"_s);
         qWarning("Added {--remote-allow-origins=*} to command-line arguments "
                  "to avoid web socket connection errors during remote debugging.");
     }
diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp
index 452ba639330..6e159658ff9 100644
--- a/src/core/web_engine_settings.cpp
+++ b/src/core/web_engine_settings.cpp
@@ -25,6 +25,8 @@
 #include <QFont>
 #include <QTimer>
 
+using namespace Qt::StringLiterals;
+
 namespace QtWebEngineCore {
 
 QHash<QWebEngineSettings::WebAttribute, bool> WebEngineSettings::s_defaultAttributes;
@@ -333,7 +335,7 @@ void WebEngineSettings::initDefaults()
         s_defaultFontSizes.insert(QWebEngineSettings::DefaultFontSize, 16);
     }
 
-    m_defaultEncoding = QStringLiteral("ISO-8859-1");
+    m_defaultEncoding = u"ISO-8859-1"_s;
     m_unknownUrlSchemePolicy = QWebEngineSettings::InheritedUnknownUrlSchemePolicy;
     m_imageAnimationPolicy = QWebEngineSettings::ImageAnimationPolicy::Inherited;
 }

From 1e6539f7a5249ce666159e552d1e14dcf4817de5 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 20 Feb 2025 11:07:14 +0100
Subject: [PATCH 282/356] Add WebEngineContext::isGbmSupported()

Factor GBM support detection out to avoid repetitive Nvidia checks.

Also add QTWEBENGINE_FORCE_USE_GBM environment variable to be able to
force disable/enable GBM and dma-buf code paths for debugging
purposes. Setting the variable to 0 force disables GBM, setting any
other integer value force enables it.

Merge conflict resolution for 6.8:
- No EGLHelper in 6.8
- No BUILDFLAG(IS_OZONE) in 6.8

Change-Id: I39fc0161467a6a8d86dd9f380be3bfb2018aa4e6
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 284d269eda53575d681c5d9f91bc934cf19b2f07)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 3aab3da507cc55dea5833369892c9a72b05082f2)
---
 src/core/ozone/gl_context_qt.cpp | 22 +++++-----------
 src/core/web_engine_context.cpp  | 44 ++++++++++++++++++++++++++++++--
 src/core/web_engine_context.h    |  3 +++
 3 files changed, 52 insertions(+), 17 deletions(-)

diff --git a/src/core/ozone/gl_context_qt.cpp b/src/core/ozone/gl_context_qt.cpp
index ce099a4a3d6..f59c3fa14d0 100644
--- a/src/core/ozone/gl_context_qt.cpp
+++ b/src/core/ozone/gl_context_qt.cpp
@@ -2,6 +2,7 @@
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
 
 #include "gl_context_qt.h"
+#include "web_engine_context.h"
 
 #include <QGuiApplication>
 #include <QOpenGLContext>
@@ -298,23 +299,14 @@ EGLHelper::EGLHelper()
     Q_ASSERT(QThread::currentThread() == qApp->thread());
     m_offscreenSurface->create();
 
-    const char *displayExtensions = m_functions->eglQueryString(eglDisplay, EGL_EXTENSIONS);
-    m_isDmaBufSupported = strstr(displayExtensions, "EGL_EXT_image_dma_buf_import")
-            && strstr(displayExtensions, "EGL_EXT_image_dma_buf_import_modifiers")
-            && strstr(displayExtensions, "EGL_MESA_image_dma_buf_export");
+    m_isDmaBufSupported = QtWebEngineCore::WebEngineContext::isGbmSupported();
 
+    // Check extensions.
     if (m_isDmaBufSupported) {
-        // FIXME: This disables GBM for nvidia. Remove this when nvidia fixes its GBM support.
-        //
-        // "Buffer allocation and submission to DRM KMS using gbm is not currently supported."
-        // See: https://download.nvidia.com/XFree86/Linux-x86_64/550.40.07/README/kms.html
-        //
-        // Chromium uses GBM to allocate scanout buffers. Scanout requires DRM KMS. If KMS is
-        // enabled, gbm_device and gbm_buffer are created without any issues but rendering to the
-        // buffer will malfunction. It is not known how to detect this problem before rendering
-        // so we just disable GBM for nvidia.
-        const char *displayVendor = m_functions->eglQueryString(eglDisplay, EGL_VENDOR);
-        m_isDmaBufSupported = !strstr(displayVendor, "NVIDIA");
+        const char *displayExtensions = m_functions->eglQueryString(eglDisplay, EGL_EXTENSIONS);
+        m_isDmaBufSupported = strstr(displayExtensions, "EGL_EXT_image_dma_buf_import")
+                && strstr(displayExtensions, "EGL_EXT_image_dma_buf_import_modifiers")
+                && strstr(displayExtensions, "EGL_MESA_image_dma_buf_export");
     }
 
     // Try to create dma-buf.
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index c8de0a83cd9..f77b380db33 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -952,7 +952,7 @@ WebEngineContext::WebEngineContext()
     }
 
 #if defined(USE_OZONE)
-    if (GPUInfo::instance()->vendor() == GPUInfo::Nvidia) {
+    if (!isGbmSupported()) {
         disableFeatures.push_back(media::kVaapiVideoDecodeLinux.name);
         parsedCommandLine->AppendSwitch(switches::kDisableGpuMemoryBufferVideoFrames);
     }
@@ -965,7 +965,7 @@ WebEngineContext::WebEngineContext()
         if (parsedCommandLine->HasSwitch(switches::kUseGL))
             usingANGLE = (parsedCommandLine->GetSwitchValueASCII(switches::kUseGL)
                           == gl::kGLImplementationANGLEName);
-        if (usingANGLE && GPUInfo::instance()->vendor() == GPUInfo::Nvidia) {
+        if (usingANGLE && !isGbmSupported()) {
             qWarning("Disable ANGLE because GBM is not supported with the current configuration. "
                      "Fallback to Vulkan rendering in Chromium.");
             parsedCommandLine->RemoveSwitch(switches::kUseANGLE);
@@ -1229,6 +1229,46 @@ bool WebEngineContext::closingDown()
     return m_closingDown;
 }
 
+#if defined(USE_OZONE)
+bool WebEngineContext::isGbmSupported()
+{
+    static bool supported = []() {
+        const static char kForceGbmEnv[] = "QTWEBENGINE_FORCE_USE_GBM";
+        if (Q_UNLIKELY(qEnvironmentVariableIsSet(kForceGbmEnv))) {
+            qWarning("%s environment variable is set and it is for debugging purposes only.",
+                     kForceGbmEnv);
+            bool ok;
+            int forceGbm = qEnvironmentVariableIntValue(kForceGbmEnv, &ok);
+            if (ok) {
+                qWarning("GBM support is force %s.", forceGbm != 0 ? "enabled" : "disabled");
+                return (forceGbm != 0);
+            }
+
+            qWarning("Ignoring invalid value of %s and do not force GBM. "
+                     "Use 0 to force disable or 1 to force enable.",
+                     kForceGbmEnv);
+        }
+
+        if (GPUInfo::instance()->vendor() == GPUInfo::Nvidia) {
+            // FIXME: This disables GBM for Nvidia. Remove this when Nvidia fixes its GBM support.
+            //
+            // "Buffer allocation and submission to DRM KMS using gbm is not currently supported."
+            // See: https://download.nvidia.com/XFree86/Linux-x86_64/570.86.16/README/kms.html"
+            //
+            // Chromium uses GBM to allocate scanout buffers. Scanout requires DRM KMS. If KMS is
+            // enabled, gbm_device and gbm_buffer are created without any issues but rendering to
+            // the buffer will malfunction. It is not known how to detect this problem before
+            // rendering so we just disable GBM for Nvidia.
+            return false;
+        }
+
+        return true;
+    }();
+
+    return supported;
+}
+#endif
+
 void WebEngineContext::registerMainThreadFactories()
 {
     content::UtilityProcessHost::RegisterUtilityMainThreadFactory(content::CreateInProcessUtilityThread);
diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h
index 7a36fd00187..606c41ef238 100644
--- a/src/core/web_engine_context.h
+++ b/src/core/web_engine_context.h
@@ -67,6 +67,9 @@ class WebEngineContext : public base::RefCounted<WebEngineContext> {
     static ProxyAuthentication qProxyNetworkAuthentication(QString host, int port);
     static void flushMessages();
     static bool closingDown();
+#if defined(USE_OZONE)
+    static bool isGbmSupported();
+#endif
     ProfileAdapter *createDefaultProfileAdapter();
     ProfileAdapter *defaultProfileAdapter();
 

From 3a0dad099d1966879a9f41eb56735a971958e7b8 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 9 Jan 2025 13:26:02 +0100
Subject: [PATCH 283/356] Disable dma-buf and GBM for nvidia with GLX

It is already disabled with EGL.

Checking the existence of a GBM device is just not enough. It is
possible to create GBM device and buffer with nvidia driver but it
will not work.

Merge conflict resolution for 6.8:
- No GLXHelper in 6.8

Change-Id: I3806594371d3e266d499bdc396c8f2a4ca17580d
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Moss Heim <moss.heim@qt.io>
(cherry picked from commit a3604e0a41b586d1f32865d9c60003ed31e46884)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit b1b0246839b97a5c642ae8093e0c7d61a22eea37)
---
 src/core/ozone/surface_factory_qt.cpp | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/core/ozone/surface_factory_qt.cpp b/src/core/ozone/surface_factory_qt.cpp
index 726c2c0465f..835d2fed210 100644
--- a/src/core/ozone/surface_factory_qt.cpp
+++ b/src/core/ozone/surface_factory_qt.cpp
@@ -9,6 +9,7 @@
 #include "ozone/gl_ozone_angle_qt.h"
 #include "ozone/gl_ozone_egl_qt.h"
 #include "qtwebenginecoreglobal_p.h"
+#include "web_engine_context.h"
 
 #include "media/gpu/buildflags.h"
 #include "ui/base/ozone_buildflags.h"
@@ -265,8 +266,10 @@ bool SurfaceFactoryQt::SupportsNativePixmaps()
 {
 #if QT_CONFIG(opengl)
 #if BUILDFLAG(IS_OZONE_X11)
-    if (GLContextHelper::getGlxPlatformInterface())
-        return ui::GpuMemoryBufferSupportX11::GetInstance()->has_gbm_device();
+    if (GLContextHelper::getGlxPlatformInterface()) {
+        return QtWebEngineCore::WebEngineContext::isGbmSupported()
+                && ui::GpuMemoryBufferSupportX11::GetInstance()->has_gbm_device();
+    }
 #endif // BUILDFLAG(IS_OZONE_X11)
 
     if (GLContextHelper::getEglPlatformInterface())

From d35615c60b3e353122e60b86159dd0d9f423843f Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 20 Feb 2025 09:05:14 +0100
Subject: [PATCH 284/356] Fix importing memory object for rendering without
 NativePixmap

This fixes rendering with newer Nvidia drivers on Linux.

- Make memory object dedicated to match Vulkan allocation
- Set tiling of the GL texture to match VkImage tiling
- Make the TexStorage command non-DSA to uniform GL calls

Amends 8ce04357b4ce39b8c4c2243991eae70f78f9b61b

Merge conflict resolution for 6.8:
- No GLHelper in 6.8, add GL function bindings to
  NativeSkiaOutputDeviceOpenGL
- No GLXHelper and EGLHelper in 6.8, do not change guards around header
  includes

Change-Id: I43e953412acf6d39b67dcd8af02aac4003fc5c8e
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Moss Heim <moss.heim@qt.io>
(cherry picked from commit 558bbf10544c9c96cde4ef3c7923c8b3bb8aa237)
(cherry picked from commit 8de829cb150989673c6051d4c8e8d04b3b9c89db)
---
 .../native_skia_output_device_opengl.cpp      | 36 ++++++++++++++-----
 1 file changed, 27 insertions(+), 9 deletions(-)

diff --git a/src/core/compositor/native_skia_output_device_opengl.cpp b/src/core/compositor/native_skia_output_device_opengl.cpp
index ac967f26da9..195d4dc72f3 100644
--- a/src/core/compositor/native_skia_output_device_opengl.cpp
+++ b/src/core/compositor/native_skia_output_device_opengl.cpp
@@ -24,7 +24,10 @@
 #undef glGenTextures
 #undef glGetError
 #undef glImportMemoryFdEXT
-#undef glTextureStorageMem2DEXT
+#undef glIsMemoryObjectEXT
+#undef glMemoryObjectParameterivEXT
+#undef glTexParameteri
+#undef glTexStorageMem2DEXT
 
 #include "base/posix/eintr_wrapper.h"
 #include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h"
@@ -350,17 +353,32 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
                         "glCreateMemoryObjectsEXT");
         static PFNGLIMPORTMEMORYFDEXTPROC glImportMemoryFdEXT =
                 (PFNGLIMPORTMEMORYFDEXTPROC)glContext->getProcAddress("glImportMemoryFdEXT");
-        static PFNGLTEXTURESTORAGEMEM2DEXTPROC glTextureStorageMem2DEXT =
-                (PFNGLTEXTURESTORAGEMEM2DEXTPROC)glContext->getProcAddress(
-                        "glTextureStorageMem2DEXT");
-
+        static PFNGLISMEMORYOBJECTEXTPROC glIsMemoryObjectEXT =
+                (PFNGLISMEMORYOBJECTEXTPROC)glContext->getProcAddress("glIsMemoryObjectEXT");
+        static PFNGLMEMORYOBJECTPARAMETERIVEXTPROC glMemoryObjectParameterivEXT =
+                (PFNGLMEMORYOBJECTPARAMETERIVEXTPROC)glContext->getProcAddress(
+                        "glMemoryObjectParameterivEXT");
+        static PFNGLTEXSTORAGEMEM2DEXTPROC glTexStorageMem2DEXT =
+                (PFNGLTEXSTORAGEMEM2DEXTPROC)glContext->getProcAddress("glTexStorageMem2DEXT");
+
+        // Import memory object
         GLuint glMemoryObject;
-        glFun->glGenTextures(1, &glTexture);
-        glFun->glBindTexture(GL_TEXTURE_2D, glTexture);
         glCreateMemoryObjectsEXT(1, &glMemoryObject);
+        GLint dedicated = GL_TRUE;
+        glMemoryObjectParameterivEXT(glMemoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT, &dedicated);
         glImportMemoryFdEXT(glMemoryObject, importedImageSize, GL_HANDLE_TYPE_OPAQUE_FD_EXT, fd);
-        glTextureStorageMem2DEXT(glTexture, 1, GL_RGBA8_OES, size().width(), size().height(),
-                                 glMemoryObject, 0);
+        if (!glIsMemoryObjectEXT(glMemoryObject))
+            qFatal("VULKAN: Failed to import memory object.");
+
+        // Bind memory object to texture
+        glFun->glGenTextures(1, &glTexture);
+        glFun->glBindTexture(GL_TEXTURE_2D, glTexture);
+        glFun->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_TILING_EXT,
+                               vkImageInfo.fImageTiling == VK_IMAGE_TILING_OPTIMAL
+                                       ? GL_OPTIMAL_TILING_EXT
+                                       : GL_LINEAR_TILING_EXT);
+        glTexStorageMem2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, size().width(), size().height(),
+                             glMemoryObject, 0);
         glFun->glBindTexture(GL_TEXTURE_2D, 0);
 
         m_frontBuffer->textureCleanupCallback = [glTexture, glMemoryObject]() {

From ea7cb8ea1f9ae56f0eb1c89cc7608c7514e8ea11 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Fri, 21 Feb 2025 13:56:16 +0100
Subject: [PATCH 285/356] Make MotionEventQt assert more informative

Change-Id: I1a91b8fa3004d70f2467085f198d8eaa0ecfdc10
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 254d7db17d09b6c567a3c22567ba322ff952c358)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 0da0582bf8359180bca0edc91a97e5018a7155a9)
---
 ...er_widget_host_view_qt_delegate_client.cpp | 30 ++++++++++++++++---
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/src/core/render_widget_host_view_qt_delegate_client.cpp b/src/core/render_widget_host_view_qt_delegate_client.cpp
index 934df0ce489..493648ceaa4 100644
--- a/src/core/render_widget_host_view_qt_delegate_client.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_client.cpp
@@ -14,6 +14,7 @@
 #include "content/browser/renderer_host/render_widget_host_input_event_router.h"
 #include "ui/touch_selection/touch_selection_controller.h"
 
+#include <QDebug>
 #include <QEvent>
 #include <QInputMethodEvent>
 #include <QSet>
@@ -24,6 +25,8 @@
 #include <QtGui/private/qguiapplication_p.h>
 #include <QtGui/private/qinputcontrol_p.h>
 
+using namespace Qt::StringLiterals;
+
 namespace QtWebEngineCore {
 
 static inline int firstAvailableId(const QMap<int, int> &map)
@@ -76,12 +79,31 @@ class MotionEventQt : public ui::MotionEvent
         , flags(flagsFromModifiers(modifiers))
         , index(index)
     {
+#if !defined(QT_NO_DEBUG) || defined(QT_FORCE_ASSERTS)
         // index is only valid for POINTER_DOWN and POINTER_UP and should correspond to the point
         // causing it see blink_event_util.cc:ToWebTouchPointState for details
-        Q_ASSERT_X((action != Action::POINTER_DOWN && action != Action::POINTER_UP && index == -1)
-                || (action == Action::POINTER_DOWN && index >= 0 && touchPoint(index).state() == QEventPoint::Pressed)
-                || (action == Action::POINTER_UP && index >= 0 && touchPoint(index).state() == QEventPoint::Released),
-                "MotionEventQt", qPrintable(QString("action: %1, index: %2, state: %3").arg(int(action)).arg(index).arg(touchPoint(index).state())));
+        if (action == Action::POINTER_DOWN || action == Action::POINTER_UP) {
+            const auto actionString = (action == Action::POINTER_DOWN ? "Action::POINTER_DOWN"_L1
+                                                                      : "Action::POINTER_UP"_L1);
+            Q_ASSERT_X(index >= 0 && index < touchPoints.size(), "MotionEventQt",
+                       qPrintable("Invalid index for "_L1 + actionString + ": "_L1
+                                  + QString::number(index)));
+
+            const QEventPoint::State state = touchPoint(index).state();
+            QString stateString;
+            QDebug(&stateString) << state;
+            Q_ASSERT_X(
+                    (action == Action::POINTER_DOWN && state == QEventPoint::Pressed)
+                            || (action == Action::POINTER_UP && state == QEventPoint::Released),
+                    "MotionEventQt",
+                    qPrintable("Unexpected state for "_L1 + actionString + ": "_L1 + stateString));
+        } else {
+            Q_ASSERT_X(index == -1, "MotionEventQt",
+                       qPrintable("Unexpected index for action "_L1
+                                  + QString::number(static_cast<int>(action)) + ": "_L1
+                                  + QString::number(index)));
+        }
+#endif
     }
 
     uint32_t GetUniqueEventId() const override { return eventId; }

From 5efb3c2e246709fe4591ae4c7781570b0aede17e Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 13 Feb 2025 13:22:12 +0100
Subject: [PATCH 286/356] Use QStringList::append() where the string can be
 moved into the list

As a drive-by, refactor web_engine_library_info.cpp's fromEnv
occurrences to use them in the if blocks only and make the code a little
bit more readable.

Merge conflict resolution for 6.8:
- Adapt change to initializer list in
  DownloadManagerDelegateQt::ChooseSavePath()

Change-Id: Ib3ee6390003bc6e196398979d992e71b7fc50a8a
Reviewed-by: Moss Heim <moss.heim@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit 26c43ef73cf6a5184ded71d173224e1cd733c90f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 2d73011de5276e997a9af159531a5830ba97b371)
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
---
 src/core/api/qwebenginedownloadrequest.cpp    |  2 +-
 ...thenticator_request_client_delegate_qt.cpp |  2 +-
 src/core/content_client_qt.cpp                |  6 +-
 src/core/download_manager_delegate_qt.cpp     |  6 +-
 src/core/file_picker_controller.cpp           |  6 +-
 src/core/web_engine_library_info.cpp          | 62 ++++++++++---------
 6 files changed, 45 insertions(+), 39 deletions(-)

diff --git a/src/core/api/qwebenginedownloadrequest.cpp b/src/core/api/qwebenginedownloadrequest.cpp
index cbf46b4481b..70f4b094197 100644
--- a/src/core/api/qwebenginedownloadrequest.cpp
+++ b/src/core/api/qwebenginedownloadrequest.cpp
@@ -465,7 +465,7 @@ void QWebEngineDownloadRequest::setDownloadDirectory(const QString &directory)
                                                                                  d->suggestedFileName,
                                                                                  d->startTime)).fileName();
         if (d->downloadFileName != newFileName) {
-            d->downloadFileName = newFileName;
+            d->downloadFileName = std::move(newFileName);
             Q_EMIT downloadFileNameChanged();
         }
     }
diff --git a/src/core/authenticator_request_client_delegate_qt.cpp b/src/core/authenticator_request_client_delegate_qt.cpp
index 5f9fd9ca37d..8837dd85e96 100644
--- a/src/core/authenticator_request_client_delegate_qt.cpp
+++ b/src/core/authenticator_request_client_delegate_qt.cpp
@@ -150,7 +150,7 @@ void AuthenticatorRequestClientDelegateQt::SelectAccount(
         if (has_user_identifying_info) {
             QString userName = toQt(*response.user_entity->name);
             m_userMap[userName] = nIndex;
-            userList.append(userName);
+            userList.append(std::move(userName));
         }
     }
     m_dialogController->selectAccount(userList);
diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index b5f40590a3c..0901f39b6b4 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -218,7 +218,7 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path,
             const QString versionDirPath = widevineVersionDirs.at(i).absoluteFilePath();
             QString potentialWidevinePluginPath = versionDirPath + "/_platform_specific/"_L1 + archDir
                     + QLatin1StringView(kWidevineCdmFileName);
-            pluginPaths << potentialWidevinePluginPath;
+            pluginPaths.append(std::move(potentialWidevinePluginPath));
         }
     }
 #elif defined(Q_OS_WIN)
@@ -240,7 +240,7 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path,
                                                         "/WidevineCdm/_platform_specific/win_x86/"_L1 +
                                                         QLatin1StringView(kWidevineCdmFileName);
 #endif
-                pluginPaths << potentialWidevinePluginPath;
+                pluginPaths.append(std::move(potentialWidevinePluginPath));
             }
         }
     }
@@ -254,7 +254,7 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path,
 #else
             QString potentialWidevinePluginPath = versionDirPath + "/_platform_specific/win_x86/"_L1 + QLatin1StringView(kWidevineCdmFileName);
 #endif
-            pluginPaths << potentialWidevinePluginPath;
+            pluginPaths.append(std::move(potentialWidevinePluginPath));
         }
     }
 #elif defined(Q_OS_LINUX)
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index 43a853fdca5..afd616e5468 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -193,8 +193,8 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
             item->GetState(),
             item->GetTotalBytes(),
             item->GetReceivedBytes(),
-            mimeTypeString,
-            suggestedFilePath,
+            std::move(mimeTypeString),
+            std::move(suggestedFilePath),
             ProfileAdapterClient::UnknownSavePageFormat,
             acceptedByDefault,
             false /* paused */,
@@ -202,7 +202,7 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
             isSavePageDownload,
             item->GetLastReason(),
             adapterClient,
-            suggestedFilename,
+            std::move(suggestedFilename),
             item->GetStartTime().ToTimeT()
         };
 
diff --git a/src/core/file_picker_controller.cpp b/src/core/file_picker_controller.cpp
index 1c98b90c74c..8f6bd40702c 100644
--- a/src/core/file_picker_controller.cpp
+++ b/src/core/file_picker_controller.cpp
@@ -260,16 +260,16 @@ QStringList FilePickerController::nameFilters(const QStringList &acceptedMimeTyp
             const QMimeType &mimeType = mimeDatabase.mimeTypeForFile("filename"_L1 + type);
             if (mimeType.isValid()) {
                 QString glob = u'*' + type;
-                acceptedGlobs.append(glob);
                 nameFilters.append(mimeType.comment() + " ("_L1 + glob + u')');
+                acceptedGlobs.append(std::move(glob));
             }
         } else if (type.contains(u'/') && !type.endsWith(u'*')) {
             // All suffixes for a given MIME type
             const QMimeType &mimeType = mimeDatabase.mimeTypeForName(type);
             if (mimeType.isValid() && !mimeType.globPatterns().isEmpty()) {
                 QString globs = mimeType.globPatterns().join(u' ');
-                acceptedGlobs.append(mimeType.globPatterns());
                 nameFilters.append(mimeType.comment() + " ("_L1 + globs + u')');
+                acceptedGlobs.append(mimeType.globPatterns());
             }
         } else if (type.endsWith("/*"_L1)) {
             // All MIME types for audio/*, image/* or video/*
@@ -279,8 +279,8 @@ QStringList FilePickerController::nameFilters(const QStringList &acceptedMimeTyp
             for (const QMimeType &m : allMimeTypes) {
                 if (m.name().startsWith(type) && !m.globPatterns().isEmpty()) {
                     QString globs = m.globPatterns().join(u' ');
-                    acceptedGlobs.append(m.globPatterns());
                     nameFilters.append(m.comment() + " ("_L1 + globs + u')');
+                    acceptedGlobs.append(m.globPatterns());
                 }
             }
         } else {
diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp
index 960b768d701..f7ab89681eb 100644
--- a/src/core/web_engine_library_info.cpp
+++ b/src/core/web_engine_library_info.cpp
@@ -129,11 +129,9 @@ QString subProcessPath()
 #endif
 
         QStringList candidatePaths;
-        const QString fromEnv = qEnvironmentVariable("QTWEBENGINEPROCESS_PATH");
-        if (!fromEnv.isEmpty()) {
-            // Only search in QTWEBENGINEPROCESS_PATH if set
-            candidatePaths << fromEnv;
-        } else {
+        bool includeOverrideMessage = false;
+        if (QString fromEnv = qEnvironmentVariable("QTWEBENGINEPROCESS_PATH"); fromEnv.isEmpty()) {
+            includeOverrideMessage = true;
 #if defined(Q_OS_DARWIN) && defined(QT_MAC_FRAMEWORK_BUILD)
             candidatePaths << getBundlePath(frameworkBundle()) % "/Helpers/"_L1
                             % qWebEngineProcessName() % ".app/Contents/MacOS/"_L1
@@ -146,6 +144,9 @@ QString subProcessPath()
 #endif
             candidatePaths << QCoreApplication::applicationDirPath()
                               % QLatin1Char('/') % processBinary;
+        } else {
+            // Only search in QTWEBENGINEPROCESS_PATH if set
+            candidatePaths.append(std::move(fromEnv));
         }
 
         for (const QString &candidate : std::as_const(candidatePaths)) {
@@ -162,7 +163,7 @@ QString subProcessPath()
             for (const QString &candidate : std::as_const(candidatePaths))
                 errorMessage += "  "_L1 + candidate + u'\n';
             errorMessage += "but could not find it.\n"_L1;
-            if (fromEnv.isEmpty()) {
+            if (includeOverrideMessage) {
                 errorMessage += "You may override the default search path by using "
                                 "QTWEBENGINEPROCESS_PATH environment variable.\n"_L1;
             }
@@ -190,11 +191,9 @@ QString localesPath()
         QStringList candidatePaths;
         const QString translationPakFilename =
                 QLatin1StringView(WebEngineLibraryInfo::getResolvedLocale()) % ".pak"_L1;
-        const QString fromEnv = qEnvironmentVariable("QTWEBENGINE_LOCALES_PATH");
-        if (!fromEnv.isEmpty()) {
-            // Only search in QTWEBENGINE_LOCALES_PATH if set
-            candidatePaths << fromEnv;
-        } else {
+        bool includeOverrideMessage = false;
+        if (QString fromEnv = qEnvironmentVariable("QTWEBENGINE_LOCALES_PATH"); fromEnv.isEmpty()) {
+            includeOverrideMessage = true;
 #if defined(Q_OS_DARWIN) && defined(QT_MAC_FRAMEWORK_BUILD)
             candidatePaths << getResourcesPath(frameworkBundle()) % QDir::separator()
                             % "qtwebengine_locales"_L1;
@@ -202,6 +201,9 @@ QString localesPath()
             candidatePaths << QLibraryInfo::path(QLibraryInfo::TranslationsPath) % QDir::separator()
                             % "qtwebengine_locales"_L1;
             candidatePaths << fallbackDir();
+        } else {
+            // Only search in QTWEBENGINE_LOCALES_PATH if set
+            candidatePaths.append(std::move(fromEnv));
         }
 
         for (const QString &candidate : std::as_const(candidatePaths)) {
@@ -220,7 +222,7 @@ QString localesPath()
                 warningMessage += "  "_L1 % candidate + u'\n';
             warningMessage += "but could not find the translation file for the current locale: "_L1
                     + translationPakFilename + u'\n';
-            if (fromEnv.isEmpty()) {
+            if (includeOverrideMessage) {
                 warningMessage += "You may override the default search paths by using "
                                   "QTWEBENGINE_LOCALES_PATH environment variable.\n"_L1;
             }
@@ -242,31 +244,33 @@ QString dictionariesPath(bool showWarnings)
     if (!initialized) {
         initialized = true;
 
-        const QString fromEnv = qEnvironmentVariable("QTWEBENGINE_DICTIONARIES_PATH");
-        if (!fromEnv.isEmpty()) {
-            // Only search in QTWEBENGINE_DICTIONARIES_PATH if set
-            candidatePaths << fromEnv;
-        } else {
+        bool includeOverrideMessage = false;
+        if (QString fromEnv = qEnvironmentVariable("QTWEBENGINE_DICTIONARIES_PATH");
+            fromEnv.isEmpty()) {
+            includeOverrideMessage = true;
             // First try to find dictionaries near the application.
 #ifdef Q_OS_DARWIN
             QString resourcesDictionariesPath = getMainApplicationResourcesPath()
                     % QDir::separator() % "qtwebengine_dictionaries"_L1;
-            candidatePaths << resourcesDictionariesPath;
+            candidatePaths.append(std::move(resourcesDictionariesPath));
 #endif
             QString applicationDictionariesPath = QCoreApplication::applicationDirPath()
                     % QDir::separator() % "qtwebengine_dictionaries"_L1;
-            candidatePaths << applicationDictionariesPath;
+            candidatePaths.append(std::move(applicationDictionariesPath));
 
             // Then try to find dictionaries near the installed library.
 #if defined(Q_OS_DARWIN) && defined(QT_MAC_FRAMEWORK_BUILD)
             QString frameworkDictionariesPath =
                     getResourcesPath(frameworkBundle()) % "/qtwebengine_dictionaries"_L1;
-            candidatePaths << frameworkDictionariesPath;
+            candidatePaths.append(std::move(frameworkDictionariesPath));
 #endif
 
             QString libraryDictionariesPath = QLibraryInfo::path(QLibraryInfo::DataPath)
                     % QDir::separator() % "qtwebengine_dictionaries"_L1;
-            candidatePaths << libraryDictionariesPath;
+            candidatePaths.append(std::move(libraryDictionariesPath));
+        } else {
+            // Only search in QTWEBENGINE_DICTIONARIES_PATH if set
+            candidatePaths.append(std::move(fromEnv));
         }
 
         for (const QString &candidate : std::as_const(candidatePaths)) {
@@ -283,7 +287,7 @@ QString dictionariesPath(bool showWarnings)
             for (const QString &candidate : std::as_const(candidatePaths))
                 warningMessage += "  "_L1 + candidate + u'\n';
             warningMessage += "but could not find it.\n"_L1;
-            if (fromEnv.isEmpty()) {
+            if (includeOverrideMessage) {
                 warningMessage += "You may override the default search path by using "
                                   "QTWEBENGINE_DICTIONARIES_PATH environment variable.\n"_L1;
             }
@@ -305,11 +309,10 @@ QString resourcesPath()
     if (potentialResourcesPath.isEmpty()) {
         QStringList candidatePaths;
         const auto resourcesPakFilename = "qtwebengine_resources.pak"_L1;
-        const QString fromEnv = qEnvironmentVariable("QTWEBENGINE_RESOURCES_PATH");
-        if (!fromEnv.isEmpty()) {
-            // Only search in QTWEBENGINE_RESOURCES_PATH if set
-            candidatePaths << fromEnv;
-        } else {
+        bool includeOverrideMessage = false;
+        if (QString fromEnv = qEnvironmentVariable("QTWEBENGINE_RESOURCES_PATH");
+            fromEnv.isEmpty()) {
+            includeOverrideMessage = true;
 #if defined(Q_OS_DARWIN) && defined(QT_MAC_FRAMEWORK_BUILD)
             candidatePaths << getResourcesPath(frameworkBundle());
 #endif
@@ -318,6 +321,9 @@ QString resourcesPath()
             candidatePaths << QLibraryInfo::path(QLibraryInfo::DataPath);
             candidatePaths << QCoreApplication::applicationDirPath();
             candidatePaths << fallbackDir();
+        } else {
+            // Only search in QTWEBENGINE_RESOURCES_PATH if set
+            candidatePaths.append(std::move(fromEnv));
         }
 
         for (const QString &candidate : std::as_const(candidatePaths)) {
@@ -335,7 +341,7 @@ QString resourcesPath()
             for (const QString &candidate : std::as_const(candidatePaths))
                 errorMessage += "  "_L1 + candidate + u'\n';
             errorMessage += "but could not find any.\n"_L1;
-            if (fromEnv.isEmpty()) {
+            if (includeOverrideMessage) {
                 errorMessage += "You may override the default search paths by using "
                                 "QTWEBENGINE_RESOURCES_PATH environment variable.\n"_L1;
             }

From 73784f64689cd527bee71708027d08202eaa4d70 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Fri, 28 Feb 2025 08:11:51 +0000
Subject: [PATCH 287/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I9b56213b7d5235c9c1e3319776a0d33a696096e4
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 6b4c0c5a26f..393eda358ed 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 72d314d1e51709a71d856fa0bf1eb0d146013f8e
+    ref: 38a2283787edfe6f3d2f873599792c695a02afb0
     required: true
   ../qtpositioning:
-    ref: d439b858a902e16f198a973ac605bdc13c171ad7
+    ref: b78a3269dd1fafbd6ce7b314f609b00b70b9d6e3
     required: false
   ../qttools:
-    ref: 53798d1ceb1ff9fa4fc1b291b49f656929f8059d
+    ref: cab5a7992bd13c789882d6d25a62fa2fa272edbb
     required: false
   ../qtwebchannel:
-    ref: fcfe7c1a7d3f841111bb6e5409411e46d0f5b116
+    ref: c5d6e02e2653551433035268daf0a0724900c408
     required: false

From 4a8cc427fb9c8bfa97efc78a437104deb67014d0 Mon Sep 17 00:00:00 2001
From: Topi Reinio <topi.reinio@qt.io>
Date: Fri, 7 Feb 2025 12:31:15 +0000
Subject: [PATCH 288/356] Doc: Fix documentation issues

PdfStyle.qml:
  (qdoc) warning: Unknown base 'QtObject' for QML type 'PdfStyle'

Fixed by introducing a doc dependency to `qtqml`.

qwebenginenewwindowrequest.cpp:
  (qdoc) warning: Invalid QML property type: QUrl
  (qdoc) warning: Invalid QML property type: QRect

Replaced with QML types (url, rect) instead.

qwebenginewebauthuxrequest.cpp:
  (qdoc) warning: Can't link to 'WebEngineWebAuthUxRequest.WebAuthUxState.CollectPin'
  (qdoc) warning: Can't link to 'WebEngineWebAuthPinRequest::reason'

Fixes: QTBUG-134248
Change-Id: I313dddba6a374e65c23d371437d0fb148374bd2c
Reviewed-by: Andreas Eliasson <andreas.eliasson@qt.io>
(cherry picked from commit 5f976f185d3ead42e1dbb028deca60a2cfc0b9c6)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit e258edec23a24c6b308455c2706e945612787aff)
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
---
 src/core/api/qwebenginenewwindowrequest.cpp | 4 ++--
 src/core/api/qwebenginewebauthuxrequest.cpp | 7 ++++---
 src/pdf/doc/qtpdf.qdocconf                  | 1 +
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/core/api/qwebenginenewwindowrequest.cpp b/src/core/api/qwebenginenewwindowrequest.cpp
index 1f0be9aa03c..500f3ac2bf2 100644
--- a/src/core/api/qwebenginenewwindowrequest.cpp
+++ b/src/core/api/qwebenginenewwindowrequest.cpp
@@ -98,7 +98,7 @@ QWebEngineNewWindowRequest::DestinationType QWebEngineNewWindowRequest::destinat
     \brief The URL that is requested for the new page.
 */
 /*!
-    \qmlproperty QUrl WebEngineNewWindowRequest::requestedUrl
+    \qmlproperty url WebEngineNewWindowRequest::requestedUrl
     \brief The URL that is requested for the new page.
     \since QtWebEngine 1.5
  */
@@ -112,7 +112,7 @@ QUrl QWebEngineNewWindowRequest::requestedUrl() const
     \brief The size that is requested for the new page.
 */
 /*!
-    \qmlproperty QRect WebEngineNewWindowRequest::requestedGeometry
+    \qmlproperty rect WebEngineNewWindowRequest::requestedGeometry
     \brief The size that is requested for the new page.
     \since QtWebEngine 2.0
  */
diff --git a/src/core/api/qwebenginewebauthuxrequest.cpp b/src/core/api/qwebenginewebauthuxrequest.cpp
index 18ebbb70ea9..3c289fd5c3a 100644
--- a/src/core/api/qwebenginewebauthuxrequest.cpp
+++ b/src/core/api/qwebenginewebauthuxrequest.cpp
@@ -109,8 +109,9 @@
         \c{WebEngineWebAuthUxRequest.PinEntryReason.Challenge}.
     \li The minimum PIN length that the authenticator will accept for the PIN.
     \endlist
-    Use this structure to update the WebAuth UX dialog when the WebAuth UX state is \l
-    WebEngineWebAuthUxRequest.WebAuthUxState.CollectPin.
+    Use this structure to update the WebAuth UX dialog when the WebAuth UX
+    \l {WebEngineWebAuthUxRequest::}{state} is
+    \c {WebEngineWebAuthUxRequest.WebAuthUxState.CollectPin}.
 */
 
 /*!
@@ -137,7 +138,7 @@
 /*!
     \qmlproperty int QtWebEngine::webEngineWebAuthPinRequest::remainingAttempts
     \brief The number of attempts remaining before a hard lock. Should be ignored unless
-           \l{WebEngineWebAuthPinRequest::reason} is
+           \l{webEngineWebAuthPinRequest::reason} is
            \c{WebEngineWebAuthUxRequest.PinEntryReason.Challenge}.
 */
 
diff --git a/src/pdf/doc/qtpdf.qdocconf b/src/pdf/doc/qtpdf.qdocconf
index d0340fe8317..d208188df8d 100644
--- a/src/pdf/doc/qtpdf.qdocconf
+++ b/src/pdf/doc/qtpdf.qdocconf
@@ -38,6 +38,7 @@ depends += qtcore \
            qtdoc \
            qmake \
            qtdesigner \
+           qtqml \
            qtquick \
            qtquickcontrols \
            qtcmake \

From f33a4a521f7472c44808dab83af595ff0f76692b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucie=20G=C3=A9rard?= <lucie.gerard@qt.io>
Date: Wed, 15 Jan 2025 15:01:39 +0100
Subject: [PATCH 289/356] Make module ready for source SBOM checking

This includes:
- turning VERIFY_SOURCE_SBOM ON
- adding rules to the licenseRule.json files
- correcting the licensing given via REUSE.toml files

A lot of files are skipped during the license test,
but all are present in the source SBOM.
This is why corrections are needed before turning the
source SBOM check on.

Task-number: QTBUG-131434
Change-Id: Iabe0bee0ed0fc9de42ee69508eb0dd7d84601647
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 815ea62cc2f4a20b8c19e6d62146e07c0876ab19)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 56065dae710699f332ccb9f1e306b639a6b284aa)
---
 REUSE.toml              | 12 +++++-----
 coin/module_config.yaml |  3 +++
 licenseRule.json        | 49 +++++++++++++++++++++++++++++++++++++++--
 3 files changed, 57 insertions(+), 7 deletions(-)

diff --git a/REUSE.toml b/REUSE.toml
index 9474f351661..18dbbabe24b 100644
--- a/REUSE.toml
+++ b/REUSE.toml
@@ -11,7 +11,8 @@ path = ["src/core/doc/QtWebEngineDoc",
         "src/process/QtWebEngineProcess.exe.manifest",
         "src/webenginequick/ui/information.png",
         "src/webenginequick/ui/question.png",
-        "src/webenginewidgets/plugins/qwebengineview/images/qwebengineview.png"]
+        "src/webenginewidgets/plugins/qwebengineview/images/qwebengineview.png",
+        "src/pdf/plugins/imageformats/pdf/pdf.json"]
 precedence = "closest"
 comment = "module and plugin"
 SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
@@ -70,8 +71,9 @@ SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
 SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GPL-3.0-only"
 
 [[annotations]]
-path = ["**.pro", "**.qrc", "**CMakeLists.txt", ".cmake.conf", "**.yaml", "**.json",
-        "**.cfg", "**BLACKLIST", "**.plist", "**.plist.in", "**BUILD**.in"]
+path = ["**.pro", "**.qrc", "**CMakeLists.txt", ".cmake.conf", "**.yaml",
+        "**.cfg", "**BLACKLIST", "**.plist", "**.plist.in", "**BUILD**.in", "coin.nodes",
+        "coin/qt-installer-package-config.json", ".gitmodules"]
 precedence = "closest"
 comment = "build system"
 SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
@@ -85,14 +87,14 @@ SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
 SPDX-License-Identifier = "BSD-3-Clause"
 
 [[annotations]]
-path = ["**/doc/images/**", "examples/**", "tests/manual/examples/**", "**/doc/snippets/**"]
+path = ["examples/**", "tests/manual/examples/**", "**/doc/snippets/**"]
 comment = "this must be after the build system table because example and snippets take precedence over build system"
 precedence = "closest"
 SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
 SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause"
 
 [[annotations]]
-path = ["**.qdocconf", "config_help.txt", ".gitmodules"]
+path = ["**/doc/images/**", "**.qdocconf", "config_help.txt"]
 comment = "documentation"
 precedence = "closest"
 SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
diff --git a/coin/module_config.yaml b/coin/module_config.yaml
index 9c6e1d003e5..cceb2502a34 100644
--- a/coin/module_config.yaml
+++ b/coin/module_config.yaml
@@ -13,6 +13,9 @@ machine_type:
 
 instructions:
   Build:
+    - type: EnvironmentVariable
+      variableName: VERIFY_SOURCE_SBOM
+      variableValue: "ON"
     - type: EnvironmentVariable
       variableName: CMAKE_BUILD_TIMEOUT
       variableValue: "36000"
diff --git a/licenseRule.json b/licenseRule.json
index 5f78a7dc8c1..695e3a422fe 100644
--- a/licenseRule.json
+++ b/licenseRule.json
@@ -10,7 +10,11 @@
                      "Files with other endings can also be build system files"
                      ],
         "file_pattern_ending" : ["CMakeLists.txt", ".cmake", ".pro", ".pri", ".prf",
-                     "configure", "configure.bat", "cmake.in", "plist.in", "CMakeLists.txt.in", ".clang-format"],
+                     "configure", "configure.bat", "cmake.in", "plist.in", "CMakeLists.txt.in",
+                     ".clang-format", ".plist", ".qrc", "BLACKLIST", ".gitignore", ".gitattributes",
+                     ".tag", ".cmake.conf", ".yaml", "coin/qt-installer-package-config.json",
+                     "BUILD.root.gn.in", "BUILD.toolchain.gn.in", "BUILD.msvc.toolchain.gn.in",
+                     ".cfg", "coin.nodes", ".gitmodules"],
         "location" : {
             "" : {
                 "comment" : "Default",
@@ -44,7 +48,8 @@
     },
     {
         "comment" : "Files with the following endings are Documentation licensed.",
-        "file_pattern_ending" : [".qdoc", ".qdoc.in", ".qdocinc" , ".qdocconf", ".txt", "README", "qt_attribution.json"],
+        "file_pattern_ending" : [".qdoc", ".qdoc.in", ".qdocinc" , ".qdocconf", "README", "qt_attribution.json",
+                                 "REUSE.toml", "config_help.txt", "licenseRule.json"],
         "location" :{
             "" : {
                 "comment" : "",
@@ -64,6 +69,11 @@
                 "file type" : "module and plugin",
                 "spdx"      : ["LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only"]
             },
+            "dist/" : {
+                "comment" : "Default",
+                "file type" : "documentation",
+                "spdx"      : ["LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"]
+            },
             "src/" : {
                 "comment" : "Default",
                 "file type" : "module and plugin",
@@ -79,6 +89,11 @@
                 "file type" : "examples and snippets",
                 "spdx" : ["LicenseRef-Qt-Commercial OR BSD-3-Clause"]
             },
+            "(.*|examples).*doc/images/" : {
+                "comment" : "Default",
+                "file type" : "documentation",
+                "spdx" : ["LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"]
+            },
             "src/host/config\\.tests/" : {
                 "comment" : "Default",
                 "file type" : "build system",
@@ -98,6 +113,36 @@
                 "comment" : "Partially from Chromium",
                 "file type" : "module and plugin",
                 "spdx" : ["BSD-3-Clause"]
+            },
+            "tests/auto/widgets/qwebengine(view|script|page|history)/tst_qwebengine.*.cpp" : {
+                "comment" : "exception",
+                "file type" : "test",
+                "spdx" : ["LGPL-2.0-or-later"]
+            },
+            "tests/auto/widgets/accessibility/tst_accessibility.cpp" : {
+                "comment" : "exception",
+                "file type" : "test",
+                "spdx" : ["LGPL-2.0-or-later"]
+            },
+            "tests/auto/core/qwebengine(settings|frame)/tst_qwebengine.*.cpp" : {
+                "comment" : "exception",
+                "file type" : "test",
+                "spdx" : ["LGPL-2.0-or-later"]
+            },
+            "examples/webenginewidgets/contentmanipulation/jquery.min.js" : {
+                "comment" : "",
+                "file type" : "3rd party",
+                "spdx" : ["MIT"]
+            },
+            "src/core/ozone/(ozone_extra.gni|BUILD.gn)" : {
+                "comment" : "Chrominum",
+                "file type" : "3rd party",
+                "spdx" : ["BSD-3-Clause"]
+            },
+            "CHROMIUM_VERSION" : {
+                "comment" : "Chrominum",
+                "file type" : "3rd party",
+                "spdx" : ["CC0-1.0"]
             }
         }
     }

From 9ab8432ee9c64668e7413a526309874410c5ee4e Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Tue, 4 Mar 2025 16:31:36 +0000
Subject: [PATCH 290/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I3134fdeddb32f55509c8248abe408c94a78a8fa1
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 393eda358ed..3245aafc1ed 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 38a2283787edfe6f3d2f873599792c695a02afb0
+    ref: 7b4837d3e34a206ccbd3b921e65f1401b09066ee
     required: true
   ../qtpositioning:
-    ref: b78a3269dd1fafbd6ce7b314f609b00b70b9d6e3
+    ref: 83cc61df4afb3b81da03c9ec6d3536b32d60b07d
     required: false
   ../qttools:
-    ref: cab5a7992bd13c789882d6d25a62fa2fa272edbb
+    ref: feda5851ddced220d26ce80624fca527dde0a0ea
     required: false
   ../qtwebchannel:
-    ref: c5d6e02e2653551433035268daf0a0724900c408
+    ref: ca7d35059a0effe4fbdb57a1b5e604f3d815b12a
     required: false

From 596d1125105842250396de35f683c5ef77e1fe96 Mon Sep 17 00:00:00 2001
From: Topi Reinio <topi.reinio@qt.io>
Date: Mon, 17 Feb 2025 17:20:25 +0000
Subject: [PATCH 291/356] Doc: Add WebEngineDriver source directory to
 documentation build

While there is no documentation sources to parse there, the Chromium
code attribution script uses it as the output directory for the
generated 3rd party licenses. Add the directory to make QDoc
parse the generated output.

Fixes: QTBUG-133495
Pick-to: 6.5
Change-Id: I06643163e1b7791664afcfead90a91b65d3039af
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
Reviewed-by: Moss Heim <moss.heim@qt.io>
(cherry picked from commit d34d887f271df107ff0ec668cf85de149feeae6d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 706e582b2016090b68fe6b4ebdc6904dd92ec628)
---
 src/core/doc/qtwebengine.qdocconf | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/core/doc/qtwebengine.qdocconf b/src/core/doc/qtwebengine.qdocconf
index 25f55f154cf..ee875780165 100644
--- a/src/core/doc/qtwebengine.qdocconf
+++ b/src/core/doc/qtwebengine.qdocconf
@@ -70,6 +70,7 @@ headerdirs  += ../../core/api \
 
 sourcedirs  += ../../core/api \
                ../../core/doc \
+               ../../core/tools/webenginedriver \
                ../../webenginequick/api \
                ../../webenginequick/doc \
                ../../webenginewidgets/api \

From f0090ef1bad65e682659c0de445ccc7b3a38d15e Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Tue, 4 Mar 2025 15:17:19 +0100
Subject: [PATCH 292/356] NativeSkiaOutputDevice: Fix leaking texture

Release texture resources before unbinding the compositor. Otherwise we
don't have compositor to release texture after navigating to a new page.

Detected by Vulkan validation layer but supposedly affects all backends.

Amends 6781151fc Compositor: do not call unbind() from the base destructor

Change-Id: I4d9330de64a81c195091691e92164bd9eeb6d121
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 53b6d433d70d6992652d7031d8a6f0600a22eacd)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 2d2f63211b80a77cddfbb608f601051d7beebbd5)
---
 src/core/compositor/native_skia_output_device.cpp     | 2 ++
 src/core/render_widget_host_view_qt_delegate_item.cpp | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/core/compositor/native_skia_output_device.cpp b/src/core/compositor/native_skia_output_device.cpp
index 64688f9a018..aef0a8158f7 100644
--- a/src/core/compositor/native_skia_output_device.cpp
+++ b/src/core/compositor/native_skia_output_device.cpp
@@ -215,6 +215,8 @@ NativeSkiaOutputDevice::Buffer::Buffer(NativeSkiaOutputDevice *parent)
 
 NativeSkiaOutputDevice::Buffer::~Buffer()
 {
+    DCHECK(!textureCleanupCallback);
+
     if (m_scopedSkiaWriteAccess)
         endWriteSkia(false);
 
diff --git a/src/core/render_widget_host_view_qt_delegate_item.cpp b/src/core/render_widget_host_view_qt_delegate_item.cpp
index 94f786d1ca8..85d0c9111e8 100644
--- a/src/core/render_widget_host_view_qt_delegate_item.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_item.cpp
@@ -37,8 +37,8 @@ RenderWidgetHostViewQtDelegateItem::RenderWidgetHostViewQtDelegateItem(RenderWid
 
 RenderWidgetHostViewQtDelegateItem::~RenderWidgetHostViewQtDelegateItem()
 {
-    unbind(); // Compositor::Observer
     releaseTextureResources();
+    unbind(); // Compositor::Observer
     if (m_widgetDelegate) {
         m_widgetDelegate->Unbind();
         m_widgetDelegate->Destroy();

From f488766eb4f716158c7f993a8fe33e942d2da5cc Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Fri, 7 Mar 2025 15:08:05 +0100
Subject: [PATCH 293/356] Update Chromium

Submodule src/3rdparty c8dcfa48..b9e733ff:
* [Backport] Security bug 396481096
* [Backport] CVE-2024-11477 / Security bug 383772517
* [Backport] CVE-2025-1426: Heap buffer overflow in GPU
* [Backport] CVE-2025-1006: Use after free in Network
* [Backport] CVE-2025-0999: Heap buffer overflow in V8
* [Backport] CVE-2025-0996: Inappropriate implementation in Browser UI
* [Backport] CVE-2025-0998: Out of bounds memory access in V8
* [Backport] Security bug 390465670
* [Backport] Security bug 379418979
* [Backport] Security bug 378917565 (2/2)
* [Backport] Security bug 378917565 (1/2)
* [Backport] Security bug 359992017
* [Backport] CVE-2025-0762: Use after free in DevTools
* [fixup][ffmpeg] Fix building with system ffmpeg
* Disable DCHECK in property_tree.cc, layer_tree_impl.cc
* [fixup][msvc22] IWYU adding missing includes
* [fixup][msvc22] Add missing include for Supplement
* Fix invalid iterator access inside LockManager

Fixes: QTBUG-133881
Fixes: QTBUG-133889
Fixes: QTBUG-133883
Fixes: QTBUG-134132
Change-Id: I4ddef14e27dc7f5517571f6fca9dc074a109fba3
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
---
 CHROMIUM_VERSION                | 2 +-
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index 4a17fe015bd..c386131a578 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
 Based on Chromium version:                                      122.0.6261.171
-Patched with security patches up to Chromium version:           132.0.6834.111
+Patched with security patches up to Chromium version:           133.0.6943.141
diff --git a/src/3rdparty b/src/3rdparty
index c8dcfa4891c..b9e733fff4c 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit c8dcfa4891c8dcf733b0c6ecc6ddcfe781d4567d
+Subproject commit b9e733fff4cb73f6c417ec6c6d8fc78113ea1904
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index f77b380db33..59c946f0f1d 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1296,7 +1296,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "132.0.6834.111"; // FIXME: Remember to update
+    return "133.0.6943.141"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From 2b231fe3fd283eccb4df0dac6685eb68e1f6e9b1 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 6 Mar 2025 13:11:27 +0100
Subject: [PATCH 294/356] Fix modifier flags for lock keys on Linux

Amends 2dc642d3f Forward modifier flags for lock keys

Fixes: QTBUG-134107
Change-Id: I3bb5bff0fb43f2db4c91411f3d4e78469aa41747
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit e4785c85d61ae3a4694ddd105a66ef5869b36038)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 885c263791af9cddb1056af9ed092225099046f3)
---
 src/core/web_event_factory.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp
index fc15134eb27..52100048da0 100644
--- a/src/core/web_event_factory.cpp
+++ b/src/core/web_event_factory.cpp
@@ -1252,9 +1252,9 @@ static WebInputEvent::Modifiers lockKeyModifiers(const quint32 nativeModifiers)
 {
     unsigned result = 0;
     if (keyboardDriver() == KeyboardDriver::Xkb) {
-        if (nativeModifiers & 0x42) /* Caps_Lock */
+        if (nativeModifiers & 0x2) /* XCB_MOD_MASK_LOCK */
             result |= WebInputEvent::kCapsLockOn;
-        if (nativeModifiers & 0x4d) /* Num_Lock */
+        if (nativeModifiers & 0x10) /* XCB_MOD_MASK_2 */
             result |= WebInputEvent::kNumLockOn;
     } else if (keyboardDriver() == KeyboardDriver::Windows) {
         if (nativeModifiers & 0x100) /* CapsLock */

From 5425f083555c2b0761b4027bbceb41c513be0957 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Wed, 12 Mar 2025 15:16:20 +0100
Subject: [PATCH 295/356] Update Chromium

Submodule src/3rdparty b9e733ff..a3fcb1e2:
* [backport] CVE-2025-1915
* [backport] CVE-2025-1919
* [backport] CVE-2025-1921
* [backport] CVE-2025-1918

Pick-to: 6.8.3
Fixes: QTBUG-134644
Change-Id: I04cd7417930cd43653a914be05781d40ba5df626
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
---
 CHROMIUM_VERSION                | 2 +-
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index c386131a578..4ab0b3cdbcd 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
 Based on Chromium version:                                      122.0.6261.171
-Patched with security patches up to Chromium version:           133.0.6943.141
+Patched with security patches up to Chromium version:           134.0.6998.35
diff --git a/src/3rdparty b/src/3rdparty
index b9e733fff4c..a3fcb1e25e5 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit b9e733fff4cb73f6c417ec6c6d8fc78113ea1904
+Subproject commit a3fcb1e25e55e372d52c37722fad3074e8403d65
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 59c946f0f1d..b7aafd3a050 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1296,7 +1296,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "133.0.6943.141"; // FIXME: Remember to update
+    return "134.0.6998.35"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From a953359ed855ad91b848f22e7d38b13d0f2eb61e Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Wed, 12 Mar 2025 15:23:54 +0100
Subject: [PATCH 296/356] Update Chromium

Submodule src/3rdparty a3fcb1e2..55749ed0:
* [backport] CVE-2025-24201 2/2
* [backport] CVE-2025-24201 1/2
* [backport] CVE-2025-2136

Pick-to: 6.8.3
Fixes: QTBUG-134642
Change-Id: I5b7657b0f88f08365bdfd51818f1aa1279b14626
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
---
 CHROMIUM_VERSION                | 2 +-
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index 4ab0b3cdbcd..58db9e1086a 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
 Based on Chromium version:                                      122.0.6261.171
-Patched with security patches up to Chromium version:           134.0.6998.35
+Patched with security patches up to Chromium version:           134.0.6998.89
diff --git a/src/3rdparty b/src/3rdparty
index a3fcb1e25e5..55749ed0af5 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit a3fcb1e25e55e372d52c37722fad3074e8403d65
+Subproject commit 55749ed0af5869215b88007df0cba430746583ae
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index b7aafd3a050..5eea0c45622 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1296,7 +1296,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "134.0.6998.35"; // FIXME: Remember to update
+    return "134.0.6998.89"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From 8933c29eb1c6979beb2d26063d7861b7a999bd79 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Fri, 7 Feb 2025 13:24:22 +0100
Subject: [PATCH 297/356] Use printf-like syntax for qFatal, qWarning and qInfo
 where appropriate

Also use qUtf16Printable() where appropriate.

Merge conflict resolution for 6.8:
- compositor.cpp: adapt to more compositor type
- native_skia_output_device_opengl.cpp: no getGLErrorString() and no
  clearing GL error flags
- wgl_helper.cpp: no WGLHelper and no ::GetLastError to replace
- download_manager_delegate_qt.cpp: the qWarning is in another method
- egl_helper.cpp: no EGLHelper, qWarnings are in gl_context_qt.cpp
- glx_helper.cpp: no GLXHelper, qWarning is in
  native_skia_output_device_opengl.cpp
- surface_factory_qt.cpp: no EGLHelper::getLastEGLErrorString(), adapt
  fix to eglGetError()

Change-Id: I23e8a9b6b419f692dfd719f38c9a8a39086dffd2
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit 51d36fdd193d7acd597bed713e278fc26cd1f0e6)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit cbef11c876c3cc8a8859c8644e687235deb045dc)
---
 src/core/api/qwebenginescript.cpp                |  2 +-
 src/core/api/qwebengineurlscheme.cpp             | 14 +++++++++-----
 src/core/compositor/compositor.cpp               |  4 ++--
 .../native_skia_output_device_direct3d11.cpp     |  4 ++--
 .../native_skia_output_device_opengl.cpp         |  6 +++---
 .../native_skia_output_device_vulkan.cpp         |  4 ++--
 src/core/desktop_media_controller.cpp            |  4 ++--
 src/core/devtools_manager_delegate_qt.cpp        |  8 ++++++--
 src/core/download_manager_delegate_qt.cpp        |  3 ++-
 src/core/file_picker_controller.cpp              | 11 ++++++++---
 src/core/media_capture_devices_dispatcher.cpp    |  8 ++++++--
 src/core/net/url_request_custom_job_proxy.cpp    |  4 +++-
 src/core/ozone/gl_context_qt.cpp                 | 12 ++++++------
 src/core/ozone/surface_factory_qt.cpp            |  8 +++-----
 src/core/profile_io_data_qt.cpp                  |  2 +-
 src/core/profile_qt.cpp                          |  3 ++-
 src/core/web_contents_adapter.cpp                |  2 +-
 src/core/web_engine_context.cpp                  | 13 ++++++-------
 src/core/web_engine_library_info.cpp             | 16 ++++++++--------
 19 files changed, 73 insertions(+), 55 deletions(-)

diff --git a/src/core/api/qwebenginescript.cpp b/src/core/api/qwebenginescript.cpp
index 772dd7dfb2c..ab91576bd89 100644
--- a/src/core/api/qwebenginescript.cpp
+++ b/src/core/api/qwebenginescript.cpp
@@ -168,7 +168,7 @@ void QWebEngineScript::setSourceUrl(const QUrl &url)
     }
 
     if (!file.open(QIODevice::ReadOnly)) {
-        qWarning() << "Can't open user script " << url;
+        qWarning("Can't open user script %ls", qUtf16Printable(url.toString()));
         return;
     }
 
diff --git a/src/core/api/qwebengineurlscheme.cpp b/src/core/api/qwebengineurlscheme.cpp
index be56a304801..d2ca56f62d8 100644
--- a/src/core/api/qwebengineurlscheme.cpp
+++ b/src/core/api/qwebengineurlscheme.cpp
@@ -335,29 +335,33 @@ void QWebEngineUrlScheme::setFlags(Flags newValue)
 void QWebEngineUrlScheme::registerScheme(const QWebEngineUrlScheme &scheme)
 {
     if (scheme.d->name.empty()) {
-        qWarning() << "QWebEngineUrlScheme::registerScheme: Scheme name cannot be empty";
+        qWarning("QWebEngineUrlScheme::registerScheme: Scheme name cannot be empty");
         return;
     }
 
     bool needsPort = scheme.d->has_port_component();
     bool hasPort = scheme.d->default_port != url::PORT_UNSPECIFIED;
     if (needsPort && !hasPort) {
-        qWarning() << "QWebEngineUrlScheme::registerScheme: Scheme" << scheme.name() << "needs a default port";
+        qWarning("QWebEngineUrlScheme::registerScheme: Scheme %s needs a default port",
+                 scheme.d->name.data());
         return;
     }
 
     if (url::CustomScheme::FindScheme(scheme.d->name)) {
-        qWarning() << "QWebEngineUrlScheme::registerScheme: Scheme" << scheme.name() << "already registered";
+        qWarning("QWebEngineUrlScheme::registerScheme: Scheme %s already registered",
+                 scheme.d->name.data());
         return;
     }
 
     if (url::IsStandard(scheme.d->name.data(), url::Component(0, static_cast<int>(scheme.d->name.size())))) {
-        qWarning() << "QWebEngineUrlScheme::registerScheme: Scheme" << scheme.name() << "is a standard scheme";
+        qWarning("QWebEngineUrlScheme::registerScheme: Scheme %s is a standard scheme",
+                 scheme.d->name.data());
         return;
     }
 
     if (g_schemesLocked) {
-        qWarning() << "QWebEngineUrlScheme::registerScheme: Too late to register scheme" << scheme.name();
+        qWarning("QWebEngineUrlScheme::registerScheme: Too late to register scheme %s",
+                 scheme.d->name.data());
         return;
     }
 
diff --git a/src/core/compositor/compositor.cpp b/src/core/compositor/compositor.cpp
index 1ea92250501..9a99ddfd952 100644
--- a/src/core/compositor/compositor.cpp
+++ b/src/core/compositor/compositor.cpp
@@ -179,8 +179,8 @@ Compositor::Compositor(Type type) : m_type(type)
             break;
         }
     }
-    qCDebug(lcWebEngineCompositor, "QPA Platform Plugin: %s",
-            qPrintable(QGuiApplication::platformName()));
+    qCDebug(lcWebEngineCompositor, "QPA Platform Plugin: %ls",
+            qUtf16Printable(QGuiApplication::platformName()));
 }
 
 Compositor::~Compositor()
diff --git a/src/core/compositor/native_skia_output_device_direct3d11.cpp b/src/core/compositor/native_skia_output_device_direct3d11.cpp
index e2f33506890..ff469382f84 100644
--- a/src/core/compositor/native_skia_output_device_direct3d11.cpp
+++ b/src/core/compositor/native_skia_output_device_direct3d11.cpp
@@ -81,9 +81,9 @@ QSGTexture *NativeSkiaOutputDeviceDirect3D11::texture(QQuickWindow *win, uint32_
     ID3D11Texture2D *qtTexture = nullptr;
     hr = device1->OpenSharedResource1(sharedHandle, IID_PPV_ARGS(&qtTexture));
     if (FAILED(hr)) {
-        qWarning("D3D: Failed to share D3D11 texture (%s). This will result in failed rendering. "
+        qWarning("D3D: Failed to share D3D11 texture (%ls). This will result in failed rendering. "
                  "Report the bug, and try restarting with QTWEBENGINE_CHROMIUM_FLAGS=--disble-gpu",
-                 qPrintable(QSystemError::windowsComString(hr)));
+                 qUtf16Printable(QSystemError::windowsComString(hr)));
         ::CloseHandle(sharedHandle);
         return nullptr;
     }
diff --git a/src/core/compositor/native_skia_output_device_opengl.cpp b/src/core/compositor/native_skia_output_device_opengl.cpp
index 195d4dc72f3..deccd247b8d 100644
--- a/src/core/compositor/native_skia_output_device_opengl.cpp
+++ b/src/core/compositor/native_skia_output_device_opengl.cpp
@@ -97,9 +97,9 @@ x11::Pixmap XPixmapFromNativePixmap(const gfx::NativePixmap &nativePixmap)
                             .Sync();
 
     if (response.error) {
-        qWarning() << "Could not import the dma-buf as an XPixmap because "
-                      "PixmapFromBuffer() failed; error: "
-                   << response.error->ToString();
+        qWarning("Could not import the dma-buf as an XPixmap because PixmapFromBuffer() "
+                 "failed; error: %s",
+                 response.error->ToString().c_str());
         return x11::Pixmap::None;
     }
 
diff --git a/src/core/compositor/native_skia_output_device_vulkan.cpp b/src/core/compositor/native_skia_output_device_vulkan.cpp
index 1e3ba2d51c3..428dc06cf65 100644
--- a/src/core/compositor/native_skia_output_device_vulkan.cpp
+++ b/src/core/compositor/native_skia_output_device_vulkan.cpp
@@ -248,7 +248,7 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
     result = df->vkCreateImage(qtVulkanDevice, &importedImageCreateInfo, nullptr /* pAllocator */,
                                &importedImage);
     if (result != VK_SUCCESS)
-        qFatal() << "VULKAN: vkCreateImage failed result:" << result;
+        qFatal("VULKAN: vkCreateImage failed result: %d", static_cast<int>(result));
 
 #if defined(USE_OZONE)
     VkImportMemoryFdInfoKHR importMemoryHandleInfo = {
@@ -309,7 +309,7 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
     result = df->vkAllocateMemory(qtVulkanDevice, &memoryAllocateInfo, nullptr /* pAllocator */,
                                   &importedImageMemory);
     if (result != VK_SUCCESS)
-        qFatal() << "VULKAN: vkAllocateMemory failed result:" << result;
+        qFatal("VULKAN: vkAllocateMemory failed result: %d", static_cast<int>(result));
 
     df->vkBindImageMemory(qtVulkanDevice, importedImage, importedImageMemory, 0);
 
diff --git a/src/core/desktop_media_controller.cpp b/src/core/desktop_media_controller.cpp
index 09c1aea1914..2321d31047c 100644
--- a/src/core/desktop_media_controller.cpp
+++ b/src/core/desktop_media_controller.cpp
@@ -42,7 +42,7 @@ std::unique_ptr<DesktopMediaList> createMediaList(DesktopMediaType type)
         std::unique_ptr<webrtc::DesktopCapturer> screenCapturer =
                 webrtc::DesktopCapturer::CreateScreenCapturer(options);
         if (!screenCapturer) {
-            qWarning() << "Screen capturing is not available. Media list will be empty.";
+            qWarning("Screen capturing is not available. Media list will be empty.");
             return nullptr;
         }
         auto capturer = std::make_unique<DesktopCapturerWrapper>(std::move(screenCapturer));
@@ -52,7 +52,7 @@ std::unique_ptr<DesktopMediaList> createMediaList(DesktopMediaType type)
         std::unique_ptr<webrtc::DesktopCapturer> windowCapturer =
                 webrtc::DesktopCapturer::CreateWindowCapturer(options);
         if (!windowCapturer) {
-            qWarning() << "Window capturing is not available. Media list will be empty.";
+            qWarning("Window capturing is not available. Media list will be empty.");
             return nullptr;
         }
         auto capturer = std::make_unique<DesktopCapturerWrapper>(std::move(windowCapturer));
diff --git a/src/core/devtools_manager_delegate_qt.cpp b/src/core/devtools_manager_delegate_qt.cpp
index 838964d01be..b584ecb0de7 100644
--- a/src/core/devtools_manager_delegate_qt.cpp
+++ b/src/core/devtools_manager_delegate_qt.cpp
@@ -84,8 +84,12 @@ void DevToolsServerQt::parseAddressAndPort()
 
     m_port = portStr.toInt(&m_valid);
     m_valid = m_valid && (m_port > 0 && m_port < 65535);
-    if (!m_valid)
-        qWarning("Invalid port given for the inspector server \"%s\". Examples of valid input: \"12345\" or \"192.168.2.14:12345\" (with the address of one of this host's network interface).", qPrintable(portStr));
+    if (!m_valid) {
+        qWarning("Invalid port given for the inspector server \"%ls\". "
+                 "Examples of valid input: \"12345\" or \"192.168.2.14:12345\" "
+                 "(with the address of one of this host's network interface).",
+                 qUtf16Printable(portStr));
+    }
 }
 
 std::unique_ptr<content::DevToolsSocketFactory> DevToolsServerQt::CreateSocketFactory()
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index afd616e5468..bbe487fc918 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -220,7 +220,8 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
             QDir suggestedDir = QDir(suggestedFile.absolutePath());
             if (!suggestedDir.isRoot() || !suggestedDir.exists()) {
 #endif
-            qWarning("Creating download path failed, download cancelled: %s", suggestedFile.absolutePath().toUtf8().data());
+            qWarning("Creating download path failed, download cancelled: %ls",
+                     qUtf16Printable(suggestedFile.absolutePath()));
             info.accepted = false;
 #if defined(Q_OS_WIN)
             }
diff --git a/src/core/file_picker_controller.cpp b/src/core/file_picker_controller.cpp
index 8f6bd40702c..3aeb0f5da5f 100644
--- a/src/core/file_picker_controller.cpp
+++ b/src/core/file_picker_controller.cpp
@@ -96,7 +96,9 @@ void FilePickerController::accepted(const QStringList &files)
                     absolutePath += scheme.at(5) + ":/"_L1;
                 } else {
 #endif
-                    qWarning("Ignoring invalid item in FilePickerController::accepted(QStringList): %s", qPrintable(urlString));
+                    qWarning("Ignoring invalid item in "
+                             "FilePickerController::accepted(QStringList): %ls",
+                             qUtf16Printable(urlString));
                     continue;
 #if defined(Q_OS_WIN)
                 }
@@ -115,7 +117,9 @@ void FilePickerController::accepted(const QStringList &files)
                     absolutePath += u'/';
 #endif
                 } else {
-                    qWarning("Ignoring invalid item in FilePickerController::accepted(QStringList): %s", qPrintable(urlString));
+                    qWarning("Ignoring invalid item in "
+                             "FilePickerController::accepted(QStringList): %ls",
+                             qUtf16Printable(urlString));
                     continue;
                 }
             }
@@ -132,7 +136,8 @@ void FilePickerController::accepted(const QStringList &files)
                 continue;
             }
         }
-        qWarning("Ignoring invalid item in FilePickerController::accepted(QStringList): %s", qPrintable(urlString));
+        qWarning("Ignoring invalid item in FilePickerController::accepted(QStringList): %ls",
+                 qUtf16Printable(urlString));
     }
 
     FilePickerController::filesSelectedInChooser(stringList);
diff --git a/src/core/media_capture_devices_dispatcher.cpp b/src/core/media_capture_devices_dispatcher.cpp
index 73885b6f203..73cf2be6cac 100644
--- a/src/core/media_capture_devices_dispatcher.cpp
+++ b/src/core/media_capture_devices_dispatcher.cpp
@@ -361,8 +361,12 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content:
     bool securityOriginsMatch = (requestSecurityOrigin.host() == securityOrigin.host()
                                  && requestSecurityOrigin.scheme() == securityOrigin.scheme()
                                  && requestSecurityOrigin.port() == securityOrigin.port());
-    if (!securityOriginsMatch)
-        qWarning("Security origin mismatch for media access permission: %s requested and %s provided\n", qPrintable(requestSecurityOrigin.toString()), qPrintable(securityOrigin.toString()));
+    if (!securityOriginsMatch) {
+        qWarning("Security origin mismatch for media access permission: %ls requested "
+                 "and %ls provided\n",
+                 qUtf16Printable(requestSecurityOrigin.toString()),
+                 qUtf16Printable(securityOrigin.toString()));
+    }
 
     WebContentsAdapterClient::MediaRequestFlags requestFlags = mediaRequestFlagsForRequest(request);
     WebContentsAdapterClient::MediaRequestFlags finalFlags = requestFlags & authorizationFlags;
diff --git a/src/core/net/url_request_custom_job_proxy.cpp b/src/core/net/url_request_custom_job_proxy.cpp
index 54faddc6227..21d73730d4b 100644
--- a/src/core/net/url_request_custom_job_proxy.cpp
+++ b/src/core/net/url_request_custom_job_proxy.cpp
@@ -55,7 +55,9 @@ void URLRequestCustomJobProxy::reply(std::string contentType, QIODevice *device,
             m_client->m_charset = qcontentType.mid(cidx + 8).trimmed().toStdString();
             qcontentType = qcontentType.first(sidx);
         } else {
-            qWarning() << "QWebEngineUrlRequestJob::reply(): Unrecognized content-type format with ';'" << qcontentType;
+            qWarning("QWebEngineUrlRequestJob::reply(): Unrecognized content-type format with ';' "
+                     "%s",
+                     qcontentType.constData());
         }
     }
     m_client->m_mimeType = qcontentType.trimmed().toStdString();
diff --git a/src/core/ozone/gl_context_qt.cpp b/src/core/ozone/gl_context_qt.cpp
index f59c3fa14d0..ab6717b5e19 100644
--- a/src/core/ozone/gl_context_qt.cpp
+++ b/src/core/ozone/gl_context_qt.cpp
@@ -342,21 +342,21 @@ void EGLHelper::queryDmaBuf(const int width, const int height, int *fd, int *str
     EGLImage eglImage = m_functions->eglCreateImage(eglDisplay, eglContext, EGL_GL_TEXTURE_2D,
                                                     (EGLClientBuffer)textureId, NULL);
     if (eglImage == EGL_NO_IMAGE) {
-        qWarning() << "EGL: Failed to create EGLImage:"
-                   << ui::GetEGLErrorString(m_functions->eglGetError());
+        qWarning("EGL: Failed to create EGLImage: %s",
+                 ui::GetEGLErrorString(m_functions->eglGetError()));
         return;
     }
 
     int numPlanes = 0;
     if (!m_functions->eglExportDMABUFImageQueryMESA(eglDisplay, eglImage, nullptr, &numPlanes,
                                                     modifiers))
-        qWarning() << "EGL: Failed to retrieve the pixel format of the buffer:"
-                   << ui::GetEGLErrorString(m_functions->eglGetError());
+        qWarning("EGL: Failed to retrieve the pixel format of the buffer: %s",
+                 ui::GetEGLErrorString(m_functions->eglGetError()));
     Q_ASSERT(numPlanes == 1);
 
     if (!m_functions->eglExportDMABUFImageMESA(eglDisplay, eglImage, fd, stride, offset))
-        qWarning() << "EGL: Failed to retrieve the dma_buf file descriptor:"
-                   << ui::GetEGLErrorString(m_functions->eglGetError());
+        qWarning("EGL: Failed to retrieve the dma_buf file descriptor: %s",
+                 ui::GetEGLErrorString(m_functions->eglGetError()));
 
     m_functions->eglDestroyImage(eglDisplay, eglImage);
 #endif // QT_CONFIG(egl)
diff --git a/src/core/ozone/surface_factory_qt.cpp b/src/core/ozone/surface_factory_qt.cpp
index 835d2fed210..e2aec542d67 100644
--- a/src/core/ozone/surface_factory_qt.cpp
+++ b/src/core/ozone/surface_factory_qt.cpp
@@ -69,7 +69,7 @@ ui::GLOzone *SurfaceFactoryQt::GetGLOzone(const gl::GLImplementationParts &imple
             return impl.second.get();
     }
 
-    qFatal() << "GLOzone not found for" << gl::GetGLImplementationGLName(implementation);
+    qFatal("GLOzone not found for %s", gl::GetGLImplementationGLName(implementation));
     return nullptr;
 }
 
@@ -223,8 +223,7 @@ SurfaceFactoryQt::CreateNativePixmapFromHandle(
                 eglFun->eglCreateImage(eglDisplay, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT,
                                        (EGLClientBuffer)NULL, attrs.data());
         if (eglImage == EGL_NO_IMAGE_KHR) {
-            qFatal() << "Failed to import EGLImage:"
-                     << ui::GetEGLErrorString(eglFun->eglGetError());
+            qFatal("Failed to import EGLImage: %s", ui::GetEGLErrorString(eglFun->eglGetError()));
         }
 
         Q_ASSERT(numPlanes <= 3);
@@ -232,8 +231,7 @@ SurfaceFactoryQt::CreateNativePixmapFromHandle(
         int strides[3];
         int offsets[3];
         if (!eglFun->eglExportDMABUFImageMESA(eglDisplay, eglImage, fds, strides, offsets)) {
-            qFatal() << "Failed to export EGLImage:"
-                     << ui::GetEGLErrorString(eglFun->eglGetError());
+            qFatal("Failed to export EGLImage: %s", ui::GetEGLErrorString(eglFun->eglGetError()));
         }
 
         bufferHandle.modifier = handle.modifier;
diff --git a/src/core/profile_io_data_qt.cpp b/src/core/profile_io_data_qt.cpp
index 31a85a534c1..7bab41530dc 100644
--- a/src/core/profile_io_data_qt.cpp
+++ b/src/core/profile_io_data_qt.cpp
@@ -62,7 +62,7 @@ void ProfileIODataQt::shutdownOnUIThread()
 
     bool posted = content::BrowserThread::DeleteSoon(content::BrowserThread::IO, FROM_HERE, this);
     if (!posted) {
-        qWarning() << "Could not delete ProfileIODataQt on io thread !";
+        qWarning("Could not delete ProfileIODataQt on io thread !");
         delete this;
     }
 }
diff --git a/src/core/profile_qt.cpp b/src/core/profile_qt.cpp
index 5bb9599bc79..eaaa4f2536b 100644
--- a/src/core/profile_qt.cpp
+++ b/src/core/profile_qt.cpp
@@ -278,7 +278,8 @@ void ProfileQt::setupStoragePath()
     auto it = std::find(storagePaths.begin(), storagePaths.end(), thisStoragePath);
     if (it == storagePaths.end()) {
         if (storagePaths.size() >= (PATH_QT_END - PATH_QT_START)) {
-            qWarning() << "Number of profile paths exceeded " << PATH_QT_END - PATH_QT_START << ", storage may break";
+            qWarning("Number of profile paths exceeded %ull, storage may break",
+                     static_cast<qulonglong>(PATH_QT_END - PATH_QT_START));
             return;
         }
 
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index adbae106017..a34de4e501c 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -1071,7 +1071,7 @@ void WebContentsAdapter::runJavaScript(const QString &javaScript, quint32 worldI
     if (!rfh)
         return exit();
     if (!static_cast<content::RenderFrameHostImpl*>(rfh)->GetAssociatedLocalFrame()) {
-        qWarning() << "Local frame is gone, not running script";
+        qWarning("Local frame is gone, not running script");
         return exit();
     }
 
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 5eea0c45622..bc84b68fee3 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -201,7 +201,7 @@ class GPUInfo
         if (it != vendorIdMap.end())
             return it->second;
 
-        qWarning() << "Unknown Vendor ID:" << QStringLiteral("0x%1").arg(vendorId, 0, 16);
+        qWarning("Unknown Vendor ID: 0x%llx", vendorId);
         return Unknown;
     }
 
@@ -913,7 +913,7 @@ WebEngineContext::WebEngineContext()
 #endif
     } else {
         parsedCommandLine->AppendSwitch(sandbox::policy::switches::kNoSandbox);
-        qInfo() << "Sandboxing disabled by user.";
+        qInfo("Sandboxing disabled by user.");
     }
 
     // Do not advertise a feature we have removed at compile time
@@ -994,11 +994,10 @@ WebEngineContext::WebEngineContext()
                     found++;
             }
             if (found != requiredDeviceExtensions.size()) {
-                qWarning().nospace()
-                        << "Vulkan rendering may fail because " << deviceExtensionsVar
-                        << " environment variable is already set but it doesn't contain"
-                        << " some of the required Vulkan device extensions:\n"
-                        << qPrintable(requiredDeviceExtensions.join('\n'));
+                qWarning("Vulkan rendering may fail because %s environment variable is already "
+                         "set but it doesn't contain some of the required Vulkan device "
+                         "extensions:\n%s",
+                         deviceExtensionsVar, requiredDeviceExtensions.join('\n').constData());
             }
         } else {
             qputenv(deviceExtensionsVar, requiredDeviceExtensions.join(';'));
diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp
index f7ab89681eb..bb704926d33 100644
--- a/src/core/web_engine_library_info.cpp
+++ b/src/core/web_engine_library_info.cpp
@@ -152,8 +152,8 @@ QString subProcessPath()
         for (const QString &candidate : std::as_const(candidatePaths)) {
             if (QFileInfo::exists(candidate)) {
                 processPath = candidate;
-                qCDebug(webEngineLibraryInfoLog, "Qt WebEngine process path: %s",
-                        qPrintable(candidate));
+                qCDebug(webEngineLibraryInfoLog, "Qt WebEngine process path: %ls",
+                        qUtf16Printable(candidate));
                 break;
             }
         }
@@ -209,8 +209,8 @@ QString localesPath()
         for (const QString &candidate : std::as_const(candidatePaths)) {
             if (QFileInfo::exists(candidate % QDir::separator() % translationPakFilename)) {
                 potentialLocalesPath = candidate;
-                qCDebug(webEngineLibraryInfoLog, "Qt WebEngine locales path: %s",
-                        qPrintable(candidate));
+                qCDebug(webEngineLibraryInfoLog, "Qt WebEngine locales path: %ls",
+                        qUtf16Printable(candidate));
                 break;
             }
         }
@@ -276,8 +276,8 @@ QString dictionariesPath(bool showWarnings)
         for (const QString &candidate : std::as_const(candidatePaths)) {
             if (QFileInfo::exists(candidate)) {
                 potentialDictionariesPath = candidate;
-                qCDebug(webEngineLibraryInfoLog, "Qt WebEngine dictionaries path: %s",
-                        qPrintable(candidate));
+                qCDebug(webEngineLibraryInfoLog, "Qt WebEngine dictionaries path: %ls",
+                        qUtf16Printable(candidate));
                 break;
             }
         }
@@ -329,8 +329,8 @@ QString resourcesPath()
         for (const QString &candidate : std::as_const(candidatePaths)) {
             if (QFileInfo::exists(candidate % QDir::separator() % resourcesPakFilename)) {
                 potentialResourcesPath = candidate;
-                qCDebug(webEngineLibraryInfoLog, "Qt WebEngine resources path: %s",
-                        qPrintable(candidate));
+                qCDebug(webEngineLibraryInfoLog, "Qt WebEngine resources path: %ls",
+                        qUtf16Printable(candidate));
                 break;
             }
         }

From 317de2ae549b5efd150abe53dc7010e42d810ac4 Mon Sep 17 00:00:00 2001
From: Topi Reinio <topi.reinio@qt.io>
Date: Wed, 5 Mar 2025 13:28:18 +0000
Subject: [PATCH 298/356] Doc: Instruct QDoc to ignore output file overwrite
 warnings

We have two components (WebEngine Core, WebEngineDriver) that
both have associated 3rd party attributions originating from
Chromium. These attributions overlap each other, and cause
multiple `Output file already exist` warnings when generating
the documentation.

Instruct QDoc to ignore these, in order to reduce noise
during documentation build.

Fixes: QTBUG-134416
Change-Id: I57842910fe4835ac5f536a757d3347fa7cee636a
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
(cherry picked from commit b0f0471d44fbe0e61e4901625f01a6626a3fe981)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 6435f29112c6c56ad6c6be5182c169b93296e2f4)
---
 src/core/doc/qtwebengine.qdocconf | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/core/doc/qtwebengine.qdocconf b/src/core/doc/qtwebengine.qdocconf
index ee875780165..d67c6c69fea 100644
--- a/src/core/doc/qtwebengine.qdocconf
+++ b/src/core/doc/qtwebengine.qdocconf
@@ -98,5 +98,9 @@ navigation.qmltypespage = "Qt WebEngine QML Types"
 # \QWE macro expands to 'Qt WebEngine' without auto-linking anywhere.
 macro.QWE    = "Qt \\WebEngine"
 
+# QTBUG-134416: Ignore overwrite warnings, attribution
+# documentation generates many of these
+spurious += "Output file already exists, overwriting .*"
+
 # Enforce zero documentation warnings
 warninglimit = 2

From a3c48b2d3eb5e1fcc28141eb4221562107185251 Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Wed, 19 Feb 2025 15:06:39 +0100
Subject: [PATCH 299/356] Docs: fix typo

Change-Id: I0e973f599218a719aa8cff0ce65c4d35cefe4b3f
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit cf84eee54f218a01bc85d428501c7c7bba347b3e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 7c7af8ecd0dc4ed144b915a59283046ccae55c99)
---
 .../webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc b/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc
index a312da3ad1e..8523ed6896f 100644
--- a/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc
+++ b/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc
@@ -180,7 +180,7 @@
 
     We add a menu item to the context menu, so that users can right-click to have an inspector
     opened in a new window. We override QWebEngineView::contextMenuEvent and use
-    QWebEnginePage::createStandardContextMenu to create a default QMenu with a
+    QWebEngineView::createStandardContextMenu to create a default QMenu with a
     default list of QWebEnginePage::WebAction actions.
 
     The default name for QWebEnginePage::InspectElement action is

From aebd217c579d4beb29b66de992c54f148372039c Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Tue, 23 Jul 2024 10:53:48 +0200
Subject: [PATCH 300/356] Fix webrtc manual test

Fixed compilation error due to mismatched signatures

Fixed crash when no selection was made

Change-Id: If1e6a70a40c04e211f5f7c9be99ac45642a11d63
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit 0e48cf6a96dbe78c33d6374d499126a7979ae5d8)
Reviewed-by: Moss Heim <moss.heim@qt.io>
---
 tests/manual/widgets/webrtc/main.cpp | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/tests/manual/widgets/webrtc/main.cpp b/tests/manual/widgets/webrtc/main.cpp
index 7eecf0735a0..a6c2ff8d43c 100644
--- a/tests/manual/widgets/webrtc/main.cpp
+++ b/tests/manual/widgets/webrtc/main.cpp
@@ -28,7 +28,7 @@ class Page : public QWebEnginePage
 public:
     Page(QWebEngineProfile *profile, QObject *parent = nullptr);
 private slots:
-    void handlePermissionRequest(const QUrl &origin, Feature feature);
+    void handlePermissionRequest(QWebEnginePermission permission);
     void handleDesktopMediaRequest(const QWebEngineDesktopMediaRequest &request);
 };
 
@@ -66,13 +66,21 @@ void Page::handleDesktopMediaRequest(const QWebEngineDesktopMediaRequest &reques
     windowsView->setModel(windowsModel);
 
     if (dialog.exec() == QDialog::Accepted) {
-        if (mediaPickerDialog.tabWidget->currentIndex() == 0)
-            request.selectWindow(windowsView->selectionModel()->selectedIndexes().first());
-        else
-            request.selectScreen(screensView->selectionModel()->selectedIndexes().first());
-    } else {
-        request.cancel();
+        if (mediaPickerDialog.tabWidget->currentIndex() == 0) {
+            auto list = windowsView->selectionModel()->selectedIndexes();
+            if (!list.empty()) {
+                request.selectWindow(list.first());
+                return;
+            }
+        } else {
+            auto list = screensView->selectionModel()->selectedIndexes();
+            if (!list.empty()) {
+                request.selectScreen(list.first());
+                return;
+            }
+        }
     }
+    request.cancel();
 }
 
 int main(int argc, char *argv[])

From 802c43c199a8cb75f43210d14f5777f3db332fce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucie=20G=C3=A9rard?= <lucie.gerard@qt.io>
Date: Tue, 11 Mar 2025 21:06:18 +0100
Subject: [PATCH 301/356] Update licensing of files with infrastructure type

A QUIP 18[1] update sets git files, REUSE.toml and licenseRule.json
as infrastructure type files. They are licensed with:
LicenseRef-Qt-Commercial OR BSD-3-Clause

[1]: https://contribute.qt-project.org/quips/18

Change-Id: I4ff3f1ce79565153d23a625172c2760dba8e4a8e
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
(cherry picked from commit 0546e3d722350c31d04f9a74446d02f79c928fbe)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 775f6976b5c6437d9189dd592945c23b535d0923)
---
 REUSE.toml       |  12 +--
 licenseRule.json | 242 +++++++++++++++++++++++++----------------------
 2 files changed, 133 insertions(+), 121 deletions(-)

diff --git a/REUSE.toml b/REUSE.toml
index 18dbbabe24b..faaa2093da1 100644
--- a/REUSE.toml
+++ b/REUSE.toml
@@ -73,18 +73,18 @@ SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GPL-3.0-only"
 [[annotations]]
 path = ["**.pro", "**.qrc", "**CMakeLists.txt", ".cmake.conf", "**.yaml",
         "**.cfg", "**BLACKLIST", "**.plist", "**.plist.in", "**BUILD**.in", "coin.nodes",
-        "coin/qt-installer-package-config.json", ".gitmodules"]
+        "coin/qt-installer-package-config.json", ".tag"]
 precedence = "closest"
 comment = "build system"
 SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
 SPDX-License-Identifier = "BSD-3-Clause"
 
 [[annotations]]
-path = [".tag", "**/.gitattributes", "**.gitignore"]
+path = ["**/.gitattributes", "**.gitignore", ".gitmodules", "**.gitreview"]
 precedence = "closest"
-comment = "version control system. Licensed as build system"
+comment = "version control system. Infrastructure"
 SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
-SPDX-License-Identifier = "BSD-3-Clause"
+SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause"
 
 [[annotations]]
 path = ["examples/**", "tests/manual/examples/**", "**/doc/snippets/**"]
@@ -102,10 +102,10 @@ SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-on
 
 [[annotations]]
 path = ["**.toml", "licenseRule.json"]
-comment = "documentation"
+comment = "infrastructure"
 precedence = "override"
 SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
-SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"
+SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause"
 
 [[annotations]]
 path = ["**/qt_attribution.json"]
diff --git a/licenseRule.json b/licenseRule.json
index 695e3a422fe..4ae4a4e8453 100644
--- a/licenseRule.json
+++ b/licenseRule.json
@@ -1,6 +1,6 @@
 [
     {
-        "comment" : ["file_pattern_ending: strings matched against the end of a file name.",
+        "comment": ["file_pattern_ending: strings matched against the end of a file name.",
                      "location keys: regular expression matched against the beginning of",
                      "the file path (relative to the git submodule root).",
                      "spdx: list of SPDX-License-Expression's allowed in the matching files.",
@@ -9,140 +9,152 @@
                      "unless they are examples",
                      "Files with other endings can also be build system files"
                      ],
-        "file_pattern_ending" : ["CMakeLists.txt", ".cmake", ".pro", ".pri", ".prf",
+        "file_pattern_ending": ["CMakeLists.txt", ".cmake", ".pro", ".pri", ".prf",
                      "configure", "configure.bat", "cmake.in", "plist.in", "CMakeLists.txt.in",
-                     ".clang-format", ".plist", ".qrc", "BLACKLIST", ".gitignore", ".gitattributes",
+                     ".clang-format", ".plist", ".qrc", "BLACKLIST",
                      ".tag", ".cmake.conf", ".yaml", "coin/qt-installer-package-config.json",
                      "BUILD.root.gn.in", "BUILD.toolchain.gn.in", "BUILD.msvc.toolchain.gn.in",
-                     ".cfg", "coin.nodes", ".gitmodules"],
-        "location" : {
-            "" : {
-                "comment" : "Default",
-                "file type" : "build system",
-                "spdx"      : ["BSD-3-Clause"]
-            },
-            "(.*)(examples/|snippets/)" : {
-                "comment" : "Example takes precedence",
-                "file type" : "examples and snippets",
-                "spdx" : ["LicenseRef-Qt-Commercial OR BSD-3-Clause"]
+                     "BUILD.clang-cl.toolchain.gn.in", ".cfg", "coin.nodes"],
+        "location": {
+            "": {
+                "comment": "Default",
+                "file type": "build system",
+                "spdx": ["BSD-3-Clause"]
+            },
+            "(.*)(examples/|snippets/)": {
+                "comment": "Example takes precedence",
+                "file type": "examples and snippets",
+                "spdx": ["LicenseRef-Qt-Commercial OR BSD-3-Clause"]
             }
         }
     },
     {
-        "comments" : ["Files with the following endings are Tool licensed,",
+        "comments": ["Files with the following endings are infrastructure licensed"],
+        "file_pattern_ending": [".gitattributes", ".gitignore", ".gitmodules", ".gitreview",
+                                "clang-format", "licenseRule.json", "REUSE.toml"],
+        "location":{
+            "": {
+                "comment": "Default",
+                "file type": "infrastructure",
+                "spdx": ["LicenseRef-Qt-Commercial OR BSD-3-Clause"]
+            }
+        }
+    },
+    {
+        "comments": ["Files with the following endings are Tool licensed,",
                       "unless they are examples.",
                       "Files with other endings can also be tool files."],
-        "file_pattern_ending" : [".sh", ".py", ".pl", ".bat", ".ps1"],
-        "location" :{
-            "" : {
-                "comment" : "Default",
-                "file type" : "tools and utils",
-                "spdx"      : ["LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0"]
-            },
-            "(.*)(examples/|snippets/)" : {
-                "comment" : "Example takes precedence",
-                "file type" : "examples and snippets",
-                "spdx" : ["LicenseRef-Qt-Commercial OR BSD-3-Clause"]
+        "file_pattern_ending": [".sh", ".py", ".pl", ".bat", ".ps1"],
+        "location":{
+            "": {
+                "comment": "Default",
+                "file type": "tools and utils",
+                "spdx": ["LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0"]
+            },
+            "(.*)(examples/|snippets/)": {
+                "comment": "Example takes precedence",
+                "file type": "examples and snippets",
+                "spdx": ["LicenseRef-Qt-Commercial OR BSD-3-Clause"]
             }
         }
     },
     {
-        "comment" : "Files with the following endings are Documentation licensed.",
-        "file_pattern_ending" : [".qdoc", ".qdoc.in", ".qdocinc" , ".qdocconf", "README", "qt_attribution.json",
-                                 "REUSE.toml", "config_help.txt", "licenseRule.json"],
-        "location" :{
-            "" : {
-                "comment" : "",
-                "file type" : "documentation",
-                "spdx"      : ["LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"]
+        "comment": "Files with the following endings are Documentation licensed.",
+        "file_pattern_ending": [".qdoc", ".qdoc.in", ".qdocinc" , ".qdocconf", "README", "qt_attribution.json",
+                                 "config_help.txt"],
+        "location":{
+            "": {
+                "comment": "",
+                "file type": "documentation",
+                "spdx": ["LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"]
             }
         }
     },
     {
-        "comment" : ["All other files",
+        "comment": ["All other files",
                      "The licensing is defined only by the file location in the Qt module repository.",
                      "NO <file_pattern_ending> key for this case!",
                      "This needs to be the last entry of the file."],
-        "location" : {
-            "" : {
-                "comment" : "Default",
-                "file type" : "module and plugin",
-                "spdx"      : ["LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only"]
-            },
-            "dist/" : {
-                "comment" : "Default",
-                "file type" : "documentation",
-                "spdx"      : ["LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"]
-            },
-            "src/" : {
-                "comment" : "Default",
-                "file type" : "module and plugin",
-                "spdx"      : ["LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only"]
-            },
-            "tests/" : {
-                "comment" : "Default",
-                "file type" : "test",
-                "spdx" : ["LicenseRef-Qt-Commercial OR GPL-3.0-only"]
-            },
-            "(.*)(examples/|snippets/)" : {
-                "comment" : "Default",
-                "file type" : "examples and snippets",
-                "spdx" : ["LicenseRef-Qt-Commercial OR BSD-3-Clause"]
-            },
-            "(.*|examples).*doc/images/" : {
-                "comment" : "Default",
-                "file type" : "documentation",
-                "spdx" : ["LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"]
-            },
-            "src/host/config\\.tests/" : {
-                "comment" : "Default",
-                "file type" : "build system",
-                "spdx" : ["BSD-3-Clause"]
-            },
-            "src/core/clipboard_util_win.cpp" : {
-                "comment" : "Partially from Chromium",
-                "file type" : "module and plugin",
-                "spdx" : ["BSD-3-Clause"]
-            },
-            "src/core/common/qt_messages.*" : {
-                "comment" : "Partially from Chromium",
-                "file type" : "module and plugin",
-                "spdx" : ["BSD-3-Clause"]
-            },
-            "src/core/tools/qwebengine_convert_dict/main.cpp" : {
-                "comment" : "Partially from Chromium",
-                "file type" : "module and plugin",
-                "spdx" : ["BSD-3-Clause"]
-            },
-            "tests/auto/widgets/qwebengine(view|script|page|history)/tst_qwebengine.*.cpp" : {
-                "comment" : "exception",
-                "file type" : "test",
-                "spdx" : ["LGPL-2.0-or-later"]
-            },
-            "tests/auto/widgets/accessibility/tst_accessibility.cpp" : {
-                "comment" : "exception",
-                "file type" : "test",
-                "spdx" : ["LGPL-2.0-or-later"]
-            },
-            "tests/auto/core/qwebengine(settings|frame)/tst_qwebengine.*.cpp" : {
-                "comment" : "exception",
-                "file type" : "test",
-                "spdx" : ["LGPL-2.0-or-later"]
-            },
-            "examples/webenginewidgets/contentmanipulation/jquery.min.js" : {
-                "comment" : "",
-                "file type" : "3rd party",
-                "spdx" : ["MIT"]
-            },
-            "src/core/ozone/(ozone_extra.gni|BUILD.gn)" : {
-                "comment" : "Chrominum",
-                "file type" : "3rd party",
-                "spdx" : ["BSD-3-Clause"]
-            },
-            "CHROMIUM_VERSION" : {
-                "comment" : "Chrominum",
-                "file type" : "3rd party",
-                "spdx" : ["CC0-1.0"]
+        "location": {
+            "": {
+                "comment": "Default",
+                "file type": "module and plugin",
+                "spdx": ["LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only"]
+            },
+            "dist/": {
+                "comment": "Default",
+                "file type": "documentation",
+                "spdx": ["LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"]
+            },
+            "src/": {
+                "comment": "Default",
+                "file type": "module and plugin",
+                "spdx": ["LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only"]
+            },
+            "tests/": {
+                "comment": "Default",
+                "file type": "test",
+                "spdx": ["LicenseRef-Qt-Commercial OR GPL-3.0-only"]
+            },
+            "(.*)(examples/|snippets/)": {
+                "comment": "Default",
+                "file type": "examples and snippets",
+                "spdx": ["LicenseRef-Qt-Commercial OR BSD-3-Clause"]
+            },
+            "(.*|examples).*doc/images/": {
+                "comment": "Default",
+                "file type": "documentation",
+                "spdx": ["LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"]
+            },
+            "src/host/config\\.tests/": {
+                "comment": "Default",
+                "file type": "build system",
+                "spdx": ["BSD-3-Clause"]
+            },
+            "src/core/clipboard_util_win.cpp": {
+                "comment": "Partially from Chromium",
+                "file type": "module and plugin",
+                "spdx": ["BSD-3-Clause"]
+            },
+            "src/core/common/qt_messages.*": {
+                "comment": "Partially from Chromium",
+                "file type": "module and plugin",
+                "spdx": ["BSD-3-Clause"]
+            },
+            "src/core/tools/qwebengine_convert_dict/main.cpp": {
+                "comment": "Partially from Chromium",
+                "file type": "module and plugin",
+                "spdx": ["BSD-3-Clause"]
+            },
+            "tests/auto/widgets/qwebengine(view|script|page|history)/tst_qwebengine.*.cpp": {
+                "comment": "exception",
+                "file type": "test",
+                "spdx": ["LGPL-2.0-or-later"]
+            },
+            "tests/auto/widgets/accessibility/tst_accessibility.cpp": {
+                "comment": "exception",
+                "file type": "test",
+                "spdx": ["LGPL-2.0-or-later"]
+            },
+            "tests/auto/core/qwebengine(settings|frame)/tst_qwebengine.*.cpp": {
+                "comment": "exception",
+                "file type": "test",
+                "spdx": ["LGPL-2.0-or-later"]
+            },
+            "examples/webenginewidgets/contentmanipulation/jquery.min.js": {
+                "comment": "",
+                "file type": "3rd party",
+                "spdx": ["MIT"]
+            },
+            "src/core/ozone/(ozone_extra.gni|BUILD.gn)": {
+                "comment": "Chrominum",
+                "file type": "3rd party",
+                "spdx": ["BSD-3-Clause"]
+            },
+            "CHROMIUM_VERSION": {
+                "comment": "Chrominum",
+                "file type": "3rd party",
+                "spdx": ["CC0-1.0"]
             }
         }
     }

From 6c2e507e6139c662d00a48cd1aca53452cf8b3ec Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Thu, 20 Mar 2025 10:26:58 +0100
Subject: [PATCH 302/356] Add missing TOOLKIT_QT define

When compiling "api" part or "covert_dict" targets
we never set TOOLKIT_QT, meaning BUILDFLAG(IS_QTWEBENGINE)
is not set for headers included from "api" sources.
This can lead do unexpected side effects.

Change-Id: I149da31725df94a4911562213a73f84aeb110ea8
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit f88512537efd173eb8aaebe8522e173e40b5363d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 575a8c4a58bb2b9b0ae9e36cf8877f14ef7b6d5f)
---
 src/core/api/CMakeLists.txt                           | 1 +
 src/core/tools/qwebengine_convert_dict/CMakeLists.txt | 1 +
 2 files changed, 2 insertions(+)

diff --git a/src/core/api/CMakeLists.txt b/src/core/api/CMakeLists.txt
index 9ca610d3299..3d2a153a39e 100644
--- a/src/core/api/CMakeLists.txt
+++ b/src/core/api/CMakeLists.txt
@@ -45,6 +45,7 @@ qt_internal_add_module(WebEngineCore
         qwebenginewebauthuxrequest.cpp qwebenginewebauthuxrequest.h qwebenginewebauthuxrequest_p.h
     DEFINES
         BUILDING_CHROMIUM
+        TOOLKIT_QT
     INCLUDE_DIRECTORIES
         ../
         ../../3rdparty/chromium
diff --git a/src/core/tools/qwebengine_convert_dict/CMakeLists.txt b/src/core/tools/qwebengine_convert_dict/CMakeLists.txt
index fcc11bdcb8c..4d36ca004fb 100644
--- a/src/core/tools/qwebengine_convert_dict/CMakeLists.txt
+++ b/src/core/tools/qwebengine_convert_dict/CMakeLists.txt
@@ -7,6 +7,7 @@ if(QT_FEATURE_webengine_spellchecker AND NOT CMAKE_CROSSCOMPILING)
         TARGET_DESCRIPTION "QtWebEngine Dictionary Conversion Tool"
         INSTALL_DIR ${INSTALL_LIBEXECDIR}
         TOOLS_TARGET WebEngineCore
+        DEFINES TOOLKIT_QT
         SOURCES main.cpp
         INCLUDE_DIRECTORIES
             ../../../3rdparty/chromium/third_party/abseil-cpp

From d69ed3f38b51817d60460bf869826cd3b05b5603 Mon Sep 17 00:00:00 2001
From: Paul Wicking <paul.wicking@qt.io>
Date: Mon, 17 Feb 2025 09:21:53 +0100
Subject: [PATCH 303/356] Add .gitreview file

`git-review` is a command line tool for interacting with Gerrit.
Some IDEs offer support for this tool, either natively or through
plugins. The tool relies on a configuration file, .gitreview. Adding
this configuration file to our repositories simplifies initial setup
for contributors that use the tool directly or through their IDE of
choice.

The configuration file adds a remote called 'gerrit'. This is the
default for the tool, and also the name set for
codereview.qt-project.org by Qt's `init-repository` script. Thus,
the configuration should work seamlessly alongside other repository
helpers.

Task-number: QTBUG-132604
Change-Id: Ib122816f9e73a19406b7227ec401f7cf0574b52e
Reviewed-by: Samuel Gaist <samuel.gaist@idiap.ch>
(cherry picked from commit 1d3793644519ca93a50cbc3173d11be39a4840f7)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 6e1cea1afd4ff72ca12538b7d5eafb59cd2b09c8)
---
 .gitreview | 4 ++++
 1 file changed, 4 insertions(+)
 create mode 100644 .gitreview

diff --git a/.gitreview b/.gitreview
new file mode 100644
index 00000000000..a17ec896fca
--- /dev/null
+++ b/.gitreview
@@ -0,0 +1,4 @@
+[gerrit]
+host=codereview.qt-project.org
+project=qt/qtwebengine
+defaultbranch=dev

From b54d2fa59023c6c6908c151b7b9ee2ea9e3b1699 Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Mon, 24 Mar 2025 13:07:10 +0100
Subject: [PATCH 304/356] CMake: fix example target name conflict

This conflicts with a target named server in qtbase benchmarks. Give the
targets more unique names.

Change-Id: I52d71e37c976ada5bf48813ecaf200923b07aef6
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit 211dc916fd0a1f57171c634e0849c84cd1fb8a97)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 9682155a1360ad9af779c9d3a06b106667dc3ce3)
---
 .../clientcertificate/CMakeLists.txt             | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/examples/webenginewidgets/clientcertificate/CMakeLists.txt b/examples/webenginewidgets/clientcertificate/CMakeLists.txt
index 97c9393ffce..ef1f9a6d415 100644
--- a/examples/webenginewidgets/clientcertificate/CMakeLists.txt
+++ b/examples/webenginewidgets/clientcertificate/CMakeLists.txt
@@ -14,20 +14,20 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/clientcertificat
 
 find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineWidgets)
 
-qt_add_executable(server
+qt_add_executable(example_cert_server
     server.cpp
 )
 
-qt_add_executable(client
+qt_add_executable(example_cert_client
     client.cpp
 )
 
-set_target_properties(client PROPERTIES
+set_target_properties(example_cert_client PROPERTIES
     WIN32_EXECUTABLE TRUE
     MACOSX_BUNDLE TRUE
 )
 
-qt_add_resources(client "client"
+qt_add_resources(example_cert_client "client"
     PREFIX
         "/"
     FILES
@@ -35,7 +35,7 @@ qt_add_resources(client "client"
        "resources/client.key"
 )
 
-qt_add_resources(server "server"
+qt_add_resources(example_cert_server "server"
     PREFIX
         "/"
     FILES
@@ -44,16 +44,16 @@ qt_add_resources(server "server"
        "resources/ca.pem"
 )
 
-target_link_libraries(client PUBLIC
+target_link_libraries(example_cert_client PUBLIC
     Qt::WebEngineWidgets
 )
 
-target_link_libraries(server PUBLIC
+target_link_libraries(example_cert_server PUBLIC
     Qt::Core
     Qt::Network
 )
 
-install(TARGETS server client
+install(TARGETS example_cert_server example_cert_client
     RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
     BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
     LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"

From e4251fb5b4f8fcae6ba4412b786bdb8b41da6d6c Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <aacid@kde.org>
Date: Sat, 22 Mar 2025 02:26:10 +0100
Subject: [PATCH 305/356] Fix RenderWidgetHostViewQtDelegateItem::viewGeometry

We need to map the item not the scene

Task-number: QTBUG-135040
Change-Id: I1fa2087f822d3fb7fcb431592c222c2e7ddb5e34
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit e2185036c9dab55b2984a5923163482dbb4b32e5)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 538326e6dd2ff571a10c5fd60273ee02bc5f0060)
---
 ...nder_widget_host_view_qt_delegate_item.cpp |  4 +-
 .../tst_qquickwebengineview.cpp               | 69 +++++++++++++++++++
 2 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/src/core/render_widget_host_view_qt_delegate_item.cpp b/src/core/render_widget_host_view_qt_delegate_item.cpp
index 85d0c9111e8..0c38f0f7a02 100644
--- a/src/core/render_widget_host_view_qt_delegate_item.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_item.cpp
@@ -56,8 +56,8 @@ void RenderWidgetHostViewQtDelegateItem::initAsPopup(const QRect &screenRect)
 QRectF RenderWidgetHostViewQtDelegateItem::viewGeometry() const
 {
     // Transform the entire rect to find the correct top left corner.
-    const QPointF p1 = mapToGlobal(mapFromScene(QPointF(0, 0)));
-    const QPointF p2 = mapToGlobal(mapFromScene(QPointF(width(), height())));
+    const QPointF p1 = mapToGlobal(mapFromItem(this, QPointF(0, 0)));
+    const QPointF p2 = mapToGlobal(mapFromItem(this, QPointF(width(), height())));
     QRectF geometry = QRectF(p1, p2).normalized();
     // But keep the size untransformed to behave like other QQuickItems.
     geometry.setSize(size());
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index 1fdccb7d4b3..1d85c495cbe 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -76,6 +76,7 @@ private Q_SLOTS:
 #if QT_CONFIG(accessibility)
     void focusChild_data();
     void focusChild();
+    void accessibilityRect();
 #endif
     void htmlSelectPopup();
     void savePage_data();
@@ -1254,6 +1255,74 @@ void tst_QQuickWebEngineView::focusChild()
     // <html> -> <body> -> <input>
     QCOMPARE(traverseToWebDocumentAccessibleInterface(iface)->child(0)->child(0), iface->focusChild());
 }
+
+void tst_QQuickWebEngineView::accessibilityRect()
+{
+    auto *engine = new QQmlEngine(this);
+    auto *component = new QQmlComponent(engine, this);
+    component->setData(QByteArrayLiteral("import QtQuick\n"
+                                           "import QtWebEngine\n"
+                                           "Window {\n"
+                                           " visible: true; width: 600; height: 400\n"
+                                           " Text { id: textId; text: \"text\"; width: 100; Accessible.focusable: true; Accessible.name: \"text\" }\n"
+                                           " WebEngineView { anchors.left: textId.right; anchors.top: textId.bottom; anchors.right: parent.right; anchors.bottom: parent.bottom }\n"
+                                           "}")
+                         , QUrl());
+    QObject *rootObject = component->create();
+    QVERIFY(rootObject);
+
+    QQuickWebEngineView *webView = rootObject->findChild<QQuickWebEngineView*>();
+    QVERIFY(webView);
+
+    webView->loadHtml("<html><body bgcolor=\"red\"><input type='text' id='input1' /></body></html>");
+    QVERIFY(waitForLoadSucceeded(webView));
+
+    QAccessibleInterface *rootObjectIface = QAccessible::queryAccessibleInterface(rootObject);
+    QVERIFY(rootObjectIface);
+    QCOMPARE(rootObjectIface->childCount(), 2);
+
+    QAccessibleInterface *textIface = rootObjectIface->child(0);
+    QVERIFY(textIface);
+    QCOMPARE(textIface->role(), QAccessible::StaticText);
+
+    QCOMPARE(textIface->rect().width(), 100);
+    QVERIFY(textIface->rect().height() > 0);
+
+    // It takes a while for the webIface to get its width, unfortunately we can't have a
+    // QTRY_COMPARE since it seems in some platforms the iface gets recreated and we end up
+    // accessible the wrong pointer, so roll up our own try+compare
+    QAccessibleInterface *webIface = nullptr;
+    QElapsedTimer t;
+    t.start();
+    bool isWebIfaceOfCorrectWidth = false;
+    while (!isWebIfaceOfCorrectWidth && t.elapsed() < 5000) {
+        QTest::qWait(100);
+        webIface = rootObjectIface->child(1)->child(0);
+        QVERIFY(webIface);
+        QCOMPARE(webIface->role(), QAccessible::WebDocument);
+        isWebIfaceOfCorrectWidth = webIface->rect().width() == 500;
+    }
+
+    QVERIFY(isWebIfaceOfCorrectWidth);
+    QCOMPARE(webIface->rect().height(), 400 - textIface->rect().height());
+    QCOMPARE(webIface->rect().x(), textIface->rect().x() + textIface->rect().width());
+    QCOMPARE(webIface->rect().y(), textIface->rect().y() + textIface->rect().height());
+
+    // Set active focus on the input field.
+    webView->runJavaScript("document.getElementById('input1').focus();");
+    QTRY_COMPARE(evaluateJavaScriptSync(webView, "document.activeElement.id").toString(), QStringLiteral("input1"));
+
+    // Check that children of the web rect are inside it
+    QAccessibleInterface *inputIface = webIface->focusChild();
+    QVERIFY(inputIface);
+    QTRY_COMPARE(inputIface->role(), QAccessible::EditableText);
+    QVERIFY(webIface->rect().contains(inputIface->rect()));
+
+    delete rootObject;
+    delete component;
+    delete engine;
+}
+
 #endif // QT_CONFIG(accessibility)
 
 void tst_QQuickWebEngineView::htmlSelectPopup()

From ace8bf7b92284a24c0d83fd3afac119fe20ae275 Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Wed, 7 Aug 2024 16:14:07 +0200
Subject: [PATCH 306/356] Fix webrtc manual test compilation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

QHttpServer no longer has a listen() convenience function, use a
TcpServer instead.

Change-Id: I53db234590d67eabd4e23b2a8397e931178f1155
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
(cherry picked from commit a782eb6fa6c5a80b10c4af64963f903214d19ed5)
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Moss Heim <moss.heim@qt.io>
---
 tests/manual/widgets/webrtc/main.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/tests/manual/widgets/webrtc/main.cpp b/tests/manual/widgets/webrtc/main.cpp
index a6c2ff8d43c..e788f3a2936 100644
--- a/tests/manual/widgets/webrtc/main.cpp
+++ b/tests/manual/widgets/webrtc/main.cpp
@@ -8,6 +8,7 @@
 #include <QHttpServer>
 #include <QListView>
 #include <QMessageBox>
+#include <QTcpServer>
 #include <QWebEnginePage>
 #include <QWebEngineProfile>
 #include <QWebEngineSettings>
@@ -87,8 +88,6 @@ int main(int argc, char *argv[])
 {
     QApplication app(argc, argv);
 
-    QHttpServer server;
-
     QFile file(":index.html");
 
     if (!file.open(QIODeviceBase::ReadOnly)) {
@@ -102,11 +101,12 @@ int main(int argc, char *argv[])
         return 0;
     }
 
-    server.route("/index.html", [data]() {
-        return data;
-    });
+    QHttpServer httpServer;
+    httpServer.route("/index.html", [data]() { return data; });
 
-    server.listen(QHostAddress::Any, 3000);
+    auto tcpServer = new QTcpServer(&httpServer);
+    tcpServer->listen(QHostAddress::Any, 3000);
+    httpServer.bind(tcpServer);
 
     QWebEngineView view;
     Page *page = new Page(QWebEngineProfile::defaultProfile(), &view);

From aee2b8e8c49bf91b860d3204245ad6b78e3100dc Mon Sep 17 00:00:00 2001
From: Szabolcs David <davidsz@inf.u-szeged.hu>
Date: Fri, 8 Mar 2024 14:52:54 +0100
Subject: [PATCH 307/356] [Backport] Make download API asynchronous

Modify the already existing downloadRequest() API. Now the requests
not necessarily have to be answered in a directly connected signal
handler and the API users can postpone their user's decision.

The only exceptions are automatically accepted save page requests. There
is no better place to call their callback than directly after the signal
emission.

Adapt auto tests to the new lifecycle of download items. Modify the
quicknanobrowser example to use a simple async method to wait for the
user's decision. Keep simplebrowser to use its old synchronous method
to illustrate that it's still possible. Correct documentation at some
places.

[ChangeLog] QWebEngineProfile::downloadRequested() is not limited to
synchronous usage anymore. QWebEngineDownloadRequest can be accepted
or rejected later without blocking the browsing session.

Fixes: QTBUG-118584
Change-Id: I9828352a835cbaf48f0d1311179ab1d972a95668
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
---
 .../quicknanobrowser/BrowserWindow.qml        |  26 ++-
 .../quicknanobrowser/DownloadView.qml         |   1 +
 src/core/api/qwebenginedownloadrequest.cpp    |  51 +++--
 src/core/api/qwebenginedownloadrequest_p.h    |   5 +
 src/core/api/qwebengineprofile.cpp            |  24 +-
 src/core/download_manager_delegate_qt.cpp     | 213 +++++++++---------
 src/core/download_manager_delegate_qt.h       |   9 +
 src/core/profile_adapter.cpp                  |   9 +
 src/core/profile_adapter.h                    |   3 +
 src/core/profile_adapter_client.h             |  14 +-
 .../api/qquickwebengineprofile.cpp            |  21 +-
 .../tst_qwebenginedownloadrequest.cpp         |  87 ++++++-
 12 files changed, 298 insertions(+), 165 deletions(-)

diff --git a/examples/webenginequick/quicknanobrowser/BrowserWindow.qml b/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
index 1c31ea94409..1b2816583c4 100644
--- a/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
+++ b/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
@@ -5,6 +5,7 @@ import QtCore
 import QtQml
 import QtQuick
 import QtQuick.Controls.Fusion
+import QtQuick.Dialogs
 import QtQuick.Layouts
 import QtQuick.Window
 import QtWebEngine
@@ -824,10 +825,29 @@ ApplicationWindow {
         visible: false
     }
 
+    MessageDialog {
+        id: downloadAcceptDialog
+        property var downloadRequest: downloadView.pendingDownloadRequest
+        title: "Download requested"
+        text: downloadRequest ? downloadRequest.suggestedFileName : ""
+        buttons: Dialog.No | Dialog.Yes
+        onAccepted: {
+            downloadView.visible = true;
+            downloadView.append(downloadRequest);
+            downloadRequest.accept();
+        }
+        onRejected: {
+            downloadRequest.cancel();
+        }
+        onButtonClicked: {
+            visible = false;
+        }
+        visible: false
+    }
+
     function onDownloadRequested(download) {
-        downloadView.visible = true;
-        downloadView.append(download);
-        download.accept();
+        downloadView.pendingDownloadRequest = download;
+        downloadAcceptDialog.visible = true;
     }
 
     FindBar {
diff --git a/examples/webenginequick/quicknanobrowser/DownloadView.qml b/examples/webenginequick/quicknanobrowser/DownloadView.qml
index 421b4f55cc9..b116ab86734 100644
--- a/examples/webenginequick/quicknanobrowser/DownloadView.qml
+++ b/examples/webenginequick/quicknanobrowser/DownloadView.qml
@@ -9,6 +9,7 @@ import QtQuick.Layouts
 Rectangle {
     id: downloadView
     color: "lightgray"
+    property var pendingDownloadRequest: null
 
     ListModel {
         id: downloadModel
diff --git a/src/core/api/qwebenginedownloadrequest.cpp b/src/core/api/qwebenginedownloadrequest.cpp
index 70f4b094197..7471d8205a1 100644
--- a/src/core/api/qwebenginedownloadrequest.cpp
+++ b/src/core/api/qwebenginedownloadrequest.cpp
@@ -9,6 +9,7 @@
 #include "profile_adapter.h"
 #include "web_contents_adapter_client.h"
 
+#include <QDir>
 #include <QFileInfo>
 
 QT_BEGIN_NAMESPACE
@@ -81,11 +82,9 @@ static inline QWebEngineDownloadRequest::DownloadInterruptReason toDownloadInter
     requests, which it does by emitting the
     \l{QWebEngineProfile::downloadRequested}{downloadRequested} signal together
     with a newly created QWebEngineDownloadRequest. The application can then
-    examine this item and decide whether to accept it or not. A signal handler
-    must explicitly call accept() on the item for \QWE to actually start
-    downloading and writing data to disk. If no signal handler calls accept(),
-    then the download request will be automatically rejected and nothing will be
-    written to disk.
+    examine this item and decide whether to accept it or not. When a decision is
+    made, the application must explicitly call accept() or cancel() on the item
+    for \QWE to actually start downloading or rejecting the request.
 
     \note Some properties, such as setting the path and file name where the file
     will be saved (see \l downloadDirectory() and \l downloadFileName()), can
@@ -93,18 +92,10 @@ static inline QWebEngineDownloadRequest::DownloadInterruptReason toDownloadInter
 
     \section2 Object Life Cycle
 
-    All items are guaranteed to be valid during the emission of the
-    \l{QWebEngineProfile::downloadRequested}{downloadRequested} signal. If
-    accept() is \e not called by any signal handler, then the item will be
-    deleted \e immediately after signal emission. This means that the
-    application \b{must not} keep references to rejected download items. It also
-    means the application should not use a queued connection to this signal.
-
-    If accept() \e is called by a signal handler, then the QWebEngineProfile
-    will take ownership of the item. However, it is safe for the application to
-    delete the item at any time, except during the handling of the
-    \l{QWebEngineProfile::downloadRequested}{downloadRequested} signal. The
-    QWebEngineProfile being a long-lived object, it is in fact recommended that
+    In each and every case, the QWebEngineProfile takes the ownership of the item.
+    However, it is safe for the application to delete the item at any time, except
+    during the handling of the \l{QWebEngineProfile::downloadRequested}{downloadRequested}
+    signal. The QWebEngineProfile being a long-lived object, it is in fact recommended that
     the application delete any items it is no longer interested in.
 
     \note Deleting an item will also automatically cancel a download since 5.12.2,
@@ -119,6 +110,12 @@ static inline QWebEngineDownloadRequest::DownloadInterruptReason toDownloadInter
     into a special file format (\l savePageFormat). To check if a download is
     for a file or a web page, use \l isSavePageDownload.
 
+    Web page save requests are accepted automatically and started from
+    \l DownloadInProgress state by convenience reasons. The first directly connected
+    \l{QWebEngineProfile::downloadRequested}{downloadRequested} signal handler
+    can prevent this by calling cancel(), otherwise the save operation will start
+    writing data to the disk.
+
     \sa QWebEngineProfile, QWebEngineProfile::downloadRequested,
     QWebEnginePage::download, QWebEnginePage::save
 */
@@ -137,7 +134,9 @@ void QWebEngineDownloadRequestPrivate::update(const ProfileAdapterClient::Downlo
 {
     Q_Q(QWebEngineDownloadRequest);
 
-    Q_ASSERT(downloadState != QWebEngineDownloadRequest::DownloadRequested);
+    // Don't change download state until users accept/cancel the request
+    if (!answered && downloadState == QWebEngineDownloadRequest::DownloadRequested)
+        return;
 
     if (toDownloadInterruptReason(info.downloadInterruptReason) != interruptReason) {
         interruptReason = toDownloadInterruptReason(info.downloadInterruptReason);
@@ -178,6 +177,20 @@ void QWebEngineDownloadRequestPrivate::setFinished()
     Q_EMIT q_ptr->isFinishedChanged();
 }
 
+void QWebEngineDownloadRequestPrivate::answer()
+{
+    if (answered)
+        return;
+
+    if (profileAdapter) {
+        QString path = QDir(downloadDirectory).filePath(downloadFileName);
+        bool accepted = downloadState != QWebEngineDownloadRequest::DownloadCancelled
+                && downloadState != QWebEngineDownloadRequest::DownloadRequested;
+        profileAdapter->acceptDownload(downloadId, accepted, useDownloadTargetCallback, path, savePageFormat);
+        answered = true;
+    }
+}
+
 /*!
     Accepts the current download request, which will start the download.
 
@@ -197,6 +210,7 @@ void QWebEngineDownloadRequest::accept()
 
     d->downloadState = QWebEngineDownloadRequest::DownloadInProgress;
     Q_EMIT stateChanged(d->downloadState);
+    d->answer();
 }
 
 /*!
@@ -239,6 +253,7 @@ void QWebEngineDownloadRequest::cancel()
         Q_EMIT stateChanged(d->downloadState);
         d->setFinished();
     }
+    d->answer();
 }
 
 /*!
diff --git a/src/core/api/qwebenginedownloadrequest_p.h b/src/core/api/qwebenginedownloadrequest_p.h
index eef6c9bb52f..e829f94b1b3 100644
--- a/src/core/api/qwebenginedownloadrequest_p.h
+++ b/src/core/api/qwebenginedownloadrequest_p.h
@@ -36,6 +36,7 @@ class Q_WEBENGINECORE_EXPORT QWebEngineDownloadRequestPrivate
 
     void update(const QtWebEngineCore::ProfileAdapterClient::DownloadItemInfo &info);
     void setFinished();
+    void answer();
 
     bool downloadFinished = false;
     quint32 downloadId = -1;
@@ -56,10 +57,14 @@ class Q_WEBENGINECORE_EXPORT QWebEngineDownloadRequestPrivate
     bool isCustomFileName = false;
     qint64 totalBytes = -1;
     qint64 receivedBytes = 0;
+    // The user initiated the download by saving the page
     bool isSavePageDownload = false;
+    // Which type of callback should be called when the request is answered
+    bool useDownloadTargetCallback = true;
     QWebEngineDownloadRequest *q_ptr;
     QPointer<QtWebEngineCore::ProfileAdapter> profileAdapter;
     QtWebEngineCore::WebContentsAdapterClient *adapterClient = nullptr;
+    bool answered = false;
     Q_DECLARE_PUBLIC(QWebEngineDownloadRequest)
 };
 
diff --git a/src/core/api/qwebengineprofile.cpp b/src/core/api/qwebengineprofile.cpp
index b0824af3503..1c5807a9386 100644
--- a/src/core/api/qwebengineprofile.cpp
+++ b/src/core/api/qwebengineprofile.cpp
@@ -17,7 +17,7 @@
 #include "visited_links_manager_qt.h"
 #include "web_engine_settings.h"
 
-#include <QDir>
+#include <QFileInfo>
 #include <QtWebEngineCore/qwebengineurlscheme.h>
 
 QT_BEGIN_NAMESPACE
@@ -220,6 +220,12 @@ void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
 {
     Q_Q(QWebEngineProfile);
 
+    if (!q->receivers(SIGNAL(downloadRequested(QWebEngineDownloadRequest *)))) {
+        m_profileAdapter->acceptDownload(info.id, info.accepted, info.useDownloadTargetCallback, info.path,
+                                         info.savePageFormat);
+        return;
+    }
+
     Q_ASSERT(!m_ongoingDownloads.contains(info.id));
     QWebEngineDownloadRequestPrivate *itemPrivate =
             new QWebEngineDownloadRequestPrivate(m_profileAdapter);
@@ -235,6 +241,7 @@ void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
     itemPrivate->mimeType = info.mimeType;
     itemPrivate->savePageFormat = static_cast<QWebEngineDownloadRequest::SavePageFormat>(info.savePageFormat);
     itemPrivate->isSavePageDownload = info.isSavePageDownload;
+    itemPrivate->useDownloadTargetCallback = info.useDownloadTargetCallback;
     if (info.page && info.page->clientType() == QtWebEngineCore::WebContentsAdapterClient::WidgetsClient)
         itemPrivate->adapterClient = info.page;
     else
@@ -247,18 +254,9 @@ void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
 
     Q_EMIT q->downloadRequested(download);
 
-    QWebEngineDownloadRequest::DownloadState state = download->state();
-
-    info.path = QDir(download->downloadDirectory()).filePath(download->downloadFileName());
-    info.savePageFormat = static_cast<QtWebEngineCore::ProfileAdapterClient::SavePageFormat>(
-                download->savePageFormat());
-    info.accepted = state != QWebEngineDownloadRequest::DownloadCancelled;
-
-    if (state == QWebEngineDownloadRequest::DownloadRequested) {
-        // Delete unaccepted downloads.
-        info.accepted = false;
-        delete download;
-    }
+    // Callbacks of automatically accepted save operations have to be called here
+    if (info.isSavePageDownload && info.accepted)
+        itemPrivate->answer();
 }
 
 void QWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info)
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index bbe487fc918..4f0fce199a9 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -74,6 +74,8 @@ void DownloadManagerDelegateQt::cancelDownload(download::DownloadTargetCallback
 
 bool DownloadManagerDelegateQt::cancelDownload(quint32 downloadId)
 {
+    m_pendingDownloads.erase(downloadId);
+    m_pendingSaves.erase(downloadId);
     if (download::DownloadItem *download = findDownloadById(downloadId)) {
         download->Cancel(/* user_cancel */ true);
         return true;
@@ -97,6 +99,8 @@ void DownloadManagerDelegateQt::removeDownload(quint32 downloadId)
 {
     if (download::DownloadItem *download = findDownloadById(downloadId))
         download->Remove();
+    m_pendingDownloads.erase(downloadId);
+    m_pendingSaves.erase(downloadId);
 }
 
 bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *item,
@@ -187,68 +191,66 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
     item->AddObserver(this);
     QList<ProfileAdapterClient*> clients = m_profileAdapter->clients();
     if (!clients.isEmpty()) {
-        ProfileAdapterClient::DownloadItemInfo info = {
-            item->GetId(),
-            toQt(item->GetURL()),
-            item->GetState(),
-            item->GetTotalBytes(),
-            item->GetReceivedBytes(),
-            std::move(mimeTypeString),
-            std::move(suggestedFilePath),
-            ProfileAdapterClient::UnknownSavePageFormat,
-            acceptedByDefault,
-            false /* paused */,
-            false /* done */,
-            isSavePageDownload,
-            item->GetLastReason(),
-            adapterClient,
-            std::move(suggestedFilename),
-            item->GetStartTime().ToTimeT()
-        };
+        ProfileAdapterClient::DownloadItemInfo info = {};
+        info.id = item->GetId();
+        info.url = toQt(item->GetURL());
+        info.state = item->GetState();
+        info.totalBytes = item->GetTotalBytes();
+        info.receivedBytes = item->GetReceivedBytes();
+        info.mimeType = std::move(mimeTypeString);
+        info.path = std::move(suggestedFilePath);
+        info.savePageFormat = ProfileAdapterClient::UnknownSavePageFormat;
+        info.accepted = acceptedByDefault;
+        info.paused = false;
+        info.done = false;
+        info.isSavePageDownload = isSavePageDownload;
+        info.useDownloadTargetCallback = true;
+        info.downloadInterruptReason = item->GetLastReason();
+        info.page = adapterClient;
+        info.suggestedFileName = std::move(suggestedFilename);
+        info.startTime = item->GetStartTime().ToTimeT();
+
+        m_pendingDownloads.emplace(m_currentId, std::move(*callback));
+        clients[0]->downloadRequested(info);
+    } else
+        cancelDownload(std::move(*callback));
 
-        for (ProfileAdapterClient *client : std::as_const(clients)) {
-            client->downloadRequested(info);
-            if (info.accepted)
-                break;
-        }
+    return true;
+}
 
-        QFileInfo suggestedFile(info.path);
-
-        if (info.accepted && !suggestedFile.absoluteDir().mkpath(suggestedFile.absolutePath())) {
-#if defined(Q_OS_WIN)
-            // TODO: Remove this when https://bugreports.qt.io/browse/QTBUG-85997 is fixed.
-            QDir suggestedDir = QDir(suggestedFile.absolutePath());
-            if (!suggestedDir.isRoot() || !suggestedDir.exists()) {
-#endif
-            qWarning("Creating download path failed, download cancelled: %ls",
-                     qUtf16Printable(suggestedFile.absolutePath()));
-            info.accepted = false;
-#if defined(Q_OS_WIN)
-            }
-#endif
-        }
+void DownloadManagerDelegateQt::downloadTargetDetermined(quint32 downloadId, bool accepted,
+                                                         const QString &path)
+{
+    if (!m_pendingDownloads.contains(downloadId))
+        return;
+    auto callback = std::move(m_pendingDownloads.find(downloadId)->second);
+    m_pendingDownloads.erase(downloadId);
 
-        if (!info.accepted) {
-            cancelDownload(std::move(*callback));
-            return true;
-        }
+    download::DownloadItem *item = findDownloadById(downloadId);
+    if (!accepted || !item) {
+        cancelDownload(std::move(callback));
+        return;
+    }
 
-        base::FilePath filePathForCallback(toFilePathString(suggestedFile.absoluteFilePath()));
-        download::DownloadTargetInfo target_info;
-        target_info.target_disposition = download::DownloadItem::TARGET_DISPOSITION_OVERWRITE;
-        target_info.danger_type = download::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT;
-        target_info.insecure_download_status = download::DownloadItem::VALIDATED;
-        target_info.mime_type = item->GetMimeType();
-        target_info.intermediate_path =
-                filePathForCallback.AddExtension(toFilePathString("download"));
-        target_info.display_name = base::FilePath();
-        target_info.target_path = filePathForCallback;
-        target_info.interrupt_reason = download::DOWNLOAD_INTERRUPT_REASON_NONE;
-        std::move(*callback).Run(std::move(target_info));
-    } else
-        cancelDownload(std::move(*callback));
+    QFileInfo suggestedFile(path);
+    if (!suggestedFile.absoluteDir().mkpath(suggestedFile.absolutePath())) {
+        qWarning() << "Creating download path failed, download cancelled:" << suggestedFile.absolutePath();
+        cancelDownload(std::move(callback));
+        return;
+    }
+    base::FilePath targetPath(toFilePathString(suggestedFile.absoluteFilePath()));
 
-    return true;
+    download::DownloadTargetInfo target_info;
+    target_info.target_disposition = download::DownloadItem::TARGET_DISPOSITION_OVERWRITE;
+    target_info.danger_type = download::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT;
+    target_info.insecure_download_status = download::DownloadItem::VALIDATED;
+    target_info.mime_type = item->GetMimeType();
+    target_info.intermediate_path =
+            targetPath.AddExtension(toFilePathString("download"));
+    target_info.display_name = base::FilePath();
+    target_info.target_path = targetPath;
+    target_info.interrupt_reason = download::DOWNLOAD_INTERRUPT_REASON_NONE;
+    std::move(callback).Run(std::move(target_info));
 }
 
 void DownloadManagerDelegateQt::GetSaveDir(content::BrowserContext* browser_context,
@@ -303,38 +305,46 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content
     if (web_contents)
         adapterClient = static_cast<WebContentsDelegateQt *>(web_contents->GetDelegate())->adapterClient();
 
+    ProfileAdapterClient::DownloadItemInfo info = {};
     // Chromium doesn't increase download ID when saving page.
-    ProfileAdapterClient::DownloadItemInfo info = {
-        ++m_currentId,
-        toQt(web_contents->GetURL()),
-        download::DownloadItem::IN_PROGRESS,
-        -1, /* totalBytes */
-        0, /* receivedBytes */
-        u"application/x-mimearchive"_s,
-        suggestedFilePath,
-        suggestedSaveFormat,
-        acceptedByDefault,
-        false, /* paused */
-        false, /* done */
-        true, /* isSavePageDownload */
-        ProfileAdapterClient::NoReason,
-        adapterClient,
-        QFileInfo(suggestedFilePath).fileName(),
-        QDateTime::currentMSecsSinceEpoch()
-    };
-
-    for (ProfileAdapterClient *client : std::as_const(clients)) {
-        client->downloadRequested(info);
-        if (info.accepted)
-            break;
+    info.id = ++m_currentId;
+    info.url = toQt(web_contents->GetURL());
+    info.state = download::DownloadItem::IN_PROGRESS;
+    info.totalBytes = -1;
+    info.receivedBytes = 0;
+    info.mimeType = u"application/x-mimearchive"_s;
+    info.path = suggestedFilePath;
+    info.savePageFormat = suggestedSaveFormat;
+    info.accepted = acceptedByDefault;
+    info.paused = false;
+    info.done = false;
+    info.isSavePageDownload = true;
+    info.useDownloadTargetCallback = false;
+    info.downloadInterruptReason = ProfileAdapterClient::NoReason;
+    info.page = adapterClient;
+    info.suggestedFileName = QFileInfo(suggestedFilePath).fileName();
+    info.startTime = QDateTime::currentMSecsSinceEpoch();
+
+    m_pendingSaves.emplace(m_currentId, std::move(callback));
+    clients[0]->downloadRequested(info);
+}
+
+void DownloadManagerDelegateQt::savePathDetermined(quint32 downloadId, bool accepted,
+                                                   const QString &path, int format)
+{
+    if (!accepted) {
+        m_pendingSaves.erase(downloadId);
+        return;
     }
 
-    if (!info.accepted)
+    if (!m_pendingSaves.contains(downloadId))
         return;
+    auto callback = std::move(m_pendingSaves.find(downloadId)->second);
+    m_pendingSaves.erase(downloadId);
 
     content::SavePackagePathPickedParams params;
-    params.file_path = toFilePath(info.path);
-    params.save_type = static_cast<content::SavePageType>(info.savePageFormat);
+    params.file_path = toFilePath(path);
+    params.save_type = static_cast<content::SavePageType>(format);
     std::move(callback).Run(std::move(params),
                             base::BindOnce(&DownloadManagerDelegateQt::savePackageDownloadCreated,
                                            m_weakPtrFactory.GetWeakPtr()));
@@ -355,24 +365,25 @@ void DownloadManagerDelegateQt::OnDownloadUpdated(download::DownloadItem *downlo
         if (webContents)
             adapterClient = static_cast<WebContentsDelegateQt *>(webContents->GetDelegate())->adapterClient();
 
-        ProfileAdapterClient::DownloadItemInfo info = {
-            download->GetId(),
-            toQt(download->GetURL()),
-            download->GetState(),
-            download->GetTotalBytes(),
-            download->GetReceivedBytes(),
-            toQt(download->GetMimeType()),
-            QString(),
-            ProfileAdapterClient::UnknownSavePageFormat,
-            true /* accepted */,
-            download->IsPaused(),
-            download->IsDone(),
-            0 /* downloadType (unused) */,
-            download->GetLastReason(),
-            adapterClient,
-            toQt(download->GetSuggestedFilename()),
-            download->GetStartTime().ToTimeT()
-        };
+        ProfileAdapterClient::DownloadItemInfo info = {};
+        // Chromium doesn't increase download ID when saving page.
+        info.id = download->GetId();
+        info.url = toQt(download->GetURL());
+        info.state = download->GetState();
+        info.totalBytes = download->GetTotalBytes();
+        info.receivedBytes = download->GetReceivedBytes();
+        info.mimeType = toQt(download->GetMimeType());
+        info.path = QString();
+        info.savePageFormat = ProfileAdapterClient::UnknownSavePageFormat;
+        info.accepted = true;
+        info.paused = download->IsPaused();
+        info.done = download->IsDone();
+        info.isSavePageDownload = false; // unused
+        info.useDownloadTargetCallback = false; // unused
+        info.downloadInterruptReason = download->GetLastReason();
+        info.page = adapterClient;
+        info.suggestedFileName = toQt(download->GetSuggestedFilename());
+        info.startTime = download->GetStartTime().ToTimeT();
 
         for (ProfileAdapterClient *client : std::as_const(clients)) {
             client->downloadUpdated(info);
diff --git a/src/core/download_manager_delegate_qt.h b/src/core/download_manager_delegate_qt.h
index e7dfad29dcf..3b7ccc1c4a1 100644
--- a/src/core/download_manager_delegate_qt.h
+++ b/src/core/download_manager_delegate_qt.h
@@ -7,7 +7,11 @@
 #include "content/public/browser/download_manager_delegate.h"
 #include <base/memory/weak_ptr.h>
 
+#include <QString>
 #include <QtGlobal>
+#include <map>
+
+#include "profile_adapter_client.h"
 
 namespace base {
 class FilePath;
@@ -51,6 +55,9 @@ class DownloadManagerDelegateQt
     void resumeDownload(quint32 downloadId);
     void removeDownload(quint32 downloadId);
 
+    void downloadTargetDetermined(quint32 downloadId, bool accepted, const QString &path);
+    void savePathDetermined(quint32 downloadId, bool accepted, const QString &path, int format);
+
     // Inherited from content::DownloadItem::Observer
     void OnDownloadUpdated(download::DownloadItem *download) override;
     void OnDownloadDestroyed(download::DownloadItem *download) override;
@@ -62,6 +69,8 @@ class DownloadManagerDelegateQt
     ProfileAdapter *m_profileAdapter;
 
     uint32_t m_currentId;
+    std::map<quint32, download::DownloadTargetCallback> m_pendingDownloads;
+    std::map<quint32, content::SavePackagePathPickedCallback> m_pendingSaves;
     base::WeakPtrFactory<DownloadManagerDelegateQt> m_weakPtrFactory;
 };
 
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index 9f8fc958680..fa84f53e76f 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -231,6 +231,15 @@ void ProfileAdapter::removeDownload(quint32 downloadId)
     downloadManagerDelegate()->removeDownload(downloadId);
 }
 
+void ProfileAdapter::acceptDownload(quint32 downloadId, bool accepted, bool useDownloadTargetCallback,
+                                    const QString &path, int savePageFormat)
+{
+    if (useDownloadTargetCallback)
+        downloadManagerDelegate()->downloadTargetDetermined(downloadId, accepted, path);
+    else
+        downloadManagerDelegate()->savePathDetermined(downloadId, accepted, path, savePageFormat);
+}
+
 ProfileAdapter *ProfileAdapter::createDefaultProfileAdapter()
 {
     return WebEngineContext::current()->createDefaultProfileAdapter();
diff --git a/src/core/profile_adapter.h b/src/core/profile_adapter.h
index 06628632193..4301cd8a2e7 100644
--- a/src/core/profile_adapter.h
+++ b/src/core/profile_adapter.h
@@ -77,6 +77,9 @@ class Q_WEBENGINECORE_EXPORT ProfileAdapter : public QObject
     void pauseDownload(quint32 downloadId);
     void resumeDownload(quint32 downloadId);
     void removeDownload(quint32 downloadId);
+    void acceptDownload(quint32 downloadId, bool accepted,
+                        bool useDownloadTargetCallback, const QString &path,
+                        int savePageFormat);
 
     ProfileQt *profile();
     bool ensureDataPathExists();
diff --git a/src/core/profile_adapter_client.h b/src/core/profile_adapter_client.h
index 06ac0de8b37..aaeefb5440a 100644
--- a/src/core/profile_adapter_client.h
+++ b/src/core/profile_adapter_client.h
@@ -82,19 +82,19 @@ class Q_WEBENGINECORE_EXPORT ProfileAdapterClient
     };
 
     struct DownloadItemInfo {
-        const quint32 id;
-        const QUrl url;
-        const int state;
-        const qint64 totalBytes;
-        const qint64 receivedBytes;
-        const QString mimeType;
-
+        quint32 id;
+        QUrl url;
+        int state;
+        qint64 totalBytes;
+        qint64 receivedBytes;
+        QString mimeType;
         QString path;
         int savePageFormat;
         bool accepted;
         bool paused;
         bool done;
         bool isSavePageDownload;
+        bool useDownloadTargetCallback;
         int downloadInterruptReason;
         WebContentsAdapterClient *page;
         QString suggestedFileName;
diff --git a/src/webenginequick/api/qquickwebengineprofile.cpp b/src/webenginequick/api/qquickwebengineprofile.cpp
index eb6a3199595..e5308b43f6a 100644
--- a/src/webenginequick/api/qquickwebengineprofile.cpp
+++ b/src/webenginequick/api/qquickwebengineprofile.cpp
@@ -246,6 +246,12 @@ void QQuickWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
 {
     Q_Q(QQuickWebEngineProfile);
 
+    if (!q->receivers(SIGNAL(downloadRequested(QQuickWebEngineDownloadRequest *)))) {
+        m_profileAdapter->acceptDownload(info.id, info.accepted, info.useDownloadTargetCallback, info.path,
+                                         info.savePageFormat);
+        return;
+    }
+
     Q_ASSERT(!m_ongoingDownloads.contains(info.id));
     QWebEngineDownloadRequestPrivate *itemPrivate =
             new QWebEngineDownloadRequestPrivate(m_profileAdapter);
@@ -262,6 +268,7 @@ void QQuickWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
     itemPrivate->savePageFormat = static_cast<QWebEngineDownloadRequest::SavePageFormat>(
                 info.savePageFormat);
     itemPrivate->isSavePageDownload = info.isSavePageDownload;
+    itemPrivate->useDownloadTargetCallback = info.useDownloadTargetCallback;
     if (info.page && info.page->clientType() == QtWebEngineCore::WebContentsAdapterClient::QmlClient)
         itemPrivate->adapterClient = info.page;
     else
@@ -275,17 +282,9 @@ void QQuickWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
     QQmlEngine::setObjectOwnership(download, QQmlEngine::JavaScriptOwnership);
     Q_EMIT q->downloadRequested(download);
 
-    QWebEngineDownloadRequest::DownloadState state = download->state();
-    info.path = QDir(download->downloadDirectory()).filePath(download->downloadFileName());
-    info.savePageFormat = itemPrivate->savePageFormat;
-    info.accepted = state != QWebEngineDownloadRequest::DownloadCancelled
-                      && state != QWebEngineDownloadRequest::DownloadRequested;
-
-    if (state == QWebEngineDownloadRequest::DownloadRequested) {
-        // Delete unaccepted downloads.
-        info.accepted = false;
-        delete download;
-    }
+    // Callbacks of automatically accepted save operations have to be called here
+    if (info.isSavePageDownload && info.accepted)
+        itemPrivate->answer();
 }
 
 void QQuickWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info)
diff --git a/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp b/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
index 30c480f951f..c9f048976f3 100644
--- a/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
+++ b/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
@@ -76,10 +76,12 @@ private Q_SLOTS:
     void downloadPage_data();
     void downloadPage();
     void downloadViaSetUrl();
-    void downloadFileNot1();
-    void downloadFileNot2();
+    void downloadAnswerLater_data();
+    void downloadAnswerLater();
+    void downloadFileCancel();
     void downloadDeleted();
     void downloadDeletedByProfile();
+    void downloadRequestedWithoutHandler();
     void downloadUniqueFilename_data();
     void downloadUniqueFilename();
     void downloadUniqueFilenameWithTimestamp();
@@ -717,6 +719,7 @@ void tst_QWebEngineDownloadRequest::downloadViaSetUrl()
     QList<QUrl> downloadUrls;
     ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadRequest *item) {
         downloadUrls.append(item->url());
+        item->cancel();
     });
 
     // Set up the test scenario by trying to load some unrelated HTML.
@@ -746,29 +749,88 @@ void tst_QWebEngineDownloadRequest::downloadViaSetUrl()
     }
 }
 
-void tst_QWebEngineDownloadRequest::downloadFileNot1()
+void tst_QWebEngineDownloadRequest::downloadRequestedWithoutHandler()
+{
+    ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+        rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/html"));
+        rr->setResponseBody(QByteArrayLiteral("<html><body>Hello</body></html>"));
+        rr->sendResponse();
+    });
+
+    QTemporaryDir tmpDir;
+    QVERIFY(tmpDir.isValid());
+    QString downloadPath = tmpDir.filePath("test.html");
+
+    QWebEngineProfile profile;
+    QWebEnginePage page(&profile);
+
+    // Load some HTML
+    QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+    page.load(m_server->url());
+    QTRY_COMPARE(loadSpy.size(), 1);
+    QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true);
+
+    // Save and verify
+    page.save(downloadPath, QWebEngineDownloadRequest::SingleHtmlSaveFormat);
+    QFile file(downloadPath);
+    QTRY_VERIFY(file.exists());
+}
+
+void tst_QWebEngineDownloadRequest::downloadAnswerLater_data()
 {
-    // Trigger file download via download() but don't accept().
+    QTest::addColumn<bool>("answer");
+    QTest::addColumn<bool>("accept");
+
+    QTest::newRow("accept") << true << true;
+    QTest::newRow("cancel") << true << false;
+    QTest::newRow("ignore") << false << true;
+}
+
+void tst_QWebEngineDownloadRequest::downloadAnswerLater()
+{
+    QFETCH(bool, answer);
+    QFETCH(bool, accept);
 
     ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
-        rr->sendResponse(404);
+        rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment"));
+        rr->setResponseBody(QByteArrayLiteral("a"));
+        rr->sendResponse();
     });
 
-    QPointer<QWebEngineDownloadRequest> downloadItem;
+    QTemporaryDir tmpDir;
+    QVERIFY(tmpDir.isValid());
+    m_profile->setDownloadPath(tmpDir.path());
+
+    QPointer<QWebEngineDownloadRequest> downloadRequest;
     int downloadCount = 0;
-    ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadRequest *item) {
-        QVERIFY(item);
-        QCOMPARE(item->state(), QWebEngineDownloadRequest::DownloadRequested);
-        downloadItem = item;
+    ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadRequest *request) {
+        QVERIFY(request);
+        QCOMPARE(request->state(), QWebEngineDownloadRequest::DownloadRequested);
+        downloadRequest = request;
         downloadCount++;
     });
 
     m_page->download(m_server->url(QByteArrayLiteral("/file")));
     QTRY_COMPARE(downloadCount, 1);
-    QVERIFY(!downloadItem);
+    QVERIFY(downloadRequest);
+
+    if (answer) {
+        if (accept) {
+            downloadRequest->accept();
+            QCOMPARE(downloadRequest->state(), QWebEngineDownloadRequest::DownloadInProgress);
+            QTRY_COMPARE(m_finishedDownloads.size(), 1);
+            QCOMPARE(downloadRequest->state(), QWebEngineDownloadRequest::DownloadCompleted);
+        } else {
+            downloadRequest->cancel();
+            QCOMPARE(downloadRequest->state(), QWebEngineDownloadRequest::DownloadCancelled);
+        }
+    }
+
+    QVERIFY(downloadRequest);
+    delete downloadRequest;
 }
 
-void tst_QWebEngineDownloadRequest::downloadFileNot2()
+void tst_QWebEngineDownloadRequest::downloadFileCancel()
 {
     // Trigger file download via download() but call cancel() instead of accept().
 
@@ -1306,6 +1368,7 @@ void tst_QWebEngineDownloadRequest::downloadDataUrls()
         QCOMPARE(item->state(), QWebEngineDownloadRequest::DownloadRequested);
         QCOMPARE(item->downloadFileName(), expectedFileName);
         downloadRequestCount++;
+        item->cancel();
     });
 
     QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished);

From 7c8f507840ba9615bd880f0da6ae356bbd5333b4 Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Thu, 26 Sep 2024 15:03:42 +0200
Subject: [PATCH 308/356] tests: disable print/pdf tests when feature is off

Change-Id: I20203b0e4b40e8829d77d1b6ae700157319ac6bb
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 70ca58326b4727c7080ab141ef276d2c88274432)
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
---
 tests/auto/core/qwebengineframe/CMakeLists.txt          | 1 +
 tests/auto/core/qwebengineframe/tst_qwebengineframe.cpp | 5 +++++
 2 files changed, 6 insertions(+)

diff --git a/tests/auto/core/qwebengineframe/CMakeLists.txt b/tests/auto/core/qwebengineframe/CMakeLists.txt
index 7d73e5a4aac..0f4d24289ed 100644
--- a/tests/auto/core/qwebengineframe/CMakeLists.txt
+++ b/tests/auto/core/qwebengineframe/CMakeLists.txt
@@ -8,6 +8,7 @@ qt_internal_add_test(tst_qwebengineframe
         tst_qwebengineframe.cpp
     LIBRARIES
         Qt::WebEngineCore
+        Qt::WebEngineCorePrivate
         Qt::WebEngineWidgets
         Test::Util
 )
diff --git a/tests/auto/core/qwebengineframe/tst_qwebengineframe.cpp b/tests/auto/core/qwebengineframe/tst_qwebengineframe.cpp
index 8bbefd5f58a..0e036ac7449 100644
--- a/tests/auto/core/qwebengineframe/tst_qwebengineframe.cpp
+++ b/tests/auto/core/qwebengineframe/tst_qwebengineframe.cpp
@@ -22,6 +22,7 @@
 #include <QtTest/QtTest>
 
 #include <QtWebEngineCore/qwebengineframe.h>
+#include <QtWebEngineCore/private/qtwebenginecore-config_p.h>
 
 class tst_QWebEngineFrame : public QObject
 {
@@ -39,10 +40,12 @@ private Q_SLOTS:
     void size();
     void isMainFrame();
     void runJavaScript();
+#if QT_CONFIG(webengine_printing_and_pdf)
     void printRequestedByFrame();
     void printToPdfFile();
     void printToPdfFileFailures();
     void printToPdfFunction();
+#endif
 
 private:
 };
@@ -207,6 +210,7 @@ void tst_QWebEngineFrame::runJavaScript()
     QCOMPARE(result, QString("test-subframe0"));
 }
 
+#if QT_CONFIG(webengine_printing_and_pdf)
 void tst_QWebEngineFrame::printRequestedByFrame()
 {
     QWebEnginePage page;
@@ -340,6 +344,7 @@ void tst_QWebEngineFrame::printToPdfFunction()
     QVERIFY(invalidSpy.wasCalled());
     QCOMPARE(invalidPdfData.size(), 0);
 }
+#endif
 
 QTEST_MAIN(tst_QWebEngineFrame)
 

From 132a0273c57d2e341adbf13a464ad4828cc909f7 Mon Sep 17 00:00:00 2001
From: Shawn Rutledge <shawn.rutledge@qt.io>
Date: Mon, 24 Mar 2025 16:07:51 +0100
Subject: [PATCH 309/356] multipage example: correct the qrc file to support
 build with qmake

Change-Id: Ib3ff4394009364c673ef45e4244b65ed38e41379
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
(cherry picked from commit ef03fa46d3bcdb4bc188fcd0038610e0a036d340)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 52b3d114ddcdb4f10cd83562ad46a9ed7a6f8ac9)
---
 examples/pdf/multipage/viewer.qrc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/examples/pdf/multipage/viewer.qrc b/examples/pdf/multipage/viewer.qrc
index e786ae4ce6c..b8ec1c8c68e 100644
--- a/examples/pdf/multipage/viewer.qrc
+++ b/examples/pdf/multipage/viewer.qrc
@@ -1,5 +1,5 @@
 <RCC>
-    <qresource prefix="/singlepage">
+    <qresource prefix="/multipage">
         <file>viewer.qml</file>
         <file>resources/document-open.svg</file>
         <file>resources/edit-clear.svg</file>

From 9618fe173ee3b5a9fe538dd24f03efa17f1c15e5 Mon Sep 17 00:00:00 2001
From: Szabolcs David <davidsz@inf.u-szeged.hu>
Date: Fri, 7 Feb 2025 14:34:36 +0100
Subject: [PATCH 310/356] Fix QWebEngineDownloadRequest::pause()

Calling pause() (or any method which causes state update) in a directly
connected signal handler of a download request causes an assertion fail
in DownloadItemImpl::UpdateObservers() because it is protected from
nested updates. Use QTimer::singleShot() to detach download requests
and updates from the direct code path.

Add auto test to check if pausing and resuming a download work.

Change-Id: Ia8c977a626fd0d39ca51df42984381a75cca2101
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 1ffe3392eae1e70f76d621c8a4ee1b20feb004f2)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 2727607f8ff974b7c69453eed0d6356f8f4cd535)
---
 src/core/api/qwebenginedownloadrequest.cpp    | 18 +++----
 src/core/api/qwebengineprofile.cpp            |  2 +-
 src/core/api/qwebengineprofile_p.h            |  2 +-
 src/core/download_manager_delegate_qt.cpp     | 12 +++--
 src/core/profile_adapter_client.h             |  2 +-
 .../api/qquickwebengineprofile.cpp            |  2 +-
 .../api/qquickwebengineprofile_p.h            |  2 +-
 .../tst_qwebenginedownloadrequest.cpp         | 50 +++++++++++++++++++
 8 files changed, 69 insertions(+), 21 deletions(-)

diff --git a/src/core/api/qwebenginedownloadrequest.cpp b/src/core/api/qwebenginedownloadrequest.cpp
index 7471d8205a1..f67454134bd 100644
--- a/src/core/api/qwebenginedownloadrequest.cpp
+++ b/src/core/api/qwebenginedownloadrequest.cpp
@@ -146,17 +146,13 @@ void QWebEngineDownloadRequestPrivate::update(const ProfileAdapterClient::Downlo
         downloadState = toDownloadState(info.state);
         Q_EMIT q->stateChanged(downloadState);
     }
-
-    if (info.receivedBytes != receivedBytes || info.totalBytes != totalBytes) {
-
-      if (info.receivedBytes != receivedBytes) {
-          receivedBytes = info.receivedBytes;
-          Q_EMIT q->receivedBytesChanged();
-      }
-      if (info.totalBytes != totalBytes) {
-          totalBytes = info.totalBytes;
-          Q_EMIT q->totalBytesChanged();
-      }
+    if (info.receivedBytes != receivedBytes) {
+        receivedBytes = info.receivedBytes;
+        Q_EMIT q->receivedBytesChanged();
+    }
+    if (info.totalBytes != totalBytes) {
+        totalBytes = info.totalBytes;
+        Q_EMIT q->totalBytesChanged();
     }
 
     if (info.done)
diff --git a/src/core/api/qwebengineprofile.cpp b/src/core/api/qwebengineprofile.cpp
index 1c5807a9386..45b5a349d26 100644
--- a/src/core/api/qwebengineprofile.cpp
+++ b/src/core/api/qwebengineprofile.cpp
@@ -216,7 +216,7 @@ void QWebEngineProfilePrivate::cleanDownloads()
     m_ongoingDownloads.clear();
 }
 
-void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
+void QWebEngineProfilePrivate::downloadRequested(const DownloadItemInfo &info)
 {
     Q_Q(QWebEngineProfile);
 
diff --git a/src/core/api/qwebengineprofile_p.h b/src/core/api/qwebengineprofile_p.h
index 0ccc2703756..d4b3513cd5d 100644
--- a/src/core/api/qwebengineprofile_p.h
+++ b/src/core/api/qwebengineprofile_p.h
@@ -51,7 +51,7 @@ class Q_WEBENGINECORE_EXPORT QWebEngineProfilePrivate : public QtWebEngineCore::
 
     void cleanDownloads();
 
-    void downloadRequested(DownloadItemInfo &info) override;
+    void downloadRequested(const DownloadItemInfo &info) override;
     void downloadUpdated(const DownloadItemInfo &info) override;
 
     void showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &) override;
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index 4f0fce199a9..0d4983fb6b8 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -14,6 +14,7 @@
 #include <QFileInfo>
 #include <QMimeDatabase>
 #include <QStandardPaths>
+#include <QTimer>
 
 #include "profile_adapter_client.h"
 #include "profile_adapter.h"
@@ -211,7 +212,8 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
         info.startTime = item->GetStartTime().ToTimeT();
 
         m_pendingDownloads.emplace(m_currentId, std::move(*callback));
-        clients[0]->downloadRequested(info);
+        QTimer::singleShot(0, m_profileAdapter,
+                           [client = clients[0], info]() { client->downloadRequested(info); });
     } else
         cancelDownload(std::move(*callback));
 
@@ -326,7 +328,8 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content
     info.startTime = QDateTime::currentMSecsSinceEpoch();
 
     m_pendingSaves.emplace(m_currentId, std::move(callback));
-    clients[0]->downloadRequested(info);
+    QTimer::singleShot(0, m_profileAdapter,
+                       [client = clients[0], info]() { client->downloadRequested(info); });
 }
 
 void DownloadManagerDelegateQt::savePathDetermined(quint32 downloadId, bool accepted,
@@ -385,9 +388,8 @@ void DownloadManagerDelegateQt::OnDownloadUpdated(download::DownloadItem *downlo
         info.suggestedFileName = toQt(download->GetSuggestedFilename());
         info.startTime = download->GetStartTime().ToTimeT();
 
-        for (ProfileAdapterClient *client : std::as_const(clients)) {
-            client->downloadUpdated(info);
-        }
+        QTimer::singleShot(0, m_profileAdapter,
+                           [client = clients[0], info]() { client->downloadUpdated(info); });
     }
 }
 
diff --git a/src/core/profile_adapter_client.h b/src/core/profile_adapter_client.h
index aaeefb5440a..cb83e82799b 100644
--- a/src/core/profile_adapter_client.h
+++ b/src/core/profile_adapter_client.h
@@ -103,7 +103,7 @@ class Q_WEBENGINECORE_EXPORT ProfileAdapterClient
 
     virtual ~ProfileAdapterClient() { }
 
-    virtual void downloadRequested(DownloadItemInfo &info) = 0;
+    virtual void downloadRequested(const DownloadItemInfo &info) = 0;
     virtual void downloadUpdated(const DownloadItemInfo &info) = 0;
     virtual void showNotification(QSharedPointer<UserNotificationController> &) { }
 
diff --git a/src/webenginequick/api/qquickwebengineprofile.cpp b/src/webenginequick/api/qquickwebengineprofile.cpp
index e5308b43f6a..47f8a1e95a4 100644
--- a/src/webenginequick/api/qquickwebengineprofile.cpp
+++ b/src/webenginequick/api/qquickwebengineprofile.cpp
@@ -242,7 +242,7 @@ void QQuickWebEngineProfilePrivate::cleanDownloads()
     m_ongoingDownloads.clear();
 }
 
-void QQuickWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
+void QQuickWebEngineProfilePrivate::downloadRequested(const DownloadItemInfo &info)
 {
     Q_Q(QQuickWebEngineProfile);
 
diff --git a/src/webenginequick/api/qquickwebengineprofile_p.h b/src/webenginequick/api/qquickwebengineprofile_p.h
index 477936f98c4..fde24763665 100644
--- a/src/webenginequick/api/qquickwebengineprofile_p.h
+++ b/src/webenginequick/api/qquickwebengineprofile_p.h
@@ -50,7 +50,7 @@ class QQuickWebEngineProfilePrivate : public QtWebEngineCore::ProfileAdapterClie
 
     void cleanDownloads();
 
-    void downloadRequested(DownloadItemInfo &info) override;
+    void downloadRequested(const DownloadItemInfo &info) override;
     void downloadUpdated(const DownloadItemInfo &info) override;
 
     void showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &controller) override;
diff --git a/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp b/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
index c9f048976f3..b01d7b8c933 100644
--- a/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
+++ b/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
@@ -92,6 +92,7 @@ private Q_SLOTS:
     void downloadToDirectoryWithFileName();
     void downloadDataUrls_data();
     void downloadDataUrls();
+    void pauseDownload();
 
 private:
     void saveLink(QPoint linkPos);
@@ -1383,5 +1384,54 @@ void tst_QWebEngineDownloadRequest::downloadDataUrls()
     QTRY_COMPARE(downloadRequestCount, 1);
 }
 
+void tst_QWebEngineDownloadRequest::pauseDownload()
+{
+    const int fileSize = 1024 * 1024 * 512;
+
+    // Set up HTTP server
+    ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+        if (rr->requestMethod() == "GET" && rr->requestPath() == "/") {
+            rr->setResponseHeader(QByteArrayLiteral("content-type"),
+                                  QByteArrayLiteral("application/octet-stream"));
+            static const QByteArray bigfile(fileSize, '0');
+            rr->setResponseBody(bigfile);
+            rr->sendResponse();
+        }
+    });
+
+    // Set up profile and download handler
+    QTemporaryDir tmpDir;
+    QVERIFY(tmpDir.isValid());
+    m_profile->setDownloadPath(tmpDir.path());
+
+    bool firstBytesReceived = true;
+    int pausedCount = 0;
+    ScopedConnection sc2 = connect(
+            m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadRequest *item) {
+                QCOMPARE(item->state(), QWebEngineDownloadRequest::DownloadRequested);
+                connect(item, &QWebEngineDownloadRequest::receivedBytesChanged, [item, &firstBytesReceived] {
+                    if (firstBytesReceived) {
+                        firstBytesReceived = false;
+                        item->pause();
+                    }
+                });
+                connect(item, &QWebEngineDownloadRequest::isPausedChanged, [item, &pausedCount]() {
+                    if (item->isPaused()) {
+                        pausedCount++;
+                        item->resume();
+                    }
+                });
+                item->accept();
+            });
+
+    QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished);
+    m_view->load(m_server->url());
+    QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 10000);
+    QTRY_COMPARE_WITH_TIMEOUT(pausedCount, 1, 10000);
+    QTRY_COMPARE_WITH_TIMEOUT(m_finishedDownloads.size(), 1, 10000);
+    QTRY_COMPARE(m_finishedDownloads.values()[0]->isPaused(), false);
+    QTRY_COMPARE(m_finishedDownloads.values()[0]->receivedBytes(), fileSize);
+}
+
 QTEST_MAIN(tst_QWebEngineDownloadRequest)
 #include "tst_qwebenginedownloadrequest.moc"

From 3e19092ef719a5a25c350af0bf801eb00cb1bf1c Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Mon, 31 Mar 2025 15:39:26 +0000
Subject: [PATCH 311/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Ie2b2b1474d11adc75846b3ccd624af45c5082b5e
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 3245aafc1ed..680ebaf7a63 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 7b4837d3e34a206ccbd3b921e65f1401b09066ee
+    ref: 5a5b4e295b433c7cf4b9f391eb1bc1b9623d83b0
     required: true
   ../qtpositioning:
-    ref: 83cc61df4afb3b81da03c9ec6d3536b32d60b07d
+    ref: 2f486d06d23195263922f702cfdf4354eb5c5365
     required: false
   ../qttools:
-    ref: feda5851ddced220d26ce80624fca527dde0a0ea
+    ref: f8b263a8309e0d1db742cec9df7eb39aae382ecb
     required: false
   ../qtwebchannel:
-    ref: ca7d35059a0effe4fbdb57a1b5e604f3d815b12a
+    ref: 6d8d2689731e9337c7362355bc166e7ec7ee8361
     required: false

From 331461fb2c0a946318f043143512555ff383b463 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Fri, 28 Mar 2025 13:22:32 +0100
Subject: [PATCH 312/356] Fix flaky tst_qwebengineview::inputContextQueryInput

TestInputContext relies on focus object. Wait for the focus object to be
set before trying to record input.

Fixes: QTBUG-128440
Change-Id: Idc4a985d0f7305d13a4cb18f69da542c5e0469bd
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit eb9bde4be0ecfeaee58415d52d63f64b4fbfe5fa)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 55fbfea91ade85235ef1f3cc77c819e4dc219930)
---
 tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 0d9b078c064..a6383c63023 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -2069,6 +2069,7 @@ void tst_QWebEngineView::inputContextQueryInput()
                  "</body></html>");
     QTRY_COMPARE(loadFinishedSpy.size(), 1);
     QVERIFY(QTest::qWaitForWindowExposed(&view));
+    QTRY_VERIFY(qApp->focusObject());
     QCOMPARE(testContext.infos.size(), 0);
 
     // Set focus on an input field.

From 74930dda2ce4fff4bcd5914dde3d6f36412bccc2 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Wed, 2 Apr 2025 10:10:50 +0000
Subject: [PATCH 313/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Iaa056e2de57cc3a9e5fb0155e7f52814c906065d
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 680ebaf7a63..b615ef44ead 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 5a5b4e295b433c7cf4b9f391eb1bc1b9623d83b0
+    ref: 3103d51986b8b982267a768b7f29c249e942c81a
     required: true
   ../qtpositioning:
-    ref: 2f486d06d23195263922f702cfdf4354eb5c5365
+    ref: e062e3457e70fadee0e37ee4989b6f2fa693343f
     required: false
   ../qttools:
-    ref: f8b263a8309e0d1db742cec9df7eb39aae382ecb
+    ref: 45cb129d38b8025c7832320fa8ec3b54a286a07b
     required: false
   ../qtwebchannel:
-    ref: 6d8d2689731e9337c7362355bc166e7ec7ee8361
+    ref: e6969f5c5585463f75066cd8ac20203767bb7d48
     required: false

From df165e564b60822f2d66080e68e983455f9dc6cc Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Thu, 3 Apr 2025 09:24:23 +0000
Subject: [PATCH 314/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I3df296af90647b686e8be494f185b938424586e4
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index b615ef44ead..2c0ecb48769 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 3103d51986b8b982267a768b7f29c249e942c81a
+    ref: 253bed4ab8cd6f68d677c1dc8b459bb14cd37833
     required: true
   ../qtpositioning:
-    ref: e062e3457e70fadee0e37ee4989b6f2fa693343f
+    ref: 2b92855c184f342d99edddb91e53e887bf2b049e
     required: false
   ../qttools:
-    ref: 45cb129d38b8025c7832320fa8ec3b54a286a07b
+    ref: e2637b0c459f801d06df79fb68329cf0a76f0d10
     required: false
   ../qtwebchannel:
-    ref: e6969f5c5585463f75066cd8ac20203767bb7d48
+    ref: 57f6b62b83163335733e664de00877d370a09929
     required: false

From df01b4bcdfa1a5f15bfcbb60353f461e8ee4e492 Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Thu, 6 Feb 2025 16:24:03 +0100
Subject: [PATCH 315/356] Cleanup permissionbrowser example

Remove an unused member, dynamically populate the policy combo box so
its items and data stay synced, fix a documentation typo, and simplify a
few expressions.

Change-Id: I37997fbbeca51ed4c71c83a86d989917ce92b3df
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit a0da756ef2a3281ef32a063e9a5397aa29268ae6)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 927d80e518e1350f124696433c6b86461234a10b)
---
 .../doc/src/permissionbrowser.qdoc            |  2 +-
 .../permissionbrowser/mainwindow.cpp          | 47 +++++++------------
 .../permissionbrowser/mainwindow.h            |  6 +--
 .../permissionbrowser/mainwindow.ui           | 15 ------
 4 files changed, 21 insertions(+), 49 deletions(-)

diff --git a/examples/webenginewidgets/permissionbrowser/doc/src/permissionbrowser.qdoc b/examples/webenginewidgets/permissionbrowser/doc/src/permissionbrowser.qdoc
index 995d0046afe..8a394e5c8e4 100644
--- a/examples/webenginewidgets/permissionbrowser/doc/src/permissionbrowser.qdoc
+++ b/examples/webenginewidgets/permissionbrowser/doc/src/permissionbrowser.qdoc
@@ -193,7 +193,7 @@
     \list
         \li \l QWebEngineProfile::StoreOnDisk is the default, and it ensures
         that any permissions that have been granted in the current application run will be
-        loaded back up at next startup. A permission onlycneeds to be granted once, and
+        loaded back up at next startup. A permission only needs to be granted once, and
         subsequent uses of the API that triggered the request will automatically be granted,
         until the application calls QWebEnginePermission::reset().
         \li \l QWebEngineProfile::StoreInMemory Has the same behavior as above,
diff --git a/examples/webenginewidgets/permissionbrowser/mainwindow.cpp b/examples/webenginewidgets/permissionbrowser/mainwindow.cpp
index 8fd811e8383..1cc9b74efd6 100644
--- a/examples/webenginewidgets/permissionbrowser/mainwindow.cpp
+++ b/examples/webenginewidgets/permissionbrowser/mainwindow.cpp
@@ -9,30 +9,23 @@
 #include <QUrl>
 
 PermissionDialog::PermissionDialog(const QWebEngineProfile *profile, QWidget *parent)
-    : QDialog(parent)
-    , m_profile(profile)
-    , m_permission(nullptr)
+    : QDialog(parent), m_profile(profile)
 {
     setupUi(this);
 
     auto metaEnum = QMetaEnum::fromType<QWebEnginePermission::PermissionType>();
-    Q_ASSERT(metaEnum.value((quint8)QWebEnginePermission::PermissionType::Unsupported) == 0);
-    for (int i = 1; i < metaEnum.keyCount(); ++i) {
-        QWebEnginePermission::PermissionType permissionType = QWebEnginePermission::PermissionType(metaEnum.value(i));
+    for (int i = 0; i < metaEnum.keyCount(); ++i) {
+        auto permissionType = QWebEnginePermission::PermissionType(metaEnum.value(i));
         if (QWebEnginePermission::isPersistent(permissionType))
-            m_permissionTypeComboBox->addItem(metaEnum.valueToKey((quint8)permissionType), QVariant::fromValue(permissionType));
+            m_permissionTypeComboBox->addItem(metaEnum.key(i), QVariant::fromValue(permissionType));
     }
 }
 
-PermissionDialog::~PermissionDialog()
+QWebEnginePermission PermissionDialog::permission() const
 {
-    delete m_permission;
-}
-
-QWebEnginePermission PermissionDialog::permission()
-{
-    return m_profile->queryPermission(QUrl(m_originLineEdit->text()),
-        QWebEnginePermission::PermissionType(m_permissionTypeComboBox->itemData(m_permissionTypeComboBox->currentIndex()).toInt()));
+    return m_profile->queryPermission(
+            QUrl(m_originLineEdit->text()),
+            m_permissionTypeComboBox->currentData().value<QWebEnginePermission::PermissionType>());
 }
 
 PermissionWidget::PermissionWidget(const QWebEnginePermission &permission, QWidget *parent)
@@ -92,6 +85,13 @@ MainWindow::MainWindow(const QUrl &url)
     , m_pendingWidget(nullptr)
 {
     setupUi(this);
+
+    auto metaEnum = QMetaEnum::fromType<QWebEngineProfile::PersistentPermissionsPolicy>();
+    for (int i = 0; i < metaEnum.keyCount(); ++i) {
+        auto policy = QWebEngineProfile::PersistentPermissionsPolicy(metaEnum.value(i));
+        m_policyComboBox->addItem(metaEnum.key(i), QVariant::fromValue(policy));
+    }
+
     m_urlLineEdit->setText(url.toString());
 
     m_layout->addItem(new QSpacerItem(0,0, QSizePolicy::Minimum, QSizePolicy::Expanding));
@@ -204,21 +204,10 @@ void MainWindow::handleForwardClicked()
     m_webview->triggerPageAction(QWebEnginePage::Forward);
 }
 
-void MainWindow::handlePolicyComboBoxIndexChanged(int index)
+void MainWindow::handlePolicyComboBoxIndexChanged(int)
 {
-    QWebEngineProfile::PersistentPermissionsPolicy policy;
-    switch (index) {
-    case 0:
-        policy = QWebEngineProfile::PersistentPermissionsPolicy::AskEveryTime;
-        break;
-    case 1:
-        policy = QWebEngineProfile::PersistentPermissionsPolicy::StoreInMemory;
-        break;
-    case 2:
-        policy = QWebEngineProfile::PersistentPermissionsPolicy::StoreOnDisk;
-        break;
-    }
-
+    auto policy =
+            m_policyComboBox->currentData().value<QWebEngineProfile::PersistentPermissionsPolicy>();
     if (policy == m_profile->persistentPermissionsPolicy())
         return;
 
diff --git a/examples/webenginewidgets/permissionbrowser/mainwindow.h b/examples/webenginewidgets/permissionbrowser/mainwindow.h
index 8f7a0945035..ce239be8250 100644
--- a/examples/webenginewidgets/permissionbrowser/mainwindow.h
+++ b/examples/webenginewidgets/permissionbrowser/mainwindow.h
@@ -20,12 +20,10 @@ class PermissionDialog : public QDialog, public Ui_PermissionDialog
     Q_OBJECT
 public:
     PermissionDialog(const QWebEngineProfile *profile, QWidget *parent = nullptr);
-    ~PermissionDialog();
-    QWebEnginePermission permission();
+    QWebEnginePermission permission() const;
 
 private:
     const QWebEngineProfile *m_profile;
-    QWebEnginePermission *m_permission;
 };
 
 class PermissionWidget : public QWidget, public Ui_PermissionWidget
@@ -60,7 +58,7 @@ private slots:
     void handleRefreshClicked();
     void handleBackClicked();
     void handleForwardClicked();
-    void handlePolicyComboBoxIndexChanged(int index);
+    void handlePolicyComboBoxIndexChanged(int);
 
 private:
     bool containsPermission(const QWebEnginePermission &permission);
diff --git a/examples/webenginewidgets/permissionbrowser/mainwindow.ui b/examples/webenginewidgets/permissionbrowser/mainwindow.ui
index 4496b8c0782..2cef35130ab 100644
--- a/examples/webenginewidgets/permissionbrowser/mainwindow.ui
+++ b/examples/webenginewidgets/permissionbrowser/mainwindow.ui
@@ -215,21 +215,6 @@
             <property name="sizeAdjustPolicy">
              <enum>QComboBox::AdjustToContents</enum>
             </property>
-            <item>
-             <property name="text">
-              <string>Persist on disk</string>
-             </property>
-            </item>
-            <item>
-             <property name="text">
-              <string>Persist in memory</string>
-             </property>
-            </item>
-            <item>
-             <property name="text">
-              <string>Do not persist</string>
-             </property>
-            </item>
            </widget>
           </item>
          </layout>

From 15d1563cd11a76c7401ffcad2bae90eb56e5fbe2 Mon Sep 17 00:00:00 2001
From: Alexandru Croitor <alexandru.croitor@qt.io>
Date: Thu, 3 Apr 2025 14:47:02 +0200
Subject: [PATCH 316/356] CMake: Avoid CMP0174 warning due to empty
 NINJA_DATA_STAMP

Starting with CMake 3.31, the following warning is shown if the data
stamp option is passed an empty string:

CMake Warning (dev) at cmake/Functions.cmake:332
  (cmake_parse_arguments):
  The NINJA_DATA_STAMP keyword was followed by an empty string or no
  value at all.  Policy CMP0174 is not set, so cmake_parse_arguments()
  will unset the arg_NINJA_DATA_STAMP variable rather than setting it
  to an empty string.
Call Stack (most recent call first):
  src/core/CMakeLists.txt:615 (add_gn_build_artifacts_to_target)

Only pass the option if it has a value.

Change-Id: I19a38b2eb05ab902e4c176f36b2410f62c403d32
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 0c589dc6f46b27478066f18326a08077e7b3a35b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 669950582129dcefa22425f99a6d4e1f4d4e58ee)
---
 cmake/Functions.cmake   | 6 +++++-
 src/core/CMakeLists.txt | 5 +++--
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/cmake/Functions.cmake b/cmake/Functions.cmake
index 8d5a977771d..02276e46b91 100644
--- a/cmake/Functions.cmake
+++ b/cmake/Functions.cmake
@@ -1208,12 +1208,16 @@ function(add_gn_build_artifacts_to_target)
         foreach(arch ${archs})
             set(target ${arg_NINJA_TARGET}_${config}_${arch})
             set(stamps ${arg_NINJA_STAMP} ${arg_NINJA_DATA_STAMP})
+            set(data_stamp_option "")
+            if(arg_NINJA_DATA_STAMP)
+                set(data_stamp_option NINJA_DATA_STAMP ${arg_NINJA_DATA_STAMP})
+            endif()
             add_ninja_target(
                 TARGET ${target}
                 NINJA_TARGET ${arg_NINJA_TARGET}
                 CMAKE_TARGET ${arg_CMAKE_TARGET}
                 NINJA_STAMP ${arg_NINJA_STAMP}
-                NINJA_DATA_STAMP ${arg_NINJA_DATA_STAMP}
+                ${data_stamp_option}
                 CONFIG ${config}
                 ARCH ${arch}
                 BUILDDIR ${arg_BUILDDIR}
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 8059d1dcf90..487d0a004e2 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -589,8 +589,9 @@ target_include_directories(WebEngineCore PRIVATE
 )
 
 set(stamps QtWebEngineCore.stamp)
+set(dataStampOption "")
 if(QT_FEATURE_webengine_v8_context_snapshot)
-    set(dataStamp obj/tools/v8_context_snapshot/v8_context_snapshot.stamp)
+    set(dataStampOption NINJA_DATA_STAMP obj/tools/v8_context_snapshot/v8_context_snapshot.stamp)
 endif()
 
 add_gn_build_artifacts_to_target(
@@ -601,7 +602,7 @@ add_gn_build_artifacts_to_target(
     BUILDDIR ${buildDir}
     COMPLETE_STATIC FALSE
     NINJA_STAMP QtWebEngineCore.stamp
-    NINJA_DATA_STAMP ${dataStamp}
+    ${dataStampOption}
 )
 add_dependencies(WebEngineCore run_core_NinjaDone)
 if(COIN_BUG_699)

From 3c1488eb0c114742b12c00e50f2b3cd44050b0fa Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Tue, 4 Feb 2025 13:53:33 +0100
Subject: [PATCH 317/356] CMake: silence warning configuring examples

When configuring qtwebengine as its own module, Svg is not searched as
an optional component, leading to the warning in
examples/pdf/CMakeLists.txt always being printed even when QtSvg is
available.

Add Svg as an optional package in find_package and move the checks
into the individual examples so the warning will also appear when the
individual example is built.

Change-Id: I387dfd70ae1abc1a70f28dbfe74ac45b75bdf387
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 50db3f69ec74926ffc360c865a8c0e1740e2ca64)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 9575d9c2acb57abde7139ca0e67c83f71a98749e)
---
 examples/pdf/CMakeLists.txt            | 3 ---
 examples/pdf/multipage/CMakeLists.txt  | 5 ++++-
 examples/pdf/singlepage/CMakeLists.txt | 5 ++++-
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/examples/pdf/CMakeLists.txt b/examples/pdf/CMakeLists.txt
index bdc1d0f0524..7255752b814 100644
--- a/examples/pdf/CMakeLists.txt
+++ b/examples/pdf/CMakeLists.txt
@@ -3,6 +3,3 @@
 
 qt_internal_add_example(singlepage)
 qt_internal_add_example(multipage)
-if(NOT TARGET Qt::Svg)
-    message(WARNING "QtSvg is required as runtime dependency for qtpdfquick examples.")
-endif()
diff --git a/examples/pdf/multipage/CMakeLists.txt b/examples/pdf/multipage/CMakeLists.txt
index 8f8111c826d..fb4e449fd7a 100644
--- a/examples/pdf/multipage/CMakeLists.txt
+++ b/examples/pdf/multipage/CMakeLists.txt
@@ -12,7 +12,10 @@ endif()
 
 set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/pdf/multipage")
 
-find_package(Qt6 REQUIRED COMPONENTS Gui Qml)
+find_package(Qt6 REQUIRED COMPONENTS Gui Qml OPTIONAL_COMPONENTS Svg)
+if(NOT TARGET Qt::Svg)
+    message(WARNING "QtSvg is required as runtime dependency for qtpdfquick examples.")
+endif()
 
 qt_add_executable(multipage
     main.cpp
diff --git a/examples/pdf/singlepage/CMakeLists.txt b/examples/pdf/singlepage/CMakeLists.txt
index fac95f54a98..647a30f8d4d 100644
--- a/examples/pdf/singlepage/CMakeLists.txt
+++ b/examples/pdf/singlepage/CMakeLists.txt
@@ -12,7 +12,10 @@ endif()
 
 set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/pdf/singlepage")
 
-find_package(Qt6 REQUIRED COMPONENTS Gui Qml)
+find_package(Qt6 REQUIRED COMPONENTS Gui Qml OPTIONAL_COMPONENTS Svg)
+if(NOT TARGET Qt::Svg)
+    message(WARNING "QtSvg is required as runtime dependency for qtpdfquick examples.")
+endif()
 
 qt_add_executable(pdfviewerquick
     main.cpp

From 2a3d355db0516e428594632ec94c46cd10d08332 Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Mon, 7 Apr 2025 20:09:12 +0000
Subject: [PATCH 318/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I087e179a2e914b55262c02e2556a648272364aa9
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 2c0ecb48769..349f94d6da0 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 253bed4ab8cd6f68d677c1dc8b459bb14cd37833
+    ref: 32452675dc7661de32013969f9d2eb613da70096
     required: true
   ../qtpositioning:
-    ref: 2b92855c184f342d99edddb91e53e887bf2b049e
+    ref: 73e77ed97a9384eb73140b83a364d3866358e364
     required: false
   ../qttools:
-    ref: e2637b0c459f801d06df79fb68329cf0a76f0d10
+    ref: 31ec5e9c0f3388756d06aa8ffd1c59c5f097dbaa
     required: false
   ../qtwebchannel:
-    ref: 57f6b62b83163335733e664de00877d370a09929
+    ref: 5d51387a00af8cb76ca7e879583f398faef1f602
     required: false

From 23d1c956c243d3bab5fd8e2d8e12526fe9166907 Mon Sep 17 00:00:00 2001
From: Alexandru Croitor <alexandru.croitor@qt.io>
Date: Fri, 4 Apr 2025 17:22:20 +0200
Subject: [PATCH 319/356] CMake: Fix QtWebEngine deployment when DESTDIR is set

If DESTDIR is set, the install destination for all files should be
$ENV{DESTDIR}/${CMAKE_INSTALL_PREFIX} by default. And that is the
actual default value for QT_DEPLOY_PREFIX.

The problem is that file(INSTALL) always prepends $ENV{DESTDIR} to the
install destination, which when used with QT_DEPLOY_PREFIX results in
DESTDIR being prepended twice to a path.

Change the code to use CMAKE_INSTALL_PREFIX for file(INSTALL)
commands and QT_DEPLOY_PREFIX for other commands.

This was discovered while trying to create an installer for a deployed
WebEngine application using CPack, which always sets a DESTDIR.

Amends 73d58b489e8f4f900042f0ab6c1104e6431752e1

Fixes: QTBUG-135620
Task-number: QTBUG-109553
Task-number: QTBUG-119077
Change-Id: I5860c58454d6a204b36b2185b76b6f974e88f652
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit 19fac197602effd0f46b511753098b5191d2e964)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 2889a6136cca7f7dfb8250c64c105b878129c8c6)
---
 .../api/Qt6WebEngineCoreDeploySupport.cmake   | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/src/core/api/Qt6WebEngineCoreDeploySupport.cmake b/src/core/api/Qt6WebEngineCoreDeploySupport.cmake
index e67eb212b3d..a74616bc3b7 100644
--- a/src/core/api/Qt6WebEngineCoreDeploySupport.cmake
+++ b/src/core/api/Qt6WebEngineCoreDeploySupport.cmake
@@ -74,24 +74,31 @@ function(_qt_internal_deploy_webenginecore_binary)
         endif()
     endforeach()
 
-    set(install_destination "${QT_DEPLOY_PREFIX}/")
+    # CMAKE_INSTALL_PREFIX does not contain $ENV{DESTDIR}, whereas QT_DEPLOY_PREFIX does.
+    # The install_ variant should be used in file(INSTALL) to avoid double DESTDIR in paths.
+    # Other code should reference the destdir_ variant instead.
+    set(install_destination "${CMAKE_INSTALL_PREFIX}/")
+    set(destdir_destination "${QT_DEPLOY_PREFIX}/")
+
     if(__QT_DEPLOY_SYSTEM_NAME STREQUAL "Windows")
         string(APPEND install_destination "${QT_DEPLOY_BIN_DIR}")
+        string(APPEND destdir_destination "${QT_DEPLOY_BIN_DIR}")
     else()
         string(APPEND install_destination "${QT_DEPLOY_LIBEXEC_DIR}")
+        string(APPEND destdir_destination "${QT_DEPLOY_LIBEXEC_DIR}")
     endif()
     file(INSTALL "${process_path}" DESTINATION "${install_destination}")
 
     get_filename_component(process_file_name "${process_path}" NAME)
     if(CMAKE_VERSION GREATER_EQUAL "3.19")
-        file(CHMOD "${install_destination}/${process_file_name}"
+        file(CHMOD "${destdir_destination}/${process_file_name}"
             PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE
                         GROUP_EXECUTE GROUP_READ
                         WORLD_EXECUTE WORLD_READ
         )
     else()
         execute_process(
-            COMMAND chmod 0755 "${install_destination}/${process_file_name}"
+            COMMAND chmod 0755 "${destdir_destination}/${process_file_name}"
         )
     endif()
 endfunction()
@@ -117,8 +124,9 @@ function(_qt_internal_deploy_webenginecore_data)
         list(APPEND data_files "${snapshot_file}")
     endif()
 
+    # See comment above why we use CMAKE_INSTALL_PREFIX instead of QT_DEPLOY_PREFIX.
     get_filename_component(install_destination "${QT_DEPLOY_WEBENGINECORE_RESOURCES_DIR}" ABSOLUTE
-        BASE_DIR "${QT_DEPLOY_PREFIX}/${QT_DEPLOY_DATA_DIR}"
+        BASE_DIR "${CMAKE_INSTALL_PREFIX}/${QT_DEPLOY_DATA_DIR}"
     )
     foreach(data_file IN LISTS data_files)
         file(INSTALL "${resources_dir}/${data_file}" DESTINATION "${install_destination}")
@@ -163,8 +171,9 @@ function(_qt_internal_deploy_webenginecore_translations)
     get_filename_component(locales_dir "qtwebengine_locales" ABSOLUTE
         BASE_DIR "${__QT_DEPLOY_QT_INSTALL_PREFIX}/${__QT_DEPLOY_QT_INSTALL_TRANSLATIONS}"
     )
+    # See comment above why we use CMAKE_INSTALL_PREFIX instead of QT_DEPLOY_PREFIX.
     get_filename_component(install_destination "qtwebengine_locales" ABSOLUTE
-        BASE_DIR "${QT_DEPLOY_PREFIX}/${QT_DEPLOY_TRANSLATIONS_DIR}"
+        BASE_DIR "${CMAKE_INSTALL_PREFIX}/${QT_DEPLOY_TRANSLATIONS_DIR}"
     )
     file(GLOB locale_files "${locales_dir}/*.pak")
     foreach(locale_file IN LISTS locale_files)

From baf86f78b9de95b4a5727bccb9c6eca19e0cf008 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 6 Mar 2025 09:56:13 +0100
Subject: [PATCH 320/356] Add "default" and "gl" ANGLE implementation support
 to Ozone

The EGL_EXT_image_dma_buf_import display extension is not available for
non EGL display thus importing NativePixmap with EGL is not possible.
Make possible to import NativePixmap as X11 pixmap.

This makes
--webEngineArgs --use-gl=angle
--webEngineArgs --use-gl=angle --use-angle=default
--webEngineArgs --use-gl=angle --use-angle=gl
configurations work on Linux.

Merge conflict resolution for 6.8:
- Adapt to guards around header includes
- NativePixmapEGLBinding::IsBufferFormatSupported() and
  NativePixmapEGLX11Binding::IsBufferFormatSupported() are not available
  in 122-based Chromium

Task-number: QTBUG-129769
Task-number: QTBUG-133570
Change-Id: Ic6a40de373c5fd27c62abc3effb2f3ddee9210a8
Reviewed-by: Moss Heim <moss.heim@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 75b0d12f6a7f506d8d06a96ab4aa77d89358becd)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit a56ea1e9cf1004d475932dc954c9cc494fbf32b1)
---
 src/core/configure/BUILD.root.gn.in  |  3 ++
 src/core/ozone/gl_ozone_angle_qt.cpp | 53 +++++++++++++++++++++++++---
 2 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/src/core/configure/BUILD.root.gn.in b/src/core/configure/BUILD.root.gn.in
index 42b06d4f7b7..c5cef0c7606 100644
--- a/src/core/configure/BUILD.root.gn.in
+++ b/src/core/configure/BUILD.root.gn.in
@@ -391,11 +391,14 @@ source_set("qtwebengine_sources") {
       deps += [
         "//ui/base/x:gl",
         "//ui/gfx/linux:gpu_memory_buffer_support_x11",
+        "//ui/gfx/x",
       ]
 
       sources += [
         "//ui/ozone/platform/x11/gl_egl_utility_x11.cc",
         "//ui/ozone/platform/x11/gl_egl_utility_x11.h",
+        "//ui/ozone/platform/x11/native_pixmap_egl_x11_binding.cc",
+        "//ui/ozone/platform/x11/native_pixmap_egl_x11_binding.h",
       ]
     }
   }
diff --git a/src/core/ozone/gl_ozone_angle_qt.cpp b/src/core/ozone/gl_ozone_angle_qt.cpp
index 66692ed09a6..13258e4247f 100644
--- a/src/core/ozone/gl_ozone_angle_qt.cpp
+++ b/src/core/ozone/gl_ozone_angle_qt.cpp
@@ -1,6 +1,10 @@
-// Copyright (C) 2024 The Qt Company Ltd.
+// Copyright (C) 2025 The Qt Company Ltd.
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
 
+// Copyright 2016 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
 #if defined(USE_OZONE)
 #include "gl_context_qt.h"
 #include "gl_ozone_angle_qt.h"
@@ -15,6 +19,8 @@
 
 #if BUILDFLAG(IS_OZONE_X11)
 #include "ui/gl/gl_glx_api_implementation.h"
+
+#include "ui/ozone/platform/x11/native_pixmap_egl_x11_binding.h"
 #endif
 
 extern "C" {
@@ -23,6 +29,34 @@ extern __eglMustCastToProperFunctionPointerType EGL_GetProcAddress(const char *p
 }
 
 namespace ui {
+namespace {
+// Based on //ui/ozone/platform/x11/x11_surface_factory.cc
+enum class NativePixmapSupportType {
+    // Importing native pixmaps not supported.
+    kNone,
+
+    // Native pixmaps are imported directly into EGL using the
+    // EGL_EXT_image_dma_buf_import extension.
+    kDMABuf,
+
+    // Native pixmaps are first imported as X11 pixmaps using DRI3 and then into
+    // EGL.
+    kX11Pixmap,
+};
+
+NativePixmapSupportType GetNativePixmapSupportType()
+{
+    if (gl::GLSurfaceEGL::GetGLDisplayEGL()->ext->b_EGL_EXT_image_dma_buf_import)
+        return NativePixmapSupportType::kDMABuf;
+
+#if BUILDFLAG(IS_OZONE_X11)
+    if (NativePixmapEGLX11Binding::CanImportNativeGLXPixmap())
+        return NativePixmapSupportType::kX11Pixmap;
+#endif
+
+    return NativePixmapSupportType::kNone;
+}
+} // namespace
 
 bool GLOzoneANGLEQt::LoadGLES2Bindings(const gl::GLImplementationParts & /*implementation*/)
 {
@@ -101,7 +135,7 @@ gl::EGLDisplayPlatform GLOzoneANGLEQt::GetNativeDisplay()
 
 bool GLOzoneANGLEQt::CanImportNativePixmap()
 {
-    return gl::GLSurfaceEGL::GetGLDisplayEGL()->ext->b_EGL_EXT_image_dma_buf_import;
+    return GetNativePixmapSupportType() != NativePixmapSupportType::kNone;
 }
 
 std::unique_ptr<NativePixmapGLBinding>
@@ -110,8 +144,19 @@ GLOzoneANGLEQt::ImportNativePixmap(scoped_refptr<gfx::NativePixmap> pixmap,
                                    gfx::Size plane_size, const gfx::ColorSpace &color_space,
                                    GLenum target, GLuint texture_id)
 {
-    return NativePixmapEGLBinding::Create(pixmap, plane_format, plane, plane_size, color_space,
-                                          target, texture_id);
+    switch (GetNativePixmapSupportType()) {
+    case NativePixmapSupportType::kDMABuf:
+        return NativePixmapEGLBinding::Create(pixmap, plane_format, plane, plane_size, color_space,
+                                              target, texture_id);
+#if BUILDFLAG(IS_OZONE_X11)
+    case NativePixmapSupportType::kX11Pixmap:
+        return NativePixmapEGLX11Binding::Create(pixmap, plane_format, plane_size, target,
+                                                 texture_id);
+#endif
+    default:
+        NOTREACHED();
+        return nullptr;
+    }
 }
 
 } // namespace ui

From ad147705c6e248fc423096ebcea94c2c9866b252 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Mon, 24 Mar 2025 10:53:12 +0100
Subject: [PATCH 321/356] NativeSkiaOutputDeviceOpenGL: Fix leaking X11 Pixmap

Merge conflict resolution for 6.8:
- No GLXHelper in 6.8, call xcb_free_pixmap() through Chromium's xcb
  protos

Fixes: QTBUG-135047
Change-Id: I42b6387407551079241350661adadedf7d71a303
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit dbf459268d4bbc20e0a7e83e7889e0f6da79cf84)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 08f793a6ef5da886e1282a3fb9a2829bd14413b2)
---
 .../compositor/native_skia_output_device_opengl.cpp    | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/core/compositor/native_skia_output_device_opengl.cpp b/src/core/compositor/native_skia_output_device_opengl.cpp
index deccd247b8d..d418bfe5c97 100644
--- a/src/core/compositor/native_skia_output_device_opengl.cpp
+++ b/src/core/compositor/native_skia_output_device_opengl.cpp
@@ -106,6 +106,12 @@ x11::Pixmap XPixmapFromNativePixmap(const gfx::NativePixmap &nativePixmap)
     return pixmapId;
 }
 
+void FreeXPixmap(x11::Pixmap pixmap)
+{
+    auto *connection = x11::Connection::Get();
+    connection->FreePixmap({ pixmap });
+}
+
 GLXFBConfig GetFBConfig(Display *display)
 {
     // clang-format off
@@ -269,9 +275,11 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
             glXBindTexImageEXT(display, glxPixmap, GLX_FRONT_LEFT_EXT, nullptr);
             glFun->glBindTexture(GL_TEXTURE_2D, 0);
 
-            m_frontBuffer->textureCleanupCallback = [glFun, glTexture, display, glxPixmap]() {
+            m_frontBuffer->textureCleanupCallback = [glFun, glTexture, display, glxPixmap,
+                                                     pixmapId]() {
                 glFun->glDeleteTextures(1, &glTexture);
                 glXDestroyGLXPixmap(display, glxPixmap);
+                FreeXPixmap(pixmapId);
             };
         }
 #endif // BUILDFLAG(IS_OZONE_X11)

From 2af24f9058442ea123eaea303316297b2f6c2f3f Mon Sep 17 00:00:00 2001
From: Alexandru Croitor <alexandru.croitor@qt.io>
Date: Mon, 7 Apr 2025 15:21:46 +0200
Subject: [PATCH 322/356] CMake: Adjust rpath of WebEngineProcess binary during
 deployment

If the deployed lib dir is different from the Qt configured one (e.g.
lib64 vs lib), __QT_DEPLOY_MUST_ADJUST_PLUGINS_RPATH will be set to
true.

In that case we need to adjust the rpath of the WebEngineProcess
binary to point to the new lib dir.

Amends 73d58b489e8f4f900042f0ab6c1104e6431752e1

Fixes: QTBUG-135620
Task-number: QTBUG-109553
Task-number: QTBUG-119077
Change-Id: Ic8b730386f4ab7d77da7e1ffb44d8482bd150209
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
(cherry picked from commit a46b19e16f629d013c9b55d200b3fa645489bd5a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 77b4452f8369ce4646a7cafff3d01f33ac7b5154)
---
 src/core/api/Qt6WebEngineCoreDeploySupport.cmake | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/core/api/Qt6WebEngineCoreDeploySupport.cmake b/src/core/api/Qt6WebEngineCoreDeploySupport.cmake
index a74616bc3b7..b6f8b146380 100644
--- a/src/core/api/Qt6WebEngineCoreDeploySupport.cmake
+++ b/src/core/api/Qt6WebEngineCoreDeploySupport.cmake
@@ -101,6 +101,19 @@ function(_qt_internal_deploy_webenginecore_binary)
             COMMAND chmod 0755 "${destdir_destination}/${process_file_name}"
         )
     endif()
+
+    # Checking for __QT_DEPLOY_MUST_ADJUST_PLUGINS_RPATH is a bit strange because this is not a
+    # plugin, but it gives a single common way to detect when the rpath adjustment must be done,
+    # because the lib dir is different than the original Qt configured one.
+    if(__QT_DEPLOY_MUST_ADJUST_PLUGINS_RPATH)
+        _qt_internal_get_rpath_origin(rpath_origin)
+        file(RELATIVE_PATH rel_lib_dir "${destdir_destination}"
+            "${QT_DEPLOY_PREFIX}/${QT_DEPLOY_LIB_DIR}")
+        _qt_internal_set_rpath(
+            FILE "${destdir_destination}/${process_file_name}"
+            NEW_RPATH "${rpath_origin}/${rel_lib_dir}"
+        )
+    endif()
 endfunction()
 
 function(_qt_internal_deploy_webenginecore_data)

From 61bfe4b78dd863e13b7664812f2ad0f1fd343386 Mon Sep 17 00:00:00 2001
From: Alexandru Croitor <alexandru.croitor@qt.io>
Date: Thu, 3 Apr 2025 14:44:05 +0200
Subject: [PATCH 323/356] CMake: Stop passing DEPENDS to addCopyCommand

addCopyCommand uses add_custom_target(POST_BUILD) which does not
accept the DEPENDS argument. This was causing the following warning
with CMake 3.31:

CMake Warning (dev) at cmake/Functions.cmake:469 (add_custom_command):
  The following keywords are not supported when using
  add_custom_command(TARGET): DEPENDS.

  Policy CMP0175 is not set: add_custom_command() rejects invalid
  arguments.
  Run "cmake --help-policy CMP0175" for policy details.  Use the
  cmake_policy command to set the policy and suppress this warning.
Call Stack (most recent call first):
  src/core/api/CMakeLists.txt:241 (addCopyCommand)

Stop passing the DEPENDS option.

Change-Id: If58c3fa12f484b1ddf3136c79756f917bb8cfec3
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit 324a4f6bec6a4612e4534d41e9a27ab6db480eca)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit c4b39cac33b5b567f908cf16ff5430a0a16e2d07)
---
 cmake/Functions.cmake | 1 -
 1 file changed, 1 deletion(-)

diff --git a/cmake/Functions.cmake b/cmake/Functions.cmake
index 02276e46b91..5788efea56a 100644
--- a/cmake/Functions.cmake
+++ b/cmake/Functions.cmake
@@ -1352,7 +1352,6 @@ function(addCopyCommand target src dst)
         COMMAND ${CMAKE_COMMAND} -E make_directory ${dst}
         COMMAND ${CMAKE_COMMAND} -E copy ${src} ${dst}
         TARGET ${target}
-        DEPENDS ${src}
         USES_TERMINAL
     )
 endfunction()

From 97947de3e897515bfafb24246a52afc4f6c3c8ad Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Fri, 28 Mar 2025 09:38:15 +0100
Subject: [PATCH 324/356] Fix detection of VMware graphics driver

Amends 83e85bebc Add more vendors to GPU detection

Fixes: QTBUG-126722
Change-Id: Ie14c66d593e6ac8e1b55c377b73895397ef373ca
Reviewed-by: Moss Heim <moss.heim@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 0738a7eca23acf1a14bdc37855245391f4b145cf)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit e6c6ea2f68b79e6cb4aec38a2485d985e42ae1b9)
---
 src/core/web_engine_context.cpp | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index bc84b68fee3..5d99dc70f43 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -151,7 +151,7 @@ class GPUInfo
         Qualcomm,
         Samsung,
         Broadcom,
-        VMWare,
+        VMware,
         VirtIO,
 
         // Khronos-registered vendors
@@ -186,7 +186,7 @@ class GPUInfo
             {0x5143, Qualcomm},
             {0x144D, Samsung},
             {0x14E4, Broadcom},
-            {0x15AD, VMWare},
+            {0x15AD, VMware},
             {0x1AF4, VirtIO},
             {0x10001, Vivante},
             {0x10002, VeriSilicon},
@@ -214,6 +214,8 @@ class GPUInfo
             return Intel;
         if (deviceName.contains("Nvidia"_L1, Qt::CaseInsensitive))
             return Nvidia;
+        if (deviceName.contains("VMware"_L1, Qt::CaseInsensitive))
+            return VMware;
 
 #if defined(USE_OZONE)
         if (deviceName.contains("Mesa llvmpipe"_L1))
@@ -244,7 +246,7 @@ class GPUInfo
             {Qualcomm, "Qualcomm"},
             {Samsung, "Samsung"},
             {Broadcom, "Broadcom"},
-            {VMWare, "VMWare"},
+            {VMware, "VMware"},
             {VirtIO, "VirtIO"},
             {Vivante, "Vivante"},
             {VeriSilicon, "VeriSilicon"},

From bbf9599da65065a8418a6335eb7a2bfb09bbafa9 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Tue, 25 Mar 2025 14:53:38 +0100
Subject: [PATCH 325/356] NativeSkiaOutputDeviceVulkan: Use minimal set of
 usage flags for VkImage

VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT usage flag is not necessary because
the native VkImage imported into QSG seems to be only accessed via
sampling. VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT also seems to conflict
with the VK_IMAGE_LAYOUT_UNDEFINED initial layout with Nvidia driver.
VK_IMAGE_LAYOUT_UNDEFINED is a requirement for importing external
texture from Chromium.

Keep VK_IMAGE_USAGE_SAMPLE_BIT usage flag because it is a requirement
for sampling.

Remove the corressponding VK_IMAGE_LAYOUT_PRINITIALIZED initial layout
workaround for Nvidia. It is not necessary without the
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT flag and fixes validation layer
warning.

Also remove VK_IMAGE_USAGE_TRANSFER_DST_BIT and
VK_IMAGE_TRANSFER_SRC_BIT usage flags because those are not used and
seem to be leftover from an earlier implementation.

Task-number: QTBUG-123607
Change-Id: If9dba4b6ff9d584e3d103ec8d05b7fe0cdaec339
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit f88fa0c83c7f0c063475539b327065f8615fe9d7)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit b829ca7c36d3d525b3f794d8c3ebf3417bdcb43a)
---
 .../native_skia_output_device_vulkan.cpp      | 24 +++++--------------
 1 file changed, 6 insertions(+), 18 deletions(-)

diff --git a/src/core/compositor/native_skia_output_device_vulkan.cpp b/src/core/compositor/native_skia_output_device_vulkan.cpp
index 428dc06cf65..d65a609b94f 100644
--- a/src/core/compositor/native_skia_output_device_vulkan.cpp
+++ b/src/core/compositor/native_skia_output_device_vulkan.cpp
@@ -112,16 +112,6 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
     QVulkanFunctions *f = win->vulkanInstance()->functions();
     QVulkanDeviceFunctions *df = win->vulkanInstance()->deviceFunctions(qtVulkanDevice);
 
-    VkImageLayout imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
-    VkPhysicalDeviceProperties deviceProperties;
-    f->vkGetPhysicalDeviceProperties(qtPhysicalDevice, &deviceProperties);
-    if (deviceProperties.vendorID == 0x10DE) {
-        // FIXME: This is a workaround for Nvidia driver.
-        // The imported image is empty if the initialLayout is not
-        // VK_IMAGE_LAYOUT_PREINITIALIZED.
-        imageLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
-    }
-
     VkExternalMemoryImageCreateInfoKHR externalMemoryImageCreateInfo = {
         .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR,
         .pNext = nullptr,
@@ -210,10 +200,6 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
     Q_ASSERT(sharedHandle != INVALID_HANDLE_VALUE);
 #endif
 
-    constexpr VkImageUsageFlags kUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
-            | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT
-            | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
-
     VkImageCreateInfo importedImageCreateInfo = {
         .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
         .pNext = &externalMemoryImageCreateInfo,
@@ -229,11 +215,13 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
         .arrayLayers = 1,
         .samples = VK_SAMPLE_COUNT_1_BIT,
         .tiling = VK_IMAGE_TILING_OPTIMAL,
-        .usage = kUsage,
+        // The image is fed into a combined image sampler
+        .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
         .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
         .queueFamilyIndexCount = 0,
         .pQueueFamilyIndices = nullptr,
-        .initialLayout = imageLayout,
+        // VkExternalMemoryImageCreateInfo only allows UNDEFINED
+        .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
     };
 
 #if defined(USE_OZONE)
@@ -314,8 +302,8 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
     df->vkBindImageMemory(qtVulkanDevice, importedImage, importedImageMemory, 0);
 
     QQuickWindow::CreateTextureOptions texOpts(textureOptions);
-    QSGTexture *texture = QNativeInterface::QSGVulkanTexture::fromNative(importedImage, imageLayout,
-                                                                         win, size(), texOpts);
+    QSGTexture *texture = QNativeInterface::QSGVulkanTexture::fromNative(
+            importedImage, importedImageCreateInfo.initialLayout, win, size(), texOpts);
 
     m_frontBuffer->textureCleanupCallback = [=]() {
         df->vkDestroyImage(qtVulkanDevice, importedImage, nullptr);

From 778386987677cf17fd77323fe74464ed55b78d24 Mon Sep 17 00:00:00 2001
From: Ulf Hermann <ulf.hermann@qt.io>
Date: Wed, 9 Apr 2025 15:32:51 +0200
Subject: [PATCH 326/356] Turn webEngineCertificateError into a well-behaved
 value type

Allow a nullptr as the controller and add an "Ok" value to the enum to
signify "no error". This is in line with the "OK" value in Chromium's
net_errors.h. Furthermore, add a public default ctor to allow QMetaType
to create it.

Task-number: QTBUG-108649
Fixes: QTBUG-135032
Change-Id: Id06db78f273805ba117eefaa0ada3eac2f538962
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit ba79e85eb5e7e28ff494c95d405164d8b25583d7)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 3a8022c68c8598b4c5ab39b782113c11fbc2bd73)
---
 src/core/api/qwebenginecertificateerror.cpp  | 34 ++++++++++++++------
 src/core/api/qwebenginecertificateerror.h    |  3 ++
 tests/auto/quick/publicapi/tst_publicapi.cpp |  1 +
 3 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/src/core/api/qwebenginecertificateerror.cpp b/src/core/api/qwebenginecertificateerror.cpp
index 85c5d512752..60ec3c95b19 100644
--- a/src/core/api/qwebenginecertificateerror.cpp
+++ b/src/core/api/qwebenginecertificateerror.cpp
@@ -42,6 +42,7 @@ QWebEngineCertificateError::~QWebEngineCertificateError() = default;
     QSslError::SslError values are not used directly, because the Qt error
     categories cannot be mapped to the Chromium error categories.
 
+    \value Ok There was no actual certificate error.
     \value SslPinnedKeyNotInCertificateChain The certificate did not match the built-in public keys
             pinned for the host name.
     \value CertificateCommonNameInvalid The certificate's common name did not match the host name.
@@ -74,7 +75,9 @@ QWebEngineCertificateError::~QWebEngineCertificateError() = default;
 */
 bool QWebEngineCertificateError::isOverridable() const
 {
-    return d->overridable();
+    if (Q_LIKELY(d))
+        return d->overridable();
+    return false;
 }
 
 /*!
@@ -84,7 +87,9 @@ bool QWebEngineCertificateError::isOverridable() const
 */
 QUrl QWebEngineCertificateError::url() const
 {
-    return d->url();
+    if (Q_LIKELY(d))
+        return d->url();
+    return QUrl();
 }
 
 /*!
@@ -97,7 +102,9 @@ QUrl QWebEngineCertificateError::url() const
 */
 bool QWebEngineCertificateError::isMainFrame() const
 {
-    return d->isMainFrame();
+    if (Q_LIKELY(d))
+        return d->isMainFrame();
+    return false;
 }
 
 /*!
@@ -107,7 +114,9 @@ bool QWebEngineCertificateError::isMainFrame() const
 */
 QWebEngineCertificateError::Type QWebEngineCertificateError::type() const
 {
-    return d->error();
+    if (Q_LIKELY(d))
+        return d->error();
+    return Ok;
 }
 
 /*!
@@ -117,7 +126,9 @@ QWebEngineCertificateError::Type QWebEngineCertificateError::type() const
 */
 QString QWebEngineCertificateError::description() const
 {
-    return d->errorString();
+    if (Q_LIKELY(d))
+        return d->errorString();
+    return QString();
 }
 
 /*!
@@ -135,7 +146,8 @@ QString QWebEngineCertificateError::description() const
 */
 void QWebEngineCertificateError::defer()
 {
-    d->defer();
+    if (Q_LIKELY(d))
+        d->defer();
 }
 
 /*!
@@ -145,7 +157,8 @@ void QWebEngineCertificateError::defer()
 */
 void QWebEngineCertificateError::acceptCertificate()
 {
-    d->ignoreCertificateError();
+    if (Q_LIKELY(d))
+        d->ignoreCertificateError();
 }
 
 /*!
@@ -155,7 +168,8 @@ void QWebEngineCertificateError::acceptCertificate()
 */
 void QWebEngineCertificateError::rejectCertificate()
 {
-    d->rejectCertificate();
+    if (Q_LIKELY(d))
+        d->rejectCertificate();
 }
 
 /*!
@@ -167,7 +181,9 @@ void QWebEngineCertificateError::rejectCertificate()
 */
 QList<QSslCertificate> QWebEngineCertificateError::certificateChain() const
 {
-    return d->certificateChain();
+    if (Q_LIKELY(d))
+        return d->certificateChain();
+    return QList<QSslCertificate>();
 }
 
 QT_END_NAMESPACE
diff --git a/src/core/api/qwebenginecertificateerror.h b/src/core/api/qwebenginecertificateerror.h
index 3eef3dcca58..73a3ac09099 100644
--- a/src/core/api/qwebenginecertificateerror.h
+++ b/src/core/api/qwebenginecertificateerror.h
@@ -27,12 +27,15 @@ class Q_WEBENGINECORE_EXPORT QWebEngineCertificateError
     Q_PROPERTY(bool isMainFrame READ isMainFrame CONSTANT FINAL REVISION(6, 8))
 
 public:
+    QWebEngineCertificateError() = default;
     QWebEngineCertificateError(const QWebEngineCertificateError &other);
     QWebEngineCertificateError &operator=(const QWebEngineCertificateError &other);
     ~QWebEngineCertificateError();
 
     // Keep this identical to NET_ERROR in net_error_list.h, or add mapping layer.
     enum Type {
+        Ok = 0, // No actual error. See net_errors.h for that one
+
         SslPinnedKeyNotInCertificateChain = -150,
         CertificateCommonNameInvalid = -200,
         CertificateDateInvalid = -201,
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index 499acbfc51e..10b07f36050 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -138,6 +138,7 @@ static const QStringList expectedAPI = QStringList()
     << "QWebEngineCertificateError.CertificateSymantecLegacy --> Type"
     << "QWebEngineCertificateError.SslObsoleteVersion --> Type"
     << "QWebEngineCertificateError.SslPinnedKeyNotInCertificateChain --> Type"
+    << "QWebEngineCertificateError.Ok --> Type"
     << "QWebEngineCertificateError.defer() --> void"
     << "QWebEngineCertificateError.description --> QString"
     << "QWebEngineCertificateError.type --> QWebEngineCertificateError::Type"

From a1059f50897c111950e59f111b9fe766ba876bc2 Mon Sep 17 00:00:00 2001
From: Ulf Hermann <ulf.hermann@qt.io>
Date: Thu, 10 Apr 2025 10:18:56 +0200
Subject: [PATCH 327/356] Turn webEngineFileSystemAccessRequest into
 well-behaved value type

Allow a nullptr as the controller and add a public default ctor to allow
QMetaType to create it.

Task-number: QTBUG-108649
Task-number: QTBUG-135032
Change-Id: I70dc626bb7cce1fdb96c4c3b4dabce2fdfc17537
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit fc3e9ec77ffad4708b9dbc15a79cc651ab09832e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 892c0c215ddf7b59f0d7ead4b1f238e8bb9d14b0)
---
 .../api/qwebenginefilesystemaccessrequest.cpp | 22 ++++++++++++++-----
 .../api/qwebenginefilesystemaccessrequest.h   |  1 +
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/src/core/api/qwebenginefilesystemaccessrequest.cpp b/src/core/api/qwebenginefilesystemaccessrequest.cpp
index 3f901b671cf..0834468f659 100644
--- a/src/core/api/qwebenginefilesystemaccessrequest.cpp
+++ b/src/core/api/qwebenginefilesystemaccessrequest.cpp
@@ -72,7 +72,8 @@ QWebEngineFileSystemAccessRequest::QWebEngineFileSystemAccessRequest(
 */
 void QWebEngineFileSystemAccessRequest::reject()
 {
-    d_ptr->reject();
+    if (Q_LIKELY(d_ptr))
+        d_ptr->reject();
 }
 
 /*!
@@ -80,7 +81,8 @@ void QWebEngineFileSystemAccessRequest::reject()
 */
 void QWebEngineFileSystemAccessRequest::accept()
 {
-    d_ptr->accept();
+    if (Q_LIKELY(d_ptr))
+        d_ptr->accept();
 }
 
 /*!
@@ -90,7 +92,9 @@ void QWebEngineFileSystemAccessRequest::accept()
 
 QUrl QWebEngineFileSystemAccessRequest::origin() const
 {
-    return d_ptr->origin();
+    if (Q_LIKELY(d_ptr))
+        return d_ptr->origin();
+    return QUrl();
 }
 
 /*!
@@ -100,7 +104,9 @@ QUrl QWebEngineFileSystemAccessRequest::origin() const
 
 QUrl QWebEngineFileSystemAccessRequest::filePath() const
 {
-    return d_ptr->filePath();
+    if (Q_LIKELY(d_ptr))
+        return d_ptr->filePath();
+    return QUrl();
 }
 
 /*!
@@ -109,7 +115,9 @@ QUrl QWebEngineFileSystemAccessRequest::filePath() const
  */
 HandleType QWebEngineFileSystemAccessRequest::handleType() const
 {
-    return d_ptr->handleType();
+    if (Q_LIKELY(d_ptr))
+        return d_ptr->handleType();
+    return File;
 }
 
 /*!
@@ -118,7 +126,9 @@ HandleType QWebEngineFileSystemAccessRequest::handleType() const
  */
 AccessFlags QWebEngineFileSystemAccessRequest::accessFlags() const
 {
-    return d_ptr->accessFlags();
+    if (Q_LIKELY(d_ptr))
+        return d_ptr->accessFlags();
+    return {};
 }
 
 QT_END_NAMESPACE
diff --git a/src/core/api/qwebenginefilesystemaccessrequest.h b/src/core/api/qwebenginefilesystemaccessrequest.h
index 37b1e186111..7707c607c8c 100644
--- a/src/core/api/qwebenginefilesystemaccessrequest.h
+++ b/src/core/api/qwebenginefilesystemaccessrequest.h
@@ -24,6 +24,7 @@ class Q_WEBENGINECORE_EXPORT QWebEngineFileSystemAccessRequest
     Q_PROPERTY(AccessFlags accessFlags READ accessFlags CONSTANT FINAL)
 
 public:
+    QWebEngineFileSystemAccessRequest() = default;
     QWebEngineFileSystemAccessRequest(const QWebEngineFileSystemAccessRequest &other);
     QWebEngineFileSystemAccessRequest &operator=(const QWebEngineFileSystemAccessRequest &other);
     QWebEngineFileSystemAccessRequest(QWebEngineFileSystemAccessRequest &&other) noexcept = default;

From bf7ca506a3999950748d615fba445147d0bd8a47 Mon Sep 17 00:00:00 2001
From: Ulf Hermann <ulf.hermann@qt.io>
Date: Thu, 10 Apr 2025 10:27:37 +0200
Subject: [PATCH 328/356] Turn fullScreenRequest into a well-behaved value type

Add a default constructor so that QMetaType can create it.

Task-number: QTBUG-108649
Task-number: QTBUG-135032
Change-Id: If82aa9e318f17ba5727b3bd6ad3684afb8b36c7f
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit c3cc6f868351401b07f162b06f1196df2e7f3794)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit f0ee80397bb6b2a10bf734740dd154983c85d135)
---
 src/core/api/qwebenginefullscreenrequest.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/core/api/qwebenginefullscreenrequest.h b/src/core/api/qwebenginefullscreenrequest.h
index 8e25286b64f..b07d158fd35 100644
--- a/src/core/api/qwebenginefullscreenrequest.h
+++ b/src/core/api/qwebenginefullscreenrequest.h
@@ -23,6 +23,7 @@ class Q_WEBENGINECORE_EXPORT QWebEngineFullScreenRequest
     Q_PROPERTY(QUrl origin READ origin CONSTANT)
 
 public:
+    QWebEngineFullScreenRequest() : QWebEngineFullScreenRequest(QUrl(), false, [](bool){}) {}
     QWebEngineFullScreenRequest(const QWebEngineFullScreenRequest &other);
     QWebEngineFullScreenRequest &operator=(const QWebEngineFullScreenRequest &other);
     QWebEngineFullScreenRequest(QWebEngineFullScreenRequest &&other);

From 43e863088ba415cc197a74fadbbe0b20750fe1f9 Mon Sep 17 00:00:00 2001
From: Ulf Hermann <ulf.hermann@qt.io>
Date: Thu, 10 Apr 2025 10:35:00 +0200
Subject: [PATCH 329/356] Turn webEngineLoadingInfo into a well-behaved value
 type

Add a default constructor so that QMetaType can create it.

Task-number: QTBUG-108649
Task-number: QTBUG-135032
Change-Id: I9390392f24f29cc16e0f36367a6a77e60a76b068
Reviewed-by: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 82cd5895d72cb5a0d555d5dcefa2719a1986169b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 998a2a0a3d1ccd4d9b099d6533c893e936d2c52f)
---
 src/core/api/qwebengineloadinginfo.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/core/api/qwebengineloadinginfo.h b/src/core/api/qwebengineloadinginfo.h
index 48d14601ab6..5c206d9a709 100644
--- a/src/core/api/qwebengineloadinginfo.h
+++ b/src/core/api/qwebengineloadinginfo.h
@@ -50,6 +50,7 @@ class Q_WEBENGINECORE_EXPORT QWebEngineLoadingInfo
     };
     Q_ENUM(ErrorDomain)
 
+    QWebEngineLoadingInfo() : QWebEngineLoadingInfo(QUrl(), LoadStartedStatus) {}
     QWebEngineLoadingInfo(const QWebEngineLoadingInfo &other);
     QWebEngineLoadingInfo &operator=(const QWebEngineLoadingInfo &other);
     QWebEngineLoadingInfo(QWebEngineLoadingInfo &&other);

From fe932330413d1965954a58d66001c28ce614432c Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Fri, 11 Apr 2025 16:32:03 +0000
Subject: [PATCH 330/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: Iba6ad0b73fbdb80103e5b60e31b0c78245282b40
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 349f94d6da0..54ac8c407a5 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: 32452675dc7661de32013969f9d2eb613da70096
+    ref: b206c4e687f2c942cd429258b93be6aae245bb34
     required: true
   ../qtpositioning:
-    ref: 73e77ed97a9384eb73140b83a364d3866358e364
+    ref: 82ba4ba2bf4dfcb582a91d75ba65eb01999c6276
     required: false
   ../qttools:
-    ref: 31ec5e9c0f3388756d06aa8ffd1c59c5f097dbaa
+    ref: 7176f0d188d648293859e232854fd1858ae71694
     required: false
   ../qtwebchannel:
-    ref: 5d51387a00af8cb76ca7e879583f398faef1f602
+    ref: f10f75ab8fa9fb6fdcb4a3d5182e9462c0ea258a
     required: false

From 5e100030a9b6e2bf42d3cd6f133190a0387afdc2 Mon Sep 17 00:00:00 2001
From: Christophe Marin <christophe@krop.fr>
Date: Thu, 26 Dec 2024 13:11:51 +0100
Subject: [PATCH 331/356] Build system: remove libxml2 compilation test

Chromium doesn't need LIBXML_ICU_ENABLED to be defined to build.

Change-Id: I5788bfca058a7b65f1b2e80e9ad740b04b3dc7c6
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit d036335a9367e3631c92e247155334d15a14b1fe)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit a7c14eebd17ea974fb42de10720043fee1a385ed)
---
 configure.cmake | 17 +----------------
 1 file changed, 1 insertion(+), 16 deletions(-)

diff --git a/configure.cmake b/configure.cmake
index 7df4c2b797a..c0276751f10 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -129,21 +129,6 @@ int main() {
 }"
 )
 
-qt_config_compile_test(libxml2
-    LABEL "compatible libxml2 and libxslt"
-    LIBRARIES
-        PkgConfig::LIBXML2
-    CODE
-"
-#include \"libxml/xmlversion.h\"
-#if !defined(LIBXML_ICU_ENABLED)
-#error libxml icu not enabled
-#endif
-int main() {
-    return 0;
-}"
-)
-
 qt_config_compile_test(jpeg
     LABEL "compatible libjpeg"
     LIBRARIES
@@ -373,7 +358,7 @@ qt_feature("webengine-system-libevent" PRIVATE
 )
 qt_feature("webengine-system-libxml" PRIVATE
     LABEL "libxml2 and libxslt"
-    CONDITION UNIX AND TEST_libxml2
+    CONDITION UNIX AND LIBXML2_FOUND
 )
 qt_feature("webengine-system-lcms2" PRIVATE
     LABEL "lcms2"

From f1d1f6b4f6f24ae60e46f604ed11f489f761fbdf Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Tue, 15 Apr 2025 14:14:03 +0200
Subject: [PATCH 332/356] Update Chromium

Submodule src/3rdparty 55749ed0..5fff3583:
* [fixup] Reinstate jumbo-builds
* [Backport] CVE-2025-3071: Inappropriate implementation in Navigations (2/2)
* [Backport] CVE-2025-3071: Inappropriate implementation in Navigations (1/2)
* [Backport] Security bug 396460489 (2/2)
* [Backport] Security bug 396460489 (1/2)
* [Backport] CVE-2025-24855 Fix use-after-free of XPath context node
* [Backport] CVE-2024-55549: Fix UAF related to excluded namespaces
* [Backport] Security bug 397187119
* [Backport] Security bug 399002829
* [backport] Security bug 389707046 4/4
* [backport] Security bug 389707046 3/4
* [backport] Security bug 389707046 2/4
* [backport] Security bug 389707046 1/4
* Dependency for Security bug 389707046
* [Backport] CVE-2025-2783: Incorrect handle provided in unspecified circumstances in Mojo on Windows
* Allow MAP_DROPPABLE memory mappings in Linux sandbox
* Support clang-14 on macos-13 build
* [fixup] Adapt favicon and history component for WebEngine

Fixes: QTBUG-135998
Task-number: QTBUG-134644
Fixes: QTBUG-135837
Fixes: QTBUG-135424
Fixes: QTBUG-135902
Change-Id: If377e2f720ce6ca1df644c8f42d1c247d2929969
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
---
 CHROMIUM_VERSION                | 2 +-
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index 58db9e1086a..bce67801379 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
 Based on Chromium version:                                      122.0.6261.171
-Patched with security patches up to Chromium version:           134.0.6998.89
+Patched with security patches up to Chromium version:           135.0.7049.85
diff --git a/src/3rdparty b/src/3rdparty
index 55749ed0af5..5fff35835d9 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit 55749ed0af5869215b88007df0cba430746583ae
+Subproject commit 5fff35835d9b8a62348173a76466f18001113bca
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 5d99dc70f43..ce7332f0d10 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1297,7 +1297,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "134.0.6998.89"; // FIXME: Remember to update
+    return "135.0.7049.85"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From c36197b11e99d91f4f7dc56fb44f1457e3aea3bf Mon Sep 17 00:00:00 2001
From: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
Date: Thu, 17 Apr 2025 10:37:35 +0000
Subject: [PATCH 333/356] Update dependencies on '6.8' in qt/qtwebengine

Change-Id: I8f2e80c38fe40d66c132f17d16f0efa11f392117
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
---
 dependencies.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/dependencies.yaml b/dependencies.yaml
index 54ac8c407a5..31d95285f1f 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
 dependencies:
   ../qtdeclarative:
-    ref: b206c4e687f2c942cd429258b93be6aae245bb34
+    ref: f9e719687fe5160894203a5030bbb2e33ab0cf6f
     required: true
   ../qtpositioning:
-    ref: 82ba4ba2bf4dfcb582a91d75ba65eb01999c6276
+    ref: 8277b8175e31ae6c81a79d8677a42c5e84db6261
     required: false
   ../qttools:
-    ref: 7176f0d188d648293859e232854fd1858ae71694
+    ref: 77db9c950477d9aa89d583b025f01c9e13e3ae44
     required: false
   ../qtwebchannel:
-    ref: f10f75ab8fa9fb6fdcb4a3d5182e9462c0ea258a
+    ref: 36e6623be61e4d12376dcc1ed4c9ae059fa64bc3
     required: false

From 0f674a889aa4f6b2cbbb489521e9c74354aa7ab8 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Tue, 22 Apr 2025 14:32:52 +0200
Subject: [PATCH 334/356] Update Chromium
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Submodule src/3rdparty 5fff3583..4a348a11:
* [backport] CVE-2025-3619
* [fixup] Fix QtWebEngine build on Windows

Fixes: QTBUG-136040
Change-Id: I4c48e90781443af774aee26ef24af2050976211d
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
---
 CHROMIUM_VERSION                | 2 +-
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index bce67801379..bc95fd83e00 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
 Based on Chromium version:                                      122.0.6261.171
-Patched with security patches up to Chromium version:           135.0.7049.85
+Patched with security patches up to Chromium version:           135.0.7049.95
diff --git a/src/3rdparty b/src/3rdparty
index 5fff35835d9..4a348a11cae 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit 5fff35835d9b8a62348173a76466f18001113bca
+Subproject commit 4a348a11cae30c8d99591e093db895ad514a0a88
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index ce7332f0d10..0802e7f182f 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1297,7 +1297,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "135.0.7049.85"; // FIXME: Remember to update
+    return "135.0.7049.95"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From 2df37bb1e76d68773ad2cdb3cd8ba3359dc4c018 Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Tue, 8 Apr 2025 12:28:48 +0200
Subject: [PATCH 335/356] CMake: fix Svg dependency handling for pdf examples

Since the find_package() calls in the example CMakeLists only create
targets when the example is being built standalone, we still get
warnings when configuring the full module.

Without Svg support the example will look a bit broken, but this way
it is still possible to build without qtsvg and deploy for a system
which has svg rendering runtime.

Amends 50db3f69e CMake: silence warning configuring examples

Change-Id: Ifc17f00e1ba7d29638296c823f2af005996a44c5
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 0ddb417eb702f388ee1ddd94fa62a693587d467d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 1135b356ef377e3bcadc21090cc43d0448e49efa)
---
 CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index c647140e604..ee7fbca49ad 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -32,7 +32,7 @@ find_package(Qt6 ${PROJECT_VERSION} CONFIG QUIET OPTIONAL_COMPONENTS
     WebChannel WebChannelQuick Positioning QuickControls2
     Test QuickWidgets QuickTest WebSockets Designer
     JpegPrivate PngPrivate HarfbuzzPrivate FreetypePrivate ZlibPrivate
-    HttpServer
+    HttpServer Svg
 )
 
 if(MATRIX_BUILD AND NOT MATRIX_SUBBUILD AND NOT QT_SUPERBUILD)

From 6cf0a23c785e1c72c308c42987b978a60fee30a1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Wed, 23 Apr 2025 20:19:42 +0200
Subject: [PATCH 336/356] Update Chromium

Submodule src/3rdparty 4a348a11..b110b061:
  * [Backport] Security bug 409243443

Pick-to: 6.5
Fixes: QTBUG-136168
Change-Id: Ibc719dde36ff29707e4c63967eee5fd47ff82b38
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
---
 CHROMIUM_VERSION                | 2 +-
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index bc95fd83e00..80e969763e7 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
 Based on Chromium version:                                      122.0.6261.171
-Patched with security patches up to Chromium version:           135.0.7049.95
+Patched with security patches up to Chromium version:           135.0.7049.115
diff --git a/src/3rdparty b/src/3rdparty
index 4a348a11cae..b110b0619ad 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit 4a348a11cae30c8d99591e093db895ad514a0a88
+Subproject commit b110b0619ad8c53a32362c384f2012a7333f0dfd
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 0802e7f182f..a2da0a71e37 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1297,7 +1297,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "135.0.7049.95"; // FIXME: Remember to update
+    return "135.0.7049.115"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From b6f421c3621e1306f6ee86d2c3cd67018307629a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Fri, 2 May 2025 17:29:39 +0200
Subject: [PATCH 337/356] Update Chromium

Submodule src/3rdparty b110b061..35b2fd5a:
  * [Backport] CVE-2025-4051: Insufficient data validation in DevTools
  * [Backport] CVE-2025-4052: Inappropriate implementation in DevTools
  * [Backport] Security bug 403364367
  * Avoid crash due to long dictionary commands
  * [fixup] Qt GN Integration
  * [fixup][android] Support android build for qtpdf

Task-number: QTBUG-136542
Change-Id: I37cf620ea6d8037f6bf3d04483b9e3aa1e967196
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
---
 CHROMIUM_VERSION                | 2 +-
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index 80e969763e7..fc3c8fc70fa 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
 Based on Chromium version:                                      122.0.6261.171
-Patched with security patches up to Chromium version:           135.0.7049.115
+Patched with security patches up to Chromium version:           136.0.7103.59
diff --git a/src/3rdparty b/src/3rdparty
index b110b0619ad..35b2fd5a667 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit b110b0619ad8c53a32362c384f2012a7333f0dfd
+Subproject commit 35b2fd5a66733b0d57b94bdb1df2baad4d888f5e
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index a2da0a71e37..404ec74a60a 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1297,7 +1297,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "135.0.7049.115"; // FIXME: Remember to update
+    return "136.0.7103.59"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From 51343a5e9902b10465f77f44bbc935045ad12535 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Tue, 8 Apr 2025 17:52:08 +0200
Subject: [PATCH 338/356] Do pass -isysroot optionally for gn build

With cmake 4.0 changes, we can no longer expect CMAKE_OSX_SYSROOT
to be set:
https://cmake.org/cmake/help/latest/release/4.0.html#other-changes

Therefore make the setting optional for gn, as it should not be
required on "modern macOS".

Task-number: QTBUG-135621
Change-Id: I48ed72d6e920fec4c395eb04c8a18619e045c1b4
Reviewed-by: Moss Heim <moss.heim@qt.io>
(cherry picked from commit 4bf8f28aeeba3f416bc411c396f2be92f5a1c4b9)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 7c01d710dbfc7441077d9c0fecb6acc674715307)
---
 src/gn/CMakeLists.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/gn/CMakeLists.txt b/src/gn/CMakeLists.txt
index 9782f17abc8..fdf0b11a1ac 100644
--- a/src/gn/CMakeLists.txt
+++ b/src/gn/CMakeLists.txt
@@ -70,8 +70,8 @@ add_custom_command(
         --platform ${platform}
         --ar ${CMAKE_AR}
         --qt-version "${QT_REPO_MODULE_VERSION}.qtwebengine.qt.io"
-        $<$<PLATFORM_ID:Darwin>:--isysroot>
-        $<$<PLATFORM_ID:Darwin>:${CMAKE_OSX_SYSROOT}>
+        $<$<AND:$<PLATFORM_ID:Darwin>,$<BOOL:${CMAKE_OSX_SYSROOT}>>:--isysroot>
+        $<$<AND:$<PLATFORM_ID:Darwin>,$<BOOL:${CMAKE_OSX_SYSROOT}>>:${CMAKE_OSX_SYSROOT}>
         $<$<AND:$<PLATFORM_ID:Darwin>,$<BOOL:${OSX_ARCH}>>:--osx-architectures>
         $<$<AND:$<PLATFORM_ID:Darwin>,$<BOOL:${OSX_ARCH}>>:${OSX_ARCH}>
     COMMAND Ninja::ninja -C ${GN_BINARY_DIR}/$<CONFIG> ${GN_EXECUTABLE}

From 13e34061f279c57caeb83f5812779649221e8a5c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Mon, 12 May 2025 10:34:20 +0200
Subject: [PATCH 339/356] Update Chromium

Submodule src/3rdparty 35b2fd5a..681cfd93:
  * [Backport] CVE-2025-3277

Fixes: QTBUG-136644
Change-Id: Iaf211d3f0fa7741c9fe3b479d7f86a3b5a39fae0
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
---
 CHROMIUM_VERSION                | 2 +-
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index fc3c8fc70fa..6babc4b88e0 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
 Based on Chromium version:                                      122.0.6261.171
-Patched with security patches up to Chromium version:           136.0.7103.59
+Patched with security patches up to Chromium version:           136.0.7103.92
diff --git a/src/3rdparty b/src/3rdparty
index 35b2fd5a667..681cfd93f2a 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit 35b2fd5a66733b0d57b94bdb1df2baad4d888f5e
+Subproject commit 681cfd93f2a4b5b3e3644e95f40b6a58e05aaabe
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 404ec74a60a..9ab2790da80 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1297,7 +1297,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "136.0.7103.59"; // FIXME: Remember to update
+    return "136.0.7103.92"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From 8f01d41808eb2097eea187cbb92ae6d5d1beddf3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
Date: Mon, 19 May 2025 16:41:25 +0200
Subject: [PATCH 340/356] Update Chromium

Submodule src/3rdparty 681cfd93..5f5c3ab2:
  * [Backport] Fixup for bugs 414858409 and 413080347
  * [Backport] Security bug 413080347
  * [Backport] Security bug 414858409 (2/2)
  * [Backport] Security bug 414858409 (1/2)
  * [Backport] CVE-2025-4609: Incorrect handle provided in unspecified circumstances in Mojo
  * [Backport] CVE-2025-4664: Insufficient policy enforcement in Loader

Fixes: QTBUG-136994
Change-Id: Ifebb3a864aec7128556484554eeed1ca60e753a0
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
---
 CHROMIUM_VERSION                | 2 +-
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index 6babc4b88e0..eb2bd1e90dc 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
 Based on Chromium version:                                      122.0.6261.171
-Patched with security patches up to Chromium version:           136.0.7103.92
+Patched with security patches up to Chromium version:           136.0.7103.114
diff --git a/src/3rdparty b/src/3rdparty
index 681cfd93f2a..5f5c3ab297f 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit 681cfd93f2a4b5b3e3644e95f40b6a58e05aaabe
+Subproject commit 5f5c3ab297fe330253f0630b1e9b6f2112c5cb41
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 9ab2790da80..8dc83fcc99e 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1297,7 +1297,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "136.0.7103.92"; // FIXME: Remember to update
+    return "136.0.7103.114"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From 8a65a43b07ef210aa069c7db3c1d3fa1d168f19c Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 3 Apr 2025 14:25:11 +0200
Subject: [PATCH 341/356] NativeSkiaOutputDeviceVulkan: Fix Vulkan rendering
 with AMD GPU on Linux

gbm_bo_get_modifier() may return invalid DRM format modifier for AMD
driver. In this case, create VkImage without DRM format modifier and
fallback tiling to VK_IMAGE_TILING_OPTIMAL instead of
VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT.

Fixes: QTBUG-123607
Change-Id: Iacf4fc514ab42fa9ab712f5d9fde2d20000f599d
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 0af1b2b24955d77815642e005a3e528b2c0151d0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit a4b729fe555f92a0708bc5131f0396b9648ed932)
---
 .../native_skia_output_device_vulkan.cpp      | 22 ++++++++++++-------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/src/core/compositor/native_skia_output_device_vulkan.cpp b/src/core/compositor/native_skia_output_device_vulkan.cpp
index d65a609b94f..8cb01cd22c1 100644
--- a/src/core/compositor/native_skia_output_device_vulkan.cpp
+++ b/src/core/compositor/native_skia_output_device_vulkan.cpp
@@ -136,17 +136,23 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
         .pPlaneLayouts = &planeLayout,
     };
 
+    bool usingDrmModifier = false;
     if (nativePixmap) {
         qCDebug(lcWebEngineCompositor, "VULKAN: Importing NativePixmap into VkImage.");
         gfx::NativePixmapHandle nativePixmapHandle = nativePixmap->ExportHandle();
-        if (nativePixmapHandle.planes.size() != 1)
-            qFatal("VULKAN: Multiple planes are not supported.");
+        qCDebug(lcWebEngineCompositor, "  DRM Format Modifier: 0x%lx", nativePixmapHandle.modifier);
 
-        planeLayout.offset = nativePixmapHandle.planes[0].offset;
-        planeLayout.rowPitch = nativePixmapHandle.planes[0].stride;
-        modifierInfo.drmFormatModifier = nativePixmapHandle.modifier;
+        if (nativePixmapHandle.modifier != gfx::NativePixmapHandle::kNoModifier) {
+            usingDrmModifier = true;
+            if (nativePixmapHandle.planes.size() != 1)
+                qFatal("VULKAN: Multiple planes are not supported.");
 
-        externalMemoryImageCreateInfo.pNext = &modifierInfo;
+            planeLayout.offset = nativePixmapHandle.planes[0].offset;
+            planeLayout.rowPitch = nativePixmapHandle.planes[0].stride;
+            modifierInfo.drmFormatModifier = nativePixmapHandle.modifier;
+
+            externalMemoryImageCreateInfo.pNext = &modifierInfo;
+        }
         externalMemoryImageCreateInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
 
         scopedFd = std::move(nativePixmapHandle.planes[0].fd);
@@ -225,9 +231,9 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
     };
 
 #if defined(USE_OZONE)
-    if (nativePixmap)
+    if (usingDrmModifier)
         importedImageCreateInfo.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
-    else
+    else if (vkImageInfo.fAlloc.fMemory != VK_NULL_HANDLE)
         importedImageCreateInfo.tiling = vkImageInfo.fImageTiling;
 #endif
 

From bda80db6e35b5a029c99940d86211df4dffdd635 Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Fri, 28 Feb 2025 13:11:33 +0100
Subject: [PATCH 342/356] Remove custom Content-Type parsing code from
 URLRequestCustomJobProxy

We don't need to be parsing Content-Type headers ourselves, and the
existing code won't parse the charset correctly in all cases. Instead,
the parsing is now done through net::HttpUtil::ParseContentType().

Change-Id: I94054a8fc1aa3a2b9f8c504e194530719ccdcc11
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
(cherry picked from commit 852efca0d0a7a98f2c49063ed49e6dec14176391)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 21ec504050314397a0a9bb4f8f48c80324409609)
---
 src/core/net/url_request_custom_job_proxy.cpp | 17 +++--------------
 1 file changed, 3 insertions(+), 14 deletions(-)

diff --git a/src/core/net/url_request_custom_job_proxy.cpp b/src/core/net/url_request_custom_job_proxy.cpp
index 21d73730d4b..977a1a2f1ef 100644
--- a/src/core/net/url_request_custom_job_proxy.cpp
+++ b/src/core/net/url_request_custom_job_proxy.cpp
@@ -6,6 +6,7 @@
 
 #include "content/public/browser/browser_thread.h"
 #include "net/base/net_errors.h"
+#include "net/http/http_util.h"
 #include "services/network/public/cpp/resource_request_body.h"
 
 #include "api/qwebengineurlrequestjob.h"
@@ -47,20 +48,8 @@ void URLRequestCustomJobProxy::reply(std::string contentType, QIODevice *device,
     if (!m_client)
         return;
     DCHECK (!m_ioTaskRunner || m_ioTaskRunner->RunsTasksInCurrentSequence());
-    QByteArray qcontentType = QByteArray::fromStdString(contentType).toLower();
-    const int sidx = qcontentType.indexOf(';');
-    if (sidx > 0) {
-        const int cidx = qcontentType.indexOf("charset=", sidx);
-        if (cidx > 0) {
-            m_client->m_charset = qcontentType.mid(cidx + 8).trimmed().toStdString();
-            qcontentType = qcontentType.first(sidx);
-        } else {
-            qWarning("QWebEngineUrlRequestJob::reply(): Unrecognized content-type format with ';' "
-                     "%s",
-                     qcontentType.constData());
-        }
-    }
-    m_client->m_mimeType = qcontentType.trimmed().toStdString();
+    bool hadCharset = false;
+    net::HttpUtil::ParseContentType(contentType, &m_client->m_mimeType, &m_client->m_charset, &hadCharset, nullptr);
     m_client->m_device = device;
     m_client->m_additionalResponseHeaders = std::move(additionalResponseHeaders);
     if (m_client->m_device && !m_client->m_device->isReadable())

From 21c5ce0f6ff7c3dd182cea10d92f450c1307112c Mon Sep 17 00:00:00 2001
From: Anu Aliyas <anu.aliyas@qt.io>
Date: Tue, 3 Jun 2025 17:28:08 +0200
Subject: [PATCH 343/356] Update Chromium

Submodule src/3rdparty 5f5c3ab2..fb7cda49:
* [Backport] Fix primary display race condition crash on Windows
* [Backport] CVE-2025-5281: Inappropriate implementation in BFCache
* [Backport] [CVE-2024-50602] Stop XML_ResumeParser from crashing #915 (2/2)
* [Backport] [CVE-2024-50602] Stop XML_ResumeParser from crashing #915 (1/2)
* [Backport] CVE-2019-16707
* [Backport] CVE-2025-5063: Use after free in Compositing
* [Backport] CVE-2025-5064: Inappropriate implementation in Background Fetch
* [Backport] CVE-2025-5065: Inappropriate implementation in FileSystemAccess API
* [Backport] CVE-2025-5283: Use after free in libvpx
* [Backport] Don't apply /*FALLTHROUGH*/ edit to gperf 3.2 output
* [fixup] Add missing dependencies to avoid compilation errors
* [fixup] Fixes for jumbo build
* [fixup] Fix QtWebEngine build on Windows

Change-Id: I419112328ed00d1509503779c4c123032b95ddd9
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
---
 src/3rdparty | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/3rdparty b/src/3rdparty
index 5f5c3ab297f..fb7cda4952b 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit 5f5c3ab297fe330253f0630b1e9b6f2112c5cb41
+Subproject commit fb7cda4952b8f84b79e52f2d31dc05636f9e0935

From 9d2e56d06a3da9c081fcefa7c65e04cb0f2f35ba Mon Sep 17 00:00:00 2001
From: Marc Mutz <marc.mutz@qt.io>
Date: Tue, 3 Jun 2025 22:30:32 +0200
Subject: [PATCH 344/356] Normalize signal/slot signatures 2025

This is the result of running util/normalize on the code base. The
following manual edits were needed:

(none)

Pick-to: 6.5
Change-Id: Ia59174aaf154559f7445e13d059723a282f75aae
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 4a96df5e60aeff0bfd3f7aadea5a941d9abc90c6)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 1dc81a71bc24176113ad37c6e4c08200c172a8c6)
(cherry picked from commit d3b7f3d7767e425d022a47818f7295ecc2970288)
---
 src/core/api/qwebengineprofile.cpp            |  2 +-
 ...nder_widget_host_view_qt_delegate_item.cpp |  2 +-
 .../api/qquickwebengineprofile.cpp            |  2 +-
 .../doc/src/qtwebkitportingguide.qdoc         |  4 +--
 .../tst_qwebenginecookiestore.cpp             | 26 +++++++++----------
 .../qwebengineframe/tst_qwebengineframe.cpp   |  4 +--
 .../tst_qquickwebengineview.cpp               |  2 +-
 .../tst_qwebenginehistory.cpp                 |  4 +--
 .../tst_qwebengineprofile.cpp                 |  2 +-
 9 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/src/core/api/qwebengineprofile.cpp b/src/core/api/qwebengineprofile.cpp
index 45b5a349d26..a7955549ac1 100644
--- a/src/core/api/qwebengineprofile.cpp
+++ b/src/core/api/qwebengineprofile.cpp
@@ -220,7 +220,7 @@ void QWebEngineProfilePrivate::downloadRequested(const DownloadItemInfo &info)
 {
     Q_Q(QWebEngineProfile);
 
-    if (!q->receivers(SIGNAL(downloadRequested(QWebEngineDownloadRequest *)))) {
+    if (!q->receivers(SIGNAL(downloadRequested(QWebEngineDownloadRequest*)))) {
         m_profileAdapter->acceptDownload(info.id, info.accepted, info.useDownloadTargetCallback, info.path,
                                          info.savePageFormat);
         return;
diff --git a/src/core/render_widget_host_view_qt_delegate_item.cpp b/src/core/render_widget_host_view_qt_delegate_item.cpp
index 0c38f0f7a02..e82dabb5fff 100644
--- a/src/core/render_widget_host_view_qt_delegate_item.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_item.cpp
@@ -348,7 +348,7 @@ void RenderWidgetHostViewQtDelegateItem::itemChange(ItemChange change, const Ite
                             &RenderWidgetHostViewQtDelegateItem::releaseTextureResources,
                             Qt::DirectConnection));
             if (!m_isPopup)
-                m_windowConnections.append(connect(value.window, SIGNAL(closing(QQuickCloseEvent *)), SLOT(onHide())));
+                m_windowConnections.append(connect(value.window, SIGNAL(closing(QQuickCloseEvent*)), SLOT(onHide())));
         }
         m_client->visualPropertiesChanged();
     } else if (change == QQuickItem::ItemVisibleHasChanged) {
diff --git a/src/webenginequick/api/qquickwebengineprofile.cpp b/src/webenginequick/api/qquickwebengineprofile.cpp
index 47f8a1e95a4..49091dccf46 100644
--- a/src/webenginequick/api/qquickwebengineprofile.cpp
+++ b/src/webenginequick/api/qquickwebengineprofile.cpp
@@ -246,7 +246,7 @@ void QQuickWebEngineProfilePrivate::downloadRequested(const DownloadItemInfo &in
 {
     Q_Q(QQuickWebEngineProfile);
 
-    if (!q->receivers(SIGNAL(downloadRequested(QQuickWebEngineDownloadRequest *)))) {
+    if (!q->receivers(SIGNAL(downloadRequested(QQuickWebEngineDownloadRequest*)))) {
         m_profileAdapter->acceptDownload(info.id, info.accepted, info.useDownloadTargetCallback, info.path,
                                          info.savePageFormat);
         return;
diff --git a/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc b/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
index 37b73c010cc..f3ac9fa555f 100644
--- a/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
+++ b/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
@@ -92,13 +92,13 @@
     \b {Qt \WebKit}
     \code
         QWebPage page;
-        connect(page.mainFrame(), SIGNAL(urlChanged(const QUrl&)), SLOT(mySlotName()));
+        connect(page.mainFrame(), SIGNAL(urlChanged(QUrl)), SLOT(mySlotName()));
         page.mainFrame()->load(url);
     \endcode
     \b {\QWE}
     \code
         QWebEnginePage page;
-        connect(&page, SIGNAL(urlChanged(const QUrl&)), SLOT(mySlotName()));
+        connect(&page, SIGNAL(urlChanged(QUrl)), SLOT(mySlotName()));
         page.load(url);
     \endcode
 
diff --git a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
index a75002ae51c..e0db542c827 100644
--- a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
+++ b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
@@ -79,8 +79,8 @@ void tst_QWebEngineCookieStore::cookieSignals()
     QWebEngineCookieStore *client = m_profile->cookieStore();
 
     QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
-    QSignalSpy cookieAddedSpy(client, SIGNAL(cookieAdded(const QNetworkCookie &)));
-    QSignalSpy cookieRemovedSpy(client, SIGNAL(cookieRemoved(const QNetworkCookie &)));
+    QSignalSpy cookieAddedSpy(client, SIGNAL(cookieAdded(QNetworkCookie)));
+    QSignalSpy cookieRemovedSpy(client, SIGNAL(cookieRemoved(QNetworkCookie)));
 
     page.load(QUrl("qrc:///resources/index.html"));
 
@@ -108,8 +108,8 @@ void tst_QWebEngineCookieStore::setAndDeleteCookie()
     QWebEngineCookieStore *client = m_profile->cookieStore();
 
     QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
-    QSignalSpy cookieAddedSpy(client, SIGNAL(cookieAdded(const QNetworkCookie &)));
-    QSignalSpy cookieRemovedSpy(client, SIGNAL(cookieRemoved(const QNetworkCookie &)));
+    QSignalSpy cookieAddedSpy(client, SIGNAL(cookieAdded(QNetworkCookie)));
+    QSignalSpy cookieRemovedSpy(client, SIGNAL(cookieRemoved(QNetworkCookie)));
 
     QNetworkCookie cookie1(QNetworkCookie::parseCookies(QByteArrayLiteral("khaos=I9GX8CWI; Domain=.example.com; Path=/docs")).first());
     QNetworkCookie cookie2(QNetworkCookie::parseCookies(QByteArrayLiteral("Test%20Cookie=foobar; domain=example.com; Path=/")).first());
@@ -155,8 +155,8 @@ void tst_QWebEngineCookieStore::setInvalidCookie()
     QWebEngineCookieStore *client = m_profile->cookieStore();
 
     QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
-    QSignalSpy cookieAddedSpy(client, SIGNAL(cookieAdded(const QNetworkCookie &)));
-    QSignalSpy cookieRemovedSpy(client, SIGNAL(cookieRemoved(const QNetworkCookie &)));
+    QSignalSpy cookieAddedSpy(client, SIGNAL(cookieAdded(QNetworkCookie)));
+    QSignalSpy cookieRemovedSpy(client, SIGNAL(cookieRemoved(QNetworkCookie)));
 
     QNetworkCookie goodCookie(
             QNetworkCookie::parseCookies(
@@ -186,8 +186,8 @@ void tst_QWebEngineCookieStore::batchCookieTasks()
     QWebEngineCookieStore *client = m_profile->cookieStore();
 
     QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
-    QSignalSpy cookieAddedSpy(client, SIGNAL(cookieAdded(const QNetworkCookie &)));
-    QSignalSpy cookieRemovedSpy(client, SIGNAL(cookieRemoved(const QNetworkCookie &)));
+    QSignalSpy cookieAddedSpy(client, SIGNAL(cookieAdded(QNetworkCookie)));
+    QSignalSpy cookieRemovedSpy(client, SIGNAL(cookieRemoved(QNetworkCookie)));
 
     QNetworkCookie cookie1(QNetworkCookie::parseCookies(QByteArrayLiteral("khaos=I9GX8CWI; Domain=.example.com; Path=/docs")).first());
     QNetworkCookie cookie2(QNetworkCookie::parseCookies(QByteArrayLiteral("Test%20Cookie=foobar; domain=example.com; Path=/")).first());
@@ -230,8 +230,8 @@ void tst_QWebEngineCookieStore::basicFilter()
     client->setCookieFilter([&](const QWebEngineCookieStore::FilterRequest &){ ++accessTested; return true;});
 
     QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
-    QSignalSpy cookieAddedSpy(client, SIGNAL(cookieAdded(const QNetworkCookie &)));
-    QSignalSpy cookieRemovedSpy(client, SIGNAL(cookieRemoved(const QNetworkCookie &)));
+    QSignalSpy cookieAddedSpy(client, SIGNAL(cookieAdded(QNetworkCookie)));
+    QSignalSpy cookieRemovedSpy(client, SIGNAL(cookieRemoved(QNetworkCookie)));
 
     page.load(QUrl("qrc:///resources/index.html"));
 
@@ -284,9 +284,9 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP()
     });
 
     QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
-    QSignalSpy cookieAddedSpy(client, SIGNAL(cookieAdded(const QNetworkCookie &)));
-    QSignalSpy cookieRemovedSpy(client, SIGNAL(cookieRemoved(const QNetworkCookie &)));
-    QSignalSpy serverSpy(&httpServer, SIGNAL(newRequest(HttpReqRep *)));
+    QSignalSpy cookieAddedSpy(client, SIGNAL(cookieAdded(QNetworkCookie)));
+    QSignalSpy cookieRemovedSpy(client, SIGNAL(cookieRemoved(QNetworkCookie)));
+    QSignalSpy serverSpy(&httpServer, SIGNAL(newRequest(HttpReqRep*)));
 
     QUrl firstPartyUrl = httpServer.url("/test.html");
     page.load(firstPartyUrl);
diff --git a/tests/auto/core/qwebengineframe/tst_qwebengineframe.cpp b/tests/auto/core/qwebengineframe/tst_qwebengineframe.cpp
index 0e036ac7449..fdfefea20c5 100644
--- a/tests/auto/core/qwebengineframe/tst_qwebengineframe.cpp
+++ b/tests/auto/core/qwebengineframe/tst_qwebengineframe.cpp
@@ -244,7 +244,7 @@ void tst_QWebEngineFrame::printToPdfFile()
     QVERIFY(maybeInnerFrame);
     auto innerFrame = *maybeInnerFrame;
 
-    QSignalSpy savePdfSpy{ &page, SIGNAL(pdfPrintingFinished(QString, bool)) };
+    QSignalSpy savePdfSpy{ &page, SIGNAL(pdfPrintingFinished(QString,bool)) };
 
     QString outerPath = tempDir.path() + "/outer.pdf";
     outerFrame.printToPdf(outerPath);
@@ -284,7 +284,7 @@ void tst_QWebEngineFrame::printToPdfFileFailures()
     QVERIFY(maybeInnerFrame);
     auto innerFrame = *maybeInnerFrame;
 
-    QSignalSpy savePdfSpy{ &page, SIGNAL(pdfPrintingFinished(QString, bool)) };
+    QSignalSpy savePdfSpy{ &page, SIGNAL(pdfPrintingFinished(QString,bool)) };
 
 #if !defined(Q_OS_WIN)
     auto badPath = tempDir.path() + "/print_//2_failed.pdf";
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index 1d85c495cbe..d00c879e27d 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -847,7 +847,7 @@ void tst_QQuickWebEngineView::printToPdf()
     view->setUrl(urlFromTestPath("html/basic_page.html"));
     QVERIFY(waitForLoadSucceeded(view));
 
-    QSignalSpy savePdfSpy(view, SIGNAL(pdfPrintingFinished(const QString&, bool)));
+    QSignalSpy savePdfSpy(view, SIGNAL(pdfPrintingFinished(QString,bool)));
     QString path = tempDir.path() + "/print_success.pdf";
     view->printToPdf(path, QQuickWebEngineView::A4, QQuickWebEngineView::Portrait);
     QTRY_VERIFY2(savePdfSpy.size() == 1, "Printing to PDF file failed without signal");
diff --git a/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp b/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp
index ad66e972c61..b4084a22d56 100644
--- a/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp
+++ b/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp
@@ -145,7 +145,7 @@ void tst_QWebEngineHistory::count()
   */
 void tst_QWebEngineHistory::back()
 {
-    QSignalSpy titleChangedSpy(page, SIGNAL(titleChanged(const QString&)));
+    QSignalSpy titleChangedSpy(page, SIGNAL(titleChanged(QString)));
 
     for (int i = histsize;i > 1;i--) {
         QTRY_COMPARE(toPlainTextSync(page), QString("page") + QString::number(i));
@@ -171,7 +171,7 @@ void tst_QWebEngineHistory::forward()
         QTRY_COMPARE(loadFinishedSpy->size(), histBackCount);
     }
 
-    QSignalSpy titleChangedSpy(page, SIGNAL(titleChanged(const QString&)));
+    QSignalSpy titleChangedSpy(page, SIGNAL(titleChanged(QString)));
     for (int i = 1;i < histsize;i++) {
         QTRY_COMPARE(toPlainTextSync(page), QString("page") + QString::number(i));
         hist->forward();
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index 97e5bd6017f..eefb418638f 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -862,7 +862,7 @@ void tst_QWebEngineProfile::downloadItem()
     qRegisterMetaType<QWebEngineDownloadRequest *>();
     QWebEngineProfile testProfile;
     QWebEnginePage page(&testProfile);
-    QSignalSpy downloadSpy(&testProfile, SIGNAL(downloadRequested(QWebEngineDownloadRequest *)));
+    QSignalSpy downloadSpy(&testProfile, SIGNAL(downloadRequested(QWebEngineDownloadRequest*)));
     page.load(QUrl::fromLocalFile(QCoreApplication::applicationFilePath()));
     QTRY_COMPARE(downloadSpy.size(), 1);
 }

From 870c18c1bba5686ea1a7fa6b9db1ee783f8af38a Mon Sep 17 00:00:00 2001
From: Alexei Cazacov <alexei.cazacov@qt.io>
Date: Thu, 27 Mar 2025 15:26:24 +0200
Subject: [PATCH 345/356] Docs: Qt WebEngine documentation doesn't mention the
 module requirements

This commit adds a note with optional dependences.

Fixes: QTBUG-133608
Change-Id: I9ac4971e2a8b0cbde754a249fb6115112a7fac96
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 5cfa442218c649b7bb7805bb0f90ed92c66cd402)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 28ecd9fa0c177246eab31426aee81a52d400840d)
(cherry picked from commit ff982a083165540d0e8aadeb29b71c497ff06e08)
---
 src/core/doc/src/qtwebengine-index.qdoc | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/core/doc/src/qtwebengine-index.qdoc b/src/core/doc/src/qtwebengine-index.qdoc
index b20a96dc1fe..b4243d9f824 100644
--- a/src/core/doc/src/qtwebengine-index.qdoc
+++ b/src/core/doc/src/qtwebengine-index.qdoc
@@ -9,6 +9,10 @@
 
     \QWE provides functionality for rendering regions of dynamic web content.
 
+    \note By default, Qt WebEngine depends on the \l {Qt Positioning} and
+    \l {Qt WebChannel} optional modules, but can be built without them. Be sure to
+    install these add-ons when using the online installer.
+
     The functionality in \QWE is divided into the following modules:
 
     \annotatedlist qtwebengine-modules
@@ -25,7 +29,6 @@
         \li \l{Porting from Qt WebKit to Qt WebEngine}
     \endlist
 
-
     \section1 Module Evolution
 
     \l{Changes to Qt WebEngine} lists important changes in the module API

From a485d67059da458f785291f1d504c43fd09eed65 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Fri, 25 Apr 2025 13:31:55 +0200
Subject: [PATCH 346/356] Fix deployment of render process on linux

When deployed on linux qwebengineprocess ends in libexec and
needs qt.conf otherwise qt libraries prefix render process is unknown
and running the process will fail.

Change-Id: If44d4689d11eb8a9f25e2aee28ddef73861575ad
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
(cherry picked from commit cf2d52b0b9287714c2fa99a9eb94a62f1585d576)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit a9c6fb505d4bb53f7f07bd312728fdffa934474e)
---
 src/core/api/Qt6WebEngineCoreDeploySupport.cmake | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/core/api/Qt6WebEngineCoreDeploySupport.cmake b/src/core/api/Qt6WebEngineCoreDeploySupport.cmake
index b6f8b146380..7334be4e742 100644
--- a/src/core/api/Qt6WebEngineCoreDeploySupport.cmake
+++ b/src/core/api/Qt6WebEngineCoreDeploySupport.cmake
@@ -102,6 +102,15 @@ function(_qt_internal_deploy_webenginecore_binary)
         )
     endif()
 
+    if(NOT __QT_DEPLOY_SYSTEM_NAME STREQUAL "Windows")
+        qt6_deploy_qt_conf("${install_destination}/qt.conf"
+            PREFIX "${QT_DEPLOY_PREFIX}"
+            BIN_DIR "${QT_DEPLOY_BIN_DIR}"
+            LIB_DIR "${QT_DEPLOY_LIB_DIR}"
+            PLUGINS_DIR "${QT_DEPLOY_PLUGINS_DIR}"
+            QML_DIR "${QT_DEPLOY_QML_DIR}"
+        )
+    endif()
     # Checking for __QT_DEPLOY_MUST_ADJUST_PLUGINS_RPATH is a bit strange because this is not a
     # plugin, but it gives a single common way to detect when the rpath adjustment must be done,
     # because the lib dir is different than the original Qt configured one.

From c4dcc78654b33a028c14a03a2ea51b5d9d7ef65f Mon Sep 17 00:00:00 2001
From: Anu Aliyas <anu.aliyas@qt.io>
Date: Tue, 18 Mar 2025 12:30:56 +0100
Subject: [PATCH 347/356] Avoid clipping of the popup window in webengine quick

Currently webenginequick uses a window as popup, and the contents are
getting clipped with respect to the parent's boundary. To avoid this,
set the transient parent instead of the parent. This is based on
the documentation.

Fixes: QTBUG-132794
Change-Id: I527ae55d130bc122c903a39738ffea5cec29eb90
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 6caecaa52c6912b2948dd86cdb277fce396e4445)
Reviewed-by: Moss Heim <moss.heim@qt.io>
(cherry picked from commit 42ba815c84dc040eaac647d788ff2f0b6d3555a2)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 ...render_widget_host_view_qt_delegate_quickwindow.cpp |  5 +++--
 .../qquickwebengineview/tst_qquickwebengineview.cpp    | 10 +++++++++-
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp
index b507d760b79..52538b652c1 100644
--- a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp
+++ b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp
@@ -32,7 +32,7 @@ static inline QPoint getOffset(QQuickItem *item)
     QPointF offset = item->mapFromScene(QPoint(0, 0));
     offset = item->mapToGlobal(offset);
     // get local offset
-    offset -= item->mapToScene(QPoint(0, 0));
+    offset -= item->mapToGlobal(QPoint(0, 0));
     return offset.toPoint();
 }
 
@@ -51,10 +51,11 @@ static inline QPointF transformPoint(const QPointF &point, const QTransform &tra
 
 RenderWidgetHostViewQtDelegateQuickWindow::RenderWidgetHostViewQtDelegateQuickWindow(
         RenderWidgetHostViewQtDelegateItem *realDelegate, QWindow *parent)
-    : QQuickWindow(parent), m_realDelegate(realDelegate), m_virtualParent(nullptr), m_transformed(false)
+    : QQuickWindow(), m_realDelegate(realDelegate), m_virtualParent(nullptr), m_transformed(false)
 {
     setFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
     realDelegate->setParentItem(contentItem());
+    setTransientParent(parent);
 }
 
 RenderWidgetHostViewQtDelegateQuickWindow::~RenderWidgetHostViewQtDelegateQuickWindow()
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index d00c879e27d..8185bc47eb7 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -1,6 +1,7 @@
 // Copyright (C) 2016 The Qt Company Ltd.
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
+#include "QtWidgets/qapplication.h"
 #include "testwindow.h"
 #include "quickutil.h"
 #include "util.h"
@@ -1344,7 +1345,14 @@ void tst_QQuickWebEngineView::htmlSelectPopup()
 
     makeTouch(view.window(), elementCenter(&view, "select"));
     QPointer<QQuickWindow> popup;
-    QTRY_VERIFY((popup = m_window->findChild<QQuickWindow *>()));
+    auto findPopup = [](QQuickView *view) -> QQuickWindow * {
+        for (auto window : QApplication::topLevelWindows()) {
+            if (window->transientParent() == view)
+                return dynamic_cast<QQuickWindow *>(window);
+        }
+        return nullptr;
+    };
+    QTRY_VERIFY((popup = findPopup(m_window.get())));
     QCOMPARE(activeElementId(&view), QStringLiteral("select"));
 
     makeTouch(popup, QPoint(popup->width() / 2, popup->height() / 2));

From 259b7e88d66c54f539e7753b9411169b43739f35 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Mon, 17 Feb 2025 11:44:20 +0100
Subject: [PATCH 348/356] Add debug resources for debug builds

As unofficial builds do not use scrambled message ids
for mojo messages, this causes ipc errors, if
we run in debug mode. Therefore for debug builds
be explicit and do not use scrambled messages, unlike
for any other type.

As shipping debug resources (without scrambled messages)
increases overall installation size by less then 3MB,
simply support creating debug resources with javsscript
files created without scrambling messages.

Initial idea to keep the resource files in sync with
qWebEngineProcessd use case (so for only multi config
generator with CMAKE_DEBUG_POSTFIX) did not look good.

Therefore, keep things aligned with how we handle v8 sanpshot
context files for debug, add "debug" postfix to affected
resource files if config is debug.

Fixes: QTBUG-131897
Change-Id: I34fa4b4842db521c782af4f4f61212c8cf04ddae
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Moss Heim <moss.heim@qt.io>
(cherry picked from commit 76d317c082b2492cc1fe1fcf2afad26be5369d3f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 5f0e4094137ab8a6f038dd33fe71ce49027fdfec)
---
 cmake/Functions.cmake                         | 21 +++++++++++++---
 src/core/CMakeLists.txt                       |  5 ++++
 src/core/api/CMakeLists.txt                   | 21 ++++++++++------
 .../api/Qt6WebEngineCoreDeploySupport.cmake   | 25 +++++++++++++------
 src/core/configure/BUILD.root.gn.in           | 25 ++++++++++++++++---
 src/core/web_engine_library_info.cpp          | 15 +++++++++++
 6 files changed, 90 insertions(+), 22 deletions(-)

diff --git a/cmake/Functions.cmake b/cmake/Functions.cmake
index 5788efea56a..b0a9fd26168 100644
--- a/cmake/Functions.cmake
+++ b/cmake/Functions.cmake
@@ -830,21 +830,34 @@ macro(append_build_type_setup)
         enable_rust=false # We do not yet support rust
     )
     if(${config} STREQUAL "Debug")
-        list(APPEND gnArgArg is_debug=true symbol_level=2)
+        list(APPEND gnArgArg
+            is_debug=true
+            symbol_level=2
+            enable_mojom_message_id_scrambling=false
+        )
         if(WIN32)
             list(APPEND gnArgArg enable_iterator_debugging=true)
         endif()
     elseif(${config} STREQUAL "Release")
-        list(APPEND gnArgArg is_debug=false symbol_level=0)
+        list(APPEND gnArgArg
+            is_debug=false
+            symbol_level=0
+            enable_mojom_message_id_scrambling=true
+        )
     elseif(${config} STREQUAL "RelWithDebInfo")
-        list(APPEND gnArgArg is_debug=false)
+        list(APPEND gnArgArg is_debug=false enable_mojom_message_id_scrambling=true)
         if(WIN32 AND NOT CLANG)
             list(APPEND gnArgArg symbol_level=2)
         else()
             list(APPEND gnArgArg symbol_level=1)
         endif()
     elseif(${config} STREQUAL "MinSizeRel")
-        list(APPEND gnArgArg is_debug=false symbol_level=0 optimize_for_size=true)
+        list(APPEND gnArgArg
+            is_debug=false
+            symbol_level=0
+            optimize_for_size=true
+            enable_mojom_message_id_scrambling=true
+        )
     endif()
     if(FEATURE_developer_build OR (${config} STREQUAL "Debug") OR QT_FEATURE_webengine_sanitizer)
         list(APPEND gnArgArg
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 487d0a004e2..c64b2cf78b8 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -195,6 +195,11 @@ foreach(arch ${archs})
                 authenticator_request_dialog_controller.cpp authenticator_request_dialog_controller.h authenticator_request_dialog_controller_p.h
         )
 
+        extend_gn_target(${buildGn} CONDITION config STREQUAL "Debug"
+            DEFINES
+                QT_USE_DEBUG_RESOURCES
+        )
+
         extend_gn_target(${buildGn} CONDITION QT_FEATURE_accessibility
             SOURCES
                 accessibility_activation_observer.cpp accessibility_activation_observer.h
diff --git a/src/core/api/CMakeLists.txt b/src/core/api/CMakeLists.txt
index 3d2a153a39e..25028c701ec 100644
--- a/src/core/api/CMakeLists.txt
+++ b/src/core/api/CMakeLists.txt
@@ -136,10 +136,10 @@ set(localeList am ar bg bn ca cs da de el en-GB en-US es-419 es et fa fi fil fr
     gu he hi hr hu id it ja kn ko lt lv ml mr ms nb nl pl pt-BR pt-PT ro ru sk
     sl sr sv sw ta te th tr uk vi zh-CN zh-TW)
 
-set(resourceList qtwebengine_resources.pak
-    qtwebengine_resources_100p.pak
-    qtwebengine_resources_200p.pak
-    qtwebengine_devtools_resources.pak)
+set(resourceList qtwebengine_resources
+    qtwebengine_resources_100p
+    qtwebengine_resources_200p
+    qtwebengine_devtools_resources)
 
 set(stamps ${buildDir}/${config}/${arch}/QtWebEngineCore.stamp)
 
@@ -176,9 +176,16 @@ foreach(loc ${localeList})
     list(APPEND localeFiles ${locSourcePath})
 endforeach()
 
-foreach(res ${resourceList})
-    get_filename_component(resSourcePath ${buildDir}/${config}/${arch}/${res} ${path_mode})
-    list(APPEND resourceFiles ${resSourcePath})
+foreach(config ${configs})
+    if("${config}" STREQUAL "Debug")
+        set(ext_debug ".debug")
+    else()
+        unset(ext_debug)
+    endif()
+    foreach(res ${resourceList})
+        get_filename_component(resSourcePath ${buildDir}/${config}/${arch}/${res}${ext_debug}.pak ${path_mode})
+        list(APPEND resourceFiles ${resSourcePath})
+    endforeach()
 endforeach()
 
 
diff --git a/src/core/api/Qt6WebEngineCoreDeploySupport.cmake b/src/core/api/Qt6WebEngineCoreDeploySupport.cmake
index 7334be4e742..2ff3d9e70de 100644
--- a/src/core/api/Qt6WebEngineCoreDeploySupport.cmake
+++ b/src/core/api/Qt6WebEngineCoreDeploySupport.cmake
@@ -126,14 +126,25 @@ function(_qt_internal_deploy_webenginecore_binary)
 endfunction()
 
 function(_qt_internal_deploy_webenginecore_data)
+    # used for deployment on Linux, using the CMake deployment API.
     _qt_internal_webenginecore_status_message("Deploying the WebEngineCore data files")
-    set(data_files
-        icudtl.dat
-        qtwebengine_devtools_resources.pak
-        qtwebengine_resources.pak
-        qtwebengine_resources_100p.pak
-        qtwebengine_resources_200p.pak
-    )
+    if(__QT_DEPLOY_ACTIVE_CONFIG STREQUAL "Debug")
+        set(data_files
+            icudtl.dat
+            qtwebengine_devtools_resources.debug.pak
+            qtwebengine_resources.debug.pak
+            qtwebengine_resources_100p.debug.pak
+            qtwebengine_resources_200p.debug.pak
+        )
+    else()
+        set(data_files
+            icudtl.dat
+            qtwebengine_devtools_resources.pak
+            qtwebengine_resources.pak
+            qtwebengine_resources_100p.pak
+            qtwebengine_resources_200p.pak
+        )
+    endif()
     get_filename_component(resources_dir "resources" ABSOLUTE
         BASE_DIR "${__QT_DEPLOY_QT_INSTALL_PREFIX}/${__QT_DEPLOY_QT_INSTALL_DATA}"
     )
diff --git a/src/core/configure/BUILD.root.gn.in b/src/core/configure/BUILD.root.gn.in
index c5cef0c7606..a50c6dd6299 100644
--- a/src/core/configure/BUILD.root.gn.in
+++ b/src/core/configure/BUILD.root.gn.in
@@ -604,7 +604,12 @@ repack("qtwebengine_repack_resources") {
     "$root_gen_dir/third_party/blink/public/resources/blink_resources.pak",
     "$root_gen_dir/ui/resources/webui_resources.pak",
   ]
-  output = "$root_out_dir/qtwebengine_resources.pak"
+  if (!is_debug) {
+    output = "$root_out_dir/qtwebengine_resources.pak"
+  } else {
+    output = "$root_out_dir/qtwebengine_resources.debug.pak"
+  }
+
   deps = [
      "//qtwebengine/browser:qt_webengine_resources",
      "//chrome/browser:dev_ui_browser_resources_grit",
@@ -684,7 +689,11 @@ repack("qtwebengine_repack_resources_100") {
     "$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_100_percent.pak",
     "$root_gen_dir/ui/resources/ui_resources_100_percent.pak",
   ]
-  output = "$root_out_dir/qtwebengine_resources_100p.pak"
+  if (!is_debug) {
+    output = "$root_out_dir/qtwebengine_resources_100p.pak"
+  } else {
+    output = "$root_out_dir/qtwebengine_resources_100p.debug.pak"
+  }
   deps = [
     "//chrome/renderer:resources_grit",
     "//components/resources:components_scaled_resources_grit",
@@ -708,7 +717,11 @@ repack("qtwebengine_repack_resources_200") {
     "$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_200_percent.pak",
     "$root_gen_dir/ui/resources/ui_resources_200_percent.pak",
   ]
-  output = "$root_out_dir/qtwebengine_resources_200p.pak"
+  if (!is_debug) {
+    output = "$root_out_dir/qtwebengine_resources_200p.pak"
+  } else {
+    output = "$root_out_dir/qtwebengine_resources_200p.debug.pak"
+  }
   deps = [
     "//chrome/renderer:resources_grit",
     "//components/resources:components_scaled_resources_grit",
@@ -730,7 +743,11 @@ repack("qtwebengine_repack_resources_devtools") {
     "$root_gen_dir/content/browser/devtools/devtools_resources.pak",
     "$root_gen_dir/third_party/blink/public/resources/inspector_overlay_resources.pak",
   ]
-  output = "$root_out_dir/qtwebengine_devtools_resources.pak"
+  if (!is_debug) {
+    output = "$root_out_dir/qtwebengine_devtools_resources.pak"
+  } else {
+    output = "$root_out_dir/qtwebengine_devtools_resources.debug.pak"
+  }
   deps = [
     "//content/browser/devtools:devtools_resources_grit",
     "//third_party/blink/public:devtools_inspector_resources_grit",
diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp
index bb704926d33..cd132b2ad11 100644
--- a/src/core/web_engine_library_info.cpp
+++ b/src/core/web_engine_library_info.cpp
@@ -308,7 +308,11 @@ QString resourcesPath()
     static QString potentialResourcesPath;
     if (potentialResourcesPath.isEmpty()) {
         QStringList candidatePaths;
+#if !defined(QT_USE_DEBUG_RESOURCES)
         const auto resourcesPakFilename = "qtwebengine_resources.pak"_L1;
+#else
+        const auto resourcesPakFilename = "qtwebengine_resources.debug.pak"_L1;
+#endif
         bool includeOverrideMessage = false;
         if (QString fromEnv = qEnvironmentVariable("QTWEBENGINE_RESOURCES_PATH");
             fromEnv.isEmpty()) {
@@ -357,6 +361,7 @@ base::FilePath WebEngineLibraryInfo::getPath(int key, bool showWarnings)
 {
     QString directory;
     switch (key) {
+#if !defined(QT_USE_DEBUG_RESOURCES)
     case QT_RESOURCES_PAK:
         return toFilePath(resourcesPath() % "/qtwebengine_resources.pak"_L1);
     case QT_RESOURCES_100P_PAK:
@@ -365,6 +370,16 @@ base::FilePath WebEngineLibraryInfo::getPath(int key, bool showWarnings)
         return toFilePath(resourcesPath() % "/qtwebengine_resources_200p.pak"_L1);
     case QT_RESOURCES_DEVTOOLS_PAK:
         return toFilePath(resourcesPath() % "/qtwebengine_devtools_resources.pak"_L1);
+#else
+    case QT_RESOURCES_PAK:
+        return toFilePath(resourcesPath() % "/qtwebengine_resources.debug.pak"_L1);
+    case QT_RESOURCES_100P_PAK:
+        return toFilePath(resourcesPath() % "/qtwebengine_resources_100p.debug.pak"_L1);
+    case QT_RESOURCES_200P_PAK:
+        return toFilePath(resourcesPath() % "/qtwebengine_resources_200p.debug.pak"_L1);
+    case QT_RESOURCES_DEVTOOLS_PAK:
+        return toFilePath(resourcesPath() % "/qtwebengine_devtools_resources.debug.pak"_L1);
+#endif
 #if defined(Q_OS_DARWIN) && defined(QT_MAC_FRAMEWORK_BUILD)
     case QT_FRAMEWORK_BUNDLE:
         return toFilePath(getBundlePath(frameworkBundle()));

From 0d3c97479a98894d2abf1041b689607ae87edd37 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Fri, 13 Jun 2025 15:43:35 +0200
Subject: [PATCH 349/356] Update Chromium

Submodule src/3rdparty fb7cda49..d0e0abc0:
* [backport] CVE-2025-5068 (2/2)
* [backport] CVE-2025-5068 (1/2)
* [backport] CVE-2025-5419
* [backport] Security bug 325123679
* [backport] Security bug 408294914
* [backport] Security bug 407898107 (3/3)
* [backport] Security bug 407898107 (2/3)
* [backport] Security bug 407898107 (1/3)
* [Backport] Security bug 420637585

Fixes: QTBUG-137376
Fixes: QTBUG-137384
Change-Id: Id863a9a0e0384535a56f983d8b9cf00c3db60f11
Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
---
 CHROMIUM_VERSION                | 2 +-
 src/3rdparty                    | 2 +-
 src/core/web_engine_context.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index eb2bd1e90dc..d5745c8155d 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
 
 Based on Chromium version:                                      122.0.6261.171
-Patched with security patches up to Chromium version:           136.0.7103.114
+Patched with security patches up to Chromium version:           137.0.7151.68
diff --git a/src/3rdparty b/src/3rdparty
index fb7cda4952b..d0e0abc064b 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit fb7cda4952b8f84b79e52f2d31dc05636f9e0935
+Subproject commit d0e0abc064b8b8434ce92194ff76043a6b32033a
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 8dc83fcc99e..f5cb8be2098 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1297,7 +1297,7 @@ const char *qWebEngineChromiumVersion() noexcept
 
 const char *qWebEngineChromiumSecurityPatchVersion() noexcept
 {
-    return "136.0.7103.114"; // FIXME: Remember to update
+    return "137.0.7151.68"; // FIXME: Remember to update
 }
 
 QT_END_NAMESPACE

From e66b5a12ac1d6c4c0ea612ebaad2894d87286bce Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Tue, 17 Jun 2025 09:32:49 +0200
Subject: [PATCH 350/356] Update Chromium
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Submodule src/3rdparty d0e0abc0..1cacccf9:
* [fixup] Fixes for jumbo build

Task-number: QTBUG-137730
Change-Id: Iae5a40af36c8d48c451e6efe39b445abb40671fa
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
---
 src/3rdparty | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/3rdparty b/src/3rdparty
index d0e0abc064b..1cacccf93f1 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit d0e0abc064b8b8434ce92194ff76043a6b32033a
+Subproject commit 1cacccf93f18d0f7267989001c509a5196b25bf7

From 77646d09b37c1678f4eba968f049349994fc59f4 Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Tue, 1 Jul 2025 00:43:03 +0200
Subject: [PATCH 351/356] Workaround for broken system header on rhel-8.10
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

In ci on rhel-8.10 system header
/usr/include/libxslt/xsltutils.h has not working
header guards, the file ends on:

#ifdef __cplusplus
}
#endif /* __XML_XSLTUTILS_H__ */

so one #end if is missplaced, same header in
third_party/libxslt/src/libxslt/xsltutils.h looks correct.

The reason why this is incorrect on vm in ci
is unknown, however simply use bundled libxslt
in case of ci broken machine. The other workaround
would be dropping jumbo build which would not
require broken header guard.

Deals with:
error: ‘XSLT_DEBUG_INIT’ conflicts with a previous declaration

Task-number: COIN-1249
Change-Id: I94efdc14ce49cd51ff8a320765bcd55a7deb0d6f
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
---
 coin/module_config.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/coin/module_config.yaml b/coin/module_config.yaml
index cceb2502a34..968c504b0b6 100644
--- a/coin/module_config.yaml
+++ b/coin/module_config.yaml
@@ -13,6 +13,13 @@ machine_type:
 
 instructions:
   Build:
+    - type: AppendToEnvironmentVariable
+      variableName: COMMON_NON_QTBASE_CMAKE_ARGS
+      variableValue: " -DFEATURE_webengine_system_libxml=OFF"
+      enable_if:
+        condition: runtime
+        env_var: COIN_PLATFORM_ID
+        contains_value: "rhel-8.10"
     - type: EnvironmentVariable
       variableName: VERIFY_SOURCE_SBOM
       variableValue: "ON"

From c4ef7727eb2674dfcd3818cf009f674a8345cfae Mon Sep 17 00:00:00 2001
From: Michal Klocek <michal.klocek@qt.io>
Date: Thu, 3 Jul 2025 09:42:53 +0200
Subject: [PATCH 352/356] Fix crash if ui delegates are not deployed
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

In case delegate for touch handle can not be loaded
bail out and simply return nullptr as TouchHandleDrawableQt
works fine without delegate (guards against nullptr).

Note all other dialog already bailout in case default delegate
can not be loaded.

Tested on bookworm with 6.8.3

Fixes: QTBUG-111907
Change-Id: Ib509b63010888fa718f23148c06d973382cad428
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
(cherry picked from commit e86aa68ac75da4e20b55c2bca91d3f98a1e53090)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 1dabfd90ae8889cd2aac046f0bf7015c77735e72)
(cherry picked from commit c34d567d478b5162966bf6a30300eda85ffbef0c)
---
 src/webenginequick/api/qquickwebengineview.cpp | 8 ++++++--
 src/webenginequick/ui_delegates_manager.cpp    | 1 +
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/webenginequick/api/qquickwebengineview.cpp b/src/webenginequick/api/qquickwebengineview.cpp
index 0fa9db0f060..c1c6e3d1274 100644
--- a/src/webenginequick/api/qquickwebengineview.cpp
+++ b/src/webenginequick/api/qquickwebengineview.cpp
@@ -1450,8 +1450,9 @@ QQuickWebEngineViewPrivate::createTouchHandleDelegate(const QMap<int, QImage> &i
 {
     Q_Q(QQuickWebEngineView);
     // lifecycle managed by Chromium's TouchHandleDrawable
-    QQuickWebEngineTouchHandle *handle = new QQuickWebEngineTouchHandle();
+    QQuickWebEngineTouchHandle *handle(nullptr);
     if (m_touchHandleDelegate) {
+        handle = new QQuickWebEngineTouchHandle();
         QQmlContext *qmlContext = QQmlEngine::contextForObject(q);
         QQmlContext *context = new QQmlContext(qmlContext, handle);
         context->setContextObject(handle);
@@ -1462,7 +1463,9 @@ QQuickWebEngineViewPrivate::createTouchHandleDelegate(const QMap<int, QImage> &i
         handle->setItem(item, false);
     } else {
         QQuickItem *item = ui()->createTouchHandle();
-        Q_ASSERT(item);
+        if (!item) {
+            return nullptr;
+        }
         QQmlEngine *engine = qmlEngine(item);
         Q_ASSERT(engine);
         QQuickWebEngineTouchHandleProvider *touchHandleProvider =
@@ -1470,6 +1473,7 @@ QQuickWebEngineViewPrivate::createTouchHandleDelegate(const QMap<int, QImage> &i
                         engine->imageProvider(QQuickWebEngineTouchHandleProvider::identifier()));
         Q_ASSERT(touchHandleProvider);
         touchHandleProvider->init(images);
+        handle = new QQuickWebEngineTouchHandle();
         handle->setItem(item, true);
     }
     return handle;
diff --git a/src/webenginequick/ui_delegates_manager.cpp b/src/webenginequick/ui_delegates_manager.cpp
index f4036059d6a..22debc0bbbf 100644
--- a/src/webenginequick/ui_delegates_manager.cpp
+++ b/src/webenginequick/ui_delegates_manager.cpp
@@ -155,6 +155,7 @@ bool UIDelegatesManager::ensureComponentLoaded(ComponentType type)
         }
         return true;
     }
+    qWarning("Default ui delegate %s can not be found.", qPrintable(fileName));
     return false;
 }
 

From bbc4b83b17d221d812eb7c61dd4e3c647007f1c2 Mon Sep 17 00:00:00 2001
From: Moss Heim <moss.heim@qt.io>
Date: Fri, 11 Jul 2025 15:28:19 +0200
Subject: [PATCH 353/356] Tests: fortify window activation tests

Some tests require window activation so they can interact and query
objects with active focus. For those, merely exposing the window is not
enough because Ubuntu's default WM settings do not guarantee activation
for new windows. We request that explicitly and wait on activation.

We also need to disable those tests on platforms that don't support
QWindow::requestActivate(), add a new header with a macro based on
qtdeclarative tests to support that.

Change-Id: I7d80310e2318f9001b2dd5c581209e75b0c599fe
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit cb4854ed6abd3a39bedc6b09509f778d29099085)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 7afb76cdf037359a199945930c3be97bffb880d6)
(cherry picked from commit fbd331a725e20bd6a0d8db107b5fc5d2d31bb971)
---
 .../tst_qquickwebengineview.cpp               | 20 +++++++--
 .../quick/uidelegates/tst_uidelegates.cpp     | 31 ++++++++++---
 tests/auto/util/visualutil.h                  | 19 ++++++++
 .../qwebenginedownloadrequest/CMakeLists.txt  |  1 +
 .../tst_qwebenginedownloadrequest.cpp         |  8 ++++
 .../qwebenginepage/tst_qwebenginepage.cpp     |  9 +++-
 .../qwebengineview/tst_qwebengineview.cpp     | 45 +++++++++++++++----
 7 files changed, 114 insertions(+), 19 deletions(-)
 create mode 100644 tests/auto/util/visualutil.h

diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index 8185bc47eb7..eae1b1c9d1b 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -5,6 +5,7 @@
 #include "testwindow.h"
 #include "quickutil.h"
 #include "util.h"
+#include "visualutil.h"
 
 #include <QScopedPointer>
 #include <QtCore/qelapsedtimer.h>
@@ -448,7 +449,11 @@ void tst_QQuickWebEngineView::transparentWebEngineViews()
 
 void tst_QQuickWebEngineView::inputMethod()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
     m_window->show();
+    m_window->requestActivate();
+    QVERIFY(QTest::qWaitForWindowActive(m_window.get()));
     QQuickItem *input;
 
     QQuickWebEngineView *view = webEngineView();
@@ -550,8 +555,11 @@ void tst_QQuickWebEngineView::interruptImeTextComposition_data()
 
 void tst_QQuickWebEngineView::interruptImeTextComposition()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
     m_window->show();
-    QTRY_VERIFY(qApp->focusObject());
+    m_window->requestActivate();
+    QVERIFY(QTest::qWaitForWindowActive(m_window.get()));
     QQuickItem *input;
 
     QQuickWebEngineView *view = webEngineView();
@@ -600,8 +608,11 @@ void tst_QQuickWebEngineView::interruptImeTextComposition()
 
 void tst_QQuickWebEngineView::inputContextQueryInput()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
     m_window->show();
-    QTRY_VERIFY(qApp->focusObject());
+    m_window->requestActivate();
+    QVERIFY(QTest::qWaitForWindowActive(m_window.get()));
     TestInputContext testContext;
 
     QQuickWebEngineView *view = webEngineView();
@@ -745,8 +756,11 @@ void tst_QQuickWebEngineView::inputContextQueryInput()
 
 void tst_QQuickWebEngineView::inputMethodHints()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
     m_window->show();
-    QTRY_VERIFY(qApp->focusObject());
+    m_window->requestActivate();
+    QVERIFY(QTest::qWaitForWindowActive(m_window.get()));
     QQuickItem *input;
 
     QQuickWebEngineView *view = webEngineView();
diff --git a/tests/auto/quick/uidelegates/tst_uidelegates.cpp b/tests/auto/quick/uidelegates/tst_uidelegates.cpp
index 419f2f877fb..25702f4b870 100644
--- a/tests/auto/quick/uidelegates/tst_uidelegates.cpp
+++ b/tests/auto/quick/uidelegates/tst_uidelegates.cpp
@@ -3,6 +3,7 @@
 
 #include "testwindow.h"
 #include "quickutil.h"
+#include "visualutil.h"
 
 #include <QScopedPointer>
 #include <QtQml/QQmlEngine>
@@ -107,11 +108,14 @@ void tst_UIDelegates::javaScriptDialog_data()
 
 void tst_UIDelegates::javaScriptDialog()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
     QFETCH(QString, javaScriptCode);
     QFETCH(QString, expectedObjectName);
 
     m_window->show();
-    QTRY_VERIFY(qApp->focusObject());
+    m_window->requestActivate();
+    QVERIFY(QTest::qWaitForWindowActive(m_window.get()));
     QQuickWebEngineView *view = webEngineView();
 
     view->loadHtml("<html><body>"
@@ -124,8 +128,11 @@ void tst_UIDelegates::javaScriptDialog()
 
 void tst_UIDelegates::fileDialog()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
     m_window->show();
-    QTRY_VERIFY(qApp->focusObject());
+    m_window->requestActivate();
+    QVERIFY(QTest::qWaitForWindowActive(m_window.get()));
     QQuickWebEngineView *view = webEngineView();
 
     view->loadHtml("<html><body>"
@@ -140,8 +147,11 @@ void tst_UIDelegates::fileDialog()
 
 void tst_UIDelegates::contextMenu()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
     m_window->show();
-    QTRY_VERIFY(qApp->focusObject());
+    m_window->requestActivate();
+    QVERIFY(QTest::qWaitForWindowActive(m_window.get()));
     QQuickWebEngineView *view = webEngineView();
 
     view->loadHtml("<html><body>"
@@ -154,8 +164,11 @@ void tst_UIDelegates::contextMenu()
 
 void tst_UIDelegates::tooltip()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
     m_window->show();
-    QTRY_VERIFY(qApp->focusObject());
+    m_window->requestActivate();
+    QVERIFY(QTest::qWaitForWindowActive(m_window.get()));
     QQuickWebEngineView *view = webEngineView();
 
     view->loadHtml("<html><body>"
@@ -177,8 +190,11 @@ void tst_UIDelegates::tooltip()
 
 void tst_UIDelegates::colorDialog()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
     m_window->show();
-    QTRY_VERIFY(qApp->focusObject());
+    m_window->requestActivate();
+    QVERIFY(QTest::qWaitForWindowActive(m_window.get()));
     QQuickWebEngineView *view = webEngineView();
 
     view->loadHtml("<html><body>"
@@ -209,6 +225,8 @@ void tst_UIDelegates::authenticationDialog_data()
 
 void tst_UIDelegates::authenticationDialog()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
     QFETCH(QUrl, url);
     QFETCH(QByteArray, response);
 
@@ -218,7 +236,8 @@ void tst_UIDelegates::authenticationDialog()
     QVERIFY(server.start());
 
     m_window->show();
-    QTRY_VERIFY(qApp->focusObject());
+    m_window->requestActivate();
+    QVERIFY(QTest::qWaitForWindowActive(m_window.get()));
     QQuickWebEngineView *view = webEngineView();
     view->loadHtml("<html><body>"
                    "</body></html>");
diff --git a/tests/auto/util/visualutil.h b/tests/auto/util/visualutil.h
new file mode 100644
index 00000000000..ca967e71dda
--- /dev/null
+++ b/tests/auto/util/visualutil.h
@@ -0,0 +1,19 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef VISUALUTIL_H
+#define VISUALUTIL_H
+
+// Separate utils that require linking with GuiPrivate
+
+#include <QtTest/QtTest>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/qpa/qplatformintegration.h>
+
+#define SKIP_IF_NO_WINDOW_ACTIVATION() \
+do { \
+    if (!(QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))) \
+        QSKIP("Window activation is not supported on this platform"); \
+} while (false)
+
+#endif /* VISUALUTIL_H */
diff --git a/tests/auto/widgets/qwebenginedownloadrequest/CMakeLists.txt b/tests/auto/widgets/qwebenginedownloadrequest/CMakeLists.txt
index 5b76909b159..13b86a95666 100644
--- a/tests/auto/widgets/qwebenginedownloadrequest/CMakeLists.txt
+++ b/tests/auto/widgets/qwebenginedownloadrequest/CMakeLists.txt
@@ -9,6 +9,7 @@ qt_internal_add_test(tst_qwebenginedownloadrequest
         tst_qwebenginedownloadrequest.cpp
     LIBRARIES
         Qt::WebEngineWidgets
+        Qt::GuiPrivate
         Test::HttpServer
         Test::Util
 )
diff --git a/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp b/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
index b01d7b8c933..15e96bc0dcd 100644
--- a/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
+++ b/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
@@ -2,6 +2,7 @@
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
 
 #include <util.h>
+#include <visualutil.h>
 
 #include <QCoreApplication>
 #include <QSignalSpy>
@@ -131,6 +132,7 @@ void tst_QWebEngineDownloadRequest::initTestCase()
     m_view->setPage(m_page);
     m_view->resize(640, 480);
     m_view->show();
+    m_view->window()->windowHandle()->requestActivate();
 }
 
 void tst_QWebEngineDownloadRequest::init()
@@ -392,6 +394,8 @@ void tst_QWebEngineDownloadRequest::downloadLink_data()
 
 void tst_QWebEngineDownloadRequest::downloadLink()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
     QFETCH(UserAction, userAction);
     QFETCH(bool, anchorHasDownloadAttribute);
     QFETCH(QByteArray, fileName);
@@ -529,6 +533,8 @@ void tst_QWebEngineDownloadRequest::downloadTwoLinks_data()
 
 void tst_QWebEngineDownloadRequest::downloadTwoLinks()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
     QFETCH(UserAction, action1);
     QFETCH(UserAction, action2);
 
@@ -1348,6 +1354,8 @@ void tst_QWebEngineDownloadRequest::downloadDataUrls_data()
 
 void tst_QWebEngineDownloadRequest::downloadDataUrls()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
     QFETCH(QByteArray, htmlData);
     QFETCH(QString, expectedFileName);
     // Set up HTTP server
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 9fd9d2a58c0..08b17db83fd 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -20,6 +20,7 @@
 */
 
 #include <widgetutil.h>
+#include <visualutil.h>
 #include <QtNetwork/private/qtnetworkglobal_p.h>
 #include <QtWebEngineCore/qtwebenginecore-config.h>
 #include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
@@ -3439,13 +3440,19 @@ void tst_QWebEnginePage::mouseButtonTranslation()
 
 void tst_QWebEnginePage::mouseMovementProperties()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
+    if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
+        QSKIP("Wayland: Can't manipulating the mouse cursor in auto test.");
+
     QWebEngineView view;
     ConsolePage page;
     view.setPage(&page);
     view.resize(640, 480);
     QTest::mouseMove(&view, QPoint(10, 10));
     view.show();
-    QVERIFY(QTest::qWaitForWindowExposed(&view));
+    view.window()->windowHandle()->requestActivate();
+    QVERIFY(QTest::qWaitForWindowActive(&view));
 
     QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
     page.setHtml(QStringLiteral(
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index a6383c63023..d3100750983 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -22,6 +22,7 @@
 #include <QtWebEngineCore/private/qtwebenginecore-config_p.h>
 #include <qtest.h>
 #include <util.h>
+#include <visualutil.h>
 #include <private/qinputmethod_p.h>
 #include <qpainter.h>
 #include <qpagelayout.h>
@@ -1240,6 +1241,8 @@ void tst_QWebEngineView::focusOnNavigation()
 
 void tst_QWebEngineView::focusInternalRenderWidgetHostViewQuickItem()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
     // Create a container widget, that will hold a line edit that has initial focus, and a web
     // engine view.
     QScopedPointer<QWidget> containerWidget(new QWidget);
@@ -1261,7 +1264,8 @@ void tst_QWebEngineView::focusInternalRenderWidgetHostViewQuickItem()
     containerWidget->resize(300, 200);
     containerWidget->setLayout(layout);
     containerWidget->show();
-    QVERIFY(QTest::qWaitForWindowExposed(containerWidget.data()));
+    containerWidget->window()->windowHandle()->requestActivate();
+    QVERIFY(QTest::qWaitForWindowActive(containerWidget.data()));
 
     // Load the content, and check that focus is not set.
     QSignalSpy loadSpy(webView, SIGNAL(loadFinished(bool)));
@@ -1607,6 +1611,8 @@ class WebViewWithUrlBar : public QWidget {
 
 void tst_QWebEngineView::keyboardFocusAfterPopup()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
     const QString html = QStringLiteral(
         "<html>"
         "  <body onload=\"document.getElementById('input1').focus()\">"
@@ -1618,7 +1624,8 @@ void tst_QWebEngineView::keyboardFocusAfterPopup()
     connect(window.lineEdit, &QLineEdit::editingFinished, [&] { window.webView->setHtml(html); });
     window.webView->settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
     window.show();
-    QVERIFY(QTest::qWaitForWindowExposed(&window));
+    window.window()->windowHandle()->requestActivate();
+    QVERIFY(QTest::qWaitForWindowActive(&window));
 
     // Focus will initially go to the QLineEdit.
     QTRY_COMPARE(QApplication::focusWidget(), window.lineEdit);
@@ -1846,6 +1853,12 @@ void tst_QWebEngineView::postData()
 
 void tst_QWebEngineView::inputFieldOverridesShortcuts()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
+    if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(
+                QPlatformIntegration::WindowActivation))
+        QSKIP("Cannot test on platforms without window activation capability");
+
     QWebEngineView view;
     bool actionTriggered = false;
     QAction *action = new QAction(&view);
@@ -1861,6 +1874,7 @@ void tst_QWebEngineView::inputFieldOverridesShortcuts()
     QVERIFY(loadFinishedSpy.wait());
 
     view.show();
+    view.window()->windowHandle()->requestActivate();
     QVERIFY(QTest::qWaitForWindowActive(&view));
 
     auto inputFieldValue = [&view] () -> QString {
@@ -2054,9 +2068,12 @@ void tst_QWebEngineView::softwareInputPanel()
 
 void tst_QWebEngineView::inputContextQueryInput()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
     QWebEngineView view;
     view.resize(640, 480);
     view.show();
+    view.window()->windowHandle()->requestActivate();
 
     // testContext will be destroyed before the view, so no events are sent accidentally
     // when the view is destroyed.
@@ -2068,8 +2085,7 @@ void tst_QWebEngineView::inputContextQueryInput()
                  "  <input type='text' id='input1' value='' size='50'/>"
                  "</body></html>");
     QTRY_COMPARE(loadFinishedSpy.size(), 1);
-    QVERIFY(QTest::qWaitForWindowExposed(&view));
-    QTRY_VERIFY(qApp->focusObject());
+    QVERIFY(QTest::qWaitForWindowActive(&view));
     QCOMPARE(testContext.infos.size(), 0);
 
     // Set focus on an input field.
@@ -2562,10 +2578,13 @@ void tst_QWebEngineView::emptyInputMethodEvent()
 
 void tst_QWebEngineView::imeComposition()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
     QWebEngineView view;
     view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
     view.resize(640, 480);
     view.show();
+    view.window()->windowHandle()->requestActivate();
 
     QSignalSpy selectionChangedSpy(&view, SIGNAL(selectionChanged()));
     QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
@@ -2573,7 +2592,7 @@ void tst_QWebEngineView::imeComposition()
                  "  <input type='text' id='input1' value='QtWebEngine inputMethod'/>"
                  "</body></html>");
     QVERIFY(loadFinishedSpy.wait());
-    QVERIFY(QTest::qWaitForWindowExposed(&view));
+    QVERIFY(QTest::qWaitForWindowActive(&view));
 
     evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.focus(); inputEle.select();");
     QTRY_COMPARE(selectionChangedSpy.size(), 1);
@@ -2781,17 +2800,20 @@ void tst_QWebEngineView::imeComposition()
 
 void tst_QWebEngineView::newlineInTextarea()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
     QWebEngineView view;
     view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
     view.resize(640, 480);
     view.show();
+    view.window()->windowHandle()->requestActivate();
 
     QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
     view.page()->setHtml("<html><body>"
                          "  <textarea rows='5' cols='1' id='input1'></textarea>"
                          "</body></html>");
     QVERIFY(loadFinishedSpy.wait());
-    QVERIFY(QTest::qWaitForWindowExposed(&view));
+    QVERIFY(QTest::qWaitForWindowActive(&view));
 
     evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.focus(); inputEle.select();");
     QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString().isEmpty());
@@ -3028,18 +3050,21 @@ void tst_QWebEngineView::imeCompositionQueryEvent_data()
 
 void tst_QWebEngineView::imeCompositionQueryEvent()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
     QWebEngineView view;
     view.resize(640, 480);
     view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
 
     view.show();
+    view.window()->windowHandle()->requestActivate();
 
     QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
     view.setHtml("<html><body>"
                  "  <input type='text' id='input1' />"
                  "</body></html>");
     QVERIFY(loadFinishedSpy.wait());
-    QVERIFY(QTest::qWaitForWindowExposed(&view));
+    QVERIFY(QTest::qWaitForWindowActive(&view));
 
     evaluateJavaScriptSync(view.page(), "document.getElementById('input1').focus()");
     QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
@@ -4031,6 +4056,8 @@ void tst_QWebEngineView::deferredDelete()
 // QTBUG-111927
 void tst_QWebEngineView::setCursorOnEmbeddedView()
 {
+    SKIP_IF_NO_WINDOW_ACTIVATION();
+
     if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
         QSKIP("Wayland: Can't manipulate the mouse cursor in auto test.");
 
@@ -4055,9 +4082,9 @@ void tst_QWebEngineView::setCursorOnEmbeddedView()
     view.setHtml(html);
     parentWidget.show();
     view.show();
+    parentWidget.window()->windowHandle()->requestActivate();
 
-    QVERIFY(QTest::qWaitForWindowExposed(&parentWidget));
-    QVERIFY(QTest::qWaitForWindowExposed(&view));
+    QVERIFY(QTest::qWaitForWindowActive(&parentWidget));
 
     QTRY_VERIFY(firstPaintSpy.size());
 

From a0b6c01daa256c999efcfec6cabbfda6089886cb Mon Sep 17 00:00:00 2001
From: Allan Sandfeld Jensen <allan.jensen@qt.io>
Date: Mon, 4 Aug 2025 18:05:28 +0200
Subject: [PATCH 354/356] Stop using private V4 API

Everything we need have long been available through public API.

Change-Id: Ifc3925971e8b81852ad42d5dd535ffa9eec1b37b
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
(cherry picked from commit 6187d6ea6fe5548188b60c357fc9c62f4f567a79)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 9836d8cd99a617aaaba1899b71afdd6bf2563bb6)
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 0af59970f1ae57f129b47b8fac8ff2cd8d399730)
---
 .../api/qquickwebenginescriptcollection.cpp   | 20 +++++++------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/src/webenginequick/api/qquickwebenginescriptcollection.cpp b/src/webenginequick/api/qquickwebenginescriptcollection.cpp
index f5328a134e4..09a8d181e95 100644
--- a/src/webenginequick/api/qquickwebenginescriptcollection.cpp
+++ b/src/webenginequick/api/qquickwebenginescriptcollection.cpp
@@ -3,12 +3,10 @@
 
 #include "qquickwebenginescriptcollection_p.h"
 #include "qquickwebenginescriptcollection_p_p.h"
-#include "qwebenginescriptcollection.h"
+#include <QtWebEngineCore/qwebenginescriptcollection.h>
 #include <QtWebEngineCore/private/qwebenginescriptcollection_p.h>
 #include <QtQml/qqmlinfo.h>
-#include <QtQml/private/qqmlengine_p.h>
-#include <QtQml/private/qv4scopedvalue_p.h>
-#include <QtQml/private/qv4arrayobject_p.h>
+#include <QtQml/qqmlengine.h>
 
 /*!
     \qmltype WebEngineScriptCollection
@@ -198,15 +196,11 @@ QJSValue QQuickWebEngineScriptCollection::collection() const
     }
 
     const QList<QWebEngineScript> &list = d->toList();
-    QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(d->m_qmlEngine);
-    QV4::Scope scope(v4);
-    QV4::Scoped<QV4::ArrayObject> scriptArray(scope, v4->newArrayObject(list.size()));
-    int i = 0;
-    for (const auto &val : list) {
-        QV4::ScopedValue sv(scope, v4->fromVariant(QVariant::fromValue(val)));
-        scriptArray->put(i++, sv);
-    }
-    return QJSValuePrivate::fromReturnedValue(scriptArray.asReturnedValue());
+    QJSValue scriptArray = d->m_qmlEngine->newArray(list.size());
+    uint32_t i = 0;
+    for (const auto &val : list)
+        scriptArray.setProperty(i++, d->m_qmlEngine->toScriptValue(val));
+    return scriptArray;
 }
 
 void QQuickWebEngineScriptCollection::setCollection(const QJSValue &scripts)

From 24bd6af0fa94ce0a91de133c764e9ab0eb40cc0f Mon Sep 17 00:00:00 2001
From: Kaloyan Chehlarski <kaloyan.chehlarski@qt.io>
Date: Thu, 31 Jul 2025 11:54:44 +0200
Subject: [PATCH 355/356] CRA mark src/core/renderer_host

QUIP: 23
Task-number: QTBUG-138724
Change-Id: Icc5c4b8811de48e183975ec79f357cf9b993df45
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 57a3514b87c6e8d1c56929b1bb5d881bb908a191)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit b0268951bb0654f57c624192e2cc5b1bc4ca2f38)
(cherry picked from commit b62e17e5a069d762052d354b1f4eb980f86f92b2)
---
 src/core/renderer_host/user_resource_controller_host.cpp  | 1 +
 src/core/renderer_host/user_resource_controller_host.h    | 1 +
 src/core/renderer_host/web_channel_ipc_transport_host.cpp | 1 +
 src/core/renderer_host/web_channel_ipc_transport_host.h   | 1 +
 src/core/renderer_host/web_engine_page_host.cpp           | 1 +
 src/core/renderer_host/web_engine_page_host.h             | 1 +
 6 files changed, 6 insertions(+)

diff --git a/src/core/renderer_host/user_resource_controller_host.cpp b/src/core/renderer_host/user_resource_controller_host.cpp
index 1a6b9e935fa..a2917194234 100644
--- a/src/core/renderer_host/user_resource_controller_host.cpp
+++ b/src/core/renderer_host/user_resource_controller_host.cpp
@@ -1,5 +1,6 @@
 // Copyright (C) 2016 The Qt Company Ltd.
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
 
 #include "user_resource_controller_host.h"
 
diff --git a/src/core/renderer_host/user_resource_controller_host.h b/src/core/renderer_host/user_resource_controller_host.h
index eb4404879d7..f843c732140 100644
--- a/src/core/renderer_host/user_resource_controller_host.h
+++ b/src/core/renderer_host/user_resource_controller_host.h
@@ -1,5 +1,6 @@
 // Copyright (C) 2016 The Qt Company Ltd.
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
 
 //
 //  W A R N I N G
diff --git a/src/core/renderer_host/web_channel_ipc_transport_host.cpp b/src/core/renderer_host/web_channel_ipc_transport_host.cpp
index 41ef98c8bb9..6db578a27a0 100644
--- a/src/core/renderer_host/web_channel_ipc_transport_host.cpp
+++ b/src/core/renderer_host/web_channel_ipc_transport_host.cpp
@@ -1,5 +1,6 @@
 // Copyright (C) 2018 The Qt Company Ltd.
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
 
 #include "web_channel_ipc_transport_host.h"
 
diff --git a/src/core/renderer_host/web_channel_ipc_transport_host.h b/src/core/renderer_host/web_channel_ipc_transport_host.h
index 16ff5178933..82421199ffe 100644
--- a/src/core/renderer_host/web_channel_ipc_transport_host.h
+++ b/src/core/renderer_host/web_channel_ipc_transport_host.h
@@ -1,5 +1,6 @@
 // Copyright (C) 2018 The Qt Company Ltd.
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
 
 #ifndef WEB_CHANNEL_IPC_TRANSPORT_H
 #define WEB_CHANNEL_IPC_TRANSPORT_H
diff --git a/src/core/renderer_host/web_engine_page_host.cpp b/src/core/renderer_host/web_engine_page_host.cpp
index ea9b363eab9..2a2672159eb 100644
--- a/src/core/renderer_host/web_engine_page_host.cpp
+++ b/src/core/renderer_host/web_engine_page_host.cpp
@@ -1,5 +1,6 @@
 // Copyright (C) 2016 The Qt Company Ltd.
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
 
 #include "web_engine_page_host.h"
 
diff --git a/src/core/renderer_host/web_engine_page_host.h b/src/core/renderer_host/web_engine_page_host.h
index 20b9145b219..8fb128aeb32 100644
--- a/src/core/renderer_host/web_engine_page_host.h
+++ b/src/core/renderer_host/web_engine_page_host.h
@@ -1,5 +1,6 @@
 // Copyright (C) 2016 The Qt Company Ltd.
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:default
 
 #ifndef WEB_ENGINE_PAGE_HOST_H
 #define WEB_ENGINE_PAGE_HOST_H

From 8f32bd2949153ee08eb9a3aec87ab31ff12846e1 Mon Sep 17 00:00:00 2001
From: Peter Varga <pvarga@inf.u-szeged.hu>
Date: Thu, 31 Jul 2025 11:03:13 +0200
Subject: [PATCH 356/356] Delete OpenGL textures in the same context where they
 were created

Fixes: QTBUG-138641
Change-Id: I97ee0964ea09080917f79f40adead61dd086442a
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 092e42c0fc3708a1db1b254733603d7e2868a32b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 1f119b3302aaaa54bc9241fd577b5837a77f4f4c)
(cherry picked from commit 9dd5105673f30fa6e8dc9bb3ee5cf4f51cec6ed2)
---
 src/core/compositor/compositor.h              |  3 +
 .../compositor/native_skia_output_device.cpp  | 10 ++-
 .../compositor/native_skia_output_device.h    |  1 +
 .../native_skia_output_device_opengl.cpp      | 89 +++++++++++++++----
 ...nder_widget_host_view_qt_delegate_item.cpp | 87 +++++++++++++-----
 ...render_widget_host_view_qt_delegate_item.h |  2 +-
 6 files changed, 151 insertions(+), 41 deletions(-)

diff --git a/src/core/compositor/compositor.h b/src/core/compositor/compositor.h
index 041835dd0c2..316c19684e1 100644
--- a/src/core/compositor/compositor.h
+++ b/src/core/compositor/compositor.h
@@ -134,6 +134,9 @@ class Q_WEBENGINECORE_EXPORT Compositor
     // Is the texture produced upside down?
     virtual bool textureIsFlipped();
 
+    // Are there resources to be released?
+    virtual bool hasResources() { return false; }
+
     // Release resources created in texture()
     virtual void releaseResources();
 
diff --git a/src/core/compositor/native_skia_output_device.cpp b/src/core/compositor/native_skia_output_device.cpp
index aef0a8158f7..944f5863e08 100644
--- a/src/core/compositor/native_skia_output_device.cpp
+++ b/src/core/compositor/native_skia_output_device.cpp
@@ -170,6 +170,11 @@ void NativeSkiaOutputDevice::releaseTexture()
     }
 }
 
+bool NativeSkiaOutputDevice::hasResources()
+{
+    return m_frontBuffer && m_frontBuffer->textureCleanupCallback;
+}
+
 void NativeSkiaOutputDevice::releaseResources()
 {
     if (m_frontBuffer)
@@ -215,7 +220,10 @@ NativeSkiaOutputDevice::Buffer::Buffer(NativeSkiaOutputDevice *parent)
 
 NativeSkiaOutputDevice::Buffer::~Buffer()
 {
-    DCHECK(!textureCleanupCallback);
+    // FIXME: Can't be called in case of threaded rendering with unexposed window.
+    //DCHECK(!textureCleanupCallback);
+    if (textureCleanupCallback)
+        qWarning("NativeSkiaOutputDevice: Leaking graphics resources.");
 
     if (m_scopedSkiaWriteAccess)
         endWriteSkia(false);
diff --git a/src/core/compositor/native_skia_output_device.h b/src/core/compositor/native_skia_output_device.h
index d2101c0fbf2..fe76e26b05f 100644
--- a/src/core/compositor/native_skia_output_device.h
+++ b/src/core/compositor/native_skia_output_device.h
@@ -77,6 +77,7 @@ class NativeSkiaOutputDevice : public viz::SkiaOutputDevice, public Compositor
     void swapFrame() override;
     void waitForTexture() override;
     void releaseTexture() override;
+    bool hasResources() override;
     void releaseResources() override;
     bool textureIsFlipped() override;
     QSize size() override;
diff --git a/src/core/compositor/native_skia_output_device_opengl.cpp b/src/core/compositor/native_skia_output_device_opengl.cpp
index d418bfe5c97..be9038b84b9 100644
--- a/src/core/compositor/native_skia_output_device_opengl.cpp
+++ b/src/core/compositor/native_skia_output_device_opengl.cpp
@@ -141,6 +141,56 @@ GLXFBConfig GetFBConfig(Display *display)
 } // namespace
 #endif // BUILDFLAG(IS_OZONE_X11)
 
+class ScopedGLContextForCleanup
+{
+public:
+    ScopedGLContextForCleanup(QOpenGLContext *createContext, QSurface *createSurface)
+        : m_createContext(createContext), m_currentContext(QOpenGLContext::currentContext())
+    {
+        if (m_createContext == m_currentContext)
+            return;
+
+        if (!m_createContext->isValid()) {
+            skipCleanup = true;
+            return;
+        }
+
+        if (m_currentContext)
+            m_currentSurface = m_currentContext->surface();
+
+        if (!createContext->makeCurrent(createSurface)) {
+            skipCleanup = true;
+            qWarning("Failed to make OpenGL context current for clean-up, OpenGL resources will "
+                     "not be destroyed.");
+        }
+    }
+
+    ~ScopedGLContextForCleanup()
+    {
+        if (!m_currentContext || m_createContext == m_currentContext || skipCleanup)
+            return;
+
+        if (!m_currentContext->makeCurrent(m_currentSurface))
+            qFatal("Failed to restore OpenGL context after clean-up.");
+    }
+
+    void deleteTexture(GLuint glTexture)
+    {
+        if (skipCleanup)
+            return;
+
+        auto *glFun = m_createContext->functions();
+        Q_ASSERT(glFun->glGetError() == GL_NO_ERROR);
+        glFun->glDeleteTextures(1, &glTexture);
+    }
+
+private:
+    QOpenGLContext *m_createContext;
+    QOpenGLContext *m_currentContext;
+    QSurface *m_currentSurface = nullptr;
+    bool skipCleanup = false;
+};
+
 NativeSkiaOutputDeviceOpenGL::NativeSkiaOutputDeviceOpenGL(
         scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
         gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
@@ -275,9 +325,11 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
             glXBindTexImageEXT(display, glxPixmap, GLX_FRONT_LEFT_EXT, nullptr);
             glFun->glBindTexture(GL_TEXTURE_2D, 0);
 
-            m_frontBuffer->textureCleanupCallback = [glFun, glTexture, display, glxPixmap,
-                                                     pixmapId]() {
-                glFun->glDeleteTextures(1, &glTexture);
+            QSurface *createSurface = glContext->surface();
+            m_frontBuffer->textureCleanupCallback = [glContext, createSurface, glFun, glTexture,
+                                                     display, glxPixmap, pixmapId]() {
+                ScopedGLContextForCleanup cleanupContext(glContext, createSurface);
+                cleanupContext.deleteTexture(glTexture);
                 glXDestroyGLXPixmap(display, glxPixmap);
                 FreeXPixmap(pixmapId);
             };
@@ -327,8 +379,11 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
             imageTargetTexture(GL_TEXTURE_2D, eglImage);
             glFun->glBindTexture(GL_TEXTURE_2D, 0);
 
-            m_frontBuffer->textureCleanupCallback = [glFun, eglFun, glTexture, eglImage]() {
-                glFun->glDeleteTextures(1, &glTexture);
+            QSurface *createSurface = glContext->surface();
+            m_frontBuffer->textureCleanupCallback = [glContext, createSurface, glFun, eglFun,
+                                                     glTexture, eglImage]() {
+                ScopedGLContextForCleanup cleanupContext(glContext, createSurface);
+                cleanupContext.deleteTexture(glTexture);
                 eglFun->eglDestroyImage(GLContextHelper::getEGLDisplay(), eglImage);
             };
         }
@@ -389,19 +444,16 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
                              glMemoryObject, 0);
         glFun->glBindTexture(GL_TEXTURE_2D, 0);
 
-        m_frontBuffer->textureCleanupCallback = [glTexture, glMemoryObject]() {
-            QOpenGLContext *glContext = QOpenGLContext::currentContext();
-            if (!glContext)
-                return;
-            auto glFun = glContext->functions();
-            Q_ASSERT(glFun->glGetError() == GL_NO_ERROR);
-
+        QSurface *createSurface = glContext->surface();
+        m_frontBuffer->textureCleanupCallback = [glContext, createSurface, glTexture,
+                                                 glMemoryObject]() {
+            ScopedGLContextForCleanup cleanupContext(glContext, createSurface);
             static PFNGLDELETEMEMORYOBJECTSEXTPROC glDeleteMemoryObjectsEXT =
                     (PFNGLDELETEMEMORYOBJECTSEXTPROC)glContext->getProcAddress(
                             "glDeleteMemoryObjectsEXT");
 
             glDeleteMemoryObjectsEXT(1, &glMemoryObject);
-            glFun->glDeleteTextures(1, &glTexture);
+            cleanupContext.deleteTexture(glTexture);
         };
 #else
         Q_UNREACHABLE();
@@ -419,12 +471,11 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
     uint32_t glTexture = makeCGLTexture(win, ioSurface.get(), size());
     texture = QNativeInterface::QSGOpenGLTexture::fromNative(glTexture, win, size(), texOpts);
 
-    m_frontBuffer->textureCleanupCallback = [glTexture]() {
-        auto *glContext = QOpenGLContext::currentContext();
-        if (!glContext)
-            return;
-        auto glFun = glContext->functions();
-        glFun->glDeleteTextures(1, &glTexture);
+    QOpenGLContext *glContext = QOpenGLContext::currentContext();
+    QSurface *createSurface = glContext->surface();
+    m_frontBuffer->textureCleanupCallback = [glContext, createSurface, glTexture]() {
+        ScopedGLContextForCleanup cleanupContext(glContext, createSurface);
+        cleanupContext.deleteTexture(glTexture);
     };
 #endif // defined(USE_OZONE)
 
diff --git a/src/core/render_widget_host_view_qt_delegate_item.cpp b/src/core/render_widget_host_view_qt_delegate_item.cpp
index e82dabb5fff..7d7ae9054f2 100644
--- a/src/core/render_widget_host_view_qt_delegate_item.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_item.cpp
@@ -5,10 +5,13 @@
 
 #include "render_widget_host_view_qt_delegate_client.h"
 
+#include <QtCore/qrunnable.h>
+#include <QtCore/qthread.h>
 #include <QtGui/qevent.h>
 #include <QtGui/qguiapplication.h>
 #include <QtGui/qwindow.h>
 #include <QtQuick/qsgimagenode.h>
+#include <rhi/qrhi.h>
 
 #if QT_CONFIG(accessibility)
 #include <QtGui/qaccessible.h>
@@ -37,7 +40,9 @@ RenderWidgetHostViewQtDelegateItem::RenderWidgetHostViewQtDelegateItem(RenderWid
 
 RenderWidgetHostViewQtDelegateItem::~RenderWidgetHostViewQtDelegateItem()
 {
-    releaseTextureResources();
+    if (QQuickItem::window())
+        releaseResources();
+
     unbind(); // Compositor::Observer
     if (m_widgetDelegate) {
         m_widgetDelegate->Unbind();
@@ -326,12 +331,6 @@ void RenderWidgetHostViewQtDelegateItem::itemChange(ItemChange change, const Ite
             for (const QMetaObject::Connection &c : std::as_const(m_windowConnections))
                 disconnect(c);
             m_windowConnections.clear();
-
-            auto comp = compositor();
-            if (comp && comp->type() == Compositor::Type::Native) {
-                comp->releaseTexture();
-                comp->releaseResources();
-            }
         }
 
         if (value.window) {
@@ -343,10 +342,12 @@ void RenderWidgetHostViewQtDelegateItem::itemChange(ItemChange change, const Ite
             m_windowConnections.append(connect(value.window, SIGNAL(xChanged(int)), SLOT(onWindowPosChanged())));
             m_windowConnections.append(
                     connect(value.window, SIGNAL(yChanged(int)), SLOT(onWindowPosChanged())));
-            m_windowConnections.append(
-                    connect(value.window, &QQuickWindow::sceneGraphAboutToStop, this,
-                            &RenderWidgetHostViewQtDelegateItem::releaseTextureResources,
-                            Qt::DirectConnection));
+            m_windowConnections.append(connect(
+                    value.window, &QQuickWindow::sceneGraphAboutToStop, this,
+                    &RenderWidgetHostViewQtDelegateItem::releaseResources, Qt::DirectConnection));
+            m_windowConnections.append(connect(
+                    value.window, &QQuickWindow::sceneGraphInvalidated, this,
+                    &RenderWidgetHostViewQtDelegateItem::releaseResources, Qt::DirectConnection));
             if (!m_isPopup)
                 m_windowConnections.append(connect(value.window, SIGNAL(closing(QQuickCloseEvent*)), SLOT(onHide())));
         }
@@ -364,6 +365,61 @@ void RenderWidgetHostViewQtDelegateItem::itemChange(ItemChange change, const Ite
     }
 }
 
+class CleanupJob : public QRunnable
+{
+public:
+    CleanupJob(Compositor::Handle<Compositor> compositor) : m_compositor(std::move(compositor)) { }
+
+    ~CleanupJob()
+    {
+        if (m_compositor->hasResources()) {
+            qWarning("Failed to release graphics resources because the clean-up render job was "
+                     "deleted.");
+        }
+    }
+
+    void run() override { m_compositor->releaseResources(); }
+
+private:
+    Compositor::Handle<Compositor> m_compositor;
+};
+
+void RenderWidgetHostViewQtDelegateItem::releaseResources()
+{
+    auto comp = compositor();
+    if (!comp || comp->type() != Compositor::Type::Native || !comp->hasResources())
+        return;
+
+    comp->releaseTexture();
+
+    QQuickWindow *win = QQuickItem::window();
+    if (!win) {
+        qWarning("Failed to release graphics resources because QQuickWindow is not available.");
+        return;
+    }
+
+    QRhi *rhi = win->rhi();
+    if (!rhi) {
+        qWarning("Failed to release graphics resources because RHI is not available.");
+        return;
+    }
+
+    // Do not schedule clean-up if the resources were created on the current thread.
+    if (QThread::currentThread() == rhi->thread()) {
+        comp->releaseResources();
+        return;
+    }
+
+    if (win->isExposed())
+        win->scheduleRenderJob(new CleanupJob(std::move(comp)), QQuickWindow::NoStage);
+    else {
+        // TODO: Try to find a proper way to schedule job on the render thread if the window is
+        // not exposed.
+        // This is reproducible with ./tst_qquickwebengineviewgraphics simpleGraphics simpleGraphics
+        qWarning("Failed to release graphics resources because QQuickWindow is not exposed.");
+    }
+}
+
 QSGNode *RenderWidgetHostViewQtDelegateItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
 {
     auto comp = compositor();
@@ -445,15 +501,6 @@ void RenderWidgetHostViewQtDelegateItem::onHide()
     m_client->forwardEvent(&event);
 }
 
-void RenderWidgetHostViewQtDelegateItem::releaseTextureResources()
-{
-    auto comp = compositor();
-    if (!comp || comp->type() != Compositor::Type::Native)
-        return;
-
-    comp->releaseResources();
-}
-
 void RenderWidgetHostViewQtDelegateItem::adapterClientChanged(WebContentsAdapterClient *client)
 {
     m_adapterClient = client;
diff --git a/src/core/render_widget_host_view_qt_delegate_item.h b/src/core/render_widget_host_view_qt_delegate_item.h
index 65fbeeb175e..f0351aa9fe4 100644
--- a/src/core/render_widget_host_view_qt_delegate_item.h
+++ b/src/core/render_widget_host_view_qt_delegate_item.h
@@ -95,6 +95,7 @@ class Q_WEBENGINECORE_EXPORT RenderWidgetHostViewQtDelegateItem
     void inputMethodEvent(QInputMethodEvent *event) override;
     void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
     void itemChange(ItemChange change, const ItemChangeData &value) override;
+    void releaseResources() override;
     QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
 
     void adapterClientChanged(WebContentsAdapterClient *client) override;
@@ -104,7 +105,6 @@ private Q_SLOTS:
     void onBeforeRendering();
     void onAfterFrameEnd();
     void onWindowPosChanged();
-    void releaseTextureResources();
     void onHide();
 
 private:
