summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
m---------src/3rdparty0
-rw-r--r--src/core/CMakeLists.txt5
-rw-r--r--src/core/api/CMakeLists.txt8
-rw-r--r--src/core/api/qwebenginecertificateerror.cpp13
-rw-r--r--src/core/api/qwebenginecertificateerror.h2
-rw-r--r--src/core/api/qwebengineframe.cpp263
-rw-r--r--src/core/api/qwebengineframe.h80
-rw-r--r--src/core/api/qwebenginepage.cpp412
-rw-r--r--src/core/api/qwebenginepage.h47
-rw-r--r--src/core/api/qwebenginepage_p.h17
-rw-r--r--src/core/api/qwebenginepermission.cpp307
-rw-r--r--src/core/api/qwebenginepermission.h90
-rw-r--r--src/core/api/qwebenginepermission_p.h46
-rw-r--r--src/core/api/qwebengineprofile.cpp139
-rw-r--r--src/core/api/qwebengineprofile.h16
-rw-r--r--src/core/api/qwebengineurlrequestinfo.cpp1
-rw-r--r--src/core/api/qwebengineurlrequestinfo.h3
-rw-r--r--src/core/api/qwebengineurlrequestjob.cpp2
-rw-r--r--src/core/api/qwebengineurlrequestjob.h5
-rw-r--r--src/core/api/qwebengineurlscheme.cpp2
-rw-r--r--src/core/api/qwebenginewebauthuxrequest.cpp53
-rw-r--r--src/core/autofill_client_qt.cpp21
-rw-r--r--src/core/autofill_client_qt.h13
-rw-r--r--src/core/autofill_popup_controller.cpp6
-rw-r--r--src/core/browser_accessibility_qt.cpp2
-rw-r--r--src/core/browser_message_filter_qt.cpp2
-rw-r--r--src/core/browser_message_filter_qt.h4
-rw-r--r--src/core/certificate_error_controller.cpp9
-rw-r--r--src/core/certificate_error_controller.h4
-rw-r--r--src/core/clipboard_qt.cpp23
-rw-r--r--src/core/clipboard_qt.h7
-rw-r--r--src/core/common/extensions/extensions_api_provider_qt.cpp2
-rw-r--r--src/core/common/extensions/extensions_api_provider_qt.h2
-rw-r--r--src/core/compositor/display_skia_output_device.cpp2
-rw-r--r--src/core/compositor/native_skia_output_device_direct3d11.cpp1
-rw-r--r--src/core/compositor/native_skia_output_device_vulkan.cpp15
-rw-r--r--src/core/configure/BUILD.root.gn.in23
-rw-r--r--src/core/content_browser_client_qt.cpp93
-rw-r--r--src/core/content_browser_client_qt.h33
-rw-r--r--src/core/desktop_screen_qt.cpp7
-rw-r--r--src/core/doc/src/qtwebengine-overview.qdoc9
-rw-r--r--src/core/doc/src/qwebengine-licensing.qdoc53
-rw-r--r--src/core/doc/src/qwebenginepage_lgpl.qdoc28
-rw-r--r--src/core/download_manager_delegate_qt.cpp57
-rw-r--r--src/core/download_manager_delegate_qt.h4
-rw-r--r--src/core/extensions/extension_host_delegate_qt.cpp7
-rw-r--r--src/core/extensions/extension_host_delegate_qt.h2
-rw-r--r--src/core/extensions/extensions_browser_client_qt.cpp7
-rw-r--r--src/core/extensions/extensions_browser_client_qt.h4
-rw-r--r--src/core/extensions/file_system_delegate_qt.cpp31
-rw-r--r--src/core/extensions/file_system_delegate_qt.h17
-rw-r--r--src/core/favicon_driver_qt.cpp7
-rw-r--r--src/core/favicon_driver_qt.h3
-rw-r--r--src/core/favicon_service_factory_qt.cpp2
-rw-r--r--src/core/favicon_service_factory_qt.h2
-rw-r--r--src/core/file_picker_controller.cpp4
-rw-r--r--src/core/file_system_access/file_system_access_permission_context_qt.h2
-rw-r--r--src/core/media_capture_devices_dispatcher.cpp30
-rw-r--r--src/core/net/custom_url_loader_factory.cpp38
-rw-r--r--src/core/net/custom_url_loader_factory.h5
-rw-r--r--src/core/net/plugin_response_interceptor_url_loader_throttle.cpp36
-rw-r--r--src/core/net/proxy_config_service_qt.cpp1
-rw-r--r--src/core/net/proxying_restricted_cookie_manager_qt.cpp7
-rw-r--r--src/core/net/proxying_restricted_cookie_manager_qt.h2
-rw-r--r--src/core/net/proxying_url_loader_factory_qt.cpp1
-rw-r--r--src/core/net/ssl_host_state_delegate_qt.cpp4
-rw-r--r--src/core/net/ssl_host_state_delegate_qt.h6
-rw-r--r--src/core/net/system_network_context_manager.cpp5
-rw-r--r--src/core/net/url_request_custom_job_delegate.cpp14
-rw-r--r--src/core/net/url_request_custom_job_proxy.cpp5
-rw-r--r--src/core/net/url_request_custom_job_proxy.h2
-rw-r--r--src/core/net/webui_controller_factory_qt.cpp4
-rw-r--r--src/core/ozone/gl_context_qt.cpp36
-rw-r--r--src/core/ozone/gl_context_qt.h3
-rw-r--r--src/core/ozone/gl_share_context_qt.cpp5
-rw-r--r--src/core/ozone/gl_share_context_qt.h3
-rw-r--r--src/core/ozone/gl_surface_qt.cpp9
-rw-r--r--src/core/ozone/ozone_platform_qt.cpp17
-rw-r--r--src/core/ozone/surface_factory_qt.cpp34
-rw-r--r--src/core/ozone/surface_factory_qt.h2
-rw-r--r--src/core/permission_manager_qt.cpp355
-rw-r--r--src/core/permission_manager_qt.h40
-rw-r--r--src/core/platform_notification_service_qt.cpp20
-rw-r--r--src/core/platform_notification_service_qt.h2
-rw-r--r--src/core/pref_service_adapter.cpp3
-rw-r--r--src/core/printing/print_view_manager_base_qt.cpp1
-rw-r--r--src/core/printing/print_view_manager_qt.cpp46
-rw-r--r--src/core/printing/print_view_manager_qt.h15
-rw-r--r--src/core/profile_adapter.cpp62
-rw-r--r--src/core/profile_adapter.h29
-rw-r--r--src/core/profile_io_data_qt.cpp33
-rw-r--r--src/core/profile_io_data_qt.h6
-rw-r--r--src/core/profile_qt.cpp12
-rw-r--r--src/core/profile_qt.h2
-rw-r--r--src/core/render_widget_host_view_qt.cpp13
-rw-r--r--src/core/render_widget_host_view_qt.h4
-rw-r--r--src/core/renderer/content_renderer_client_qt.cpp38
-rw-r--r--src/core/renderer/content_renderer_client_qt.h2
-rw-r--r--src/core/renderer/content_settings_observer_qt.cpp7
-rw-r--r--src/core/renderer/content_settings_observer_qt.h3
-rw-r--r--src/core/renderer/extensions/extensions_renderer_client_qt.cpp7
-rw-r--r--src/core/renderer/extensions/resource_request_policy_qt.cpp2
-rw-r--r--src/core/renderer/extensions/resource_request_policy_qt.h2
-rw-r--r--src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp10
-rw-r--r--src/core/renderer/render_frame_observer_qt.cpp2
-rw-r--r--src/core/renderer/render_frame_observer_qt.h2
-rw-r--r--src/core/renderer/user_resource_controller.cpp5
-rw-r--r--src/core/tools/qwebengine_convert_dict/CMakeLists.txt3
-rw-r--r--src/core/type_conversion.h4
-rw-r--r--src/core/web_contents_adapter.cpp305
-rw-r--r--src/core/web_contents_adapter.h51
-rw-r--r--src/core/web_contents_adapter_client.h17
-rw-r--r--src/core/web_contents_delegate_qt.cpp18
-rw-r--r--src/core/web_contents_delegate_qt.h7
-rw-r--r--src/core/web_contents_view_qt.cpp6
-rw-r--r--src/core/web_contents_view_qt.h8
-rw-r--r--src/core/web_engine_context.cpp284
-rw-r--r--src/core/web_engine_context.h2
-rw-r--r--src/pdf/CMakeLists.txt1
-rw-r--r--src/pdf/doc/snippets/pdfpageview.qml12
-rw-r--r--src/pdfquick/PdfPageView.qml2
-rw-r--r--src/pdfquick/qquickpdfpageimage.cpp16
-rw-r--r--src/pdfwidgets/qpdfview.cpp6
-rw-r--r--src/webenginequick/api/qquickwebenginefaviconprovider.cpp224
-rw-r--r--src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h83
-rw-r--r--src/webenginequick/api/qquickwebengineforeigntypes_p.h34
-rw-r--r--src/webenginequick/api/qquickwebengineprofile.cpp229
-rw-r--r--src/webenginequick/api/qquickwebengineprofile.h20
-rw-r--r--src/webenginequick/api/qquickwebenginesettings.cpp4
-rw-r--r--src/webenginequick/api/qquickwebengineview.cpp259
-rw-r--r--src/webenginequick/api/qquickwebengineview_p.h42
-rw-r--r--src/webenginequick/api/qquickwebengineview_p_p.h16
-rw-r--r--src/webenginequick/doc/src/webengine_permission.qdoc137
-rw-r--r--src/webenginequick/doc/src/webengineframe.qdoc129
-rw-r--r--src/webenginequick/doc/src/webengineview_lgpl.qdoc70
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp42
-rw-r--r--src/webenginewidgets/api/qwebengineview.h1
-rw-r--r--src/webenginewidgets/api/qwebengineview_p.h1
138 files changed, 3897 insertions, 1147 deletions
diff --git a/src/3rdparty b/src/3rdparty
-Subproject 814db44bc99f79d0c4a847e0cac4a398034ee2f
+Subproject 6434c2d5827960f6a9ae839da3981b84965ac77
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 8ba77607b..a359cc57f 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 f2ceb2dfd..2a06baec6 100644
--- a/src/core/api/CMakeLists.txt
+++ b/src/core/api/CMakeLists.txt
@@ -19,6 +19,7 @@ qt_internal_add_module(WebEngineCore
qwebenginedownloadrequest.cpp qwebenginedownloadrequest.h qwebenginedownloadrequest_p.h
qwebenginefilesystemaccessrequest.cpp qwebenginefilesystemaccessrequest.h
qwebenginefindtextresult.cpp qwebenginefindtextresult.h
+ qwebengineframe.cpp qwebengineframe.h
qwebenginefullscreenrequest.cpp qwebenginefullscreenrequest.h
qwebenginehistory.cpp qwebenginehistory.h qwebenginehistory_p.h
qwebenginehttprequest.cpp qwebenginehttprequest.h
@@ -28,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
@@ -49,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
@@ -65,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/qwebenginecertificateerror.cpp b/src/core/api/qwebenginecertificateerror.cpp
index 90d8a542d..85c5d5127 100644
--- a/src/core/api/qwebenginecertificateerror.cpp
+++ b/src/core/api/qwebenginecertificateerror.cpp
@@ -88,6 +88,19 @@ QUrl QWebEngineCertificateError::url() const
}
/*!
+ \property QWebEngineCertificateError::isMainFrame
+ \since 6.8
+
+ Returns whether the certificate error comes from the main frame. If false,
+ the error comes from a sub-resource and most likely needs to be rejected without
+ user input.
+*/
+bool QWebEngineCertificateError::isMainFrame() const
+{
+ return d->isMainFrame();
+}
+
+/*!
Returns the type of the error.
\sa description(), isOverridable()
diff --git a/src/core/api/qwebenginecertificateerror.h b/src/core/api/qwebenginecertificateerror.h
index c4a3585f4..3eef3dcca 100644
--- a/src/core/api/qwebenginecertificateerror.h
+++ b/src/core/api/qwebenginecertificateerror.h
@@ -24,6 +24,7 @@ class Q_WEBENGINECORE_EXPORT QWebEngineCertificateError
Q_PROPERTY(Type type READ type CONSTANT FINAL)
Q_PROPERTY(QString description READ description CONSTANT FINAL)
Q_PROPERTY(bool overridable READ isOverridable CONSTANT FINAL)
+ Q_PROPERTY(bool isMainFrame READ isMainFrame CONSTANT FINAL REVISION(6, 8))
public:
QWebEngineCertificateError(const QWebEngineCertificateError &other);
@@ -57,6 +58,7 @@ public:
QUrl url() const;
bool isOverridable() const;
QString description() const;
+ bool isMainFrame() const;
Q_INVOKABLE void defer();
Q_INVOKABLE void rejectCertificate();
diff --git a/src/core/api/qwebengineframe.cpp b/src/core/api/qwebengineframe.cpp
new file mode 100644
index 000000000..fa2cbb507
--- /dev/null
+++ b/src/core/api/qwebengineframe.cpp
@@ -0,0 +1,263 @@
+// 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 "qwebengineframe.h"
+
+#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"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWebEngineFrame
+ \brief The QWebEngineFrame class gives information about and control over a page frame.
+ \since 6.8
+
+ \inmodule QtWebEngineCore
+
+ A web engine frame represents a single frame within a web page, such as those created by
+ \c <frame> or \c <iframe> HTML elements.
+ An active QWebEnginePage has one or more frames arranged in a tree structure. The top-level
+ frame, the root of this tree, can be accessed through the mainFrame() method, and
+ children() provides a frame's direct descendants.
+
+ A frame's lifetime is, at most, as long as the QWebEnginePage object that produced it.
+ However, frames may be created and deleted spontaneously and dynamically, for example through
+ navigation and script execution. Because of this, many QWebEngineFrame methods return
+ optional values, which will be \c std::nullopt if the frame no longer exists.
+*/
+
+/*! \internal
+ */
+QWebEngineFrame::QWebEngineFrame(QtWebEngineCore::WebContentsAdapterClient *adapter, quint64 id)
+ : m_adapterClient(adapter), m_id(id)
+{
+}
+
+/*!
+ Returns \c{true} if this object represents an existing frame; \c{false} otherwise.
+
+ Once a frame is invalid, it never becomes valid again.
+*/
+bool QWebEngineFrame::isValid() const
+{
+ return m_adapterClient->webContentsAdapter()->hasFrame(m_id);
+}
+
+/*!
+ Returns the frame name; that is, what would be returned by \c window.name in JavaScript.
+
+ If the frame could not be found, returns a null QString.
+
+ \sa htmlName
+*/
+QString QWebEngineFrame::name() const
+{
+ return m_adapterClient->webContentsAdapter()->frameName(m_id);
+}
+
+/*!
+ Returns the value of the frame's \c name HTML attribute, or an empty string if it has none.
+
+ If the frame could not be found, returns a null QString.
+
+ \sa name
+*/
+QString QWebEngineFrame::htmlName() const
+{
+ return m_adapterClient->webContentsAdapter()->frameHtmlName(m_id);
+}
+
+/*!
+ Returns a list of the frame's children in an arbitrary order.
+
+ If the frame could not be found, returns an empty list.
+ */
+QList<QWebEngineFrame> QWebEngineFrame::children() const
+{
+ QList<QWebEngineFrame> result;
+ for (auto childId : m_adapterClient->webContentsAdapter()->frameChildren(m_id))
+ result.push_back(QWebEngineFrame{ m_adapterClient, childId });
+ return result;
+}
+
+/*!
+ Returns the URL of the content currently loaded in this frame.
+
+ If the frame could not be found, returns an empty QUrl.
+ */
+QUrl QWebEngineFrame::url() const
+{
+ return m_adapterClient->webContentsAdapter()->frameUrl(m_id);
+}
+
+/*!
+ Returns the size of the frame within the viewport.
+
+ If the frame could not be found, returns QSizeF().
+ */
+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
+ std::function<void(const QVariant &)> &callback)
+
+ Runs the JavaScript code contained in \a script on this frame, without checking
+ whether the DOM of the page has been constructed.
+ To avoid conflicts with other scripts executed on the page, the world in
+ which the script is run is specified by \a worldId. The world ID values are
+ the same as provided by QWebEngineScript::ScriptWorldId, and between \c 0
+ and \c 256. If you leave out the \c world ID, the script is run in the
+ \c MainWorld.
+ When the script has been executed, \a callback is called with the result of the last
+ executed statement. \c callback can be any of a function pointer, a functor or a lambda,
+ and it is expected to take a QVariant parameter. For example:
+ \code
+ page.runJavaScript("document.title", [](const QVariant &v) { qDebug() << v.toString(); });
+ \endcode
+ Only plain data can be returned from JavaScript as the result value.
+ Supported data types include all of the JSON data types as well as, for
+ example, \c{Date} and \c{ArrayBuffer}. Unsupported data types include, for
+ example, \c{Function} and \c{Promise}.
+ \warning Do not execute lengthy routines in the callback function, because it might block the
+ rendering of the web engine page.
+ \warning We guarantee that the \a callback is always called, but it might be
+ done during page destruction. When QWebEnginePage is deleted, the callback is triggered with an
+ invalid value and it is not safe to use the corresponding QWebEnginePage or QWebEngineView
+ instance inside it.
+ \sa QWebEngineScript::ScriptWorldId, QWebEnginePage::runJavaScript, {Script Injection}
+ */
+void QWebEngineFrame::runJavaScript(const QString &script,
+ const std::function<void(const QVariant &)> &callback)
+{
+ runJavaScript(script, QWebEngineScript::MainWorld, callback);
+}
+
+void QWebEngineFrame::runJavaScript(const QString &script, quint32 worldId,
+ const std::function<void(const QVariant &)> &callback)
+{
+ m_adapterClient->runJavaScript(script, worldId, m_id, callback);
+}
+
+void QWebEngineFrame::runJavaScript(const QString &script, quint32 worldId)
+{
+ runJavaScript(script, worldId, std::function<void(const QVariant &)>{});
+}
+
+void QWebEngineFrame::runJavaScript(const QString &script, const QJSValue &callback)
+{
+ runJavaScript(script, QWebEngineScript::MainWorld, callback);
+}
+
+void QWebEngineFrame::runJavaScript(const QString &script, quint32 worldId,
+ const QJSValue &callback)
+{
+ std::function<void(const QVariant &)> wrappedCallback;
+ if (!callback.isUndefined()) {
+ const QObject *holdingObject = m_adapterClient->holdingQObject();
+ wrappedCallback = [holdingObject, callback](const QVariant &result) {
+ if (auto engine = qmlEngine(holdingObject)) {
+ QJSValueList args;
+ args.append(engine->toScriptValue(result));
+ callback.call(args);
+ } else {
+ qWarning("No QML engine found to execute runJavaScript() callback");
+ }
+ };
+ }
+ 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,
+ otherwise \c{false}.
+ */
+
+/*! \fn bool QWebEngineFrame::operator!=(const QWebEngineFrame &left, const QWebEngineFrame &right) noexcept
+
+ Returns \c{true} if \a left and \a right represent different frames in the same web page,
+ otherwise \c{false}.
+ */
+
+QT_END_NAMESPACE
+
+#include "moc_qwebengineframe.cpp"
diff --git a/src/core/api/qwebengineframe.h b/src/core/api/qwebengineframe.h
new file mode 100644
index 000000000..b6953cdd2
--- /dev/null
+++ b/src/core/api/qwebengineframe.h
@@ -0,0 +1,80 @@
+// 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 QWEBENGINEFRAME_H
+#define QWEBENGINEFRAME_H
+
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+#include <QtQml/qqmlregistration.h>
+#include <QtQml/qjsvalue.h>
+#include <QtCore/qcompare.h>
+#include <QtCore/QList>
+#include <QtCore/QSizeF>
+#include <QtCore/QString>
+#include <QtCore/QUrl>
+
+namespace QtWebEngineCore {
+class WebContentsAdapterClient;
+}
+
+QT_BEGIN_NAMESPACE
+
+class Q_WEBENGINECORE_EXPORT QWebEngineFrame
+{
+ Q_GADGET
+
+ Q_PROPERTY(bool isValid READ isValid FINAL)
+ Q_PROPERTY(QString name READ name FINAL)
+ 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)
+ 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);
+
+ friend inline bool comparesEqual(const QWebEngineFrame &lhs,
+ const QWebEngineFrame &rhs) noexcept
+ {
+ return lhs.m_adapterClient == rhs.m_adapterClient && lhs.m_id == rhs.m_id;
+ }
+
+ Q_DECLARE_EQUALITY_COMPARABLE(QWebEngineFrame);
+
+private:
+ friend class QWebEnginePage;
+ friend class QWebEnginePagePrivate;
+ friend class QQuickWebEngineView;
+ friend class QQuickWebEngineViewPrivate;
+
+ QWebEngineFrame(QtWebEngineCore::WebContentsAdapterClient *page, quint64 id);
+
+ QtWebEngineCore::WebContentsAdapterClient *m_adapterClient;
+ quint64 m_id;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINEFRAME_H
diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp
index 686cee391..f0260fd0d 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"
@@ -199,6 +200,12 @@ void QWebEnginePagePrivate::iconChanged(const QUrl &url)
Q_EMIT q->iconChanged(iconUrl.isEmpty() ? QIcon() : adapter->icon());
}
+void QWebEnginePagePrivate::zoomFactorChanged(qreal factor)
+{
+ Q_Q(QWebEnginePage);
+ Q_EMIT q->zoomFactorChanged(factor);
+}
+
void QWebEnginePagePrivate::loadProgressChanged(int progress)
{
Q_Q(QWebEnginePage);
@@ -268,6 +275,20 @@ void QWebEnginePagePrivate::loadFinished(QWebEngineLoadingInfo info)
});
}
+void QWebEnginePagePrivate::printToPdf(const QString &filePath, const QPageLayout &layout,
+ const QPageRanges &ranges, quint64 frameId)
+{
+ adapter->printToPDF(layout, ranges, filePath, frameId);
+}
+
+void QWebEnginePagePrivate::printToPdf(std::function<void(QSharedPointer<QByteArray>)> &&callback,
+ const QPageLayout &layout, const QPageRanges &ranges,
+ quint64 frameId)
+{
+ adapter->printToPDFCallbackResult(std::move(callback), layout, ranges, /*colorMode*/ true,
+ /*useCustomMargins*/ true, frameId);
+}
+
void QWebEnginePagePrivate::didPrintPageToPdf(const QString &filePath, bool success)
{
Q_Q(QWebEnginePage);
@@ -489,10 +510,16 @@ void QWebEnginePagePrivate::windowCloseRejected()
// Do nothing for now.
}
-void QWebEnginePagePrivate::didRunJavaScript(quint64 requestId, const QVariant& result)
+void QWebEnginePagePrivate::runJavaScript(const QString &script, quint32 worldId, quint64 frameId,
+ const std::function<void(const QVariant &)> &callback)
{
- if (auto callback = m_variantCallbacks.take(requestId))
- callback(result);
+ ensureInitialized();
+ if (adapter->lifecycleState() == WebContentsAdapter::LifecycleState::Discarded) {
+ qWarning("runJavaScript: disabled in Discarded state");
+ if (callback)
+ callback(QVariant());
+ } else
+ adapter->runJavaScript(script, worldId, frameId, callback);
}
void QWebEnginePagePrivate::didFetchDocumentMarkup(quint64 requestId, const QString& result)
@@ -507,27 +534,18 @@ void QWebEnginePagePrivate::didFetchDocumentInnerText(quint64 requestId, const Q
callback(result);
}
-void QWebEnginePagePrivate::didPrintPage(quint64 requestId, QSharedPointer<QByteArray> result)
+void QWebEnginePagePrivate::didPrintPage(QSharedPointer<QByteArray> result)
{
#if QT_CONFIG(webengine_printing_and_pdf)
- // If no currentPrinter is set that means that were printing to PDF only.
- if (!currentPrinter) {
- if (!result.data())
- return;
- if (auto callback = m_pdfResultCallbacks.take(requestId))
- callback(*(result.data()));
- return;
- }
-
+ Q_ASSERT(currentPrinter);
if (view)
view->didPrintPage(currentPrinter, result);
else
currentPrinter = nullptr;
#else
- // we should never enter this branch, but just for safe-keeping...
+ // should not get here
Q_UNUSED(result);
- if (auto callback = m_pdfResultCallbacks.take(requestId))
- callback(QByteArray());
+ Q_ASSERT(false);
#endif
}
@@ -572,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)
@@ -804,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())
@@ -971,11 +1066,9 @@ QWebEnginePage::~QWebEnginePage()
setDevToolsPage(nullptr);
emit _q_aboutToDelete();
- for (auto varFun : std::as_const(d_ptr->m_variantCallbacks))
- varFun(QVariant());
+ d_ptr->adapter->clearJavaScriptCallbacks();
for (auto strFun : std::as_const(d_ptr->m_stringCallbacks))
strFun(QString());
- d_ptr->m_variantCallbacks.clear();
d_ptr->m_stringCallbacks.clear();
}
}
@@ -1652,11 +1745,14 @@ void QWebEnginePagePrivate::setToolTip(const QString &toolTipText)
\fn void QWebEnginePage::printRequested()
\since 5.12
- This signal is emitted when the JavaScript \c{window.print()} method is called or the user pressed the print
- button of PDF viewer plugin.
+ This signal is emitted when the JavaScript \c{window.print()} method is called on the main
+ frame, or the user pressed the print button of PDF viewer plugin.
Typically, the signal handler can simply call printToPdf().
- \sa printToPdf()
+ Since 6.8, this signal is only emitted for the main frame, instead of being emitted for any
+ frame that requests printing.
+
+ \sa printToPdf(), printRequestedByFrame()
*/
void QWebEnginePagePrivate::printRequested()
@@ -1669,6 +1765,25 @@ void QWebEnginePagePrivate::printRequested()
view->printRequested();
}
+/*!
+ \fn void QWebEnginePage::printRequestedByFrame(QWebEngineFrame frame)
+ \since 6.8
+
+ 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(), QWebEngineFrame::printToPdf()
+*/
+
+void QWebEnginePagePrivate::printRequestedByFrame(quint64 frameId)
+{
+ Q_Q(QWebEnginePage);
+ QWebEngineFrame frame(this, frameId);
+ QTimer::singleShot(0, q, [q, frame]() { Q_EMIT q->printRequestedByFrame(frame); });
+ if (view)
+ view->printRequestedByFrame(frame);
+}
+
QtWebEngineCore::TouchHandleDrawableDelegate *
QWebEnginePagePrivate::createTouchHandleDelegate(const QMap<int, QImage> &images)
{
@@ -1736,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)
{
@@ -2020,7 +2095,7 @@ void QWebEnginePage::setZoomFactor(qreal factor)
Q_D(QWebEnginePage);
d->defaultZoomFactor = factor;
- if (d->adapter->isInitialized()) {
+ if (d->adapter->isInitialized() && !qFuzzyCompare(factor, zoomFactor())) {
d->adapter->setZoomFactor(factor);
// MEMO: should reset if factor was not applied due to being invalid
d->defaultZoomFactor = zoomFactor();
@@ -2029,40 +2104,13 @@ void QWebEnginePage::setZoomFactor(qreal factor)
void QWebEnginePage::runJavaScript(const QString& scriptSource, const std::function<void(const QVariant &)> &resultCallback)
{
- Q_D(QWebEnginePage);
- d->ensureInitialized();
- if (d->adapter->lifecycleState() == WebContentsAdapter::LifecycleState::Discarded) {
- qWarning("runJavaScript: disabled in Discarded state");
- if (resultCallback)
- resultCallback(QVariant());
- return;
- }
- quint64 requestId = d->adapter->runJavaScriptCallbackResult(scriptSource, QWebEngineScript::MainWorld);
- if (requestId)
- d->m_variantCallbacks.insert(requestId, resultCallback);
- else if (resultCallback)
- resultCallback(QVariant());
+ runJavaScript(scriptSource, QWebEngineScript::MainWorld, resultCallback);
}
void QWebEnginePage::runJavaScript(const QString& scriptSource, quint32 worldId, const std::function<void(const QVariant &)> &resultCallback)
{
Q_D(QWebEnginePage);
- d->ensureInitialized();
- if (d->adapter->lifecycleState() == WebContentsAdapter::LifecycleState::Discarded) {
- qWarning("runJavaScript: disabled in Discarded state");
- if (resultCallback)
- resultCallback(QVariant());
- return;
- }
- if (resultCallback) {
- quint64 requestId = d->adapter->runJavaScriptCallbackResult(scriptSource, worldId);
- if (requestId)
- d->m_variantCallbacks.insert(requestId, resultCallback);
- else
- resultCallback(QVariant());
- } else {
- d->adapter->runJavaScript(scriptSource, worldId);
- }
+ d->runJavaScript(scriptSource, worldId, WebContentsAdapter::kUseMainFrameId, resultCallback);
}
/*!
@@ -2322,7 +2370,7 @@ void QWebEnginePage::printToPdf(const QString &filePath, const QPageLayout &layo
#if QT_CONFIG(webengine_printing_and_pdf)
Q_D(QWebEnginePage);
d->ensureInitialized();
- d->adapter->printToPDF(layout, ranges, filePath);
+ d->printToPdf(filePath, layout, ranges, WebContentsAdapter::kUseMainFrameId);
#else
Q_UNUSED(filePath);
Q_UNUSED(layout);
@@ -2347,11 +2395,14 @@ void QWebEnginePage::printToPdf(const QString &filePath, const QPageLayout &layo
*/
void QWebEnginePage::printToPdf(const std::function<void(const QByteArray&)> &resultCallback, const QPageLayout &layout, const QPageRanges &ranges)
{
- Q_D(QWebEnginePage);
#if QT_CONFIG(webengine_printing_and_pdf)
+ Q_D(QWebEnginePage);
d->ensureInitialized();
- quint64 requestId = d->adapter->printToPDFCallbackResult(layout, ranges);
- d->m_pdfResultCallbacks.insert(requestId, resultCallback);
+ std::function wrappedCallback = [resultCallback](QSharedPointer<QByteArray> result) {
+ if (resultCallback && result)
+ resultCallback(*result);
+ };
+ d->printToPdf(std::move(wrappedCallback), layout, ranges, WebContentsAdapter::kUseMainFrameId);
#else
Q_UNUSED(layout);
Q_UNUSED(ranges);
@@ -2501,6 +2552,33 @@ void QWebEnginePage::setVisible(bool visible)
d->adapter->setVisible(visible);
}
+/*!
+ \since 6.8
+
+ The main, top-level frame of the page. All other frames on this page are accessible
+ as children of the main frame.
+*/
+QWebEngineFrame QWebEnginePage::mainFrame()
+{
+ Q_D(QWebEnginePage);
+ return QWebEngineFrame(d, d->adapter->mainFrameId());
+}
+
+/*!
+ \since 6.8
+
+ 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)
+{
+ Q_D(QWebEnginePage);
+ if (auto maybeId = d->adapter->findFrameIdByName(name)) {
+ return QWebEngineFrame(d, *maybeId);
+ }
+ return {};
+}
+
QDataStream &operator<<(QDataStream &stream, const QWebEngineHistory &history)
{
auto adapter = history.d_func()->adapter();
diff --git a/src/core/api/qwebenginepage.h b/src/core/api/qwebenginepage.h
index c857585ab..cca7c55e7 100644
--- a/src/core/api/qwebenginepage.h
+++ b/src/core/api/qwebenginepage.h
@@ -8,6 +8,8 @@
#include <QtWebEngineCore/qwebengineclientcertificateselection.h>
#include <QtWebEngineCore/qwebenginedownloadrequest.h>
#include <QtWebEngineCore/qwebenginequotarequest.h>
+#include <QtWebEngineCore/qwebengineframe.h>
+#include <QtWebEngineCore/qwebenginepermission.h>
#include <QtCore/qobject.h>
#include <QtCore/qurl.h>
@@ -16,6 +18,7 @@
#include <QtGui/qtgui-config.h>
#include <functional>
+#include <optional>
QT_BEGIN_NAMESPACE
@@ -49,7 +52,7 @@ class Q_WEBENGINECORE_EXPORT QWebEnginePage : public QObject
Q_PROPERTY(QString selectedText READ selectedText)
Q_PROPERTY(bool hasSelection READ hasSelection)
Q_PROPERTY(QUrl requestedUrl READ requestedUrl)
- Q_PROPERTY(qreal zoomFactor READ zoomFactor WRITE setZoomFactor)
+ Q_PROPERTY(qreal zoomFactor READ zoomFactor WRITE setZoomFactor NOTIFY zoomFactorChanged)
Q_PROPERTY(QString title READ title NOTIFY titleChanged)
Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged)
Q_PROPERTY(QUrl iconUrl READ iconUrl NOTIFY iconUrlChanged)
@@ -145,12 +148,19 @@ public:
};
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 {
@@ -164,7 +174,12 @@ public:
};
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,
@@ -177,6 +192,8 @@ public:
LocalFontsAccess,
};
Q_ENUM(Feature)
+QT_WARNING_POP
+#endif
// Ex-QWebFrame enum
@@ -234,7 +251,12 @@ public:
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;
@@ -301,6 +323,9 @@ public:
bool isVisible() const;
void setVisible(bool visible);
+ QWebEngineFrame mainFrame();
+ std::optional<QWebEngineFrame> findFrameByName(const QString &name);
+
void acceptAsNewWindow(QWebEngineNewWindowRequest &request);
Q_SIGNALS:
@@ -314,9 +339,23 @@ Q_SIGNALS:
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);
@@ -339,6 +378,7 @@ Q_SIGNALS:
void iconUrlChanged(const QUrl &url);
void iconChanged(const QIcon &icon);
+ void zoomFactorChanged(qreal factor);
void scrollPositionChanged(const QPointF &position);
void contentsSizeChanged(const QSizeF &size);
void audioMutedChanged(bool muted);
@@ -347,6 +387,7 @@ Q_SIGNALS:
void pdfPrintingFinished(const QString &filePath, bool success);
void printRequested();
+ void printRequestedByFrame(QWebEngineFrame frame);
void visibleChanged(bool visible);
diff --git a/src/core/api/qwebenginepage_p.h b/src/core/api/qwebenginepage_p.h
index 31ace7e9d..77d3dd8c2 100644
--- a/src/core/api/qwebenginepage_p.h
+++ b/src/core/api/qwebenginepage_p.h
@@ -74,6 +74,7 @@ public:
virtual void didPrintPage(QPrinter *&printer, QSharedPointer<QByteArray> result) = 0;
virtual void didPrintPageToPdf(const QString &filePath, bool success) = 0;
virtual void printRequested() = 0;
+ virtual void printRequestedByFrame(QWebEngineFrame frame) = 0;
virtual void showAutofillPopup(QtWebEngineCore::AutofillPopupController *controller,
const QRect &bounds, bool autoselectFirstSuggestion) = 0;
virtual void hideAutofillPopup() = 0;
@@ -102,6 +103,7 @@ public:
void titleChanged(const QString &) override;
void urlChanged() override;
void iconChanged(const QUrl &) override;
+ void zoomFactorChanged(qreal factor) override;
void loadProgressChanged(int progress) override;
void didUpdateTargetURL(const QUrl &) override;
void selectionChanged() override;
@@ -130,10 +132,14 @@ public:
void javascriptDialog(QSharedPointer<QtWebEngineCore::JavaScriptDialogController>) override;
void runFileChooser(QSharedPointer<QtWebEngineCore::FilePickerController>) override;
void showColorDialog(QSharedPointer<QtWebEngineCore::ColorChooserController>) override;
- void didRunJavaScript(quint64 requestId, const QVariant &result) override;
+ void runJavaScript(const QString &script, quint32 worldId, quint64 frameId,
+ 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 didPrintPage(quint64 requestId, QSharedPointer<QByteArray> result) 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, quint64 frameId) override;
void didPrintPageToPdf(const QString &filePath, bool success) override;
bool passOnFocus(bool reverse) override;
void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message,
@@ -142,7 +148,7 @@ public:
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;
@@ -161,6 +167,7 @@ public:
bool isEnabled() const override;
void setToolTip(const QString &toolTipText) override;
void printRequested() override;
+ void printRequestedByFrame(quint64 frameId) override;
QtWebEngineCore::TouchHandleDrawableDelegate *
createTouchHandleDelegate(const QMap<int, QImage> &) override;
void showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *, const QRect &,
@@ -173,6 +180,7 @@ public:
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;
@@ -184,6 +192,7 @@ public:
bool adoptWebContents(QtWebEngineCore::WebContentsAdapter *webContents);
QtWebEngineCore::WebContentsAdapter *webContents() { return adapter.data(); }
void recreateFromSerializedHistory(QDataStream &input);
+ void didPrintPage(QSharedPointer<QByteArray> result);
void setFullScreenMode(bool);
void ensureInitialized() const;
@@ -214,9 +223,7 @@ public:
QPrinter *currentPrinter = nullptr;
#endif
- mutable QMap<quint64, std::function<void(const QVariant &)>> m_variantCallbacks;
mutable QMap<quint64, std::function<void(const QString &)>> m_stringCallbacks;
- QMap<quint64, std::function<void(const QByteArray &)>> m_pdfResultCallbacks;
mutable QAction *actions[QWebEnginePage::WebActionCount];
};
diff --git a/src/core/api/qwebenginepermission.cpp b/src/core/api/qwebenginepermission.cpp
new file mode 100644
index 000000000..d898b8c7e
--- /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 000000000..09db8ce36
--- /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 000000000..94c898873
--- /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/api/qwebengineprofile.cpp b/src/core/api/qwebengineprofile.cpp
index dbb98102c..5d7bb5559 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"
@@ -93,7 +94,7 @@ using QtWebEngineCore::ProfileAdapter;
/*!
\enum QWebEngineProfile::PersistentCookiesPolicy
- This enum describes policy for cookie persistency:
+ This enum describes policy for cookie persistence:
\value NoPersistentCookies
Both session and persistent cookies are stored in memory. This is the only setting
@@ -105,6 +106,28 @@ using QtWebEngineCore::ProfileAdapter;
Both session and persistent cookies are saved to and restored from disk.
*/
+/*!
+ \enum QWebEngineProfile::PersistentPermissionsPolicy
+
+ \since 6.8
+
+ This enum describes the policy for permission persistence:
+
+ \value NoPersistentPermissions
+ 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
+ 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
+ and restored from disk. This is the default setting.
+*/
+
void QWebEngineProfilePrivate::showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &controller)
{
if (m_notificationPresenter) {
@@ -571,6 +594,31 @@ 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.
+
+ \sa setPersistentPermissionsPolicy()
+*/
+QWebEngineProfile::PersistentPermissionsPolicy QWebEngineProfile::persistentPermissionsPolicy() const
+{
+ Q_D(const QWebEngineProfile);
+ return QWebEngineProfile::PersistentPermissionsPolicy(d->profileAdapter()->persistentPermissionsPolicy());
+}
+
+/*!
+ Sets the policy for persistent permissions to \a newPersistentPermissionsPolicy.
+
+ \sa persistentPermissionsPolicy()
+*/
+void QWebEngineProfile::setPersistentPermissionsPolicy(QWebEngineProfile::PersistentPermissionsPolicy newPersistentPermissionsPolicy)
+{
+ Q_D(QWebEngineProfile);
+ d->profileAdapter()->setPersistentPermissionsPolicy(ProfileAdapter::PersistentPermissionsPolicy(newPersistentPermissionsPolicy));
+}
+
+/*!
Returns the maximum size of the HTTP cache in bytes.
Will return \c 0 if the size is automatically controlled by QtWebEngine.
@@ -930,6 +978,95 @@ 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
+ * 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.
\since 6.8
diff --git a/src/core/api/qwebengineprofile.h b/src/core/api/qwebengineprofile.h
index a0027cb81..573f39e7d 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>
@@ -49,6 +50,13 @@ public:
};
Q_ENUM(PersistentCookiesPolicy)
+ enum PersistentPermissionsPolicy : quint8 {
+ NoPersistentPermissions,
+ PersistentPermissionsInMemory,
+ PersistentPermissionsOnDisk,
+ };
+ Q_ENUM(PersistentPermissionsPolicy)
+
QString storageName() const;
bool isOffTheRecord() const;
@@ -70,6 +78,9 @@ public:
PersistentCookiesPolicy persistentCookiesPolicy() const;
void setPersistentCookiesPolicy(QWebEngineProfile::PersistentCookiesPolicy);
+ PersistentPermissionsPolicy persistentPermissionsPolicy() const;
+ void setPersistentPermissionsPolicy(QWebEngineProfile::PersistentPermissionsPolicy);
+
int httpCacheMaximumSize() const;
void setHttpCacheMaximumSize(int maxSize);
@@ -110,6 +121,11 @@ public:
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/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp
index 152cf4dd0..b323b5ec3 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 33efcbeda..b8a02d07a 100644
--- a/src/core/api/qwebengineurlrequestinfo.h
+++ b/src/core/api/qwebengineurlrequestinfo.h
@@ -47,8 +47,9 @@ public:
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/api/qwebengineurlrequestjob.cpp b/src/core/api/qwebengineurlrequestjob.cpp
index b3997a49d..5ad22f344 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.
+ The request was successful. (Deprecated since Qt 6.7)
\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 a0cb48b8b..858c03e6e 100644
--- a/src/core/api/qwebengineurlrequestjob.h
+++ b/src/core/api/qwebengineurlrequestjob.h
@@ -26,7 +26,10 @@ public:
~QWebEngineUrlRequestJob();
enum Error {
- NoError = 0,
+#if QT_DEPRECATED_SINCE(6, 7)
+ NoError Q_DECL_ENUMERATOR_DEPRECATED_X(
+ "This attribute has no effect.") = 0,
+#endif
UrlNotFound,
UrlInvalid,
RequestAborted,
diff --git a/src/core/api/qwebengineurlscheme.cpp b/src/core/api/qwebengineurlscheme.cpp
index 3093c2b8e..be56a3048 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/api/qwebenginewebauthuxrequest.cpp b/src/core/api/qwebenginewebauthuxrequest.cpp
index 6a79daec9..1f09e55bb 100644
--- a/src/core/api/qwebenginewebauthuxrequest.cpp
+++ b/src/core/api/qwebenginewebauthuxrequest.cpp
@@ -94,6 +94,59 @@
*/
/*!
+ \qmltype WebEngineWebAuthPinRequest
+ \instantiates QWebEngineWebAuthPinRequest
+ \inqmlmodule QtWebEngine
+ \since QtWebEngine 6.8
+ \brief Encapsulates the data of a PIN WebAuth UX request.
+
+ This encapsulates the following information related to a PIN request made by an authenticator.
+ \list
+ \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{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.
+*/
+
+/*!
+ \qmlproperty enumeration WebEngineWebAuthPinRequest::reason
+ \brief The reason for the PIN prompt.
+
+ \value WebEngineWebAuthUxRequest.PinEntryReason.Set A new PIN is being set.
+ \value WebEngineWebAuthUxRequest.PinEntryReason.Change The existing PIN must be changed before using this authenticator.
+ \value WebEngineWebAuthUxRequest.PinEntryReason.Challenge The existing PIN is being collected to prove user verification.
+*/
+
+/*!
+ \qmlproperty enumeration WebEngineWebAuthPinRequest::error
+ \brief The error details for the PIN prompt.
+
+ \value WebEngineWebAuthUxRequest.PinEntryError.NoError No error has occurred.
+ \value WebEngineWebAuthUxRequest.PinEntryError.InternalUvLocked Internal UV is locked, so we are falling back to PIN.
+ \value WebEngineWebAuthUxRequest.PinEntryError.WrongPin The PIN the user entered does not match the authenticator PIN.
+ \value WebEngineWebAuthUxRequest.PinEntryError.TooShort The new PIN the user entered is too short.
+ \value WebEngineWebAuthUxRequest.PinEntryError.InvalidCharacters The new PIN the user entered contains invalid characters.
+ \value WebEngineWebAuthUxRequest.PinEntryError.SameAsCurrentPin The new PIN the user entered is the same as the currently set PIN.
+*/
+
+/*!
+ \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}.
+*/
+
+/*!
+ \qmlproperty int WebEngineWebAuthPinRequest::minPinLength
+ \brief The minimum PIN length that the authenticator will accept for the PIN.
+*/
+
+/*!
\enum QWebEngineWebAuthUxRequest::WebAuthUxState
This enum describes the state of the current WebAuth UX request.
diff --git a/src/core/autofill_client_qt.cpp b/src/core/autofill_client_qt.cpp
index 3bdc62e19..15162e9e9 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);
}
@@ -99,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();
@@ -130,13 +122,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 cd38de462..4f10882d2 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"
@@ -46,20 +47,18 @@ public:
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;
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;
- void PropagateAutofillPredictionsDeprecated(autofill::AutofillDriver *,
- const std::vector<autofill::FormStructure *> &) override;
bool IsOffTheRecord() override;
scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override;
diff --git a/src/core/autofill_popup_controller.cpp b/src/core/autofill_popup_controller.cpp
index a6baf5fc2..a4ce0b7f8 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_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp
index de3347df3..ff3d21fb7 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/browser_message_filter_qt.cpp b/src/core/browser_message_filter_qt.cpp
index e8fcb994a..8708fc830 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 0f5721c82..c19d2f352 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 @@ public:
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/certificate_error_controller.cpp b/src/core/certificate_error_controller.cpp
index 014d74500..51f9f3edb 100644
--- a/src/core/certificate_error_controller.cpp
+++ b/src/core/certificate_error_controller.cpp
@@ -77,10 +77,12 @@ static int IsCertErrorFatal(int cert_error)
CertificateErrorController::CertificateErrorController(
int cert_error, const net::SSLInfo &ssl_info, const GURL &request_url,
- bool strict_enforcement, base::OnceCallback<void(content::CertificateRequestResultType)> cb)
+ bool main_frame, bool strict_enforcement,
+ base::OnceCallback<void(content::CertificateRequestResultType)> cb)
: m_certError(QWebEngineCertificateError::Type(cert_error))
, m_requestUrl(toQt(request_url))
, m_overridable(!IsCertErrorFatal(cert_error) && !strict_enforcement)
+ , m_mainFrame(main_frame)
{
// MEMO set callback anyway even for non overridable error since chromium halts load until it's called
// callback will be executed either explicitly by use code or implicitly when error goes out of scope
@@ -204,4 +206,9 @@ QList<QSslCertificate> CertificateErrorController::certificateChain() const
return m_certificateChain;
}
+bool CertificateErrorController::isMainFrame() const
+{
+ return m_mainFrame;
+}
+
}
diff --git a/src/core/certificate_error_controller.h b/src/core/certificate_error_controller.h
index cbcb60f8a..b0d38fd57 100644
--- a/src/core/certificate_error_controller.h
+++ b/src/core/certificate_error_controller.h
@@ -37,7 +37,7 @@ class Q_WEBENGINECORE_EXPORT CertificateErrorController {
public:
CertificateErrorController(
int cert_error, const net::SSLInfo &ssl_info, const GURL &request_url,
- bool strict_enforcement,
+ bool main_frame, bool strict_enforcement,
base::OnceCallback<void(content::CertificateRequestResultType)> callback);
~CertificateErrorController();
@@ -47,6 +47,7 @@ public:
QString errorString() const;
QDateTime validExpiry() const;
QList<QSslCertificate> certificateChain() const;
+ bool isMainFrame() const;
bool deferred() const;
void defer();
@@ -65,6 +66,7 @@ public:
bool m_overridable;
base::OnceCallback<void(content::CertificateRequestResultType)> m_callback;
QList<QSslCertificate> m_certificateChain;
+ bool m_mainFrame;
bool m_answered = false, m_deferred = false;
diff --git a/src/core/clipboard_qt.cpp b/src/core/clipboard_qt.cpp
index 3f49c6e3c..1140164ae 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
@@ -234,7 +238,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 +347,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
@@ -387,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,
@@ -420,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 22f24cfe5..62dc2fbe6 100644
--- a/src/core/clipboard_qt.h
+++ b/src/core/clipboard_qt.h
@@ -36,7 +36,8 @@ public:
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 @@ protected:
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 @@ protected:
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 1c8e89747..5a0f6d891 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 34e8bdd9f..b5e67aabf 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 @@ public:
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 0ca466fe8..ab891f814 100644
--- a/src/core/compositor/display_skia_output_device.cpp
+++ b/src/core/compositor/display_skia_output_device.cpp
@@ -31,7 +31,7 @@ public:
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_direct3d11.cpp b/src/core/compositor/native_skia_output_device_direct3d11.cpp
index 352fa9f92..2f1ed5f61 100644
--- a/src/core/compositor/native_skia_output_device_direct3d11.cpp
+++ b/src/core/compositor/native_skia_output_device_direct3d11.cpp
@@ -56,6 +56,7 @@ QSGTexture *NativeSkiaOutputDeviceDirect3D11::texture(QQuickWindow *win, uint32_
status = resource->CreateSharedHandle(NULL, DXGI_SHARED_RESOURCE_READ, NULL, &sharedHandle);
Q_ASSERT(status == S_OK);
Q_ASSERT(sharedHandle);
+ resource->Release();
// Pass texture between two D3D devices:
ID3D11Device1 *device = static_cast<ID3D11Device1 *>(
diff --git a/src/core/compositor/native_skia_output_device_vulkan.cpp b/src/core/compositor/native_skia_output_device_vulkan.cpp
index c2ad7a382..b775276f6 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;
@@ -187,6 +189,7 @@ QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t te
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.");
@@ -200,7 +203,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 986db5026..1fbbadf26 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,12 +352,12 @@ 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/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/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",
+ "//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,7 +369,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",
@@ -558,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",
@@ -573,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",
@@ -599,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 7192edbc2..6fec6a1e8 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);
@@ -276,14 +278,14 @@ void ContentBrowserClientQt::AllowCertificateError(content::WebContents *webCont
int cert_error,
const net::SSLInfo &ssl_info,
const GURL &request_url,
- bool /* is_main_frame_request */,
+ bool is_main_frame_request,
bool strict_enforcement,
base::OnceCallback<void(content::CertificateRequestResultType)> callback)
{
WebContentsDelegateQt* contentsDelegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate());
QSharedPointer<CertificateErrorController> errorController(new CertificateErrorController(
- cert_error, ssl_info, request_url, strict_enforcement, std::move(callback)));
+ cert_error, ssl_info, request_url, is_main_frame_request, strict_enforcement, std::move(callback)));
contentsDelegate->allowCertificateError(errorController);
}
@@ -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,22 +1042,20 @@ 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());
ProfileAdapter *profileAdapter = static_cast<ProfileQt *>(profile)->profileAdapter();
for (const QByteArray &scheme : profileAdapter->customUrlSchemes())
- factories->emplace(scheme.toStdString(), CreateCustomURLLoaderFactory(profileAdapter));
+ 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
}
@@ -1055,7 +1066,7 @@ void ContentBrowserClientQt::RegisterNonNetworkWorkerMainResourceURLLoaderFactor
ProfileAdapter *profileAdapter = static_cast<ProfileQt *>(profile)->profileAdapter();
for (const QByteArray &scheme : profileAdapter->customUrlSchemes())
- factories->emplace(scheme.toStdString(), CreateCustomURLLoaderFactory(profileAdapter));
+ factories->emplace(scheme.toStdString(), CreateCustomURLLoaderFactory(profileAdapter, nullptr));
#if BUILDFLAG(ENABLE_EXTENSIONS)
factories->emplace(
@@ -1073,7 +1084,7 @@ void ContentBrowserClientQt::RegisterNonNetworkServiceWorkerUpdateURLLoaderFacto
for (const QByteArray &scheme : profileAdapter->customUrlSchemes()) {
if (const url::CustomScheme *cs = url::CustomScheme::FindScheme(scheme.toStdString())) {
if (cs->flags & url::CustomScheme::ServiceWorkersAllowed)
- factories->emplace(scheme.toStdString(), CreateCustomURLLoaderFactory(profileAdapter));
+ factories->emplace(scheme.toStdString(), CreateCustomURLLoaderFactory(profileAdapter, nullptr));
}
}
@@ -1093,15 +1104,15 @@ void ContentBrowserClientQt::RegisterNonNetworkSubresourceURLLoaderFactories(int
Profile *profile = Profile::FromBrowserContext(process_host->GetBrowserContext());
ProfileAdapter *profileAdapter = static_cast<ProfileQt *>(profile)->profileAdapter();
- for (const QByteArray &scheme : profileAdapter->customUrlSchemes())
- factories->emplace(scheme.toStdString(), CreateCustomURLLoaderFactory(profileAdapter));
-
content::RenderFrameHost *frame_host = content::RenderFrameHost::FromID(render_process_id, render_frame_id);
content::WebContents *web_contents = content::WebContents::FromRenderFrameHost(frame_host);
GURL url;
if (web_contents)
url = web_contents->GetVisibleURL();
+ for (const QByteArray &scheme : profileAdapter->customUrlSchemes())
+ factories->emplace(scheme.toStdString(), CreateCustomURLLoaderFactory(profileAdapter, web_contents));
+
bool is_background_page = false;
#if BUILDFLAG(ENABLE_EXTENSIONS)
is_background_page = extensions::GetViewType(web_contents) == extensions::mojom::ViewType::kExtensionBackgroundPage;
@@ -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 7d8e98028..b40c2a343 100644
--- a/src/core/content_browser_client_qt.h
+++ b/src/core/content_browser_client_qt.h
@@ -150,15 +150,13 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 fb68f7b09..2b45e91d1 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/doc/src/qtwebengine-overview.qdoc b/src/core/doc/src/qtwebengine-overview.qdoc
index 6eccc669e..3a5d30338 100644
--- a/src/core/doc/src/qtwebengine-overview.qdoc
+++ b/src/core/doc/src/qtwebengine-overview.qdoc
@@ -44,8 +44,13 @@
dedicated profile for a \e {private browsing} mode, where no information is permanently saved.
\note The \QWE Widgets module uses the \l{Qt Quick Scene Graph}{Qt Quick scene graph}
- to compose the elements of a web page into one view. This means that the UI process
- requires OpenGL ES 2.0 or OpenGL 2.0 for its rendering.
+ to compose the elements of a web page into one view.
+
+ The content is rendered using the graphics card (GPU) capabilities. The scene
+ graph, in turn, relies on the Qt Rendering Hardware Interface as an abstraction
+ layer for the different capabilities and APIs a GPU might feature. For more
+ advice on how to tweak the rendering pipeline, see therefore
+ \l{Rendering via the Qt Rendering Hardware Interface}.
\section2 Qt WebEngine Module
diff --git a/src/core/doc/src/qwebengine-licensing.qdoc b/src/core/doc/src/qwebengine-licensing.qdoc
index 796a9664d..936ceff97 100644
--- a/src/core/doc/src/qwebengine-licensing.qdoc
+++ b/src/core/doc/src/qwebengine-licensing.qdoc
@@ -5,20 +5,49 @@
\group qtwebengine-licensing
\title Qt WebEngine Licensing
-The Qt specific parts of the \QWE module are dual-licensed
-under Commercial and GNU Lesser General Public License (LGPLv3).
-In addition, the module contains code licensed under LGPLv2.
-
-The module includes a snapshot of Chromium. As such, users need to
-respect the licenses of Chromium, and third-party code included in
-Chromium. The arguably most restrictive license to be respected by
-all users is LGPLv2.1.
+The \QWE module uses Chromium to provide most of its
+functionality. During the build process, Chromium becomes
+a part of the \l{Qt WebEngine Core} library.
+Therefore, when distributing \QWE, users need to comply
+to both the licenses of the \QWE part as developed under
+the Qt Project, as well as the licenses that are part of
+Chromium.
+
+The Qt specific parts of the \QWE module are available under
+commercial licenses from The Qt Company. Alternatively,
+they are available under GNU Lesser General Public License v3.0,
+or GNU General Public License v3.0, or
+GNU General Public License v2.0.
+
+The Chromium part contains code available under various
+licenses, with the most restrictive license being the
+\e{GNU Lesser General Public License v2.1} (LGPL 2.1).
+For a full list, see \l{Third-Party Licenses} below.
+
+\section1 Complying with LGPL 2.1
+
+The Qt Company allows commercial customers to
+distribute the source code of the \QWE module alongside the
+\QWE binaries, and allows recipients to customize and build
+\QWE from sources. This includes building and using
+such a modified \QWE with an application or system using
+an otherwise commercially licensed Qt.
+
+The Qt Company also keeps the Qt specific parts of the \QWE
+module available under the GNU Lesser General Public License v3.0,
+or the GNU General Public License v3.0, or
+the GNU General Public License v2.0, even if WebEngine is released
+as part of a commercial-only Long-Term Support release (LTS, see
+also \l{Long-Term Support releases}).
+
+\section1 Third-Party Licenses
+
+Third party licenses included in the sources as part of Chromium
+are found below.
\note Any GPL licenses listed below are only used to access Linux system
-resources. \QWE does not link to nor distribute GPL binary code, and
-it does not affect users of \QWE.
-
-Third party licenses included in the sources are:
+resources. The \QWE libraries and plugins does not link to nor distribute
+GPL binary code, and it does not affect users of \QWE.
*/
/*!
diff --git a/src/core/doc/src/qwebenginepage_lgpl.qdoc b/src/core/doc/src/qwebenginepage_lgpl.qdoc
index c2515cd13..630ea507e 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:
@@ -735,6 +737,8 @@
\brief The zoom factor for the page content.
Valid values are within the range from \c{0.25} to \c{5.0}. The default factor is \c{1.0}.
+
+ \sa zoomFactorChanged()
*/
/*!
@@ -772,11 +776,13 @@
during page destruction. When QWebEnginePage is deleted, the callback is triggered with an invalid
value and it is not safe to use the corresponding QWebEnginePage or QWebEngineView instance inside it.
- \sa scripts(), QWebEngineScript::ScriptWorldId, {Script Injection}
+ \sa scripts(), QWebEngineScript::ScriptWorldId, QWebEngineFrame::runJavaScript, {Script Injection}
*/
/*!
\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.
@@ -790,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.
@@ -799,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.
@@ -808,6 +816,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)
This signal is emitted whenever the title of the page changes.
@@ -836,3 +853,12 @@
\sa QWebEngineWebAuthUxRequest
*/
+
+/*!
+ \fn void QWebEnginePage::zoomFactorChanged(qreal factor)
+ \since 6.8
+
+ This signal is emitted whenever the zoom \a factor for the page changes.
+
+ \sa zoomFactor(), setZoomFactor()
+*/
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index c0fd0d3ee..7ccd063ff 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 cc6d49764..e7dfad29d 100644
--- a/src/core/download_manager_delegate_qt.h
+++ b/src/core/download_manager_delegate_qt.h
@@ -35,7 +35,7 @@ public:
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 @@ public:
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 aa408a544..16133a598 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 1c2688933..38b5d4a2f 100644
--- a/src/core/extensions/extension_host_delegate_qt.h
+++ b/src/core/extensions/extension_host_delegate_qt.h
@@ -27,7 +27,7 @@ public:
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 19fc6c808..36151cee5 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 bcc8f142b..34a846311 100644
--- a/src/core/extensions/extensions_browser_client_qt.h
+++ b/src/core/extensions/extensions_browser_client_qt.h
@@ -108,6 +108,10 @@ public:
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 7c1c5bbd8..6c5b33919 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 1e9d87c38..01b56fa56 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 @@ private:
~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_driver_qt.cpp b/src/core/favicon_driver_qt.cpp
index bb4a734b4..e710d5358 100644
--- a/src/core/favicon_driver_qt.cpp
+++ b/src/core/favicon_driver_qt.cpp
@@ -263,13 +263,6 @@ void FaviconDriverQt::DidUpdateFaviconURL(
if (!entry)
return;
- // We update |m_faviconUrls| even if the list is believed to be partial
- // (checked below), because callers of our getter favicon_urls() expect so.
- std::vector<blink::mojom::FaviconURLPtr> faviconUrls;
- for (const auto &candidate : candidates)
- faviconUrls.push_back(candidate.Clone());
- m_faviconUrls = std::move(faviconUrls);
-
if (!rfh->IsDocumentOnLoadCompletedInMainFrame())
return;
diff --git a/src/core/favicon_driver_qt.h b/src/core/favicon_driver_qt.h
index 96bd682a2..6dc377969 100644
--- a/src/core/favicon_driver_qt.h
+++ b/src/core/favicon_driver_qt.h
@@ -137,9 +137,6 @@ private:
GURL m_bypassCachePageURL;
- // nullopt until the actual list is reported via DidUpdateFaviconURL().
- absl::optional<std::vector<blink::mojom::FaviconURLPtr>> m_faviconUrls;
-
int m_completedHandlersCount = 0;
FaviconStatusQt m_latestFavicon;
diff --git a/src/core/favicon_service_factory_qt.cpp b/src/core/favicon_service_factory_qt.cpp
index dd2a1979a..1ed33d559 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 55d5f3b33..0c3bfd7b5 100644
--- a/src/core/favicon_service_factory_qt.h
+++ b/src/core/favicon_service_factory_qt.h
@@ -51,7 +51,7 @@ public:
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 9b4521358..9f9789296 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 06fbfae3f..b569c81c0 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 @@ public:
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 6dc45c442..73885b6f2 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/custom_url_loader_factory.cpp b/src/core/net/custom_url_loader_factory.cpp
index 4274def99..b91a1289b 100644
--- a/src/core/net/custom_url_loader_factory.cpp
+++ b/src/core/net/custom_url_loader_factory.cpp
@@ -4,6 +4,7 @@
#include "custom_url_loader_factory.h"
#include "base/strings/stringprintf.h"
+#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -24,7 +25,11 @@
#include "api/qwebengineurlscheme.h"
#include "net/url_request_custom_job_proxy.h"
#include "profile_adapter.h"
+#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>
#include <QtCore/qfile.h>
@@ -46,11 +51,12 @@ public:
static void CreateAndStart(const network::ResourceRequest &request,
mojo::PendingReceiver<network::mojom::URLLoader> loader,
mojo::PendingRemote<network::mojom::URLLoaderClient> client_remote,
- QPointer<ProfileAdapter> profileAdapter)
+ QPointer<ProfileAdapter> profileAdapter,
+ content::WebContents *webContents)
{
// CustomURLLoader will handle its own life-cycle, and delete when
// the client lets go.
- auto *customUrlLoader = new CustomURLLoader(request, std::move(loader), std::move(client_remote), profileAdapter);
+ auto *customUrlLoader = new CustomURLLoader(request, std::move(loader), std::move(client_remote), profileAdapter, webContents);
customUrlLoader->Start();
}
@@ -85,10 +91,12 @@ private:
CustomURLLoader(const network::ResourceRequest &request,
mojo::PendingReceiver<network::mojom::URLLoader> loader,
mojo::PendingRemote<network::mojom::URLLoaderClient> client_remote,
- QPointer<ProfileAdapter> profileAdapter)
+ QPointer<ProfileAdapter> profileAdapter,
+ content::WebContents *webContents)
// ### We can opt to run the url-loader on the UI thread instead
: m_taskRunner(content::GetIOThreadTaskRunner({}))
, m_proxy(new URLRequestCustomJobProxy(this, request.url.scheme(), profileAdapter))
+ , m_webContents(webContents)
, m_receiver(this, std::move(loader))
, m_client(std::move(client_remote))
, m_request(request)
@@ -348,6 +356,14 @@ private:
m_client->OnReceiveResponse(std::move(m_head), mojo::ScopedDataPipeConsumerHandle(), absl::nullopt);
CompleteWithFailure(net::Error(error));
}
+ void notifySuccess() override
+ {
+ if (m_webContents) {
+ WebContentsDelegateQt *delegate =
+ static_cast<WebContentsDelegateQt *>(m_webContents->GetDelegate());
+ delegate->emitLoadSucceeded(toQt(m_request.url));
+ }
+ }
void notifyReadyRead() override
{
DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
@@ -432,6 +448,7 @@ private:
scoped_refptr<base::SequencedTaskRunner> m_taskRunner;
scoped_refptr<URLRequestCustomJobProxy> m_proxy;
+ content::WebContents *m_webContents;
mojo::Receiver<network::mojom::URLLoader> m_receiver;
mojo::Remote<network::mojom::URLLoaderClient> m_client;
@@ -454,9 +471,10 @@ private:
class CustomURLLoaderFactory : public network::mojom::URLLoaderFactory {
public:
- CustomURLLoaderFactory(ProfileAdapter *profileAdapter, mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+ CustomURLLoaderFactory(ProfileAdapter *profileAdapter, content::WebContents *webContents, mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
: m_taskRunner(content::GetIOThreadTaskRunner({}))
, m_profileAdapter(profileAdapter)
+ , m_webContents(webContents)
{
m_receivers.set_disconnect_handler(base::BindRepeating(
&CustomURLLoaderFactory::OnDisconnect, base::Unretained(this)));
@@ -480,7 +498,7 @@ public:
m_taskRunner->PostTask(FROM_HERE,
base::BindOnce(&CustomURLLoader::CreateAndStart, request,
std::move(loader), std::move(client),
- m_profileAdapter));
+ m_profileAdapter, m_webContents));
}
@@ -495,24 +513,24 @@ public:
delete this;
}
- static mojo::PendingRemote<network::mojom::URLLoaderFactory> Create(ProfileAdapter *profileAdapter)
+ static mojo::PendingRemote<network::mojom::URLLoaderFactory> Create(ProfileAdapter *profileAdapter, content::WebContents *webContents)
{
mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_remote;
- new CustomURLLoaderFactory(profileAdapter, pending_remote.InitWithNewPipeAndPassReceiver());
+ new CustomURLLoaderFactory(profileAdapter, webContents, pending_remote.InitWithNewPipeAndPassReceiver());
return pending_remote;
}
const scoped_refptr<base::SequencedTaskRunner> m_taskRunner;
mojo::ReceiverSet<network::mojom::URLLoaderFactory> m_receivers;
QPointer<ProfileAdapter> m_profileAdapter;
+ content::WebContents *m_webContents;
};
} // namespace
-mojo::PendingRemote<network::mojom::URLLoaderFactory> CreateCustomURLLoaderFactory(ProfileAdapter *profileAdapter)
+mojo::PendingRemote<network::mojom::URLLoaderFactory> CreateCustomURLLoaderFactory(ProfileAdapter *profileAdapter, content::WebContents *webContents)
{
- return CustomURLLoaderFactory::Create(profileAdapter);
+ return CustomURLLoaderFactory::Create(profileAdapter, webContents);
}
} // namespace QtWebEngineCore
-
diff --git a/src/core/net/custom_url_loader_factory.h b/src/core/net/custom_url_loader_factory.h
index fb0c74627..e4a767c85 100644
--- a/src/core/net/custom_url_loader_factory.h
+++ b/src/core/net/custom_url_loader_factory.h
@@ -17,6 +17,9 @@
#include "mojo/public/cpp/bindings/pending_remote.h"
+namespace content {
+class WebContents;
+}
namespace network {
namespace mojom {
class URLLoaderFactory;
@@ -26,7 +29,7 @@ class URLLoaderFactory;
namespace QtWebEngineCore {
class ProfileAdapter;
-mojo::PendingRemote<network::mojom::URLLoaderFactory> CreateCustomURLLoaderFactory(ProfileAdapter *profileAdapter);
+mojo::PendingRemote<network::mojom::URLLoaderFactory> CreateCustomURLLoaderFactory(ProfileAdapter *profileAdapter, content::WebContents *webContents);
} // namespace QtWebEngineCore
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 159fa28ca..319d3a566 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");
@@ -121,11 +124,7 @@ void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL
if (extension_id == extension_misc::kPdfExtensionId && response_head->headers)
ClearAllButFrameAncestors(response_head);
- 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();
@@ -133,20 +132,20 @@ void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL
mojo::PendingReceiver<network::mojom::URLLoaderClient> new_client_receiver =
new_client.BindNewPipeAndPassReceiver();
-
- uint32_t data_pipe_size = 64U;
+ 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.
- *defer = extensions::MimeHandlerViewAttachHelper::OverrideBodyForInterceptedResponse(
- m_frame_tree_node_id, response_url, response_head->mime_type, view_id,
- &payload, &data_pipe_size,
- 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;
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,
@@ -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, view_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 fcce08550..d74ec699d 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_restricted_cookie_manager_qt.cpp b/src/core/net/proxying_restricted_cookie_manager_qt.cpp
index d4d5cc4ab..29e6de968 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 faf0545c3..ba30a448e 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 @@ public:
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 @@ public:
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/proxying_url_loader_factory_qt.cpp b/src/core/net/proxying_url_loader_factory_qt.cpp
index 3a83ed7ea..220f44023 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 41967f14e..809a95c8d 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 0b3d7974c..f210f028a 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 @@ public:
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 439d1066c..78098529d 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/url_request_custom_job_delegate.cpp b/src/core/net/url_request_custom_job_delegate.cpp
index c877de669..fb6b605a4 100644
--- a/src/core/net/url_request_custom_job_delegate.cpp
+++ b/src/core/net/url_request_custom_job_delegate.cpp
@@ -64,12 +64,16 @@ void URLRequestCustomJobDelegate::setAdditionalResponseHeaders(
void URLRequestCustomJobDelegate::reply(const QByteArray &contentType, QIODevice *device)
{
- if (device)
+ if (!device)
+ m_proxy->m_ioTaskRunner->PostTask(FROM_HERE,
+ base::BindOnce(&URLRequestCustomJobProxy::succeed, m_proxy));
+ else {
QObject::connect(device, &QIODevice::readyRead, this, &URLRequestCustomJobDelegate::slotReadyRead);
- m_proxy->m_ioTaskRunner->PostTask(FROM_HERE,
- base::BindOnce(&URLRequestCustomJobProxy::reply, m_proxy,
- contentType.toStdString(), device,
- std::move(m_additionalResponseHeaders)));
+ m_proxy->m_ioTaskRunner->PostTask(FROM_HERE,
+ base::BindOnce(&URLRequestCustomJobProxy::reply, m_proxy,
+ contentType.toStdString(), device,
+ std::move(m_additionalResponseHeaders)));
+ }
}
void URLRequestCustomJobDelegate::slotReadyRead()
diff --git a/src/core/net/url_request_custom_job_proxy.cpp b/src/core/net/url_request_custom_job_proxy.cpp
index 0f41a3670..54faddc62 100644
--- a/src/core/net/url_request_custom_job_proxy.cpp
+++ b/src/core/net/url_request_custom_job_proxy.cpp
@@ -118,6 +118,11 @@ void URLRequestCustomJobProxy::fail(int error)
// else we fail on the next read, or the read that might already be in progress
}
+void URLRequestCustomJobProxy::succeed()
+{
+ m_client->notifySuccess();
+}
+
void URLRequestCustomJobProxy::readyRead()
{
DCHECK (m_ioTaskRunner->RunsTasksInCurrentSequence());
diff --git a/src/core/net/url_request_custom_job_proxy.h b/src/core/net/url_request_custom_job_proxy.h
index 65c919ed0..c03992411 100644
--- a/src/core/net/url_request_custom_job_proxy.h
+++ b/src/core/net/url_request_custom_job_proxy.h
@@ -44,6 +44,7 @@ public:
virtual void notifyCanceled() = 0;
virtual void notifyAborted() = 0;
virtual void notifyStartFailure(int) = 0;
+ virtual void notifySuccess() = 0;
virtual void notifyReadyRead() = 0;
virtual base::SequencedTaskRunner *taskRunner() = 0;
};
@@ -60,6 +61,7 @@ public:
void redirect(GURL url);
void abort();
void fail(int error);
+ void succeed();
void release();
void initialize(GURL url, std::string method, absl::optional<url::Origin> initiatorOrigin,
std::map<std::string, std::string> headers,
diff --git a/src/core/net/webui_controller_factory_qt.cpp b/src/core/net/webui_controller_factory_qt.cpp
index ed35a3e36..2acd05cae 100644
--- a/src/core/net/webui_controller_factory_qt.cpp
+++ b/src/core/net/webui_controller_factory_qt.cpp
@@ -14,8 +14,8 @@
#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/devtools_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"
#include "chrome/common/url_constants.h"
diff --git a/src/core/ozone/gl_context_qt.cpp b/src/core/ozone/gl_context_qt.cpp
index 0042f2bce..2e358c0fb 100644
--- a/src/core/ozone/gl_context_qt.cpp
+++ b/src/core/ozone/gl_context_qt.cpp
@@ -179,7 +179,7 @@ bool GLContextHelper::isCreateContextRobustnessSupported()
class ScopedGLContext
{
public:
- ScopedGLContext()
+ ScopedGLContext(QOffscreenSurface *surface)
: m_context(new QOpenGLContext())
, m_previousContext(gl::GLContext::GetCurrent())
, m_previousSurface(gl::GLSurface::GetCurrent())
@@ -189,10 +189,7 @@ public:
return;
}
- QOffscreenSurface *surface = new QOffscreenSurface(m_context->screen(), m_context.get());
- surface->create();
Q_ASSERT(surface->isValid());
-
if (!m_context->makeCurrent(surface)) {
qWarning("Failed to make OpenGL context current.");
return;
@@ -269,7 +266,8 @@ EGLHelper *EGLHelper::instance()
return &eglHelper;
}
-EGLHelper::EGLHelper() : m_functions(new EGLHelper::EGLFunctions())
+EGLHelper::EGLHelper()
+ : m_functions(new EGLHelper::EGLFunctions()), m_offscreenSurface(new QOffscreenSurface())
{
const char *extensions = m_functions->eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
if (!extensions) {
@@ -288,6 +286,9 @@ EGLHelper::EGLHelper() : m_functions(new EGLHelper::EGLFunctions())
return;
}
+ 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")
@@ -306,6 +307,16 @@ EGLHelper::EGLHelper() : m_functions(new EGLHelper::EGLFunctions())
const char *displayVendor = m_functions->eglQueryString(eglDisplay, EGL_VENDOR);
m_isDmaBufSupported = !strstr(displayVendor, "NVIDIA");
}
+
+ // Try to create dma-buf.
+ if (m_isDmaBufSupported) {
+ int fd = -1;
+ queryDmaBuf(2, 2, &fd, nullptr, nullptr, nullptr);
+ if (fd == -1)
+ m_isDmaBufSupported = false;
+ else
+ close(fd);
+ }
}
void EGLHelper::queryDmaBuf(const int width, const int height, int *fd, int *stride, int *offset,
@@ -314,7 +325,7 @@ void EGLHelper::queryDmaBuf(const int width, const int height, int *fd, int *str
if (!m_isDmaBufSupported)
return;
- ScopedGLContext context;
+ ScopedGLContext context(m_offscreenSurface.get());
if (!context.isValid())
return;
@@ -350,18 +361,7 @@ void EGLHelper::queryDmaBuf(const int width, const int height, int *fd, int *str
bool EGLHelper::isDmaBufSupported()
{
- if (!m_isDmaBufSupported)
- return false;
-
- int fd = -1;
- queryDmaBuf(2, 2, &fd, nullptr, nullptr, nullptr);
- if (fd == -1) {
- m_isDmaBufSupported = false;
- return false;
- }
-
- close(fd);
- return true;
+ return m_isDmaBufSupported;
}
#endif // QT_CONFIG(opengl) && defined(USE_OZONE)
diff --git a/src/core/ozone/gl_context_qt.h b/src/core/ozone/gl_context_qt.h
index bd1137053..41c6a5f0c 100644
--- a/src/core/ozone/gl_context_qt.h
+++ b/src/core/ozone/gl_context_qt.h
@@ -21,6 +21,8 @@ class GLSurface;
QT_BEGIN_NAMESPACE
+class QOffscreenSurface;
+
class GLContextHelper : public QObject {
Q_OBJECT
public:
@@ -80,6 +82,7 @@ private:
EGLHelper();
QScopedPointer<EGLFunctions> m_functions;
+ QScopedPointer<QOffscreenSurface> m_offscreenSurface;
bool m_isDmaBufSupported = false;
};
#endif // QT_CONFIG(opengl) && defined(USE_OZONE)
diff --git a/src/core/ozone/gl_share_context_qt.cpp b/src/core/ozone/gl_share_context_qt.cpp
index b1c5e201f..f2078b597 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 89be00421..6b0546a72 100644
--- a/src/core/ozone/gl_share_context_qt.h
+++ b/src/core/ozone/gl_share_context_qt.h
@@ -18,10 +18,11 @@ 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.
- 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/ozone/gl_surface_qt.cpp b/src/core/ozone/gl_surface_qt.cpp
index 0cbe75cbd..cebeb8b67 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 e8547fa87..6384ea2db 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"
@@ -73,7 +73,8 @@ public:
if (has_initialized_gpu()) {
// This property is set when the GetPlatformRuntimeProperties is
// called on the gpu process side.
- properties.supports_native_pixmaps = surface_factory_ozone_->SupportsNativePixmaps();
+ DCHECK(m_supportsNativePixmaps);
+ properties.supports_native_pixmaps = m_supportsNativePixmaps.value();
}
return properties;
}
@@ -85,6 +86,7 @@ private:
void InitScreen(ui::PlatformScreen *) override {}
+ absl::optional<bool> m_supportsNativePixmaps;
std::unique_ptr<QtWebEngineCore::SurfaceFactoryQt> surface_factory_ozone_;
std::unique_ptr<CursorFactory> cursor_factory_;
@@ -109,10 +111,8 @@ const ui::OzonePlatform::PlatformProperties &OzonePlatformQt::GetPlatformPropert
static base::NoDestructor<ui::OzonePlatform::PlatformProperties> properties;
static bool initialized = false;
if (!initialized) {
- properties->fetch_buffer_formats_for_gmb_on_gpu = true;
-#if BUILDFLAG(USE_VAAPI)
- properties->supports_vaapi = true;
-#endif
+ DCHECK(m_supportsNativePixmaps);
+ properties->fetch_buffer_formats_for_gmb_on_gpu = m_supportsNativePixmaps.value();
initialized = true;
}
@@ -227,6 +227,7 @@ bool OzonePlatformQt::InitializeUI(const ui::OzonePlatform::InitParams &)
input_controller_ = CreateStubInputController();
cursor_factory_.reset(new BitmapCursorFactory());
gpu_platform_support_host_.reset(ui::CreateStubGpuPlatformSupportHost());
+ m_supportsNativePixmaps = QtWebEngineCore::SurfaceFactoryQt::SupportsNativePixmaps();
return true;
}
@@ -234,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([]()
@@ -259,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 204f4d62d..1bfa49c60 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
@@ -92,7 +92,8 @@ scoped_refptr<gfx::NativePixmap> SurfaceFactoryQt::CreateNativePixmap(
gfx::BufferUsage usage,
absl::optional<gfx::Size> framebuffer_size)
{
- Q_ASSERT(SupportsNativePixmaps());
+ if (!SupportsNativePixmaps())
+ return nullptr;
#if QT_CONFIG(opengl)
if (framebuffer_size && !gfx::Rect(size).Contains(gfx::Rect(*framebuffer_size)))
@@ -100,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);
@@ -141,7 +142,11 @@ void SurfaceFactoryQt::CreateNativePixmapAsync(
gfx::BufferUsage usage,
NativePixmapCallback callback)
{
- Q_ASSERT(SupportsNativePixmaps());
+ if (!SupportsNativePixmaps()) {
+ std::move(callback).Run(nullptr);
+ return;
+ }
+
// CreateNativePixmap is non-blocking operation. Thus, it is safe to call it
// and return the result with the provided callback.
std::move(callback).Run(CreateNativePixmap(widget, device_queue, size, format, usage));
@@ -154,12 +159,13 @@ SurfaceFactoryQt::CreateNativePixmapFromHandle(
gfx::BufferFormat format,
gfx::NativePixmapHandle handle)
{
- Q_ASSERT(SupportsNativePixmaps());
+ if (!SupportsNativePixmaps())
+ return nullptr;
#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));
@@ -220,7 +226,7 @@ SurfaceFactoryQt::CreateNativePixmapFromHandle(
int fd = fds[i];
int stride = strides[i];
int offset = offsets[i];
- int size = handle.planes[i].size;
+ int planeSize = handle.planes[i].size;
if (fd == -1) {
fd = fds[0];
@@ -228,7 +234,7 @@ SurfaceFactoryQt::CreateNativePixmapFromHandle(
offset = handle.planes[i].offset;
}
- gfx::NativePixmapPlane plane(stride, offset, size, base::ScopedFD(::dup(fd)));
+ gfx::NativePixmapPlane plane(stride, offset, planeSize, base::ScopedFD(::dup(fd)));
bufferHandle.planes.push_back(std::move(plane));
}
@@ -241,13 +247,13 @@ SurfaceFactoryQt::CreateNativePixmapFromHandle(
#endif // QT_CONFIG(opengl)
}
-bool SurfaceFactoryQt::SupportsNativePixmaps() const
+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/ozone/surface_factory_qt.h b/src/core/ozone/surface_factory_qt.h
index 07d7337ac..d69467a26 100644
--- a/src/core/ozone/surface_factory_qt.h
+++ b/src/core/ozone/surface_factory_qt.h
@@ -40,7 +40,7 @@ public:
gfx::BufferFormat format,
gfx::NativePixmapHandle handle) override;
- bool SupportsNativePixmaps() const;
+ static bool SupportsNativePixmaps();
private:
std::vector<gl::GLImplementationParts> m_impl;
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index b6e727ef8..2c1c0d3d6 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -3,41 +3,55 @@
#include "permission_manager_qt.h"
+#include "base/threading/thread_restrictions.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/permission_controller.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "third_party/blink/public/common/permissions/permission_utils.h"
-
+#include "chrome/browser/prefs/chrome_command_line_pref_store.h"
+#include "components/prefs/pref_member.h"
+#include "components/prefs/in_memory_pref_store.h"
+#include "components/prefs/json_pref_store.h"
+#include "components/prefs/pref_service.h"
+#include "components/prefs/pref_service_factory.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/scoped_user_pref_update.h"
+#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"
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:
@@ -54,41 +68,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 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 bool canRequestPermissionFor(ProfileAdapter::PermissionType type)
+static blink::PermissionType toBlink(QWebEnginePermission::Feature feature)
{
- switch (type) {
- case ProfileAdapter::GeolocationPermission:
- case ProfileAdapter::NotificationPermission:
- case ProfileAdapter::ClipboardReadWrite:
- case ProfileAdapter::LocalFontsPermission:
- return true;
- default:
- break;
+ switch (feature) {
+ case QWebEnginePermission::Notifications:
+ return blink::PermissionType::NOTIFICATIONS;
+ case QWebEnginePermission::Geolocation:
+ return blink::PermissionType::GEOLOCATION;
+ case QWebEnginePermission::MediaAudioCapture:
+ return blink::PermissionType::AUDIO_CAPTURE;
+ case QWebEnginePermission::MediaVideoCapture:
+ return blink::PermissionType::VIDEO_CAPTURE;
+ case QWebEnginePermission::DesktopVideoCapture:
+ case QWebEnginePermission::DesktopAudioVideoCapture:
+ return blink::PermissionType::DISPLAY_CAPTURE;
+ case QWebEnginePermission::ClipboardReadWrite:
+ return blink::PermissionType::CLIPBOARD_READ_WRITE;
+ 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;
}
- return false;
+
+ Q_UNREACHABLE();
}
-static blink::mojom::PermissionStatus toBlink(ProfileAdapter::PermissionState reply)
+static QWebEnginePermission::State toQt(blink::mojom::PermissionStatus state)
{
- switch (reply) {
- case ProfileAdapter::AskPermission:
+ 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;
+ }
+}
+
+static blink::mojom::PermissionStatus toBlink(QWebEnginePermission::State state)
+{
+ 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) {
@@ -103,44 +168,87 @@ static blink::mojom::PermissionStatus getStatusFromSettings(blink::PermissionTyp
}
}
-PermissionManagerQt::PermissionManagerQt()
+PermissionManagerQt::PermissionManagerQt(ProfileAdapter *profileAdapter)
: m_requestIdCount(0)
+ , m_persistence(true)
+ , m_profileAdapter(profileAdapter)
{
+ PrefServiceFactory factory;
+ factory.set_async(false);
+ factory.set_command_line_prefs(base::MakeRefCounted<ChromeCommandLinePrefStore>(
+ base::CommandLine::ForCurrentProcess()));
+
+ QString userPrefStorePath = profileAdapter->dataPath();
+ auto prefRegistry = base::MakeRefCounted<PrefRegistrySimple>();
+
+ auto policy = profileAdapter->persistentPermissionsPolicy();
+ if (!profileAdapter->isOffTheRecord() && policy == ProfileAdapter::PersistentPermissionsOnDisk &&
+ !userPrefStorePath.isEmpty() && profileAdapter->ensureDataPathExists()) {
+ userPrefStorePath += QDir::separator();
+ userPrefStorePath += QStringLiteral("permissions.json");
+ factory.set_user_prefs(base::MakeRefCounted<JsonPrefStore>(toFilePath(userPrefStorePath)));
+ } else {
+ 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
+ for (auto &type : m_featureTypes) {
+ prefRegistry->RegisterDictionaryPref(featureString(type));
+ }
+ PrefProxyConfigTrackerImpl::RegisterPrefs(prefRegistry.get());
+
+ if (policy == ProfileAdapter::NoPersistentPermissions)
+ m_persistence = false;
+
+ {
+ base::ScopedAllowBlocking allowBlock;
+ m_prefService = factory.Create(prefRegistry);
+ }
}
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;
- QPair<QUrl, ProfileAdapter::PermissionType> key(origin, type);
- if (reply == ProfileAdapter::AskPermission)
- m_permissions.remove(key);
+ if (state == QWebEnginePermission::Ask)
+ ResetPermission(toBlink(feature), gorigin, gorigin);
else
- m_permissions[key] = (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();
@@ -150,21 +258,23 @@ void PermissionManagerQt::permissionRequestReply(const QUrl &url, ProfileAdapter
std::vector<blink::mojom::PermissionStatus> result;
result.reserve(it->types.size());
for (blink::PermissionType permission : it->types) {
- const ProfileAdapter::PermissionType permissionType = toQt(permission);
- if (permissionType == ProfileAdapter::UnsupportedPermission) {
+ if (toQt(permission) == QWebEnginePermission::Unsupported) {
result.push_back(blink::mojom::PermissionStatus::DENIED);
continue;
}
- QPair<QUrl, ProfileAdapter::PermissionType> key(origin, permissionType);
- if (!m_permissions.contains(key)) {
- answerable = false;
- break;
+ blink::mojom::PermissionStatus permissionStatus = GetPermissionStatus(permission, gorigin, GURL());
+ if (permissionStatus == toBlink(state)) {
+ if (permissionStatus == blink::mojom::PermissionStatus::ASK) {
+ answerable = false;
+ break;
+ }
+
+ result.push_back(permissionStatus);
+ } else {
+ // Reached when the PersistentPermissionsPolicy is set to NoPersistentPermissions
+ result.push_back(toBlink(state));
}
- if (m_permissions[key])
- result.push_back(blink::mojom::PermissionStatus::GRANTED);
- else
- result.push_back(blink::mojom::PermissionStatus::DENIED);
}
if (answerable) {
std::move(it->callback).Run(result);
@@ -176,10 +286,57 @@ 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)
{
- QPair<QUrl, ProfileAdapter::PermissionType> key(origin, type);
- return m_permissions.contains(key) && m_permissions[key];
+ 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);
+ // Make sure modified permissions are written to disk
+ m_prefService->CommitPendingWrite();
}
void PermissionManagerQt::RequestPermissions(content::RenderFrameHost *frameHost,
@@ -199,19 +356,28 @@ 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;
}
- auto status = getStatusFromSettings(permission, contentsDelegate->webEngineSettings());
- if (status == blink::mojom::PermissionStatus::ASK) {
- answerable = false;
- break;
- } else
- result.push_back(status);
+ 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) {
+ // Automatically grant/deny without prompt if already asked once
+ result.push_back(permissionStatus);
+ } else {
+ answerable = false;
+ break;
+ }
+ } else {
+ // Reached when clipboard settings have been set
+ result.push_back(permissionStatus);
+ }
}
+
if (answerable) {
std::move(callback).Run(result);
return;
@@ -221,9 +387,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);
}
}
@@ -231,7 +397,6 @@ void PermissionManagerQt::RequestPermissionsFromCurrentDocument(content::RenderF
const content::PermissionRequestDescription &requestDescription,
base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus>&)> callback)
{
-
RequestPermissions(frameHost, requestDescription, std::move(callback));
}
@@ -240,14 +405,30 @@ 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;
- QPair<QUrl, ProfileAdapter::PermissionType> key(toQt(requesting_origin), permissionType);
- if (!m_permissions.contains(key))
+ permission = toBlink(toQt(permission)); // Filter out merged/unsupported permissions (e.g. clipboard)
+ auto *pref = m_prefService->FindPreference(featureString(toQt(permission)));
+ if (!pref)
+ return blink::mojom::PermissionStatus::ASK; // Permission type not in database
+
+ const auto *permissions = pref->GetValue()->GetIfDict();
+ Q_ASSERT(permissions);
+
+ auto requestedPermission = permissions->FindBool(requesting_origin.DeprecatedGetOriginAsURL().spec());
+ if (!requestedPermission)
+ return blink::mojom::PermissionStatus::ASK; // Origin is not in the current permission type's database
+
+ // 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::NoPersistentPermissions)
return blink::mojom::PermissionStatus::ASK;
- if (m_permissions[key])
+
+ if (requestedPermission.value())
return blink::mojom::PermissionStatus::GRANTED;
return blink::mojom::PermissionStatus::DENIED;
}
@@ -305,20 +486,19 @@ 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;
- QPair<QUrl, ProfileAdapter::PermissionType> key(toQt(requesting_origin), permissionType);
- m_permissions.remove(key);
+ ScopedDictPrefUpdate updater(m_prefService.get(), featureString(feature));
+ 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,
@@ -326,10 +506,27 @@ 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;
}
+void PermissionManagerQt::setPermission(
+ blink::PermissionType permission,
+ const GURL& requesting_origin,
+ bool granted)
+{
+ const QWebEnginePermission::Feature feature = toQt(permission);
+ if (feature == QWebEnginePermission::Unsupported)
+ return;
+
+ if (!m_prefService->FindPreference(featureString(feature)))
+ return;
+
+ ScopedDictPrefUpdate updater(m_prefService.get(), featureString(feature));
+ updater.Get().Set(requesting_origin.spec(), granted);
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/permission_manager_qt.h b/src/core/permission_manager_qt.h
index b91498d3d..6a4df2efa 100644
--- a/src/core/permission_manager_qt.h
+++ b/src/core/permission_manager_qt.h
@@ -7,20 +7,26 @@
#include "base/functional/callback.h"
#include "content/public/browser/permission_controller_delegate.h"
+#include <QtWebEngineCore/qwebenginepermission.h>
#include "profile_adapter.h"
#include <map>
+class PrefService;
+
namespace QtWebEngineCore {
class PermissionManagerQt : public content::PermissionControllerDelegate
{
public:
- PermissionManagerQt();
+ 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);
+ QList<QWebEnginePermission> listPermissions(const QUrl &origin, QWebEnginePermission::Feature feature);
+
+ void commit();
// content::PermissionManager implementation:
blink::mojom::PermissionStatus GetPermissionStatus(
@@ -51,20 +57,18 @@ public:
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:
- QHash<QPair<QUrl, ProfileAdapter::PermissionType>, bool> m_permissions;
struct Request {
int id;
- ProfileAdapter::PermissionType type;
+ QWebEnginePermission::Feature type;
QUrl origin;
base::OnceCallback<void(blink::mojom::PermissionStatus)> callback;
};
@@ -75,16 +79,24 @@ private:
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;
};
+
+ void setPermission(blink::PermissionType permission,
+ const GURL& requesting_origin,
+ bool granted);
+
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;
-
+ std::unique_ptr<PrefService> m_prefService;
+ QPointer<QtWebEngineCore::ProfileAdapter> m_profileAdapter;
+ bool m_persistence;
};
} // namespace QtWebEngineCore
diff --git a/src/core/platform_notification_service_qt.cpp b/src/core/platform_notification_service_qt.cpp
index 182a5ad84..2c0a39a67 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 bf8fcca04..1435f79e9 100644
--- a/src/core/platform_notification_service_qt.h
+++ b/src/core/platform_notification_service_qt.h
@@ -56,6 +56,8 @@ public:
// 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 544a84de1..ae7cf102b 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 b2b8e34fc..a691bc2b6 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/printing/print_view_manager_qt.cpp b/src/core/printing/print_view_manager_qt.cpp
index 1d21c2fb9..42bade52b 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);
@@ -333,7 +344,10 @@ void PrintViewManagerQt::SetupScriptedPrintPreview(SetupScriptedPrintPreviewCall
if (rfh)
GetPrintRenderFrame(rfh)->OnPrintPreviewDialogClosed();
- client->printRequested();
+ if (web_contents()->GetPrimaryMainFrame() == rfh)
+ client->printRequested();
+ else
+ client->printRequestedByFrame(static_cast<quint64>(rfh->GetFrameTreeNodeId()));
}
void PrintViewManagerQt::ShowScriptedPrintPreview(bool /*source_is_modifiable*/)
diff --git a/src/core/printing/print_view_manager_qt.h b/src/core/printing/print_view_manager_qt.h
index 956849ef9..879a89ef0 100644
--- a/src/core/printing/print_view_manager_qt.h
+++ b/src/core/printing/print_view_manager_qt.h
@@ -41,21 +41,18 @@ public:
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/profile_adapter.cpp b/src/core/profile_adapter.cpp
index b26f9b1de..1f0062953 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"
@@ -64,6 +63,7 @@ ProfileAdapter::ProfileAdapter(const QString &storageName):
, m_downloadPath(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation))
, m_httpCacheType(DiskHttpCache)
, m_persistentCookiesPolicy(AllowPersistentCookies)
+ , m_persistentPermissionsPolicy(PersistentPermissionsOnDisk)
, m_visitedLinksPolicy(TrackVisitedLinksOnDisk)
, m_clientHintsEnabled(true)
, m_pushServiceEnabled(false)
@@ -72,6 +72,8 @@ ProfileAdapter::ProfileAdapter(const QString &storageName):
WebEngineContext::current()->addProfileAdapter(this);
// creation of profile requires webengine context
m_profile.reset(new ProfileQt(this));
+ // initialize permissions store
+ profile()->GetPermissionControllerDelegate();
// fixme: this should not be here
m_profile->m_profileIOData->initializeOnUIThread();
m_customUrlSchemeHandlers.insert(QByteArrayLiteral("qrc"), &m_qrcHandler);
@@ -109,6 +111,7 @@ void ProfileAdapter::setStorageName(const QString &storageName)
m_name = storageName;
if (!m_offTheRecord) {
m_profile->setupPrefService();
+ m_profile->setupPermissionsManager();
if (!m_profile->m_profileIOData->isClearHttpCacheInProgress())
m_profile->m_profileIOData->resetNetworkContext();
if (m_visitedLinksManager)
@@ -124,6 +127,7 @@ void ProfileAdapter::setOffTheRecord(bool offTheRecord)
return;
m_offTheRecord = offTheRecord;
m_profile->setupPrefService();
+ m_profile->setupPermissionsManager();
if (!m_profile->m_profileIOData->isClearHttpCacheInProgress())
m_profile->m_profileIOData->resetNetworkContext();
if (m_visitedLinksManager)
@@ -329,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
@@ -371,6 +375,24 @@ void ProfileAdapter::setPersistentCookiesPolicy(ProfileAdapter::PersistentCookie
m_profile->m_profileIOData->resetNetworkContext();
}
+ProfileAdapter::PersistentPermissionsPolicy ProfileAdapter::persistentPermissionsPolicy() const
+{
+ if (m_persistentPermissionsPolicy == NoPersistentPermissions)
+ return NoPersistentPermissions;
+ if (isOffTheRecord() || m_name.isEmpty())
+ return PersistentPermissionsInMemory;
+ return m_persistentPermissionsPolicy;
+}
+
+void ProfileAdapter::setPersistentPermissionsPolicy(ProfileAdapter::PersistentPermissionsPolicy newPersistentPermissionsPolicy)
+{
+ ProfileAdapter::PersistentPermissionsPolicy oldPolicy = persistentPermissionsPolicy();
+ m_persistentPermissionsPolicy = newPersistentPermissionsPolicy;
+ if (oldPolicy == persistentPermissionsPolicy())
+ return;
+ m_profile->setupPermissionsManager();
+}
+
ProfileAdapter::VisitedLinksPolicy ProfileAdapter::visitedLinksPolicy() const
{
if (isOffTheRecord() || m_visitedLinksPolicy == DoNotTrackVisitedLinks)
@@ -468,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)
@@ -546,14 +567,25 @@ 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())->setPermission(origin, feature, state);
+}
+
+QWebEnginePermission::State ProfileAdapter::getPermissionState(const QUrl &origin, QWebEnginePermission::Feature feature)
{
- static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->permissionRequestReply(origin, type, reply);
+ if (persistentPermissionsPolicy() == ProfileAdapter::NoPersistentPermissions)
+ return QWebEnginePermission::Ask;
+
+ return static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->getPermissionState(origin, feature);
}
-bool ProfileAdapter::checkPermission(const QUrl &origin, PermissionType type)
+QList<QWebEnginePermission> ProfileAdapter::listPermissions(const QUrl &origin, QWebEnginePermission::Feature feature)
{
- return static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->checkPermission(origin, type);
+ if (persistentPermissionsPolicy() == ProfileAdapter::NoPersistentPermissions)
+ return QList<QWebEnginePermission>();
+
+ return static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->listPermissions(origin, feature);
}
QString ProfileAdapter::httpAcceptLanguageWithoutQualities() const
@@ -591,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_adapter.h b/src/core/profile_adapter.h
index 4be0ea51e..6550e6176 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)
@@ -127,20 +128,10 @@ public:
TrackVisitedLinksOnDisk,
};
- 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 PersistentPermissionsPolicy {
+ NoPersistentPermissions = 0,
+ PersistentPermissionsInMemory,
+ PersistentPermissionsOnDisk,
};
enum ClientHint : uchar {
@@ -161,6 +152,9 @@ public:
PersistentCookiesPolicy persistentCookiesPolicy() const;
void setPersistentCookiesPolicy(ProfileAdapter::PersistentCookiesPolicy);
+ PersistentPermissionsPolicy persistentPermissionsPolicy() const;
+ void setPersistentPermissionsPolicy(ProfileAdapter::PersistentPermissionsPolicy);
+
VisitedLinksPolicy visitedLinksPolicy() const;
void setVisitedLinksPolicy(ProfileAdapter::VisitedLinksPolicy);
@@ -178,8 +172,9 @@ public:
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);
+ QList<QWebEnginePermission> listPermissions(const QUrl &origin = QUrl(), QWebEnginePermission::Feature feature = QWebEnginePermission::Unsupported);
QString httpAcceptLanguageWithoutQualities() const;
QString httpAcceptLanguage() const;
@@ -191,6 +186,7 @@ public:
void setClientHintsEnabled(bool enabled);
void resetClientHints();
+
void clearHttpCache();
#if QT_CONFIG(ssl)
@@ -235,6 +231,7 @@ private:
HttpCacheType m_httpCacheType;
QString m_httpAcceptLanguage;
PersistentCookiesPolicy m_persistentCookiesPolicy;
+ PersistentPermissionsPolicy m_persistentPermissionsPolicy;
VisitedLinksPolicy m_visitedLinksPolicy;
QHash<QByteArray, QPointer<QWebEngineUrlSchemeHandler>> m_customUrlSchemeHandlers;
QHash<QByteArray, QWeakPointer<UserNotificationController>> m_ephemeralNotifications;
diff --git a/src/core/profile_io_data_qt.cpp b/src/core/profile_io_data_qt.cpp
index 859aff8d4..31a85a534 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 0d032e4dc..a871307d7 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 @@ public:
virtual ~ProfileIODataQt();
QPointer<ProfileAdapter> profileAdapter();
- content::ResourceContext *resourceContext();
#if BUILDFLAG(ENABLE_EXTENSIONS)
extensions::ExtensionSystemQt* GetExtensionSystem();
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
@@ -104,7 +99,6 @@ private:
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 293e8d557..c54e8485b 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();
@@ -181,7 +176,7 @@ content::BrowsingDataRemoverDelegate *ProfileQt::GetBrowsingDataRemoverDelegate(
content::PermissionControllerDelegate *ProfileQt::GetPermissionControllerDelegate()
{
if (!m_permissionManager)
- m_permissionManager.reset(new PermissionManagerQt());
+ setupPermissionsManager();
return m_permissionManager.get();
}
@@ -260,6 +255,11 @@ void ProfileQt::setupPrefService()
#endif
}
+void ProfileQt::setupPermissionsManager()
+{
+ m_permissionManager.reset(new PermissionManagerQt(profileAdapter()));
+}
+
PrefServiceAdapter &ProfileQt::prefServiceAdapter()
{
return m_prefServiceAdapter;
diff --git a/src/core/profile_qt.h b/src/core/profile_qt.h
index b5cd08db1..a267efbc9 100644
--- a/src/core/profile_qt.h
+++ b/src/core/profile_qt.h
@@ -40,7 +40,6 @@ public:
base::FilePath GetPath() override;
bool IsOffTheRecord() override;
- content::ResourceContext *GetResourceContext() override;
content::DownloadManagerDelegate *GetDownloadManagerDelegate() override;
content::BrowserPluginGuestManager *GetGuestManager() override;
storage::SpecialStoragePolicy *GetSpecialStoragePolicy() override;
@@ -77,6 +76,7 @@ public:
// Build/Re-build the preference service. Call when updating the storage
// data path.
void setupPrefService();
+ void setupPermissionsManager();
PrefServiceAdapter &prefServiceAdapter();
const PrefServiceAdapter &prefServiceAdapter() const;
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 888043fda..98d0471c1 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(
@@ -298,6 +300,12 @@ content::WebContentsAccessibility *RenderWidgetHostViewQt::GetWebContentsAccessi
return m_webContentsAccessibility.get();
}
+void RenderWidgetHostViewQt::OnRendererWidgetCreated()
+{
+ if (m_adapterClient)
+ SetBackgroundColor(toSk(m_adapterClient->backgroundColor()));
+}
+
QObject *WebContentsAccessibilityQt::accessibilityParentObject() const
{
return m_rwhv->m_adapterClient->accessibilityParentObject();
@@ -910,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 a55e04dd8..49c1125fc 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -95,8 +95,7 @@ public:
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);
@@ -137,6 +136,7 @@ public:
void RequestSuccessfulPresentationTimeFromHostOrDelegate(blink::mojom::RecordContentToVisibleTimeRequestPtr) override {}
void CancelSuccessfulPresentationTimeRequestForHostAndDelegate() override {}
void InvalidateLocalSurfaceIdAndAllocationGroup() override {}
+ void OnRendererWidgetCreated() override;
// Overridden from ui::GestureProviderClient.
void OnGestureEvent(const ui::GestureEventData& gesture) override;
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp
index cc127e55f..0622fc27e 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,22 +188,24 @@ 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());
#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);
-
- new autofill::AutofillAgent(render_frame, password_autofill_agent, password_generation_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,
+ { 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,
@@ -303,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)
@@ -355,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 b2231f00a..8151c9710 100644
--- a/src/core/renderer/content_renderer_client_qt.h
+++ b/src/core/renderer/content_renderer_client_qt.h
@@ -66,7 +66,7 @@ public:
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 3e3c159f5..c78f53d8a 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 415d0b6b7..f843c61ee 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 @@ public:
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 b36ed9e8b..9db6bbe36 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()));
@@ -149,7 +152,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 a61e53310..2e4eea771 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 ec108519f..6807f5091 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 @@ public:
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/renderer/plugins/loadable_plugin_placeholder_qt.cpp b/src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp
index 06fd4f71f..4d25be12a 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 e6489eefb..03fb0d9e8 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 8cab3bd9a..c3a1dd8ba 100644
--- a/src/core/renderer/render_frame_observer_qt.h
+++ b/src/core/renderer/render_frame_observer_qt.h
@@ -34,7 +34,7 @@ public:
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 eff304981..82579ea7d 100644
--- a/src/core/renderer/user_resource_controller.cpp
+++ b/src/core/renderer/user_resource_controller.cpp
@@ -110,7 +110,7 @@ private:
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 5e8a1de14..fcc11bdcb 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/type_conversion.h b/src/core/type_conversion.h
index 0da8a6931..688ea014d 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 7ffeaaa5b..e73eca7f3 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -174,19 +174,16 @@ static QVariant fromJSValue(const base::Value *result)
return ret;
}
-static void callbackOnEvaluateJS(WebContentsAdapterClient *adapterClient, quint64 requestId, base::Value result)
+static void callbackOnEvaluateJS(WebContentsAdapter *adapter, quint64 requestId, base::Value result)
{
- if (requestId)
- adapterClient->didRunJavaScript(requestId, fromJSValue(&result));
+ adapter->didRunJavaScript(requestId, result);
}
#if QT_CONFIG(webengine_printing_and_pdf)
-static void callbackOnPrintingFinished(WebContentsAdapterClient *adapterClient,
- int requestId,
+static void callbackOnPrintingFinished(WebContentsAdapter *adapter, quint64 requestId,
QSharedPointer<QByteArray> result)
{
- if (requestId)
- adapterClient->didPrintPage(requestId, result);
+ adapter->didPrintPage(requestId, result);
}
static void callbackOnPdfSavingFinished(WebContentsAdapterClient *adapterClient,
@@ -993,6 +990,9 @@ void WebContentsAdapter::setZoomFactor(qreal factor)
const content::GlobalRenderFrameHostId global_id = m_webContents->GetPrimaryMainFrame()->GetGlobalId();
zoomMap->SetTemporaryZoomLevel(global_id, zoomLevel);
}
+
+ if (m_adapterClient)
+ m_adapterClient->zoomFactorChanged(currentZoomFactor());
}
qreal WebContentsAdapter::currentZoomFactor() const
@@ -1039,36 +1039,67 @@ QAccessibleInterface *WebContentsAdapter::browserAccessible()
}
#endif // QT_CONFIG(accessibility)
-void WebContentsAdapter::runJavaScript(const QString &javaScript, quint32 worldId)
+content::RenderFrameHost *WebContentsAdapter::renderFrameHostFromFrameId(quint64 frameId) const
{
- CHECK_INITIALIZED();
- content::RenderFrameHost *rfh = m_webContents->GetPrimaryMainFrame();
- Q_ASSERT(rfh);
- if (!static_cast<content::RenderFrameHostImpl*>(rfh)->GetAssociatedLocalFrame()) {
- qWarning() << "Local frame is gone, not running script";
- return;
+ content::RenderFrameHost *result;
+ if (frameId == kUseMainFrameId) {
+ result = m_webContents->GetPrimaryMainFrame();
+ } else {
+ auto *ftn = content::FrameTreeNode::GloballyFindByID(static_cast<int>(frameId));
+ if (!ftn)
+ return nullptr;
+
+ result = ftn->current_frame_host();
}
- if (worldId == 0)
- rfh->ExecuteJavaScript(toString16(javaScript), base::NullCallback());
- else
- rfh->ExecuteJavaScriptInIsolatedWorld(toString16(javaScript), base::NullCallback(), worldId);
+ Q_ASSERT(result);
+ return result;
}
-quint64 WebContentsAdapter::runJavaScriptCallbackResult(const QString &javaScript, quint32 worldId)
+void WebContentsAdapter::runJavaScript(const QString &javaScript, quint32 worldId, quint64 frameId,
+ const std::function<void(const QVariant &)> &callback)
{
- CHECK_INITIALIZED(0);
- content::RenderFrameHost *rfh = m_webContents->GetPrimaryMainFrame();
- Q_ASSERT(rfh);
+ auto exit = [&] {
+ if (callback)
+ callback(QVariant());
+ };
+
+ if (!isInitialized())
+ return exit();
+ auto *rfh = renderFrameHostFromFrameId(frameId);
+ if (!rfh)
+ return exit();
if (!static_cast<content::RenderFrameHostImpl*>(rfh)->GetAssociatedLocalFrame()) {
qWarning() << "Local frame is gone, not running script";
- return 0;
+ return exit();
+ }
+
+ content::RenderFrameHost::JavaScriptResultCallback internalCallback = base::NullCallback();
+ if (callback) {
+ internalCallback = base::BindOnce(&callbackOnEvaluateJS, this, m_nextRequestId);
+ m_javaScriptCallbacks.insert(m_nextRequestId, callback);
+ ++m_nextRequestId;
}
- content::RenderFrameHost::JavaScriptResultCallback callback = base::BindOnce(&callbackOnEvaluateJS, m_adapterClient, m_nextRequestId);
if (worldId == 0)
- rfh->ExecuteJavaScript(toString16(javaScript), std::move(callback));
+ rfh->ExecuteJavaScript(toString16(javaScript), std::move(internalCallback));
else
- rfh->ExecuteJavaScriptInIsolatedWorld(toString16(javaScript), std::move(callback), worldId);
- return m_nextRequestId++;
+ rfh->ExecuteJavaScriptInIsolatedWorld(toString16(javaScript), std::move(internalCallback),
+ worldId);
+}
+
+void WebContentsAdapter::didRunJavaScript(quint64 requestId, const base::Value &result)
+{
+ Q_ASSERT(requestId);
+ auto callback = m_javaScriptCallbacks.take(requestId);
+ Q_ASSERT(callback);
+ callback(fromJSValue(&result));
+}
+
+// Called when QWebEnginePage is deleted
+void WebContentsAdapter::clearJavaScriptCallbacks()
+{
+ for (auto varFun : std::as_const(m_javaScriptCallbacks))
+ varFun(QVariant());
+ m_javaScriptCallbacks.clear();
}
quint64 WebContentsAdapter::fetchDocumentMarkup()
@@ -1315,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();
@@ -1325,40 +1357,44 @@ 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)
}
-quint64 WebContentsAdapter::printToPDFCallbackResult(const QPageLayout &pageLayout,
- const QPageRanges &pageRanges,
- bool colorMode,
- bool useCustomMargins)
+void WebContentsAdapter::printToPDFCallbackResult(
+ std::function<void(QSharedPointer<QByteArray>)> &&callback, const QPageLayout &pageLayout,
+ const QPageRanges &pageRanges, bool colorMode, bool useCustomMargins, quint64 frameId)
{
#if QT_CONFIG(webengine_printing_and_pdf)
- CHECK_INITIALIZED(0);
- PrintViewManagerQt::PrintToPDFCallback callback = base::BindOnce(&callbackOnPrintingFinished,
- m_adapterClient,
- m_nextRequestId);
+ CHECK_INITIALIZED();
+ Q_ASSERT(callback);
+ PrintViewManagerQt::PrintToPDFCallback internalCallback =
+ base::BindOnce(&callbackOnPrintingFinished, this, m_nextRequestId);
content::WebContents *webContents = m_webContents.get();
if (content::WebContents *guest = guestWebContents())
webContents = guest;
- PrintViewManagerQt::FromWebContents(webContents)->PrintToPDFWithCallback(pageLayout,
- pageRanges,
- colorMode,
- useCustomMargins,
- std::move(callback));
- return m_nextRequestId++;
+ PrintViewManagerQt::FromWebContents(webContents)
+ ->PrintToPDFWithCallback(pageLayout, pageRanges, colorMode, useCustomMargins, frameId,
+ std::move(internalCallback));
+ m_printCallbacks.emplace(m_nextRequestId++, std::move(callback));
#else
Q_UNUSED(pageLayout);
Q_UNUSED(colorMode);
- return 0;
#endif // QT_CONFIG(webengine_printing_and_pdf)
}
+void WebContentsAdapter::didPrintPage(quint64 requestId, QSharedPointer<QByteArray> result)
+{
+ Q_ASSERT(requestId);
+ auto mapIt = m_printCallbacks.find(requestId);
+ Q_ASSERT(mapIt != m_printCallbacks.end());
+ Q_ASSERT(mapIt->second);
+ mapIt->second(std::move(result));
+ m_printCallbacks.erase(mapIt);
+}
+
QPointF WebContentsAdapter::lastScrollOffset() const
{
CHECK_INITIALIZED(QPointF());
@@ -1375,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)
@@ -1629,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();
}
}
@@ -1812,6 +1923,80 @@ void WebContentsAdapter::changeTextDirection(bool leftToRight)
}
}
+quint64 WebContentsAdapter::mainFrameId() const
+{
+ CHECK_INITIALIZED(content::RenderFrameHost::kNoFrameTreeNodeId);
+ return static_cast<quint64>(m_webContents->GetPrimaryMainFrame()->GetFrameTreeNodeId());
+}
+
+#define CHECK_INITIALIZED_AND_VALID_FRAME(webengine_frame_id_variable, frame_tree_node_variable, \
+ return_value) \
+ CHECK_INITIALIZED(return_value); \
+ if (webengine_frame_id_variable == kInvalidFrameId) \
+ return return_value; \
+ auto *frame_tree_node_variable = content::FrameTreeNode::GloballyFindByID( \
+ static_cast<int>(webengine_frame_id_variable)); \
+ if (!frame_tree_node_variable) \
+ return return_value
+
+QString WebContentsAdapter::frameName(quint64 id) const
+{
+ CHECK_INITIALIZED_AND_VALID_FRAME(id, ftn, QString());
+ return QString::fromStdString(ftn->frame_name());
+}
+
+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("");
+}
+
+QList<quint64> WebContentsAdapter::frameChildren(quint64 id) const
+{
+ CHECK_INITIALIZED_AND_VALID_FRAME(id, ftn, {});
+ QList<quint64> result;
+ size_t numChildren = ftn->child_count();
+ result.reserve(numChildren);
+ for (size_t i = 0; i < numChildren; ++i) {
+ result.push_back(ftn->child_at(i)->frame_tree_node_id());
+ }
+ return result;
+}
+
+QUrl WebContentsAdapter::frameUrl(quint64 id) const
+{
+ CHECK_INITIALIZED_AND_VALID_FRAME(id, ftn, QUrl());
+ return toQt(ftn->current_url());
+}
+
+QSizeF WebContentsAdapter::frameSize(quint64 id) const
+{
+ CHECK_INITIALIZED_AND_VALID_FRAME(id, ftn, QSizeF());
+ auto *rfh = ftn->current_frame_host();
+ Q_ASSERT(rfh);
+ auto maybeSize = rfh->GetFrameSize();
+ return maybeSize ? toQt(*maybeSize) : QSizeF();
+}
+
+std::optional<quint64> WebContentsAdapter::findFrameIdByName(const QString &name) const
+{
+ CHECK_INITIALIZED({});
+ auto *ftn = content::FrameTreeNode::From(m_webContents->GetPrimaryMainFrame());
+ Q_ASSERT(ftn);
+ if (auto *foundFtn = ftn->frame_tree().FindByName(name.toStdString()))
+ return foundFtn->frame_tree_node_id();
+ return {};
+}
+
+bool WebContentsAdapter::hasFrame(quint64 id) const
+{
+ CHECK_INITIALIZED_AND_VALID_FRAME(id, ftn, false);
+ auto *rfh = ftn->current_frame_host();
+ Q_ASSERT(rfh);
+ return content::WebContents::FromRenderFrameHost(rfh) == m_webContents.get();
+}
+
WebContentsAdapterClient::RenderProcessTerminationStatus
WebContentsAdapterClient::renderProcessExitStatus(int terminationStatus) {
auto status = WebContentsAdapterClient::RenderProcessTerminationStatus(-1);
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 62c3f087c..66736dd21 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -16,17 +16,23 @@
#define WEB_CONTENTS_ADAPTER_H
#include <QtCore/QSharedPointer>
+#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QUrl>
+#include <QtCore/QVariant>
#include <QtCore/QPointer>
#include <QtGui/qtgui-config.h>
#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
#include <QtWebEngineCore/qwebenginecontextmenurequest.h>
#include <QtWebEngineCore/qwebenginehttprequest.h>
+#include <QtWebEngineCore/qwebengineframe.h>
+#include <QtWebEngineCore/qwebenginepermission.h>
#include "web_contents_adapter_client.h"
+#include <functional>
#include <memory>
+#include <optional>
namespace blink {
namespace web_pref {
@@ -34,9 +40,14 @@ struct WebPreferences;
}
}
+namespace base {
+class Value;
+}
+
namespace content {
class WebContents;
class SiteInstance;
+class RenderFrameHost;
}
QT_BEGIN_NAMESPACE
@@ -62,6 +73,11 @@ class WebChannelIPCTransportHost;
class Q_WEBENGINECORE_EXPORT WebContentsAdapter : public QEnableSharedFromThis<WebContentsAdapter> {
public:
+ // Sentinel to indicate that a behavior should happen on the main frame
+ static constexpr quint64 kUseMainFrameId = -2;
+ // Sentinel to indicate a frame doesn't exist, for example with `findFrameByName`
+ static constexpr quint64 kInvalidFrameId = -3;
+
static QSharedPointer<WebContentsAdapter> createFromSerializedNavigationHistory(QDataStream &input, WebContentsAdapterClient *adapterClient);
WebContentsAdapter();
WebContentsAdapter(std::unique_ptr<content::WebContents> webContents);
@@ -124,8 +140,10 @@ public:
void serializeNavigationHistory(QDataStream &output);
void setZoomFactor(qreal);
qreal currentZoomFactor() const;
- void runJavaScript(const QString &javaScript, quint32 worldId);
- quint64 runJavaScriptCallbackResult(const QString &javaScript, quint32 worldId);
+ void runJavaScript(const QString &javaScript, quint32 worldId, quint64 frameId,
+ const std::function<void(const QVariant &)> &callback);
+ void didRunJavaScript(quint64 requestId, const base::Value &result);
+ void clearJavaScriptCallbacks();
quint64 fetchDocumentMarkup();
quint64 fetchDocumentInnerText();
void updateWebPreferences(const blink::web_pref::WebPreferences &webPreferences);
@@ -161,10 +179,12 @@ public:
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();
@@ -189,10 +209,11 @@ public:
void endDragging(QDropEvent *e, const QPointF &screenPos);
void leaveDrag();
#endif // QT_CONFIG(draganddrop)
- void printToPDF(const QPageLayout&, const QPageRanges &, const QString&);
- quint64 printToPDFCallbackResult(const QPageLayout &, const QPageRanges &,
- bool colorMode = true,
- bool useCustomMargins = true);
+ void printToPDF(const QPageLayout &, const QPageRanges &, const QString &, quint64 frameId);
+ void printToPDFCallbackResult(std::function<void(QSharedPointer<QByteArray>)> &&,
+ const QPageLayout &, const QPageRanges &, bool colorMode,
+ bool useCustomMargins, quint64 frameId);
+ void didPrintPage(quint64 requestId, QSharedPointer<QByteArray> result);
void replaceMisspelling(const QString &word);
void viewSource();
@@ -204,6 +225,15 @@ public:
void resetTouchSelectionController();
void changeTextDirection(bool leftToRight);
+ quint64 mainFrameId() const;
+ QString frameName(quint64 id) const;
+ QString frameHtmlName(quint64 id) const;
+ QList<quint64> frameChildren(quint64 id) const;
+ QUrl frameUrl(quint64 id) const;
+ QSizeF frameSize(quint64 id) const;
+ std::optional<quint64> findFrameIdByName(const QString &name) const;
+ bool hasFrame(quint64 id) const;
+
// meant to be used within WebEngineCore only
void initialize(content::SiteInstance *site);
content::WebContents *webContents() const;
@@ -216,6 +246,7 @@ private:
Q_DISABLE_COPY(WebContentsAdapter)
void waitForUpdateDragActionCalled();
bool handleDropDataFileContents(const content::DropData &dropData, QMimeData *mimeData);
+ content::RenderFrameHost *renderFrameHostFromFrameId(quint64 frameId) const;
void wasShown();
void wasHidden();
@@ -241,6 +272,8 @@ private:
WebContentsAdapterClient *m_adapterClient;
quint64 m_nextRequestId;
QMap<QUrl, bool> m_pendingMouseLockPermissions;
+ QMap<quint64, std::function<void(const QVariant &)>> m_javaScriptCallbacks;
+ std::map<quint64, std::function<void(QSharedPointer<QByteArray>)>> m_printCallbacks;
std::unique_ptr<content::DropData> m_currentDropData;
uint m_currentDropAction;
bool m_updateDragActionCalled;
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index a1ad301ed..ca162833c 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"
@@ -26,6 +27,8 @@
#include <QUrl>
QT_FORWARD_DECLARE_CLASS(QKeyEvent)
+QT_FORWARD_DECLARE_CLASS(QPageLayout)
+QT_FORWARD_DECLARE_CLASS(QPageRanges)
QT_FORWARD_DECLARE_CLASS(QVariant)
QT_FORWARD_DECLARE_CLASS(QWebEngineFileSystemAccessRequest)
QT_FORWARD_DECLARE_CLASS(QWebEngineFindTextResult)
@@ -147,6 +150,7 @@ public:
virtual void titleChanged(const QString&) = 0;
virtual void urlChanged() = 0;
virtual void iconChanged(const QUrl&) = 0;
+ virtual void zoomFactorChanged(qreal factor) = 0;
virtual void loadProgressChanged(int progress) = 0;
virtual void didUpdateTargetURL(const QUrl&) = 0;
virtual void selectionChanged() = 0;
@@ -175,10 +179,15 @@ public:
virtual void javascriptDialog(QSharedPointer<JavaScriptDialogController>) = 0;
virtual void runFileChooser(QSharedPointer<FilePickerController>) = 0;
virtual void showColorDialog(QSharedPointer<ColorChooserController>) = 0;
- virtual void didRunJavaScript(quint64 requestId, const QVariant& result) = 0;
+ virtual void runJavaScript(const QString &script, quint32 worldId, quint64 frameId,
+ const std::function<void(const QVariant &)> &callback) = 0;
virtual void didFetchDocumentMarkup(quint64 requestId, const QString& result) = 0;
virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) = 0;
- virtual void didPrintPage(quint64 requestId, QSharedPointer<QByteArray>) = 0;
+ virtual void printToPdf(const QString &filePath, const QPageLayout &layout,
+ const QPageRanges &ranges, quint64 frameId) = 0;
+ virtual void printToPdf(std::function<void(QSharedPointer<QByteArray>)> &&callback,
+ 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
@@ -186,7 +195,7 @@ public:
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;
@@ -207,6 +216,7 @@ public:
virtual void setToolTip(const QString& toolTipText) = 0;
virtual ClientType clientType() = 0;
virtual void printRequested() = 0;
+ virtual void printRequestedByFrame(quint64 frameId) = 0;
virtual TouchHandleDrawableDelegate * createTouchHandleDelegate(const QMap<int, QImage> &images) = 0;
virtual void showTouchSelectionMenu(TouchSelectionMenuController *menuController, const QRect &bounds, const QSize &handleSize) = 0;
virtual void hideTouchSelectionMenu() = 0;
@@ -219,6 +229,7 @@ public:
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 4df73fb69..c2cd6981a 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());
@@ -733,7 +741,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);
}
@@ -786,13 +794,15 @@ 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:
- 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 51004878d..899d46cd0 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -106,7 +106,9 @@ public:
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;
@@ -132,11 +134,12 @@ public:
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> &);
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/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp
index 023f9e99f..50d964de7 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 8754250e6..78041a150 100644
--- a/src/core/web_contents_view_qt.h
+++ b/src/core/web_contents_view_qt.h
@@ -80,13 +80,17 @@ public:
#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 94110d51c..50821fa98 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -3,6 +3,7 @@
#include "web_engine_context.h"
+#include <map>
#include <math.h>
#include <QtGui/private/qrhi_p.h>
@@ -10,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"
@@ -105,10 +107,6 @@
#include <QGuiApplication>
#include <QMutex>
#include <QOffscreenSurface>
-#if QT_CONFIG(opengl)
-#include <QOpenGLContext>
-#include <qopenglcontext_platform.h>
-#endif
#include <QQuickWindow>
#include <QRegularExpression>
#include <QStringList>
@@ -120,6 +118,9 @@
#include <QLoggingCategory>
#if QT_CONFIG(opengl)
+#include <QOpenGLContext>
+#include <qopenglcontext_platform.h>
+
QT_BEGIN_NAMESPACE
Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
QT_END_NAMESPACE
@@ -132,6 +133,189 @@ namespace QtWebEngineCore {
Q_LOGGING_CATEGORY(webEngineContextLog, "qt.webenginecontext")
+class GPUInfo
+{
+public:
+ enum Vendor {
+ Unknown = -1,
+ AMD,
+ Apple,
+ ARM,
+ Google,
+ ImgTec,
+ Intel,
+ Microsoft,
+ Mesa,
+ Nvidia,
+ Qualcomm,
+ Samsung
+ };
+
+ static GPUInfo *instance()
+ {
+ static GPUInfo instance;
+ return &instance;
+ }
+
+ static Vendor vendorIdToVendor(quint64 vendorId)
+ {
+ // clang-format off
+ // Based on //third_party/dawn/src/dawn/gpu_info.json
+ static const std::map<quint64, Vendor> vendorIdMap = {
+ {0x0, Unknown},
+ {0x1002, AMD},
+ {0x106B, Apple},
+ {0x13B5, ARM},
+ {0x1AE0, Google},
+ {0x1010, ImgTec},
+ {0x8086, Intel},
+ {0x10005, Mesa},
+ {0x1414, Microsoft},
+ {0x10DE, Nvidia},
+ {0x5143, Qualcomm},
+ {0x144D, Samsung}
+ };
+ // clang-format on
+
+ auto it = vendorIdMap.find(vendorId);
+ if (it != vendorIdMap.end())
+ return it->second;
+
+ qWarning() << "Unknown Vendor ID:" << QString("0x%1").arg(vendorId, 0, 16);
+ return Unknown;
+ }
+
+ static Vendor deviceNameToVendor(QString deviceName)
+ {
+ // TODO: Test and add more vendors to the list.
+ if (deviceName.contains(QLatin1String("AMD"), Qt::CaseInsensitive))
+ return AMD;
+ if (deviceName.contains(QLatin1String("Intel"), Qt::CaseInsensitive))
+ return Intel;
+ if (deviceName.contains(QLatin1String("Nvidia"), Qt::CaseInsensitive))
+ return Nvidia;
+
+#if defined(USE_OZONE)
+ if (deviceName.contains(QLatin1String("Mesa llvmpipe")))
+ return Mesa;
+#endif
+
+#if defined(Q_OS_MACOS)
+ if (deviceName.contains(QLatin1String("Apple")))
+ return Apple;
+#endif
+
+ return Unknown;
+ }
+
+ static std::string vendorToString(Vendor vendor)
+ {
+ // clang-format off
+ static const std::map<Vendor, std::string> vendorNameMap = {
+ {Unknown, "Unknown"},
+ {AMD, "AMD"},
+ {Apple, "Apple"},
+ {ARM, "ARM"},
+ {Google, "Google"},
+ {ImgTec, "Img Tec"},
+ {Intel, "Intel"},
+ {Mesa, "Mesa"},
+ {Microsoft, "Microsoft"},
+ {Nvidia, "Nvidia"},
+ {Qualcomm, "Qualcomm"},
+ {Samsung, "Samsung"}
+ };
+ // clang-format on
+
+ auto it = vendorNameMap.find(vendor);
+ if (it != vendorNameMap.end())
+ return it->second;
+
+ Q_UNREACHABLE();
+ return "Unknown";
+ }
+
+ Vendor vendor() const { return m_vendor; }
+ QString getAdapterLuid() const { return m_adapterLuid; }
+
+private:
+ GPUInfo()
+ {
+#if defined(Q_OS_WIN)
+ {
+ static const bool preferSoftwareDevice =
+ qEnvironmentVariableIntValue("QSG_RHI_PREFER_SOFTWARE_RENDERER");
+ QRhiD3D11InitParams params;
+ QRhi::Flags flags;
+ if (preferSoftwareDevice) {
+ flags |= QRhi::PreferSoftwareRenderer;
+ }
+ QScopedPointer<QRhi> d3d11Rhi(QRhi::create(QRhi::D3D11, &params, flags, nullptr));
+ // mimic what QSGRhiSupport and QBackingStoreRhi does
+ if (!d3d11Rhi && !preferSoftwareDevice) {
+ flags |= QRhi::PreferSoftwareRenderer;
+ d3d11Rhi.reset(QRhi::create(QRhi::D3D11, &params, flags, nullptr));
+ }
+ if (d3d11Rhi) {
+ m_vendor = vendorIdToVendor(d3d11Rhi->driverInfo().vendorId);
+
+ const QRhiD3D11NativeHandles *handles =
+ static_cast<const QRhiD3D11NativeHandles *>(d3d11Rhi->nativeHandles());
+ Q_ASSERT(handles);
+ m_adapterLuid =
+ QString("%1,%2").arg(handles->adapterLuidHigh).arg(handles->adapterLuidLow);
+ }
+ }
+#elif defined(Q_OS_MACOS)
+ {
+ QRhiMetalInitParams params;
+ QScopedPointer<QRhi> metalRhi(
+ QRhi::create(QRhi::Metal, &params, QRhi::Flags(), nullptr));
+ if (metalRhi)
+ m_vendor = deviceNameToVendor(metalRhi->driverInfo().deviceName);
+ }
+#endif
+
+#if QT_CONFIG(opengl)
+ if (m_vendor == Unknown) {
+ QRhiGles2InitParams params;
+ params.fallbackSurface = QRhiGles2InitParams::newFallbackSurface();
+ QScopedPointer<QRhi> glRhi(
+ QRhi::create(QRhi::OpenGLES2, &params, QRhi::Flags(), nullptr));
+ if (glRhi)
+ m_vendor = deviceNameToVendor(glRhi->driverInfo().deviceName);
+ }
+#endif
+
+#if QT_CONFIG(webengine_vulkan)
+ if (m_vendor == Unknown) {
+ QVulkanInstance vulkanInstance;
+ vulkanInstance.setApiVersion(QVersionNumber(1, 1));
+ if (vulkanInstance.create()) {
+ QRhiVulkanInitParams params;
+ params.inst = &vulkanInstance;
+ QScopedPointer<QRhi> vulkanRhi(
+ QRhi::create(QRhi::Vulkan, &params, QRhi::Flags(), nullptr));
+ if (vulkanRhi) {
+ // TODO: The primary GPU is not necessarily the one which is connected to the
+ // display in case of a Multi-GPU setup on Linux. This can be workarounded by
+ // installing the Mesa's Device Selection Layer,
+ // see https://www.phoronix.com/news/Mesa-20.1-Vulkan-Dev-Selection
+ // Try to detect this case and at least warn about it.
+ m_vendor = vendorIdToVendor(vulkanRhi->driverInfo().vendorId);
+ }
+ }
+ }
+#endif
+
+ if (m_vendor == Unknown)
+ qWarning("Unable to detect GPU vendor.");
+ }
+
+ Vendor m_vendor = Unknown;
+ QString m_adapterLuid;
+};
+
static bool usingSupportedSGBackend()
{
if (QQuickWindow::graphicsApi() != QSGRendererInterface::OpenGL
@@ -280,47 +464,6 @@ static std::string getAngleType(const std::string &glType, base::CommandLine *cm
return "disabled";
}
-static quint64 getGPUVendorId()
-{
-#if QT_CONFIG(webengine_vulkan)
- QVulkanInstance vulkanInstance;
- vulkanInstance.setApiVersion(QVersionNumber(1, 1));
- if (vulkanInstance.create()) {
- QRhiVulkanInitParams params;
- params.inst = &vulkanInstance;
- QScopedPointer<QRhi> rhi(QRhi::create(QRhi::Vulkan, &params, QRhi::Flags(), nullptr));
- return rhi->driverInfo().vendorId;
- }
-#endif
-
- return 0;
-}
-
-#if defined(Q_OS_WIN)
-static QString getAdapterLuid() {
- static const bool preferSoftwareDevice = qEnvironmentVariableIntValue("QSG_RHI_PREFER_SOFTWARE_RENDERER");
- QRhiD3D11InitParams rhiParams;
- QRhi::Flags flags;
- if (preferSoftwareDevice) {
- flags |= QRhi::PreferSoftwareRenderer;
- }
- QScopedPointer<QRhi> rhi(QRhi::create(QRhi::D3D11,&rhiParams,flags,nullptr));
- // mimic what QSGRhiSupport and QBackingStoreRhi does
- if (!rhi && !preferSoftwareDevice) {
- flags |= QRhi::PreferSoftwareRenderer;
- rhi.reset(QRhi::create(QRhi::D3D11, &rhiParams, flags));
- }
- if (rhi) {
- const QRhiD3D11NativeHandles *handles =
- static_cast<const QRhiD3D11NativeHandles *>(rhi->nativeHandles());
- Q_ASSERT(handles);
- return QString("%1,%2").arg(handles->adapterLuidHigh).arg(handles->adapterLuidLow);
- } else {
- return QString();
- }
-}
-#endif
-
#if QT_CONFIG(webengine_pepper_plugins)
void dummyGetPluginCallback(const std::vector<content::WebPluginInfo>&)
{
@@ -340,34 +483,7 @@ static void logContext(const std::string &glType, base::CommandLine *cmd)
log << "QSG RHI Backend:" << QSGRhiSupport::instance()->rhiBackendName() << "\n";
log << "QSG RHI Backend Supported:" << (usingSupportedSGBackend() ? "yes" : "no") << "\n";
- log << "GPU Vendor:";
- if (quint64 vendorId = getGPUVendorId()) {
- switch (vendorId) {
- case 0x1002:
- log << "AMD";
- break;
- case 0x10DE:
- log << "NVIDIA";
- break;
- case 0x8086:
- log << "Intel";
- break;
- case 0x1010:
- log << "ImgTec";
- break;
- case 0x13B5:
- log << "ARM";
- break;
- case 0x5143:
- log << "Qualcomm";
- break;
- default:
- break;
- }
- log << QString("(0x%1)\n").arg(vendorId, 0, 16);
- } else {
- log << "Unable to detect\n";
- }
+ log << "GPU Vendor:" << GPUInfo::vendorToString(GPUInfo::instance()->vendor()).c_str();
log << "\n";
#if QT_CONFIG(opengl)
@@ -721,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()
@@ -787,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);
@@ -811,7 +924,13 @@ WebEngineContext::WebEngineContext()
parsedCommandLine->AppendSwitch(cc::switches::kDisableCompositedAntialiasing);
}
-#if QT_CONFIG(webengine_vulkan) && defined(USE_OZONE)
+#if defined(USE_OZONE)
+ if (GPUInfo::instance()->vendor() == GPUInfo::Nvidia) {
+ disableFeatures.push_back(media::kVaapiVideoDecodeLinux.name);
+ parsedCommandLine->AppendSwitch(switches::kDisableGpuMemoryBufferVideoFrames);
+ }
+
+#if QT_CONFIG(webengine_vulkan)
if (QQuickWindow::graphicsApi() == QSGRendererInterface::Vulkan) {
enableFeatures.push_back(features::kVulkan.name);
parsedCommandLine->AppendSwitchASCII(switches::kUseVulkan,
@@ -838,16 +957,21 @@ WebEngineContext::WebEngineContext()
qputenv(deviceExtensionsVar, requiredDeviceExtensions.join(';'));
}
}
-#endif // QT_CONFIG(webengine_vulkan) && defined(USE_OZONE)
+#endif // QT_CONFIG(webengine_vulkan)
+#endif // defined(USE_OZONE)
#if defined(Q_OS_WIN)
if (QQuickWindow::graphicsApi() == QSGRendererInterface::Direct3D11
|| QQuickWindow::graphicsApi() == QSGRendererInterface::Vulkan) {
- const QString luid = getAdapterLuid();
+ const QString luid = GPUInfo::instance()->getAdapterLuid();
if (!luid.isEmpty())
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 50b080db1..faed58661 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 @@ private:
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
diff --git a/src/pdf/CMakeLists.txt b/src/pdf/CMakeLists.txt
index 4a54b816e..41018e7da 100644
--- a/src/pdf/CMakeLists.txt
+++ b/src/pdf/CMakeLists.txt
@@ -38,7 +38,6 @@ qt_internal_add_module(Pdf
PUBLIC_LIBRARIES
Qt::Core
Qt::Gui
- GENERATE_CPP_EXPORTS
)
add_subdirectory(plugins/imageformats/pdf)
diff --git a/src/pdf/doc/snippets/pdfpageview.qml b/src/pdf/doc/snippets/pdfpageview.qml
new file mode 100644
index 000000000..5e233961a
--- /dev/null
+++ b/src/pdf/doc/snippets/pdfpageview.qml
@@ -0,0 +1,12 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [0]
+import QtQuick
+import QtQuick.Pdf
+
+PdfPageView {
+ document: PdfDocument { source: "my.pdf" }
+}
+//! [0]
+
diff --git a/src/pdfquick/PdfPageView.qml b/src/pdfquick/PdfPageView.qml
index 290570f2b..e1d97f57b 100644
--- a/src/pdfquick/PdfPageView.qml
+++ b/src/pdfquick/PdfPageView.qml
@@ -30,7 +30,7 @@ Rectangle {
A PdfDocument object with a valid \c source URL is required:
- \snippet multipageview.qml 0
+ \snippet pdfpageview.qml 0
*/
required property PdfDocument document
diff --git a/src/pdfquick/qquickpdfpageimage.cpp b/src/pdfquick/qquickpdfpageimage.cpp
index f2da067f1..9ff0337a5 100644
--- a/src/pdfquick/qquickpdfpageimage.cpp
+++ b/src/pdfquick/qquickpdfpageimage.cpp
@@ -42,7 +42,7 @@ QQuickPdfPageImage::~QQuickPdfPageImage()
{
Q_D(QQuickPdfPageImage);
// cancel any async rendering job that is running on my behalf
- d->pix.clear();
+ d->pendingPix->clear();
}
/*!
@@ -97,21 +97,23 @@ void QQuickPdfPageImage::load()
thisRequestFinished =
QQuickImageBase::staticMetaObject.indexOfSlot("requestFinished()");
}
+ static QMetaMethod requestFinishedSlot = staticMetaObject.method(thisRequestFinished);
- d->pix.loadImageFromDevice(qmlEngine(this), carrierFile, url,
+ d->pendingPix->loadImageFromDevice(qmlEngine(this), carrierFile, url,
d->sourceClipRect.toRect(), d->sourcesize * d->devicePixelRatio,
QQuickImageProviderOptions(), d->currentFrame, d->frameCount);
qCDebug(qLcImg) << "loading page" << d->currentFrame << "of" << d->frameCount
- << "from" << carrierFile->fileName() << "status" << d->pix.status();
+ << "from" << carrierFile->fileName() << "status" << d->pendingPix->status();
- switch (d->pix.status()) {
+ switch (d->pendingPix->status()) {
case QQuickPixmap::Ready:
+ requestFinishedSlot.invoke(this);
pixmapChange();
break;
case QQuickPixmap::Loading:
- d->pix.connectFinished(this, thisRequestFinished);
- d->pix.connectDownloadProgress(this, thisRequestProgress);
+ d->pendingPix->connectFinished(this, thisRequestFinished);
+ d->pendingPix->connectDownloadProgress(this, thisRequestProgress);
if (d->progress != 0.0) {
d->progress = 0.0;
emit progressChanged(d->progress);
@@ -122,7 +124,7 @@ void QQuickPdfPageImage::load()
}
break;
default:
- qCDebug(qLcImg) << "unexpected status" << d->pix.status();
+ qCDebug(qLcImg) << "unexpected status" << d->pendingPix->status();
break;
}
}
diff --git a/src/pdfwidgets/qpdfview.cpp b/src/pdfwidgets/qpdfview.cpp
index a67667fed..a19b77a7f 100644
--- a/src/pdfwidgets/qpdfview.cpp
+++ b/src/pdfwidgets/qpdfview.cpp
@@ -19,7 +19,7 @@
QT_BEGIN_NAMESPACE
-Q_LOGGING_CATEGORY(qLcLink, "qt.pdf.links")
+Q_LOGGING_CATEGORY(qLcWLink, "qt.pdf.widgets.links")
//#define DEBUG_LINKS
static const QColor SearchResultHighlight("#80B0C4DE");
@@ -681,7 +681,7 @@ void QPdfView::mouseMoveEvent(QMouseEvent *event)
auto dest = d->m_linkModel.linkAt(posInPoints);
setCursor(dest.isValid() ? Qt::PointingHandCursor : Qt::ArrowCursor);
if (dest.isValid())
- qCDebug(qLcLink) << event->position() << ":" << posInPoints << "pt ->" << dest;
+ qCDebug(qLcWLink) << event->position() << ":" << posInPoints << "pt ->" << dest;
}
}
}
@@ -699,7 +699,7 @@ void QPdfView::mouseReleaseEvent(QMouseEvent *event)
d->m_linkModel.setPage(page);
auto dest = d->m_linkModel.linkAt(posInPoints);
if (dest.isValid()) {
- qCDebug(qLcLink) << event << ": jumping to" << dest;
+ qCDebug(qLcWLink) << event << ": jumping to" << dest;
d->m_pageNavigator->jump(dest.page(), dest.location(), dest.zoom());
// TODO scroll and zoom to where the link tells us to
}
diff --git a/src/webenginequick/api/qquickwebenginefaviconprovider.cpp b/src/webenginequick/api/qquickwebenginefaviconprovider.cpp
index 56bbb97ac..00c7f1949 100644
--- a/src/webenginequick/api/qquickwebenginefaviconprovider.cpp
+++ b/src/webenginequick/api/qquickwebenginefaviconprovider.cpp
@@ -11,9 +11,9 @@
#include "web_contents_adapter.h"
#include <QtCore/qmimedatabase.h>
-#include <QtCore/qtimer.h>
#include <QtGui/qicon.h>
#include <QtGui/qpixmap.h>
+#include <QThread>
QT_BEGIN_NAMESPACE
@@ -79,123 +79,167 @@ static bool isIconURL(const QUrl &url)
return false;
}
-static QQuickWebEngineView *findViewById(const QString &id, QList<QQuickWebEngineView *> *views)
-{
- QQuickWebEngineView *result = nullptr;
- for (QQuickWebEngineView *view : *views) {
- if (isIconURL(QUrl(id))) {
- if (view->icon() == QQuickWebEngineFaviconProvider::faviconProviderUrl(QUrl(id))) {
- result = view;
- break;
- }
- } else if (view->url() == QUrl(id)) {
- result = view;
- break;
- }
- }
-
- return result;
-}
-
-FaviconImageResponseRunnable::FaviconImageResponseRunnable(const QString &id,
- const QSize &requestedSize,
- QList<QQuickWebEngineView *> *views)
- : m_id(id), m_requestedSize(requestedSize), m_views(views)
+FaviconImageRequester::FaviconImageRequester(const QUrl &imageSource, const QSize &requestedSize)
+ : m_imageSource(imageSource), m_requestedSize(requestedSize)
{
}
-void FaviconImageResponseRunnable::run()
+void FaviconImageRequester::start()
{
- if (tryNextView() == -1) {
+ if (!tryNextView()) {
// There is no non-otr view to access icon database.
Q_EMIT done(QPixmap());
}
}
-void FaviconImageResponseRunnable::iconRequestDone(const QIcon &icon)
+void FaviconImageRequester::iconRequestDone(const QIcon &icon)
{
if (icon.isNull()) {
- if (tryNextView() == -1) {
+ if (!tryNextView()) {
// Ran out of views.
Q_EMIT done(QPixmap());
}
return;
}
- Q_EMIT done(extractPixmap(icon, m_requestedSize).copy());
+ Q_EMIT done(extractPixmap(icon, m_requestedSize));
+}
+
+bool FaviconImageRequester::tryNextView()
+{
+ if (auto view = getNextViewForProcessing()) {
+ requestFaviconFromDatabase(view);
+ return true;
+ }
+
+ return false;
+}
+
+void FaviconImageRequester::requestFaviconFromDatabase(QPointer<QQuickWebEngineView> view)
+{
+ QtWebEngineCore::ProfileAdapter *profileAdapter = view->d_ptr->profileAdapter();
+ bool touchIconsEnabled = view->profile()->settings()->touchIconsEnabled();
+ if (isIconURL(m_imageSource)) {
+ profileAdapter->requestIconForIconURL(
+ m_imageSource, qMax(m_requestedSize.width(), m_requestedSize.height()),
+ touchIconsEnabled, [this](const QIcon &icon, const QUrl &) {
+ QMetaObject::invokeMethod(this, "iconRequestDone", Qt::QueuedConnection,
+ Q_ARG(const QIcon &, icon));
+ });
+ } else {
+ profileAdapter->requestIconForPageURL(
+ m_imageSource, qMax(m_requestedSize.width(), m_requestedSize.height()),
+ touchIconsEnabled, [this](const QIcon &icon, const QUrl &, const QUrl &) {
+ QMetaObject::invokeMethod(this, "iconRequestDone", Qt::QueuedConnection,
+ Q_ARG(const QIcon &, icon));
+ });
+ }
}
-int FaviconImageResponseRunnable::tryNextView()
+QPointer<QQuickWebEngineView> FaviconImageRequester::getNextViewForProcessing()
{
- for (; m_nextViewIndex < m_views->size(); ++m_nextViewIndex) {
- QQuickWebEngineView *view = m_views->at(m_nextViewIndex);
+ Q_ASSERT(QThread::currentThread() == QCoreApplication::instance()->thread());
+
+ for (QPointer<QQuickWebEngineView> view : FaviconProviderHelper::instance()->views()) {
+ if (view.isNull())
+ continue;
if (view->profile()->isOffTheRecord())
continue;
+ if (m_processedViews.contains(view))
+ continue;
+ m_processedViews.append(view);
+ return view;
+ }
+ return nullptr;
+}
- requestIconOnUIThread(view);
+FaviconProviderHelper::FaviconProviderHelper()
+{
+ moveToThread(qApp->thread());
+}
- return m_nextViewIndex++;
- }
+FaviconProviderHelper *FaviconProviderHelper::instance()
+{
+ static FaviconProviderHelper instance;
+ return &instance;
+}
- return -1;
+void FaviconProviderHelper::attach(QPointer<QQuickWebEngineView> view)
+{
+ if (!m_views.contains(view))
+ m_views.append(view);
}
-void FaviconImageResponseRunnable::requestIconOnUIThread(QQuickWebEngineView *view)
+void FaviconProviderHelper::detach(QPointer<QQuickWebEngineView> view)
{
- QTimer *timer = new QTimer();
- timer->moveToThread(qApp->thread());
- timer->setSingleShot(true);
- QObject::connect(timer, &QTimer::timeout, [this, view, timer]() {
- QtWebEngineCore::ProfileAdapter *profileAdapter = view->d_ptr->profileAdapter();
- bool touchIconsEnabled = view->profile()->settings()->touchIconsEnabled();
- if (isIconURL(QUrl(m_id))) {
- profileAdapter->requestIconForIconURL(QUrl(m_id),
- qMax(m_requestedSize.width(), m_requestedSize.height()),
- touchIconsEnabled,
- [this](const QIcon &icon, const QUrl &) { iconRequestDone(icon); });
- } else {
- profileAdapter->requestIconForPageURL(QUrl(m_id),
- qMax(m_requestedSize.width(), m_requestedSize.height()),
- touchIconsEnabled,
- [this](const QIcon &icon, const QUrl &, const QUrl &) { iconRequestDone(icon); });
- }
- timer->deleteLater();
- });
- QMetaObject::invokeMethod(timer, "start", Qt::QueuedConnection, Q_ARG(int, 0));
+ m_views.removeAll(view);
}
-FaviconImageResponse::FaviconImageResponse()
+void FaviconProviderHelper::handleImageRequest(QPointer<FaviconImageResponse> faviconResponse)
{
- Q_EMIT finished();
+ Q_ASSERT(QThread::currentThread() == QCoreApplication::instance()->thread());
+
+ if (faviconResponse.isNull())
+ return;
+
+ if (m_views.isEmpty()) {
+ QMetaObject::invokeMethod(faviconResponse, "handleDone", Qt::QueuedConnection,
+ Q_ARG(QPixmap, QPixmap()));
+ return;
+ }
+
+ auto view = findViewByImageSource(faviconResponse->imageSource());
+ if (view) {
+ QIcon icon = view->d_ptr->adapter->icon();
+ if (!icon.isNull()) {
+ QMetaObject::invokeMethod(
+ faviconResponse, "handleDone", Qt::QueuedConnection,
+ Q_ARG(QPixmap, extractPixmap(icon, faviconResponse->requestedSize())));
+ return;
+ }
+ }
+ startFaviconRequest(faviconResponse);
}
-FaviconImageResponse::FaviconImageResponse(const QString &id, const QSize &requestedSize,
- QList<QQuickWebEngineView *> *views, QThreadPool *pool)
+QPointer<QQuickWebEngineView> FaviconProviderHelper::findViewByImageSource(const QUrl &imageSource) const
{
- if (QQuickWebEngineView *view = findViewById(id, views)) {
- QTimer *timer = new QTimer();
- timer->moveToThread(qApp->thread());
- timer->setSingleShot(true);
- QObject::connect(timer, &QTimer::timeout, [this, id, requestedSize, views, pool, view, timer]() {
- QIcon icon = view->d_ptr->adapter->icon();
- if (icon.isNull())
- startRunnable(id, requestedSize, views, pool);
- else
- handleDone(extractPixmap(icon, requestedSize).copy());
- timer->deleteLater();
- });
- QMetaObject::invokeMethod(timer, "start", Qt::QueuedConnection, Q_ARG(int, 0));
- } else {
- startRunnable(id, requestedSize, views, pool);
+ for (QPointer<QQuickWebEngineView> view : m_views) {
+ if (view.isNull())
+ continue;
+
+ if (isIconURL(imageSource)) {
+ if (view->icon() == QQuickWebEngineFaviconProvider::faviconProviderUrl(imageSource)) {
+ return view;
+ }
+ } else if (view->url() == imageSource) {
+ return view;
+ }
}
+
+ return nullptr;
}
-FaviconImageResponse::~FaviconImageResponse() { }
+void FaviconProviderHelper::startFaviconRequest(QPointer<FaviconImageResponse> faviconResponse)
+{
+ FaviconImageRequester *requester = new FaviconImageRequester(faviconResponse->imageSource(),
+ faviconResponse->requestedSize());
+
+ connect(requester, &FaviconImageRequester::done, [requester, faviconResponse](QPixmap pixmap) {
+ QMetaObject::invokeMethod(faviconResponse, "handleDone", Qt::QueuedConnection,
+ Q_ARG(QPixmap, pixmap));
+ requester->deleteLater();
+ });
+
+ requester->start();
+}
+
+FaviconImageResponse::FaviconImageResponse(const QUrl &imageSource, const QSize &requestedSize)
+ : m_imageSource(imageSource), m_requestedSize(requestedSize)
+{
+}
void FaviconImageResponse::handleDone(QPixmap pixmap)
{
- if (m_runnable)
- delete m_runnable;
m_image = pixmap.toImage();
Q_EMIT finished();
}
@@ -205,16 +249,6 @@ QQuickTextureFactory *FaviconImageResponse::textureFactory() const
return QQuickTextureFactory::textureFactoryForImage(m_image);
}
-void FaviconImageResponse::startRunnable(const QString &id, const QSize &requestedSize,
- QList<QQuickWebEngineView *> *views, QThreadPool *pool)
-{
- m_runnable = new FaviconImageResponseRunnable(id, requestedSize, views);
- m_runnable->setAutoDelete(false);
- connect(m_runnable, &FaviconImageResponseRunnable::done, this,
- &FaviconImageResponse::handleDone);
- pool->start(m_runnable);
-}
-
QString QQuickWebEngineFaviconProvider::identifier()
{
return QStringLiteral("favicon");
@@ -238,17 +272,17 @@ QUrl QQuickWebEngineFaviconProvider::faviconProviderUrl(const QUrl &url)
return providerUrl;
}
-QQuickWebEngineFaviconProvider::QQuickWebEngineFaviconProvider() { }
-
-QQuickWebEngineFaviconProvider::~QQuickWebEngineFaviconProvider() { }
+QQuickWebEngineFaviconProvider::QQuickWebEngineFaviconProvider()
+{
+ connect(this, &QQuickWebEngineFaviconProvider::imageResponseRequested,
+ FaviconProviderHelper::instance(), &FaviconProviderHelper::handleImageRequest);
+}
QQuickImageResponse *
QQuickWebEngineFaviconProvider::requestImageResponse(const QString &id, const QSize &requestedSize)
{
- if (m_views.empty())
- return new FaviconImageResponse;
-
- FaviconImageResponse *response = new FaviconImageResponse(id, requestedSize, &m_views, &m_pool);
+ FaviconImageResponse *response = new FaviconImageResponse(QUrl(id), requestedSize);
+ emit imageResponseRequested(response);
return response;
}
diff --git a/src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h b/src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h
index 89bfb6e73..f1d948413 100644
--- a/src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h
+++ b/src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h
@@ -17,8 +17,6 @@
#include <QtWebEngineQuick/private/qtwebenginequickglobal_p.h>
#include <QtCore/qlist.h>
-#include <QtCore/qrunnable.h>
-#include <QtCore/qthreadpool.h>
#include <QtGui/qimage.h>
#include <QtQuick/qquickimageprovider.h>
@@ -26,65 +24,84 @@ QT_BEGIN_NAMESPACE
class QQuickWebEngineView;
-class FaviconImageResponseRunnable : public QObject, public QRunnable
+class FaviconImageResponse : public QQuickImageResponse
{
Q_OBJECT
public:
- FaviconImageResponseRunnable(const QString &id, const QSize &requestedSize,
- QList<QQuickWebEngineView *> *views);
- void run() override;
- void iconRequestDone(const QIcon &icon);
+ FaviconImageResponse(const QUrl &imageSource, const QSize &requestedSize);
-signals:
- void done(QPixmap pixmap);
+ QQuickTextureFactory *textureFactory() const override;
+ const QUrl &imageSource() const { return m_imageSource; }
+ const QSize &requestedSize() const { return m_requestedSize; }
-private:
- int tryNextView();
- void requestIconOnUIThread(QQuickWebEngineView *view);
+public slots:
+ void handleDone(QPixmap pixmap);
- QString m_id;
+private:
+ QImage m_image;
+ QUrl m_imageSource;
QSize m_requestedSize;
- QList<QQuickWebEngineView *> *m_views;
- int m_nextViewIndex = 0;
};
-class FaviconImageResponse : public QQuickImageResponse
+class FaviconImageRequester : public QObject
{
+ Q_OBJECT
+
public:
- FaviconImageResponse();
- FaviconImageResponse(const QString &id, const QSize &requestedSize,
- QList<QQuickWebEngineView *> *views, QThreadPool *pool);
- ~FaviconImageResponse();
- void handleDone(QPixmap pixmap);
- QQuickTextureFactory *textureFactory() const override;
+ FaviconImageRequester(const QUrl &imageSource, const QSize &requestedSize);
+ void start();
+
+public slots:
+ void iconRequestDone(const QIcon &icon);
+
+signals:
+ void done(QPixmap pixmap);
private:
- void startRunnable(const QString &id, const QSize &requestedSize,
- QList<QQuickWebEngineView *> *views, QThreadPool *pool);
+ bool tryNextView();
+ void requestFaviconFromDatabase(QPointer<QQuickWebEngineView> view);
+ QPointer<QQuickWebEngineView> getNextViewForProcessing();
- FaviconImageResponseRunnable *m_runnable = nullptr;
- QImage m_image;
+ QUrl m_imageSource;
+ QSize m_requestedSize;
+ QList<QPointer<QQuickWebEngineView>> m_processedViews;
};
class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineFaviconProvider : public QQuickAsyncImageProvider
{
+ Q_OBJECT
+
public:
static QString identifier();
static QUrl faviconProviderUrl(const QUrl &);
QQuickWebEngineFaviconProvider();
- ~QQuickWebEngineFaviconProvider();
-
- void attach(QQuickWebEngineView *view) { m_views.append(view); }
- void detach(QQuickWebEngineView *view) { m_views.removeAll(view); }
-
QQuickImageResponse *requestImageResponse(const QString &id,
const QSize &requestedSize) override;
+signals:
+ void imageResponseRequested(QPointer<FaviconImageResponse> faviconResponse);
+};
+
+class Q_WEBENGINEQUICK_EXPORT FaviconProviderHelper : public QObject
+{
+ Q_OBJECT
+
+public:
+ static FaviconProviderHelper *instance();
+ void attach(QPointer<QQuickWebEngineView> view);
+ void detach(QPointer<QQuickWebEngineView> view);
+ const QList<QPointer<QQuickWebEngineView>> &views() const { return m_views; }
+
+public slots:
+ void handleImageRequest(QPointer<FaviconImageResponse> faviconResponse);
+
private:
- QThreadPool m_pool;
- QList<QQuickWebEngineView *> m_views;
+ FaviconProviderHelper();
+ void startFaviconRequest(QPointer<FaviconImageResponse> faviconResponse);
+ QPointer<QQuickWebEngineView> findViewByImageSource(const QUrl &imageSource) const;
+ QList<QPointer<QQuickWebEngineView>> m_views;
};
QT_END_NAMESPACE
diff --git a/src/webenginequick/api/qquickwebengineforeigntypes_p.h b/src/webenginequick/api/qquickwebengineforeigntypes_p.h
index 2d205254e..58dee066f 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
@@ -231,6 +232,39 @@ struct ForeignWebEngineWebAuthUxRequest
QML_UNCREATABLE("")
};
+struct ForeginWebEngineWebAuthPinRequest
+{
+ Q_GADGET
+ QML_FOREIGN(QWebEngineWebAuthPinRequest)
+ QML_NAMED_ELEMENT(WebEngineWebAuthPinRequest)
+ QML_ADDED_IN_VERSION(6, 8)
+ 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/qquickwebengineprofile.cpp b/src/webenginequick/api/qquickwebengineprofile.cpp
index 7c3d11fcf..d3373d0b9 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>
@@ -95,6 +96,28 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \enum QQuickWebEngineProfile::PersistentPermissionsPolicy
+
+ \since 6.8
+
+ This enum describes the policy for permission persistence:
+
+ \value NoPersistentPermissions
+ 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
+ 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
+ Works the same way as \c PersistentPermissionsInMemory, but the permissions are saved to
+ and restored from disk. This is the default setting.
+*/
+
+/*!
\fn QQuickWebEngineProfile::downloadRequested(QQuickWebEngineDownloadRequest *download)
This signal is emitted whenever a download has been triggered.
@@ -105,6 +128,8 @@ QT_BEGIN_NAMESPACE
The download item is parented by the profile. If it is not accepted, it
will be deleted immediately after the signal emission.
This signal cannot be used with a queued connection.
+
+ \note To use from C++ static_cast \a download to QWebEngineDownloadRequest
*/
/*!
@@ -113,6 +138,8 @@ QT_BEGIN_NAMESPACE
This signal is emitted whenever downloading stops, because it finished successfully, was
cancelled, or was interrupted (for example, because connectivity was lost).
The \a download argument holds the state of the finished download instance.
+
+ \note To use from C++ static_cast \a download to QWebEngineDownloadRequest
*/
/*!
@@ -431,15 +458,18 @@ void QQuickWebEngineProfile::setStorageName(const QString &name)
if (d->profileAdapter()->storageName() == name)
return;
ProfileAdapter::HttpCacheType oldCacheType = d->profileAdapter()->httpCacheType();
- ProfileAdapter::PersistentCookiesPolicy oldPolicy = d->profileAdapter()->persistentCookiesPolicy();
+ ProfileAdapter::PersistentCookiesPolicy oldCookiePolicy = d->profileAdapter()->persistentCookiesPolicy();
+ ProfileAdapter::PersistentPermissionsPolicy oldPermissionsPolicy = d->profileAdapter()->persistentPermissionsPolicy();
d->profileAdapter()->setStorageName(name);
emit storageNameChanged();
emit persistentStoragePathChanged();
emit cachePathChanged();
if (d->profileAdapter()->httpCacheType() != oldCacheType)
emit httpCacheTypeChanged();
- if (d->profileAdapter()->persistentCookiesPolicy() != oldPolicy)
+ if (d->profileAdapter()->persistentCookiesPolicy() != oldCookiePolicy)
emit persistentCookiesPolicyChanged();
+ if (d->profileAdapter()->persistentPermissionsPolicy() != oldPermissionsPolicy)
+ emit persistentPermissionsPolicyChanged();
}
/*!
@@ -471,13 +501,16 @@ void QQuickWebEngineProfile::setOffTheRecord(bool offTheRecord)
if (d->profileAdapter()->isOffTheRecord() == offTheRecord)
return;
ProfileAdapter::HttpCacheType oldCacheType = d->profileAdapter()->httpCacheType();
- ProfileAdapter::PersistentCookiesPolicy oldPolicy = d->profileAdapter()->persistentCookiesPolicy();
+ ProfileAdapter::PersistentCookiesPolicy oldCookiePolicy = d->profileAdapter()->persistentCookiesPolicy();
+ ProfileAdapter::PersistentPermissionsPolicy oldPermissionsPolicy = d->profileAdapter()->persistentPermissionsPolicy();
d->profileAdapter()->setOffTheRecord(offTheRecord);
emit offTheRecordChanged();
if (d->profileAdapter()->httpCacheType() != oldCacheType)
emit httpCacheTypeChanged();
- if (d->profileAdapter()->persistentCookiesPolicy() != oldPolicy)
+ if (d->profileAdapter()->persistentCookiesPolicy() != oldCookiePolicy)
emit persistentCookiesPolicyChanged();
+ if (d->profileAdapter()->persistentPermissionsPolicy() != oldPermissionsPolicy)
+ emit persistentPermissionsPolicyChanged();
}
/*!
@@ -624,7 +657,7 @@ void QQuickWebEngineProfile::setHttpCacheType(QQuickWebEngineProfile::HttpCacheT
/*!
\qmlproperty enumeration WebEngineProfile::persistentCookiesPolicy
- This enumeration describes the policy of cookie persistency:
+ This enumeration describes the policy of cookie persistence:
\value WebEngineProfile.NoPersistentCookies
Both session and persistent cookies are stored in memory. This is the only setting
@@ -660,6 +693,51 @@ void QQuickWebEngineProfile::setPersistentCookiesPolicy(QQuickWebEngineProfile::
}
/*!
+ \qmlproperty enumeration WebEngineProfile::persistentPermissionsPolicy
+
+ \since 6.8
+
+ This enumeration describes the policy for permission persistence:
+
+ \value WebEngineProfile.NoPersistentPermissions
+ 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
+ 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
+ Works the same way as \c PersistentPermissionsInMemory, but the permissions are saved to
+ and restored from disk. This is the default setting.
+*/
+
+/*!
+ \property QQuickWebEngineProfile::persistentPermissionsPolicy
+ \since 6.8
+
+ Describes the policy of permission persistence.
+ If the profile is off-the-record, NoPersistentCookies is returned.
+*/
+
+QQuickWebEngineProfile::PersistentPermissionsPolicy QQuickWebEngineProfile::persistentPermissionsPolicy() const
+{
+ Q_D(const QQuickWebEngineProfile);
+ return QQuickWebEngineProfile::PersistentPermissionsPolicy(d->profileAdapter()->persistentPermissionsPolicy());
+}
+
+void QQuickWebEngineProfile::setPersistentPermissionsPolicy(QQuickWebEngineProfile::PersistentPermissionsPolicy newPersistentPermissionsPolicy)
+{
+ Q_D(QQuickWebEngineProfile);
+ ProfileAdapter::PersistentPermissionsPolicy oldPolicy = d->profileAdapter()->persistentPermissionsPolicy();
+ d->profileAdapter()->setPersistentPermissionsPolicy(ProfileAdapter::PersistentPermissionsPolicy(newPersistentPermissionsPolicy));
+ if (d->profileAdapter()->persistentPermissionsPolicy() != oldPolicy)
+ emit persistentPermissionsPolicyChanged();
+}
+
+/*!
\qmlproperty int WebEngineProfile::httpCacheMaximumSize
The maximum size of the HTTP cache. If \c 0, the size will be controlled automatically by
@@ -1036,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 088a971e0..186a11d7b 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>
@@ -33,6 +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(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))
@@ -61,6 +63,13 @@ public:
};
Q_ENUM(PersistentCookiesPolicy)
+ enum PersistentPermissionsPolicy : quint8 {
+ NoPersistentPermissions,
+ PersistentPermissionsInMemory,
+ PersistentPermissionsOnDisk,
+ };
+ Q_ENUM(PersistentPermissionsPolicy)
+
QString storageName() const;
void setStorageName(const QString &name);
@@ -82,6 +91,9 @@ public:
PersistentCookiesPolicy persistentCookiesPolicy() const;
void setPersistentCookiesPolicy(QQuickWebEngineProfile::PersistentCookiesPolicy);
+ PersistentPermissionsPolicy persistentPermissionsPolicy() const;
+ void setPersistentPermissionsPolicy(QQuickWebEngineProfile::PersistentPermissionsPolicy);
+
int httpCacheMaximumSize() const;
void setHttpCacheMaximumSize(int maxSize);
@@ -116,6 +128,11 @@ public:
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:
@@ -133,6 +150,7 @@ Q_SIGNALS:
Q_REVISION(1,5) void downloadPathChanged();
Q_REVISION(6,5) void pushServiceEnabledChanged();
Q_REVISION(6,7) void clearHttpCacheCompleted();
+ Q_REVISION(6,8) void persistentPermissionsPolicyChanged();
void downloadRequested(QQuickWebEngineDownloadRequest *download);
void downloadFinished(QQuickWebEngineDownloadRequest *download);
@@ -144,7 +162,7 @@ private:
QQuickWebEngineSettings *settings() const;
void ensureQmlContext(const QObject *object);
- friend class FaviconImageResponseRunnable;
+ friend class FaviconImageRequester;
friend class QQuickWebEngineSingleton;
friend class QQuickWebEngineViewPrivate;
friend class QQuickWebEngineView;
diff --git a/src/webenginequick/api/qquickwebenginesettings.cpp b/src/webenginequick/api/qquickwebenginesettings.cpp
index 31ed7a661..5dc093a44 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 89cdd20ca..852d00c76 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>
@@ -332,8 +334,7 @@ QQuickWebEngineViewPrivate::~QQuickWebEngineViewPrivate()
{
Q_ASSERT(m_profileInitialized);
m_profile->d_ptr->removeWebContentsAdapterClient(this);
- if (m_faviconProvider)
- m_faviconProvider->detach(q_ptr);
+ FaviconProviderHelper::instance()->detach(q_ptr);
bindViewAndDelegateItem(this, nullptr);
}
@@ -485,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)
@@ -573,6 +612,12 @@ void QQuickWebEngineViewPrivate::iconChanged(const QUrl &url)
QTimer::singleShot(0, q, &QQuickWebEngineView::iconChanged);
}
+void QQuickWebEngineViewPrivate::zoomFactorChanged(qreal factor)
+{
+ Q_Q(QQuickWebEngineView);
+ Q_EMIT q->zoomFactorChanged(factor);
+}
+
void QQuickWebEngineViewPrivate::loadProgressChanged(int progress)
{
Q_Q(QQuickWebEngineView);
@@ -779,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 = QQuickWebEngineView::DesktopVideoCapture;
- Q_EMIT q->featurePermissionRequested(securityOrigin, feature);
+ 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))
+ deprecatedFeature = QQuickWebEngineView::DesktopVideoCapture;
+
+ Q_EMIT q->featurePermissionRequested(securityOrigin, deprecatedFeature);
+ QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 8)
}
void QQuickWebEngineViewPrivate::runMouseLockPermissionRequest(const QUrl &securityOrigin)
@@ -837,6 +904,14 @@ void QQuickWebEngineViewPrivate::printRequested()
});
}
+void QQuickWebEngineViewPrivate::printRequestedByFrame(quint64 frameId)
+{
+ Q_Q(QQuickWebEngineView);
+ QTimer::singleShot(0, q, [this, q, frameId]() {
+ Q_EMIT q->printRequestedByFrame(QWebEngineFrame(this, frameId));
+ });
+}
+
void QQuickWebEngineViewPrivate::findTextFinished(const QWebEngineFindTextResult &result)
{
Q_Q(QQuickWebEngineView);
@@ -951,16 +1026,7 @@ void QQuickWebEngineViewPrivate::ensureContentsAdapter()
adapter->loadDefault();
}
- if (!m_faviconProvider) {
- QQmlEngine *engine = qmlEngine(q_ptr);
- // TODO: this is a workaround for QTBUG-65044
- if (!engine)
- return;
- m_faviconProvider = static_cast<QQuickWebEngineFaviconProvider *>(
- engine->imageProvider(QQuickWebEngineFaviconProvider::identifier()));
- m_faviconProvider->attach(q_ptr);
- Q_ASSERT(m_faviconProvider);
- }
+ FaviconProviderHelper::instance()->attach(q_ptr);
}
void QQuickWebEngineViewPrivate::initializationFinished()
@@ -1235,7 +1301,6 @@ void QQuickWebEngineView::setZoomFactor(qreal arg)
d->adapter->setZoomFactor(arg);
// MEMO: should reset if factor was not applied due to being invalid
d->m_zoomFactor = zoomFactor();
- emit zoomFactorChanged(d->m_zoomFactor);
} else {
d->m_zoomFactor = arg;
}
@@ -1306,22 +1371,26 @@ bool QQuickWebEngineView::activeFocusOnPress() const
return d->m_activeFocusOnPress;
}
-void QQuickWebEngineViewPrivate::didRunJavaScript(quint64 requestId, const QVariant &result)
+void QQuickWebEngineViewPrivate::runJavaScript(
+ const QString &script, quint32 worldId, quint64 frameId,
+ const std::function<void(const QVariant &)> &callback)
{
- Q_Q(QQuickWebEngineView);
- QJSValue callback = m_callbacks.take(requestId);
- QJSValueList args;
- args.append(qmlEngine(q)->toScriptValue(result));
- callback.call(args);
+ ensureContentsAdapter();
+ adapter->runJavaScript(script, worldId, frameId, callback);
}
-void QQuickWebEngineViewPrivate::didPrintPage(quint64 requestId, QSharedPointer<QByteArray> result)
+void QQuickWebEngineViewPrivate::printToPdf(const QString &filePath, const QPageLayout &layout,
+ const QPageRanges &ranges, quint64 frameId)
{
- Q_Q(QQuickWebEngineView);
- QJSValue callback = m_callbacks.take(requestId);
- QJSValueList args;
- args.append(qmlEngine(q)->toScriptValue(*(result.data())));
- callback.call(args);
+ adapter->printToPDF(layout, ranges, filePath, frameId);
+}
+
+void QQuickWebEngineViewPrivate::printToPdf(
+ std::function<void(QSharedPointer<QByteArray>)> &&callback, const QPageLayout &layout,
+ const QPageRanges &ranges, quint64 frameId)
+{
+ adapter->printToPDFCallbackResult(std::move(callback), layout, ranges, /*colorMode*/ true,
+ /*useCustomMargins*/ true, frameId);
}
void QQuickWebEngineViewPrivate::didPrintPageToPdf(const QString &filePath, bool success)
@@ -1459,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);
@@ -1497,16 +1572,15 @@ void QQuickWebEngineView::runJavaScript(const QString &script, const QJSValue &c
void QQuickWebEngineView::runJavaScript(const QString &script, quint32 worldId, const QJSValue &callback)
{
Q_D(QQuickWebEngineView);
- d->ensureContentsAdapter();
+ std::function<void(const QVariant &)> wrappedCallback;
if (!callback.isUndefined()) {
- quint64 requestId = d_ptr->adapter->runJavaScriptCallbackResult(script, worldId);
- if (requestId) {
- d->m_callbacks.insert(requestId, callback);
- } else {
- callback.call();
- }
- } else
- d->adapter->runJavaScript(script, worldId);
+ wrappedCallback = [this, callback](const QVariant &result) {
+ QJSValueList args;
+ args.append(qmlEngine(this)->toScriptValue(result));
+ callback.call(args);
+ };
+ }
+ d->runJavaScript(script, worldId, WebContentsAdapter::kUseMainFrameId, wrappedCallback);
}
qreal QQuickWebEngineView::zoomFactor() const
@@ -1581,7 +1655,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);
@@ -1602,8 +1676,14 @@ void QQuickWebEngineView::printToPdf(const QJSValue &callback, PrintedPageSizeId
return;
d->ensureContentsAdapter();
- quint64 requestId = d->adapter->printToPDFCallbackResult(pageLayout, ranges);
- d->m_callbacks.insert(requestId, callback);
+ std::function wrappedCallback = [this, callback](QSharedPointer<QByteArray> result) {
+ QJSValueList args;
+ args.append(qmlEngine(this)->toScriptValue(*result));
+ callback.call(args);
+ };
+
+ d->printToPdf(std::move(wrappedCallback), pageLayout, ranges,
+ WebContentsAdapter::kUseMainFrameId);
#else
Q_UNUSED(pageSizeId);
Q_UNUSED(orientation);
@@ -1749,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)
{
@@ -2529,6 +2603,19 @@ QQmlComponent *QQuickWebEngineView::touchHandleDelegate() const
return d_ptr->m_touchHandleDelegate;
}
+QWebEngineFrame QQuickWebEngineView::mainFrame()
+{
+ Q_D(QQuickWebEngineView);
+ return QWebEngineFrame(d, 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));
+}
+
void QQuickWebEngineView::save(const QString &filePath,
QWebEngineDownloadRequest::SavePageFormat format) const
{
diff --git a/src/webenginequick/api/qquickwebengineview_p.h b/src/webenginequick/api/qquickwebengineview_p.h
index 0fdd9f787..ea09dff9f 100644
--- a/src/webenginequick/api/qquickwebengineview_p.h
+++ b/src/webenginequick/api/qquickwebengineview_p.h
@@ -19,6 +19,8 @@
#include <QtWebEngineCore/qwebenginequotarequest.h>
#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>
@@ -91,6 +93,7 @@ class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineView : public QQuickItem {
Q_PROPERTY(qint64 renderProcessPid READ renderProcessPid NOTIFY renderProcessPidChanged FINAL REVISION(1,11))
Q_PROPERTY(QQmlComponent *touchHandleDelegate READ touchHandleDelegate WRITE
setTouchHandleDelegate NOTIFY touchHandleDelegateChanged REVISION(0) FINAL)
+ Q_PROPERTY(QWebEngineFrame mainFrame READ mainFrame FINAL REVISION(6, 8))
QML_NAMED_ELEMENT(WebEngineView)
QML_ADDED_IN_VERSION(1, 0)
QML_EXTRA_VERSION(2, 0)
@@ -164,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,
@@ -177,6 +184,8 @@ QT_WARNING_POP
LocalFontsAccess,
};
Q_ENUM(Feature)
+QT_WARNING_POP
+#endif
enum WebAction {
NoWebAction = - 1,
@@ -472,6 +481,9 @@ QT_WARNING_POP
QQmlComponent *touchHandleDelegate() const;
void setTouchHandleDelegate(QQmlComponent *delegagte);
+ QWebEngineFrame mainFrame();
+ Q_REVISION(6, 8) Q_INVOKABLE QWebEngineFrame findFrameByName(const QString &name);
+
public Q_SLOTS:
void runJavaScript(const QString&, const QJSValue & = QJSValue());
Q_REVISION(1,3) void runJavaScript(const QString&, quint32 worldId, const QJSValue & = QJSValue());
@@ -484,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);
@@ -510,9 +532,19 @@ Q_SIGNALS:
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();
@@ -556,6 +588,8 @@ Q_SIGNALS:
Q_REVISION(6,4) void fileSystemAccessRequested(const QWebEngineFileSystemAccessRequest &request);
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;
@@ -572,8 +606,8 @@ private:
QScopedPointer<QQuickWebEngineViewPrivate> d_ptr;
friend class QQuickContextMenuBuilder;
- friend class FaviconImageResponse;
- friend class FaviconImageResponseRunnable;
+ friend class FaviconProviderHelper;
+ friend class FaviconImageRequester;
#if QT_CONFIG(accessibility)
friend class QQuickWebEngineViewAccessible;
#endif // QT_CONFIG(accessibility)
diff --git a/src/webenginequick/api/qquickwebengineview_p_p.h b/src/webenginequick/api/qquickwebengineview_p_p.h
index 58236bc58..e61f32bcb 100644
--- a/src/webenginequick/api/qquickwebengineview_p_p.h
+++ b/src/webenginequick/api/qquickwebengineview_p_p.h
@@ -37,7 +37,6 @@ class WebContentsAdapter;
QT_BEGIN_NAMESPACE
class QQmlComponent;
-class QQuickWebEngineFaviconProvider;
class QQuickWebEngineScriptCollection;
class QQuickWebEngineSettings;
class QQuickWebEngineView;
@@ -65,6 +64,7 @@ public:
void titleChanged(const QString&) override;
void urlChanged() override;
void iconChanged(const QUrl&) override;
+ void zoomFactorChanged(qreal factor) override;
void loadProgressChanged(int progress) override;
void didUpdateTargetURL(const QUrl&) override;
void selectionChanged() override;
@@ -93,10 +93,14 @@ public:
void runFileChooser(QSharedPointer<QtWebEngineCore::FilePickerController>) override;
void desktopMediaRequested(QtWebEngineCore::DesktopMediaController *) override;
void showColorDialog(QSharedPointer<QtWebEngineCore::ColorChooserController>) override;
- void didRunJavaScript(quint64, const QVariant&) override;
+ void runJavaScript(const QString &script, quint32 worldId, quint64 frameId,
+ const std::function<void(const QVariant &)> &callback) override;
void didFetchDocumentMarkup(quint64, const QString&) override { }
void didFetchDocumentInnerText(quint64, const QString&) override { }
- void didPrintPage(quint64 requestId, QSharedPointer<QByteArray>) 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, 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;
@@ -110,7 +114,7 @@ public:
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;
@@ -129,11 +133,13 @@ public:
QtWebEngineCore::ProfileAdapter *profileAdapter() override;
QtWebEngineCore::WebContentsAdapter *webContentsAdapter() override;
void printRequested() override;
+ void printRequestedByFrame(quint64 frameId) override;
void findTextFinished(const QWebEngineFindTextResult &result) override;
void showAutofillPopup(QtWebEngineCore::AutofillPopupController *controller,
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);
@@ -158,7 +164,6 @@ public:
bool m_fullscreenMode;
bool isLoading;
bool m_activeFocusOnPress;
- QMap<quint64, QJSValue> m_callbacks;
QQmlWebChannel *m_webChannel;
QPointer<QQuickWebEngineView> inspectedView;
QPointer<QQuickWebEngineView> devToolsView;
@@ -178,7 +183,6 @@ private:
bool m_profileInitialized;
QWebEngineContextMenuRequest *m_contextMenuRequest;
QScopedPointer<QQuickWebEngineScriptCollection> m_scriptCollection;
- QPointer<QQuickWebEngineFaviconProvider> m_faviconProvider;
QQmlComponent *m_touchHandleDelegate;
};
diff --git a/src/webenginequick/doc/src/webengine_permission.qdoc b/src/webenginequick/doc/src/webengine_permission.qdoc
new file mode 100644
index 000000000..f59f57fa0
--- /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/webengineframe.qdoc b/src/webenginequick/doc/src/webengineframe.qdoc
new file mode 100644
index 000000000..8f852501e
--- /dev/null
+++ b/src/webenginequick/doc/src/webengineframe.qdoc
@@ -0,0 +1,129 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \qmltype webEngineFrame
+ \instantiates QQuickWebEngineFrame
+ \brief webEngineFrame provides information about and control over a page frame.
+ \since 6.8
+ \ingroup qmlvaluetypes
+ \inqmlmodule QtWebEngine
+
+ A web engine frame represents a single frame within a web page, such as those created by
+ \c <frame> or \c <iframe> HTML elements.
+ An active \l WebEngineView has one or more frames arranged in a tree structure. The top-level
+ frame, the root of this tree, can be accessed through the view's \l {WebEngineView::mainFrame}
+ {mainFrame} property.
+
+ A frame's lifetime is, at most, as long as the \l WebEngineView object that produced it.
+ However, frames may be created and deleted spontaneously and dynamically, for example through
+ navigation and script execution.
+*/
+
+/*!
+ \qmlproperty bool webEngineFrame::isValid
+
+ Returns \c{true} if this object represents an existing frame; \c{false} otherwise.
+
+ Once a frame is invalid, it never becomes valid again.
+*/
+
+/*!
+ \qmlproperty string webEngineFrame::name
+
+ Returns the frame name; that is, what would be returned by \c window.name in JavaScript.
+
+ If the frame could not be found, returns an empty string.
+
+ \sa htmlName
+*/
+
+/*!
+ \qmlproperty string webEngineFrame::htmlName
+
+ Returns the value of the frame's \c name HTML attribute, or an empty string if it has none.
+
+ If the frame could not be found, returns an empty string.
+
+ \sa name
+*/
+
+/*!
+ \qmlproperty url webEngineFrame::url
+
+ Returns the URL of the content currently loaded in this frame.
+
+ If the frame could not be found, returns an empty URL.
+*/
+
+/*!
+ \qmlproperty size webEngineFrame::size
+
+ Returns the size of the frame within the viewport.
+
+ 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)
+
+ Runs the JavaScript code contained in \a script on this frame, without checking
+ whether the DOM of the page has been constructed.
+
+ To avoid conflicts with other scripts executed on the page, the world in
+ which the script is run is specified by \a worldId. The world ID values are
+ the same as provided by QWebEngineScript::ScriptWorldId, and between \c 0
+ and \c 256. If you leave out the \c world ID, the script is run in the
+ \c MainWorld.
+
+ The \a callback parameter is optional. If a callback function is provided, it will be
+ invoked after the script finishes running.
+ \code
+ frame.runJavaScript("document.title", function(result) { console.log(result); });
+ \endcode
+
+ Only plain data can be returned from JavaScript as the result value.
+ Supported data types include all of the JSON data types as well as, for
+ example, \c{Date} and \c{ArrayBuffer}. Unsupported data types include, for
+ example, \c{Function} and \c{Promise}.
+
+ The script will run in the same \e world as other scripts that are
+ part of the loaded site.
+
+ \warning Do not execute lengthy routines in the callback function, because it might block the
+ rendering of the web content.
+
+ 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/webenginequick/doc/src/webengineview_lgpl.qdoc b/src/webenginequick/doc/src/webengineview_lgpl.qdoc
index eeae34dcc..f7b17fa7b 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
@@ -367,6 +366,8 @@
/*!
\qmlmethod void WebEngineView::runJavaScript(string script, variant callback)
+ \qmlmethod void WebEngineView::runJavaScript(string script, int worldId, variant callback)
+
Runs the specified \a script in the content of the web view.
The \a callback parameter is optional. If a callback function is provided,
@@ -381,8 +382,10 @@
example, \c{Date} and \c{ArrayBuffer}. Unsupported data types include, for
example, \c{Function} and \c{Promise}.
- The script will run in the same \e world as other scripts that are
- part of the loaded site.
+ To avoid conflicts with other scripts executed on the page, the world in
+ which the script is run can be specified by \a worldId. The world ID must be
+ between \c 0 and \c 256. If you leave out the \c world ID, the script is
+ run in the \c MainWorld.
\warning Do not execute lengthy routines in the callback function, because it might block the
rendering of the web content.
@@ -441,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.
@@ -497,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.
@@ -505,6 +510,15 @@
*/
/*!
+ \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)
This signal is emitted when a page load begins, ends, or fails.
@@ -840,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:
@@ -1343,14 +1358,27 @@
\qmlsignal WebEngineView::printRequested
\since QtWebEngine 1.8
- This signal is emitted when the JavaScript \c{window.print()} method is called or the user pressed the print
- button of PDF viewer plugin.
+ This signal is emitted when the JavaScript \c{window.print()} method is called on the main
+ frame, or the user pressed the print button of PDF viewer plugin.
Typically, the signal handler can simply call printToPdf().
+ Since QtWebEngine 6.8, this signal is only emitted for the main frame, instead of being emitted
+ for any frame that requests printing.
+
\sa printToPdf
*/
/*!
+ \qmlsignal WebEngineView::printRequestedByFrame(webEngineFrame frame)
+ \since QtWebEngine 6.8
+
+ 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
+*/
+
+/*!
\qmlsignal WebEngineView::selectClientCertificate(WebEngineClientCertificateSelection clientCertificateSelection)
\since QtWebEngine 1.9
@@ -1551,6 +1579,23 @@
*/
/*!
+ \qmlproperty webEngineFrame WebEngineView::mainFrame
+ \since QtWebEngine 6.8
+
+ The main, top-level frame of the page. All other frames on this page are accessible
+ as children of the main frame.
+ */
+
+/*!
+ \qmlmethod webEngineFrame WebEngineView::findFrameByName(string name)
+ \since QtWebEngine 6.8
+
+ 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 an
+ \l{webEngineFrame::isValid}{invalid} frame.
+*/
+
+/*!
\qmlmethod void WebEngineView::save(const QString &filePath, QWebEngineDownloadRequest::SavePageFormat format)
\since QtWebEngine 6.6
@@ -1581,5 +1626,14 @@
\sa QWebEngineWebAuthUxRequest
*/
+/*!
+ \qmlsignal WebEngineView::zoomFactorChanged(qreal factor);
+ \since QtWebEngine 6.8
+
+ This signal is emitted whenever the zoom \a factor for the page changes.
+
+ \sa zoomFactor
+*/
+
\sa {WebEngine Qt Quick Custom Touch Handle Example}
*/
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index 5b47d67bf..ebb818cbd 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -30,6 +30,7 @@
#include <QStyle>
#include <QGuiApplication>
#include <QQuickWidget>
+#include <QtWidgets/private/qapplication_p.h>
#if QT_CONFIG(accessibility)
#include "qwebengine_accessible_p.h"
@@ -187,6 +188,8 @@ public:
{
auto parentWidget = QQuickWidget::parentWidget();
if (parentWidget) {
+ if (QApplicationPrivate::wheel_widget)
+ QApplicationPrivate::wheel_widget = nullptr;
QSpontaneKeyEvent::makeSpontaneous(ev);
qApp->notify(parentWidget, ev);
}
@@ -884,6 +887,12 @@ void QWebEngineViewPrivate::printRequested()
});
}
+void QWebEngineViewPrivate::printRequestedByFrame(QWebEngineFrame frame)
+{
+ Q_Q(QWebEngineView);
+ QTimer::singleShot(0, q, [q, frame]() { Q_EMIT q->printRequestedByFrame(frame); });
+}
+
bool QWebEngineViewPrivate::isVisible() const
{
Q_Q(const QWebEngineView);
@@ -1427,7 +1436,20 @@ void QWebEngineView::printToPdf(const std::function<void(const QByteArray&)> &re
button of PDF viewer plugin.
Typically, the signal handler can simply call print().
- \sa print()
+ Since 6.8, this signal is only emitted for the main frame, instead of being emitted
+ for any frame that requests printing.
+
+ \sa printRequestedByFrame(), print()
+*/
+
+/*!
+ \fn void QWebEngineView::printRequestedByFrame(QWebEngineFrame frame)
+ \since 6.8
+
+ 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(), print()
*/
/*!
@@ -1465,17 +1487,21 @@ void QWebEngineView::printToPdf(const std::function<void(const QByteArray&)> &re
void QWebEngineView::print(QPrinter *printer)
{
#if QT_CONFIG(webengine_printing_and_pdf)
- if (page()->d_ptr->currentPrinter) {
+ auto *dPage = page()->d_ptr.get();
+ if (dPage->currentPrinter) {
qWarning("Cannot print page on printer %ls: Already printing on a device.", qUtf16Printable(printer->printerName()));
return;
}
- page()->d_ptr->currentPrinter = printer;
- page()->d_ptr->ensureInitialized();
- page()->d_ptr->adapter->printToPDFCallbackResult(printer->pageLayout(),
- printer->pageRanges(),
- printer->colorMode() == QPrinter::Color,
- false);
+ dPage->currentPrinter = printer;
+ dPage->ensureInitialized();
+ std::function callback = [dPage](QSharedPointer<QByteArray> result) {
+ dPage->didPrintPage(std::move(result));
+ };
+ dPage->adapter->printToPDFCallbackResult(std::move(callback), printer->pageLayout(),
+ printer->pageRanges(),
+ printer->colorMode() == QPrinter::Color, false,
+ QtWebEngineCore::WebContentsAdapter::kUseMainFrameId);
#else
Q_UNUSED(printer);
Q_EMIT printFinished(false);
diff --git a/src/webenginewidgets/api/qwebengineview.h b/src/webenginewidgets/api/qwebengineview.h
index f93d61b12..008aaa032 100644
--- a/src/webenginewidgets/api/qwebengineview.h
+++ b/src/webenginewidgets/api/qwebengineview.h
@@ -114,6 +114,7 @@ Q_SIGNALS:
int exitCode);
void pdfPrintingFinished(const QString &filePath, bool success);
void printRequested();
+ void printRequestedByFrame(QWebEngineFrame frame);
void printFinished(bool success);
protected:
diff --git a/src/webenginewidgets/api/qwebengineview_p.h b/src/webenginewidgets/api/qwebengineview_p.h
index aa330ac23..389bc4a66 100644
--- a/src/webenginewidgets/api/qwebengineview_p.h
+++ b/src/webenginewidgets/api/qwebengineview_p.h
@@ -73,6 +73,7 @@ public:
void didPrintPage(QPrinter *&printer, QSharedPointer<QByteArray> result) override;
void didPrintPageToPdf(const QString &filePath, bool success) override;
void printRequested() override;
+ void printRequestedByFrame(QWebEngineFrame frame) override;
void showAutofillPopup(QtWebEngineCore::AutofillPopupController *controller,
const QRect &bounds, bool autoselectFirstSuggestion) override;
void hideAutofillPopup() override;